1
0
mirror of https://github.com/vcmi/vcmi.git synced 2024-12-24 22:14:36 +02:00

Set of minor improvements and fixes.

This commit is contained in:
Michał W. Urbańczyk 2011-07-05 19:05:41 +00:00
parent 488e54688f
commit ed056cf0df
8 changed files with 46 additions and 28 deletions

View File

@ -185,6 +185,7 @@ int CBattleCallback::battleMakeAction(BattleAction* action)
template <typename T>
void CBattleCallback::sendRequest(const T* request)
{
//TODO? should be part of CClient but it would have to be very tricky cause template/serialization issues
if(waitTillRealize)
cl->waitingRequest.set(true);
@ -192,7 +193,13 @@ void CBattleCallback::sendRequest(const T* request)
*cl->serv << request;
if(waitTillRealize)
{
if(unlockGsWhenWaiting)
gs->mx->unlock_shared();
cl->waitingRequest.waitWhileTrue();
if(unlockGsWhenWaiting)
gs->mx->lock_shared();
}
}
void CCallback::swapGarrisonHero( const CGTownInstance *town )
@ -338,11 +345,6 @@ void CCallback::castSpell(const CGHeroInstance *hero, int spellID, const int3 &p
sendRequest(&cas);
}
boost::shared_mutex& CCallback::getGsMutex()
{
return *gs->mx;
}
void CCallback::unregisterMyInterface()
{
assert(player >= 0); //works only for player callback

View File

@ -36,13 +36,11 @@ struct CGPathNode;
struct CGPath;
struct CPathsInfo;
namespace boost
{class shared_mutex;}
class IBattleCallback
{
public:
bool waitTillRealize; //if true, request functions will return after they are realized by server
bool unlockGsWhenWaiting;//if true after sending each request, gs mutex will be unlocked so the changes can be applied; NOTICE caller must have gs mx locked prior to any call to actiob callback!
//battle
virtual int battleMakeAction(BattleAction* action)=0;//for casting spells by hero - DO NOT use it for moving active stack
virtual bool battleMakeTacticAction(BattleAction * action) =0; // performs tactic phase actions
@ -115,8 +113,6 @@ public:
virtual void calculatePaths(const CGHeroInstance *hero, CPathsInfo &out, int3 src = int3(-1,-1,-1), int movement = -1);
virtual void recalculatePaths(); //updates main, client pathfinder info (should be called when moving hero is over)
boost::shared_mutex &getGsMutex(); //just return a reference to mutex, does not lock nor anything
void unregisterMyInterface(); //stops delivering information about game events to that player's interface -> can be called ONLY after victory/loss
//commands

View File

@ -121,7 +121,9 @@ void CAdventureAI::battleCatapultAttacked(const CatapultAttack & ca)
void CAdventureAI::battleStart(const CCreatureSet *army1, const CCreatureSet *army2, int3 tile, const CGHeroInstance *hero1, const CGHeroInstance *hero2, bool side)
{
assert(!battleAI);
assert(cbc);
battleAI = CDynLibHandler::getNewBattleAI(battleAIName);
battleAI->init(cbc);
battleAI->battleStart(army1, army2, tile, hero1, hero2, side);
}
@ -189,4 +191,9 @@ void CAdventureAI::battleEnd(const BattleResult *br)
void CAdventureAI::battleStacksHealedRes(const std::vector<std::pair<ui32, ui32> > & healedStacks, bool lifeDrain, bool tentHeal, si32 lifeDrainFrom)
{
battleAI->battleStacksHealedRes(healedStacks, lifeDrain, tentHeal, lifeDrainFrom);
}
BattleAction CAdventureAI::activeStack(const CStack * stack)
{
return battleAI->activeStack(stack);
}

View File

@ -107,13 +107,15 @@ public:
class DLL_EXPORT CAdventureAI : public CGlobalAI
{
public:
CAdventureAI() : battleAI(NULL) {};
CAdventureAI(const std::string &BattleAIName) : battleAIName(BattleAIName), battleAI(NULL) {};
CAdventureAI() : battleAI(NULL), cbc(NULL) {};
CAdventureAI(const std::string &BattleAIName) : battleAIName(BattleAIName), battleAI(NULL), cbc(NULL) {};
std::string battleAIName;
CBattleGameInterface *battleAI;
CBattleCallback *cbc;
//battle interface
virtual BattleAction activeStack(const CStack * stack);
virtual void battleNewRound(int round);
virtual void battleCatapultAttacked(const CatapultAttack & ca);
virtual void battleStart(const CCreatureSet *army1, const CCreatureSet *army2, int3 tile, const CGHeroInstance *hero1, const CGHeroInstance *hero2, bool side);

View File

@ -34,6 +34,11 @@
extern boost::rand48 ran;
boost::shared_mutex& CCallbackBase::getGsMutex()
{
return *gs->mx;
}
si8 CBattleInfoCallback::battleHasDistancePenalty( const CStack * stack, THex destHex )
{
return gs->curB->hasDistancePenalty(stack, destHex);
@ -848,7 +853,7 @@ int CGameInfoCallback::canBuildStructure( const CGTownInstance *t, int ID )
return Buildings::ERROR;
//checking resources
if(pom->resources.canBeAfforded(getPlayer(t->tempOwner)->resources))
if(!pom->resources.canBeAfforded(getPlayer(t->tempOwner)->resources))
ret = Buildings::NO_RESOURCES; //lack of res
//checking for requirements

View File

@ -58,10 +58,12 @@ class CStackBasicDescriptor;
struct TeamState;
class CGCreature;
typedef std::vector<const CStack*> TStacks;
class CCallbackBase
namespace boost
{class shared_mutex;}
class DLL_EXPORT CCallbackBase
{
protected:
CGameState *gs;
@ -73,6 +75,9 @@ protected:
CCallbackBase()
: gs(NULL), player(-1)
{}
public:
boost::shared_mutex &getGsMutex(); //just return a reference to mutex, does not lock nor anything
};
class DLL_EXPORT CBattleInfoCallback : public virtual CCallbackBase

View File

@ -71,7 +71,8 @@ namespace Res
{
int ret = INT_MAX;
for(int i = 0; i < size(); i++)
amin(ret, at(i) / rhs[i]);
if(rhs[i])
amin(ret, at(i) / rhs[i]);
return ret;
}

View File

@ -2006,9 +2006,9 @@ void CGameHandler::close()
bool CGameHandler::arrangeStacks( si32 id1, si32 id2, ui8 what, ui8 p1, ui8 p2, si32 val, ui8 player )
{
CArmedInstance *s1 = static_cast<CArmedInstance*>(gs->map->objects[id1].get()),
const CArmedInstance *s1 = static_cast<CArmedInstance*>(gs->map->objects[id1].get()),
*s2 = static_cast<CArmedInstance*>(gs->map->objects[id2].get());
CCreatureSet &S1 = *s1, &S2 = *s2;
const CCreatureSet &S1 = *s1, &S2 = *s2;
StackLocation sl1(s1, p1), sl2(s2, p2);
if(!isAllowedExchange(id1,id2))
@ -2019,8 +2019,8 @@ bool CGameHandler::arrangeStacks( si32 id1, si32 id2, ui8 what, ui8 p1, ui8 p2,
if(what==1) //swap
{
if ( ((s1->tempOwner != player && s1->tempOwner != 254) && S1.stacks[p1]->count) //why 254??
|| ((s2->tempOwner != player && s2->tempOwner != 254) && S2.stacks[p2]->count))
if ( ((s1->tempOwner != player && s1->tempOwner != 254) && s1->getStackCount(p1)) //why 254??
|| ((s2->tempOwner != player && s2->tempOwner != 254) && s2->getStackCount(p2)))
{
complain("Can't take troops from another player!");
return false;
@ -2030,16 +2030,16 @@ bool CGameHandler::arrangeStacks( si32 id1, si32 id2, ui8 what, ui8 p1, ui8 p2,
}
else if(what==2)//merge
{
if (( S1.stacks[p1]->type != S2.stacks[p2]->type && complain("Cannot merge different creatures stacks!"))
|| (((s1->tempOwner != player && s1->tempOwner != 254) && S2.stacks[p2]->count) && complain("Can't take troops from another player!")))
if (( s1->getCreature(p1) != s2->getCreature(p2) && complain("Cannot merge different creatures stacks!"))
|| (((s1->tempOwner != player && s1->tempOwner != 254) && s2->getStackCount(p2)) && complain("Can't take troops from another player!")))
return false;
moveStack(sl1, sl2);
}
else if(what==3) //split
{
if ( (s1->tempOwner != player && S1.stacks[p1]->count < s1->getStackCount(p1) )
|| (s2->tempOwner != player && S2.stacks[p2]->count < s2->getStackCount(p2) ) )
if ( (s1->tempOwner != player && s1->getStackCount(p1) < s1->getStackCount(p1) )
|| (s2->tempOwner != player && s2->getStackCount(p2) < s2->getStackCount(p2) ) )
{
complain("Can't move troops of another player!");
return false;
@ -2055,21 +2055,21 @@ bool CGameHandler::arrangeStacks( si32 id1, si32 id2, ui8 what, ui8 p1, ui8 p2,
if(vstd::contains(S2.stacks,p2)) //dest. slot not free - it must be "rebalancing"...
{
int total = S1.stacks[p1]->count + S2.stacks[p2]->count;
int total = s1->getStackCount(p1) + s2->getStackCount(p2);
if( (total < val && complain("Cannot split that stack, not enough creatures!"))
|| (S2.stacks[p2]->type != S1.stacks[p1]->type && complain("Cannot rebalance different creatures stacks!"))
|| (s1->getCreature(p1) != s2->getCreature(p2) && complain("Cannot rebalance different creatures stacks!"))
)
{
return false;
}
moveStack(sl1, sl2, val - S2.stacks[p2]->count);
moveStack(sl1, sl2, val - s2->getStackCount(p2));
//S2.slots[p2]->count = val;
//S1.slots[p1]->count = total - val;
}
else //split one stack to the two
{
if(S1.stacks[p1]->count < val)//not enough creatures
if(s1->getStackCount(p1) < val)//not enough creatures
{
complain("Cannot split that stack, not enough creatures!");
return false;