mirror of
https://github.com/vcmi/vcmi.git
synced 2024-12-24 22:14:36 +02:00
* CCallback battle calls are more safe now when there is no battle (may prevent some bugs)
* corrected some obstacles entries * removed two stack corruption bugs * a few tweaks in battle path/available hexes calculation (more of them is needed)
This commit is contained in:
parent
fd07f7f33e
commit
b42a7fa87b
@ -1419,10 +1419,11 @@ void CBattleInterface::hexLclicked(int whichOne)
|
||||
if(LOCPLINT->cb->battleGetStackByID(activeStack)->creature->isDoubleWide())
|
||||
{
|
||||
std::vector<int> acc = LOCPLINT->cb->battleGetAvailableHexes(activeStack, false);
|
||||
int shiftedDest = whichOne + (LOCPLINT->cb->battleGetStackByID(activeStack)->attackerOwned ? 1 : -1);
|
||||
if(vstd::contains(acc, whichOne))
|
||||
giveCommand(2,whichOne,activeStack);
|
||||
else
|
||||
giveCommand(2,whichOne + (LOCPLINT->cb->battleGetStackByID(activeStack)->attackerOwned ? 1 : -1),activeStack);
|
||||
else if(vstd::contains(acc, shiftedDest))
|
||||
giveCommand(2,shiftedDest,activeStack);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -486,6 +486,11 @@ CStack* CCallback::battleGetStackByPos(int pos)
|
||||
int CCallback::battleGetPos(int stack)
|
||||
{
|
||||
boost::shared_lock<boost::shared_mutex> lock(*gs->mx);
|
||||
if(!gs->curB)
|
||||
{
|
||||
tlog2<<"battleGetPos called when there is no battle!"<<std::endl;
|
||||
return -1;
|
||||
}
|
||||
for(size_t g=0; g<gs->curB->stacks.size(); ++g)
|
||||
{
|
||||
if(gs->curB->stacks[g]->ID == stack)
|
||||
@ -512,12 +517,21 @@ std::map<int, CStack> CCallback::battleGetStacks()
|
||||
|
||||
std::vector<CStack> CCallback::battleGetStackQueue()
|
||||
{
|
||||
if(!gs->curB)
|
||||
{
|
||||
tlog2<<"battleGetStackQueue called when there is not battle!"<<std::endl;
|
||||
return std::vector<CStack>();
|
||||
}
|
||||
return gs->curB->getStackQueue();
|
||||
}
|
||||
|
||||
CCreature CCallback::battleGetCreature(int number)
|
||||
{
|
||||
boost::shared_lock<boost::shared_mutex> lock(*gs->mx); //TODO use me?
|
||||
if(!gs->curB)
|
||||
{
|
||||
tlog2<<"battleGetCreature called when there is no battle!"<<std::endl;
|
||||
}
|
||||
for(size_t h=0; h<gs->curB->stacks.size(); ++h)
|
||||
{
|
||||
if(gs->curB->stacks[h]->ID == number) //creature found
|
||||
@ -533,13 +547,23 @@ CCreature CCallback::battleGetCreature(int number)
|
||||
std::vector<int> CCallback::battleGetAvailableHexes(int ID, bool addOccupiable)
|
||||
{
|
||||
boost::shared_lock<boost::shared_mutex> lock(*gs->mx);
|
||||
if(!gs->curB)
|
||||
{
|
||||
tlog2<<"battleGetAvailableHexes called when there is no battle!"<<std::endl;
|
||||
return std::vector<int>();
|
||||
}
|
||||
return gs->curB->getAccessibility(ID, addOccupiable);
|
||||
//return gs->battleGetRange(ID);
|
||||
}
|
||||
|
||||
bool CCallback::battleIsStackMine(int ID)
|
||||
{
|
||||
boost::shared_lock<boost::shared_mutex> lock(*gs->mx); //TODO use me ?
|
||||
boost::shared_lock<boost::shared_mutex> lock(*gs->mx);
|
||||
if(!gs->curB)
|
||||
{
|
||||
tlog2<<"battleIsStackMine called when there is no battle!"<<std::endl;
|
||||
return false;
|
||||
}
|
||||
for(size_t h=0; h<gs->curB->stacks.size(); ++h)
|
||||
{
|
||||
if(gs->curB->stacks[h]->ID == ID) //creature found
|
||||
@ -549,9 +573,9 @@ bool CCallback::battleIsStackMine(int ID)
|
||||
}
|
||||
bool CCallback::battleCanShoot(int ID, int dest)
|
||||
{
|
||||
boost::shared_lock<boost::shared_mutex> lock(*gs->mx); //TODO use me?
|
||||
boost::shared_lock<boost::shared_mutex> lock(*gs->mx);
|
||||
CStack *our = battleGetStackByID(ID), *dst = battleGetStackByPos(dest);
|
||||
if(!our || !dst) return false;
|
||||
if(!our || !dst || !gs->curB) return false;
|
||||
|
||||
for(size_t g=0; g<our->effects.size(); ++g)
|
||||
{
|
||||
|
@ -190,7 +190,8 @@ void BattleInfo::getAccessibilityMap(bool *accessibility, int stackToOmmit)
|
||||
std::vector<int> blocked = VLC->heroh->obstacles[obstacles[b].ID].getBlocked(obstacles[b].pos);
|
||||
for(int c=0; c<blocked.size(); ++c)
|
||||
{
|
||||
accessibility[blocked[c]] = false;
|
||||
if(blocked[c] >=0 && blocked[c] < BFIELD_SIZE)
|
||||
accessibility[blocked[c]] = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -199,23 +200,6 @@ void BattleInfo::getAccessibilityMapForTwoHex(bool *accessibility, bool atackerS
|
||||
bool mac[BFIELD_SIZE];
|
||||
getAccessibilityMap(mac,stackToOmmit);
|
||||
memcpy(accessibility,mac,BFIELD_SIZE);
|
||||
|
||||
|
||||
if(!addOccupiable)
|
||||
{
|
||||
for(int b=0; b<BFIELD_SIZE; ++b)
|
||||
{
|
||||
if( mac[b] && !(atackerSide ? mac[b-1] : mac[b+1]))
|
||||
{
|
||||
accessibility[b] = false;
|
||||
}
|
||||
}
|
||||
|
||||
//removing accessibility for side hexes
|
||||
for(int v=0; v<BFIELD_SIZE; ++v)
|
||||
if(atackerSide ? (v%BFIELD_WIDTH)==1 : (v%BFIELD_WIDTH)==(BFIELD_WIDTH - 2))
|
||||
accessibility[v] = false;
|
||||
}
|
||||
}
|
||||
void BattleInfo::makeBFS(int start, bool*accessibility, int *predecessor, int *dists) //both pointers must point to the at least 187-elements int arrays
|
||||
{
|
||||
@ -258,10 +242,53 @@ std::vector<int> BattleInfo::getAccessibility(int stackID, bool addOccupiable)
|
||||
|
||||
int pr[BFIELD_SIZE], dist[BFIELD_SIZE];
|
||||
makeBFS(s->position,ac,pr,dist);
|
||||
|
||||
if(s->creature->isDoubleWide())
|
||||
{
|
||||
if(!addOccupiable)
|
||||
{
|
||||
std::vector<int> rem;
|
||||
for(int b=0; b<BFIELD_SIZE; ++b)
|
||||
{
|
||||
if( ac[b] && !(s->attackerOwned ? ac[b-1] : ac[b+1]))
|
||||
{
|
||||
rem.push_back(b);
|
||||
}
|
||||
}
|
||||
|
||||
for(int g=0; g<rem.size(); ++g)
|
||||
{
|
||||
ac[rem[g]] = false;
|
||||
}
|
||||
|
||||
//removing accessibility for side hexes
|
||||
for(int v=0; v<BFIELD_SIZE; ++v)
|
||||
if(s->attackerOwned ? (v%BFIELD_WIDTH)==1 : (v%BFIELD_WIDTH)==(BFIELD_WIDTH - 2))
|
||||
ac[v] = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::vector<int> rem;
|
||||
for(int b=0; b<BFIELD_SIZE; ++b)
|
||||
{
|
||||
if( ac[b] && !ac[b-1] && !ac[b+1] && b%BFIELD_WIDTH != 0 && b%BFIELD_WIDTH != (BFIELD_WIDTH-1))
|
||||
{
|
||||
rem.push_back(b);
|
||||
}
|
||||
}
|
||||
|
||||
for(int g=0; g<rem.size(); ++g)
|
||||
{
|
||||
ac[rem[g]] = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for(int i=0;i<BFIELD_SIZE;i++)
|
||||
if(dist[i] <= s->speed())
|
||||
if(dist[i] <= s->speed() && ac[i])
|
||||
{
|
||||
ret.push_back(i);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
@ -1562,6 +1589,34 @@ int CGameState::battleGetBattlefieldType(int3 tile)
|
||||
else if(tile==int3() && !curB)
|
||||
return -1;
|
||||
|
||||
//std::vector < std::pair<const CGObjectInstance*,SDL_Rect> > & objs = CGI->mh->ttiles[tile.x][tile.y][tile.z].objects;
|
||||
//for(int g=0; g<objs.size(); ++g)
|
||||
//{
|
||||
// switch(objs[g].first->ID)
|
||||
// {
|
||||
// case 222: //clover field
|
||||
// return 19;
|
||||
// case 223: //cursed ground
|
||||
// return 22;
|
||||
// case 224: //evil fog
|
||||
// return 20;
|
||||
// case 225: //favourable winds
|
||||
// return 21;
|
||||
// case 226: //fiery fields
|
||||
// return 14;
|
||||
// case 227: //holy ground
|
||||
// return 18;
|
||||
// case 228: //lucid pools
|
||||
// return 17;
|
||||
// case 229: //magic clouds
|
||||
// return 16;
|
||||
// case 230: //magic plains
|
||||
// return 9;
|
||||
// case 231: //rocklands
|
||||
// return 15;
|
||||
// }
|
||||
//}
|
||||
|
||||
switch(map->terrain[tile.x][tile.y][tile.z].tertype)
|
||||
{
|
||||
case dirt:
|
||||
|
@ -20,12 +20,12 @@ BATTLE OBSTACLES
|
||||
73 OBCFS02.DEF XXLNXX 0000000000000000001000000
|
||||
74 OBCFS03.DEF NXXLNXX 0000000000000000001000000
|
||||
0 OBDINO1.DEF XX 1111110000000010000000100
|
||||
2 OBDINO2.DEF XXX 1111110000000010000000100
|
||||
2 OBDINO2.DEF LXXX 1111110000000010000000100
|
||||
1 OBDINO3.DEF XXLXX 1111110000000010000000100
|
||||
6 OBDRK01.DEF XX 1111110000000010000000100
|
||||
7 OBDRK02.DEF LXX 1111110000000010000000100
|
||||
8 OBDRK03.DEF X 1111110000000010000000100
|
||||
9 OBDRK04.DEF XX 1111110000000010000000100
|
||||
9 OBDRK04.DEF LXX 1111110000000010000000100
|
||||
10 OBDSH01.DEF XX 1111110000000010000000100
|
||||
93 OBDSM01.DEF NXXLNXXLNNXX 1100000000000000000000000
|
||||
17 OBDSM02.DEF XXLNX 1111100000000010000000100
|
||||
|
@ -241,18 +241,16 @@ void CGameHandler::changePrimSkill(int ID, int which, int val, bool abs)
|
||||
expert.insert(hero->secSkills[i].first);
|
||||
none.erase(hero->secSkills[i].first);
|
||||
}
|
||||
//first offered skill
|
||||
if(hero->secSkills.size() < hero->type->heroClass->skillLimit) //free skill slot
|
||||
{
|
||||
hlu.skills.push_back(hero->type->heroClass->chooseSecSkill(none)); //new skill
|
||||
}
|
||||
else if(basicAndAdv.size())
|
||||
else
|
||||
{
|
||||
int s = hero->type->heroClass->chooseSecSkill(basicAndAdv);
|
||||
hlu.skills.push_back(s);
|
||||
basicAndAdv.erase(s);
|
||||
}
|
||||
//second offered skill
|
||||
if(basicAndAdv.size())
|
||||
{
|
||||
hlu.skills.push_back(hero->type->heroClass->chooseSecSkill(basicAndAdv)); //new skill
|
||||
@ -261,21 +259,8 @@ void CGameHandler::changePrimSkill(int ID, int which, int val, bool abs)
|
||||
{
|
||||
hlu.skills.push_back(hero->type->heroClass->chooseSecSkill(none)); //new skill
|
||||
}
|
||||
|
||||
if(hlu.skills.size() > 1) //apply and ask for secondary skill
|
||||
{
|
||||
boost::function<void(ui32)> callback = boost::function<void(ui32)>(boost::bind(callWith<ui16>,hlu.skills,boost::function<void(ui16)>(boost::bind(&CGameHandler::changeSecSkill,this,ID,_1,1,0)),_1));
|
||||
applyAndAsk(&hlu,hero->tempOwner,callback); //call changeSecSkill with appropriate args when client responds
|
||||
}
|
||||
else if(hlu.skills.size() == 1) //apply, give only possible skill and send info
|
||||
{
|
||||
changeSecSkill(ID,hlu.skills.back(),1,false);
|
||||
sendAndApply(&hlu);
|
||||
}
|
||||
else //apply and send info
|
||||
{
|
||||
sendAndApply(&hlu);
|
||||
}
|
||||
boost::function<void(ui32)> callback = boost::function<void(ui32)>(boost::bind(callWith<ui16>,hlu.skills,boost::function<void(ui16)>(boost::bind(&CGameHandler::changeSecSkill,this,ID,_1,1,0)),_1));
|
||||
applyAndAsk(&hlu,hero->tempOwner,callback); //call changeSecSkill with appropriate args when client responds
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1544,10 +1529,15 @@ void CGameHandler::moveStack(int stack, int dest)
|
||||
|
||||
//initing necessary tables
|
||||
bool accessibility[BFIELD_SIZE];
|
||||
if(curStack->creature->isDoubleWide())
|
||||
gs->curB->getAccessibilityMapForTwoHex(accessibility,curStack->attackerOwned,curStack->ID);
|
||||
else
|
||||
gs->curB->getAccessibilityMap(accessibility,curStack->ID);
|
||||
std::vector<int> accessible = gs->curB->getAccessibility(curStack->ID, false);
|
||||
for(int b=0; b<BFIELD_SIZE; ++b)
|
||||
{
|
||||
accessibility[b] = false;
|
||||
}
|
||||
for(int g=0; g<accessible.size(); ++g)
|
||||
{
|
||||
accessibility[accessible[g]] = true;
|
||||
}
|
||||
|
||||
//shifting destination (if we have double wide stack and we can occupy dest but not be exactly there)
|
||||
if(!stackAtEnd && curStack->creature->isDoubleWide() && !accessibility[dest])
|
||||
@ -2047,7 +2037,8 @@ void CGameHandler::setupBattle( BattleInfo * curB, int3 tile, CCreatureSet &army
|
||||
curB->obstacles.push_back(coi);
|
||||
for(int b=0; b<block.size(); ++b)
|
||||
{
|
||||
obAv[block[b]] = false;
|
||||
if(block[b] >= 0 && block[b] < BFIELD_SIZE)
|
||||
obAv[block[b]] = false;
|
||||
}
|
||||
toBlock -= block.size();
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user