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:
parent
488e54688f
commit
ed056cf0df
@ -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
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user