From b42a7fa87b461171d5480bf72f4d8d0318de6eee Mon Sep 17 00:00:00 2001 From: mateuszb Date: Sat, 14 Feb 2009 13:49:30 +0000 Subject: [PATCH] * 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) --- CBattleInterface.cpp | 5 ++- CCallback.cpp | 30 +++++++++++-- CGameState.cpp | 93 ++++++++++++++++++++++++++++++++--------- config/obstacles.txt | 4 +- server/CGameHandler.cpp | 37 +++++++--------- 5 files changed, 120 insertions(+), 49 deletions(-) diff --git a/CBattleInterface.cpp b/CBattleInterface.cpp index ccd4950c1..350325e97 100644 --- a/CBattleInterface.cpp +++ b/CBattleInterface.cpp @@ -1419,10 +1419,11 @@ void CBattleInterface::hexLclicked(int whichOne) if(LOCPLINT->cb->battleGetStackByID(activeStack)->creature->isDoubleWide()) { std::vector 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 { diff --git a/CCallback.cpp b/CCallback.cpp index c6f4548d7..e9ec1304c 100644 --- a/CCallback.cpp +++ b/CCallback.cpp @@ -486,6 +486,11 @@ CStack* CCallback::battleGetStackByPos(int pos) int CCallback::battleGetPos(int stack) { boost::shared_lock lock(*gs->mx); + if(!gs->curB) + { + tlog2<<"battleGetPos called when there is no battle!"<curB->stacks.size(); ++g) { if(gs->curB->stacks[g]->ID == stack) @@ -512,12 +517,21 @@ std::map CCallback::battleGetStacks() std::vector CCallback::battleGetStackQueue() { + if(!gs->curB) + { + tlog2<<"battleGetStackQueue called when there is not battle!"<(); + } return gs->curB->getStackQueue(); } CCreature CCallback::battleGetCreature(int number) { boost::shared_lock lock(*gs->mx); //TODO use me? + if(!gs->curB) + { + tlog2<<"battleGetCreature called when there is no battle!"<curB->stacks.size(); ++h) { if(gs->curB->stacks[h]->ID == number) //creature found @@ -533,13 +547,23 @@ CCreature CCallback::battleGetCreature(int number) std::vector CCallback::battleGetAvailableHexes(int ID, bool addOccupiable) { boost::shared_lock lock(*gs->mx); + if(!gs->curB) + { + tlog2<<"battleGetAvailableHexes called when there is no battle!"<(); + } return gs->curB->getAccessibility(ID, addOccupiable); //return gs->battleGetRange(ID); } bool CCallback::battleIsStackMine(int ID) { - boost::shared_lock lock(*gs->mx); //TODO use me ? + boost::shared_lock lock(*gs->mx); + if(!gs->curB) + { + tlog2<<"battleIsStackMine called when there is no battle!"<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 lock(*gs->mx); //TODO use me? + boost::shared_lock 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; geffects.size(); ++g) { diff --git a/CGameState.cpp b/CGameState.cpp index 1028bb765..1a6e6fe98 100644 --- a/CGameState.cpp +++ b/CGameState.cpp @@ -190,7 +190,8 @@ void BattleInfo::getAccessibilityMap(bool *accessibility, int stackToOmmit) std::vector blocked = VLC->heroh->obstacles[obstacles[b].ID].getBlocked(obstacles[b].pos); for(int c=0; 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 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 rem; + for(int b=0; battackerOwned ? ac[b-1] : ac[b+1])) + { + rem.push_back(b); + } + } + + for(int g=0; gattackerOwned ? (v%BFIELD_WIDTH)==1 : (v%BFIELD_WIDTH)==(BFIELD_WIDTH - 2)) + ac[v] = false; + } + else + { + std::vector rem; + for(int b=0; bspeed()) + 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 > & objs = CGI->mh->ttiles[tile.x][tile.y][tile.z].objects; + //for(int g=0; gID) + // { + // 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: diff --git a/config/obstacles.txt b/config/obstacles.txt index 88b46ee47..5bde12f86 100644 --- a/config/obstacles.txt +++ b/config/obstacles.txt @@ -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 diff --git a/server/CGameHandler.cpp b/server/CGameHandler.cpp index 57af6caab..95ca89488 100644 --- a/server/CGameHandler.cpp +++ b/server/CGameHandler.cpp @@ -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 callback = boost::function(boost::bind(callWith,hlu.skills,boost::function(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 callback = boost::function(boost::bind(callWith,hlu.skills,boost::function(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 accessible = gs->curB->getAccessibility(curStack->ID, false); + for(int b=0; bcreature->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= 0 && block[b] < BFIELD_SIZE) + obAv[block[b]] = false; } toBlock -= block.size(); }