mirror of
https://github.com/vcmi/vcmi.git
synced 2024-12-26 22:57:00 +02:00
commit
4df16d525a
@ -822,7 +822,7 @@ void VCAI::makeTurnInternal()
|
|||||||
{
|
{
|
||||||
if (h->movement)
|
if (h->movement)
|
||||||
logAi->warnStream() << boost::format("hero %s has %d MP left") % h->name % h->movement;
|
logAi->warnStream() << boost::format("hero %s has %d MP left") % h->name % h->movement;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch(boost::thread_interrupted &e)
|
catch(boost::thread_interrupted &e)
|
||||||
{
|
{
|
||||||
@ -891,7 +891,7 @@ bool VCAI::canGetArmy (const CGHeroInstance * army, const CGHeroInstance * sourc
|
|||||||
|
|
||||||
|
|
||||||
const CArmedInstance *armies[] = {army, source};
|
const CArmedInstance *armies[] = {army, source};
|
||||||
|
|
||||||
//we calculate total strength for each creature type available in armies
|
//we calculate total strength for each creature type available in armies
|
||||||
std::map<const CCreature*, int> creToPower;
|
std::map<const CCreature*, int> creToPower;
|
||||||
for(auto armyPtr : armies)
|
for(auto armyPtr : armies)
|
||||||
@ -988,7 +988,7 @@ void VCAI::pickBestCreatures(const CArmedInstance * army, const CArmedInstance *
|
|||||||
}
|
}
|
||||||
|
|
||||||
void VCAI::pickBestArtifacts(const CGHeroInstance * h, const CGHeroInstance * other)
|
void VCAI::pickBestArtifacts(const CGHeroInstance * h, const CGHeroInstance * other)
|
||||||
{
|
{
|
||||||
auto equipBest = [](const CGHeroInstance * h, const CGHeroInstance * otherh, bool giveStuffToFirstHero) -> void
|
auto equipBest = [](const CGHeroInstance * h, const CGHeroInstance * otherh, bool giveStuffToFirstHero) -> void
|
||||||
{
|
{
|
||||||
bool changeMade = false;
|
bool changeMade = false;
|
||||||
@ -2059,7 +2059,7 @@ void VCAI::tryRealize(Goals::CollectRes & g)
|
|||||||
cb->trade(obj, EMarketMode::RESOURCE_RESOURCE, i, g.resID, toGive);
|
cb->trade(obj, EMarketMode::RESOURCE_RESOURCE, i, g.resID, toGive);
|
||||||
if(cb->getResourceAmount(static_cast<Res::ERes>(g.resID)) >= g.value)
|
if(cb->getResourceAmount(static_cast<Res::ERes>(g.resID)) >= g.value)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
throw cannotFulfillGoalException("I cannot get needed resources by trade!");
|
throw cannotFulfillGoalException("I cannot get needed resources by trade!");
|
||||||
}
|
}
|
||||||
@ -2277,7 +2277,7 @@ Goals::TSubgoal VCAI::striveToGoalInternal(Goals::TSubgoal ultimateGoal, bool on
|
|||||||
completeGoal (goal);
|
completeGoal (goal);
|
||||||
//completed goal was main goal //TODO: find better condition
|
//completed goal was main goal //TODO: find better condition
|
||||||
if (ultimateGoal->fulfillsMe(goal) || maxGoals > searchDepth2)
|
if (ultimateGoal->fulfillsMe(goal) || maxGoals > searchDepth2)
|
||||||
return sptr(Goals::Invalid());
|
return sptr(Goals::Invalid());
|
||||||
}
|
}
|
||||||
catch(std::exception &e)
|
catch(std::exception &e)
|
||||||
{
|
{
|
||||||
@ -2530,7 +2530,7 @@ int3 VCAI::explorationDesperate(HeroPtr h)
|
|||||||
//logAi->debugStream() << "Looking for an another place for exploration...";
|
//logAi->debugStream() << "Looking for an another place for exploration...";
|
||||||
SectorMap sm(h);
|
SectorMap sm(h);
|
||||||
int radius = h->getSightRadious();
|
int radius = h->getSightRadious();
|
||||||
|
|
||||||
std::vector<std::vector<int3> > tiles; //tiles[distance_to_fow]
|
std::vector<std::vector<int3> > tiles; //tiles[distance_to_fow]
|
||||||
tiles.resize(radius);
|
tiles.resize(radius);
|
||||||
|
|
||||||
@ -2660,19 +2660,13 @@ void VCAI::finish()
|
|||||||
|
|
||||||
void VCAI::requestActionASAP(std::function<void()> whatToDo)
|
void VCAI::requestActionASAP(std::function<void()> whatToDo)
|
||||||
{
|
{
|
||||||
// static boost::mutex m;
|
boost::thread newThread([this, whatToDo]()
|
||||||
// boost::unique_lock<boost::mutex> mylock(m);
|
|
||||||
|
|
||||||
boost::barrier b(2);
|
|
||||||
boost::thread newThread([&b,this,whatToDo]()
|
|
||||||
{
|
{
|
||||||
setThreadName("VCAI::requestActionASAP::helper");
|
setThreadName("VCAI::requestActionASAP::whatToDo");
|
||||||
SET_GLOBAL_STATE(this);
|
SET_GLOBAL_STATE(this);
|
||||||
boost::shared_lock<boost::shared_mutex> gsLock(cb->getGsMutex());
|
boost::shared_lock<boost::shared_mutex> gsLock(cb->getGsMutex());
|
||||||
b.wait();
|
|
||||||
whatToDo();
|
whatToDo();
|
||||||
});
|
});
|
||||||
b.wait();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void VCAI::lostHero(HeroPtr h)
|
void VCAI::lostHero(HeroPtr h)
|
||||||
@ -2867,8 +2861,8 @@ void AIStatus::heroVisit(const CGObjectInstance *obj, bool started)
|
|||||||
objectsBeingVisited.push_back(obj);
|
objectsBeingVisited.push_back(obj);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// There can be more than one object visited at the time (eg. hero visits Subterranean Gate
|
// There can be more than one object visited at the time (eg. hero visits Subterranean Gate
|
||||||
// causing visit to hero on the other side.
|
// causing visit to hero on the other side.
|
||||||
// However, we are guaranteed that start/end visit notification maintain stack order.
|
// However, we are guaranteed that start/end visit notification maintain stack order.
|
||||||
assert(!objectsBeingVisited.empty());
|
assert(!objectsBeingVisited.empty());
|
||||||
objectsBeingVisited.pop_back();
|
objectsBeingVisited.pop_back();
|
||||||
@ -2980,7 +2974,7 @@ void SectorMap::exploreNewSector(crint3 pos, int num, CCallback * cbp)
|
|||||||
s.embarkmentPoints.push_back(neighPos);
|
s.embarkmentPoints.push_back(neighPos);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
if(t->visitable)
|
if(t->visitable)
|
||||||
{
|
{
|
||||||
auto obj = t->visitableObjects.front();
|
auto obj = t->visitableObjects.front();
|
||||||
@ -3036,7 +3030,7 @@ bool isWeeklyRevisitable (const CGObjectInstance * obj)
|
|||||||
bool shouldVisit(HeroPtr h, const CGObjectInstance * obj)
|
bool shouldVisit(HeroPtr h, const CGObjectInstance * obj)
|
||||||
{
|
{
|
||||||
switch (obj->ID)
|
switch (obj->ID)
|
||||||
{
|
{
|
||||||
case Obj::TOWN:
|
case Obj::TOWN:
|
||||||
case Obj::HERO: //never visit our heroes at random
|
case Obj::HERO: //never visit our heroes at random
|
||||||
return obj->tempOwner != h->tempOwner; //do not visit our towns at random
|
return obj->tempOwner != h->tempOwner; //do not visit our towns at random
|
||||||
@ -3087,7 +3081,7 @@ bool shouldVisit(HeroPtr h, const CGObjectInstance * obj)
|
|||||||
return canRecruitCreatures;
|
return canRecruitCreatures;
|
||||||
}
|
}
|
||||||
case Obj::HILL_FORT:
|
case Obj::HILL_FORT:
|
||||||
{
|
{
|
||||||
for (auto slot : h->Slots())
|
for (auto slot : h->Slots())
|
||||||
{
|
{
|
||||||
if (slot.second->type->upgrades.size())
|
if (slot.second->type->upgrades.size())
|
||||||
@ -3386,7 +3380,7 @@ void SectorMap::makeParentBFS(crint3 source)
|
|||||||
ui8 &sec = retreiveTile(curPos);
|
ui8 &sec = retreiveTile(curPos);
|
||||||
assert(sec == mySector); //consider only tiles from the same sector
|
assert(sec == mySector); //consider only tiles from the same sector
|
||||||
UNUSED(sec);
|
UNUSED(sec);
|
||||||
|
|
||||||
foreach_neighbour(curPos, [&](crint3 neighPos)
|
foreach_neighbour(curPos, [&](crint3 neighPos)
|
||||||
{
|
{
|
||||||
if(retreiveTile(neighPos) == mySector && !vstd::contains(parent, neighPos))
|
if(retreiveTile(neighPos) == mySector && !vstd::contains(parent, neighPos))
|
||||||
@ -3405,4 +3399,3 @@ unsigned char & SectorMap::retreiveTile(crint3 pos)
|
|||||||
{
|
{
|
||||||
return retreiveTileN(sector, pos);
|
return retreiveTileN(sector, pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -62,9 +62,9 @@ CAdvMapInt *adventureInt;
|
|||||||
|
|
||||||
|
|
||||||
CTerrainRect::CTerrainRect()
|
CTerrainRect::CTerrainRect()
|
||||||
: fadeSurface(nullptr),
|
: fadeSurface(nullptr),
|
||||||
fadeAnim(new CFadeAnimation()),
|
fadeAnim(new CFadeAnimation()),
|
||||||
curHoveredTile(-1,-1,-1),
|
curHoveredTile(-1,-1,-1),
|
||||||
currentPath(nullptr)
|
currentPath(nullptr)
|
||||||
{
|
{
|
||||||
tilesw=(ADVOPT.advmapW+31)/32;
|
tilesw=(ADVOPT.advmapW+31)/32;
|
||||||
@ -283,7 +283,7 @@ void CTerrainRect::show(SDL_Surface * to)
|
|||||||
info.heroAnim = adventureInt->heroAnim;
|
info.heroAnim = adventureInt->heroAnim;
|
||||||
if (ADVOPT.smoothMove)
|
if (ADVOPT.smoothMove)
|
||||||
info.movement = int3(moveX, moveY, 0);
|
info.movement = int3(moveX, moveY, 0);
|
||||||
|
|
||||||
lastRedrawStatus = CGI->mh->drawTerrainRectNew(to, &info);
|
lastRedrawStatus = CGI->mh->drawTerrainRectNew(to, &info);
|
||||||
if (fadeAnim->isFading())
|
if (fadeAnim->isFading())
|
||||||
{
|
{
|
||||||
@ -316,7 +316,7 @@ void CTerrainRect::showAll(SDL_Surface * to)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void CTerrainRect::showAnim(SDL_Surface * to)
|
void CTerrainRect::showAnim(SDL_Surface * to)
|
||||||
{
|
{
|
||||||
if (fadeAnim->isFading())
|
if (fadeAnim->isFading())
|
||||||
show(to);
|
show(to);
|
||||||
else if (lastRedrawStatus == EMapAnimRedrawStatus::REDRAW_REQUESTED)
|
else if (lastRedrawStatus == EMapAnimRedrawStatus::REDRAW_REQUESTED)
|
||||||
@ -357,7 +357,7 @@ void CTerrainRect::fadeFromCurrentView()
|
|||||||
return;
|
return;
|
||||||
if (adventureInt->mode == EAdvMapMode::WORLD_VIEW)
|
if (adventureInt->mode == EAdvMapMode::WORLD_VIEW)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!fadeSurface)
|
if (!fadeSurface)
|
||||||
fadeSurface = CSDL_Ext::newSurface(pos.w, pos.h);
|
fadeSurface = CSDL_Ext::newSurface(pos.w, pos.h);
|
||||||
SDL_BlitSurface(screen, &pos, fadeSurface, nullptr);
|
SDL_BlitSurface(screen, &pos, fadeSurface, nullptr);
|
||||||
@ -502,10 +502,10 @@ CAdvMapInt::CAdvMapInt():
|
|||||||
endTurn = makeButton(302, std::bind(&CAdvMapInt::fendTurn,this), ADVOPT.endTurn, SDLK_e);
|
endTurn = makeButton(302, std::bind(&CAdvMapInt::fendTurn,this), ADVOPT.endTurn, SDLK_e);
|
||||||
|
|
||||||
int panelSpaceBottom = screen->h - resdatabar.pos.h - 4;
|
int panelSpaceBottom = screen->h - resdatabar.pos.h - 4;
|
||||||
|
|
||||||
panelMain = new CAdvMapPanel(nullptr, Point(0, 0));
|
panelMain = new CAdvMapPanel(nullptr, Point(0, 0));
|
||||||
// TODO correct drawing position
|
// TODO correct drawing position
|
||||||
panelWorldView = new CAdvMapWorldViewPanel(bgWorldView, Point(heroList.pos.x - 2, 195), panelSpaceBottom, LOCPLINT->playerID);
|
panelWorldView = new CAdvMapWorldViewPanel(bgWorldView, Point(heroList.pos.x - 2, 195), panelSpaceBottom, LOCPLINT->playerID);
|
||||||
|
|
||||||
panelMain->addChildColorableButton(kingOverview);
|
panelMain->addChildColorableButton(kingOverview);
|
||||||
panelMain->addChildColorableButton(underground);
|
panelMain->addChildColorableButton(underground);
|
||||||
@ -593,7 +593,7 @@ CAdvMapInt::CAdvMapInt():
|
|||||||
Colors::WHITE, CGI->generaltexth->allTexts[618]));
|
Colors::WHITE, CGI->generaltexth->allTexts[618]));
|
||||||
|
|
||||||
activeMapPanel = panelMain;
|
activeMapPanel = panelMain;
|
||||||
|
|
||||||
changeMode(EAdvMapMode::NORMAL);
|
changeMode(EAdvMapMode::NORMAL);
|
||||||
|
|
||||||
underground->block(!CGI->mh->map->twoLevel);
|
underground->block(!CGI->mh->map->twoLevel);
|
||||||
@ -966,7 +966,7 @@ void CAdvMapInt::show(SDL_Surface * to)
|
|||||||
for(int i=0;i<4;i++)
|
for(int i=0;i<4;i++)
|
||||||
blitAt(gems[i]->ourImages[LOCPLINT->playerID.getNum()].bitmap,ADVOPT.gemX[i],ADVOPT.gemY[i],to);
|
blitAt(gems[i]->ourImages[LOCPLINT->playerID.getNum()].bitmap,ADVOPT.gemX[i],ADVOPT.gemY[i],to);
|
||||||
}
|
}
|
||||||
|
|
||||||
infoBar.show(to);
|
infoBar.show(to);
|
||||||
statusbar.showAll(to);
|
statusbar.showAll(to);
|
||||||
}
|
}
|
||||||
@ -981,7 +981,7 @@ void CAdvMapInt::selectionChanged()
|
|||||||
void CAdvMapInt::centerOn(int3 on, bool fade /* = false */)
|
void CAdvMapInt::centerOn(int3 on, bool fade /* = false */)
|
||||||
{
|
{
|
||||||
bool switchedLevels = on.z != position.z;
|
bool switchedLevels = on.z != position.z;
|
||||||
|
|
||||||
if (fade)
|
if (fade)
|
||||||
{
|
{
|
||||||
terrain.fadeFromCurrentView();
|
terrain.fadeFromCurrentView();
|
||||||
@ -1534,7 +1534,9 @@ void CAdvMapInt::tileHovered(const int3 &mapPos)
|
|||||||
}
|
}
|
||||||
else if(const CGHeroInstance *h = curHero())
|
else if(const CGHeroInstance *h = curHero())
|
||||||
{
|
{
|
||||||
const CGPathNode *pnode = LOCPLINT->cb->getPathsInfo(h)->getPathInfo(mapPos);
|
int3 mapPosCopy = mapPos;
|
||||||
|
const CGPathNode *pnode = LOCPLINT->cb->getPathsInfo(h)->getPathInfo(mapPosCopy);
|
||||||
|
assert(pnode);
|
||||||
|
|
||||||
int turns = pnode->turns;
|
int turns = pnode->turns;
|
||||||
vstd::amin(turns, 3);
|
vstd::amin(turns, 3);
|
||||||
@ -1780,9 +1782,9 @@ void CAdvMapInt::changeMode(EAdvMapMode newMode, float newScale /* = 0.4f */)
|
|||||||
townList.activate();
|
townList.activate();
|
||||||
heroList.activate();
|
heroList.activate();
|
||||||
infoBar.activate();
|
infoBar.activate();
|
||||||
|
|
||||||
worldViewOptions.clear();
|
worldViewOptions.clear();
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case EAdvMapMode::WORLD_VIEW:
|
case EAdvMapMode::WORLD_VIEW:
|
||||||
panelMain->deactivate();
|
panelMain->deactivate();
|
||||||
@ -1852,14 +1854,13 @@ CAdvMapInt::WorldViewOptions::WorldViewOptions()
|
|||||||
void CAdvMapInt::WorldViewOptions::clear()
|
void CAdvMapInt::WorldViewOptions::clear()
|
||||||
{
|
{
|
||||||
showAllTerrain = false;
|
showAllTerrain = false;
|
||||||
|
|
||||||
iconPositions.clear();
|
iconPositions.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CAdvMapInt::WorldViewOptions::adjustDrawingInfo(MapDrawingInfo& info)
|
void CAdvMapInt::WorldViewOptions::adjustDrawingInfo(MapDrawingInfo& info)
|
||||||
{
|
{
|
||||||
info.showAllTerrain = showAllTerrain;
|
info.showAllTerrain = showAllTerrain;
|
||||||
|
|
||||||
info.additionalIcons = &iconPositions;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
info.additionalIcons = &iconPositions;
|
||||||
|
}
|
||||||
|
@ -674,8 +674,8 @@ void CGameState::randomizeObject(CGObjectInstance *cur)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
cur->setType(ran.first, ran.second);
|
cur->setType(ran.first, ran.second);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int CGameState::getDate(Date::EDateType mode) const
|
int CGameState::getDate(Date::EDateType mode) const
|
||||||
@ -2899,11 +2899,11 @@ bool CGPathNode::reachable() const
|
|||||||
return turns < 255;
|
return turns < 255;
|
||||||
}
|
}
|
||||||
|
|
||||||
const CGPathNode * CPathsInfo::getPathInfo( int3 tile ) const
|
const CGPathNode * CPathsInfo::getPathInfo( const int3& tile ) const
|
||||||
{
|
{
|
||||||
boost::unique_lock<boost::mutex> pathLock(pathMx);
|
boost::unique_lock<boost::mutex> pathLock(pathMx);
|
||||||
|
if (tile.x >= sizes.x || tile.y >= sizes.y || tile.z >= sizes.z ||
|
||||||
if (tile.x >= sizes.x || tile.y >= sizes.y || tile.z >= sizes.z)
|
tile.x < 0 || tile.y < 0 || tile.z < 0)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
return &nodes[tile.x][tile.y][tile.z];
|
return &nodes[tile.x][tile.y][tile.z];
|
||||||
}
|
}
|
||||||
|
@ -158,7 +158,7 @@ struct DLL_LINKAGE CPathsInfo
|
|||||||
int3 sizes;
|
int3 sizes;
|
||||||
CGPathNode ***nodes; //[w][h][level]
|
CGPathNode ***nodes; //[w][h][level]
|
||||||
|
|
||||||
const CGPathNode * getPathInfo( int3 tile ) const;
|
const CGPathNode * getPathInfo( const int3& tile ) const;
|
||||||
bool getPath(const int3 &dst, CGPath &out) const;
|
bool getPath(const int3 &dst, CGPath &out) const;
|
||||||
int getDistance( int3 tile ) const;
|
int getDistance( int3 tile ) const;
|
||||||
CPathsInfo(const int3 &Sizes);
|
CPathsInfo(const int3 &Sizes);
|
||||||
|
@ -65,14 +65,14 @@ class ServerSpellCastEnvironment: public SpellCastEnvironment
|
|||||||
public:
|
public:
|
||||||
ServerSpellCastEnvironment(CGameHandler * gh);
|
ServerSpellCastEnvironment(CGameHandler * gh);
|
||||||
~ServerSpellCastEnvironment(){};
|
~ServerSpellCastEnvironment(){};
|
||||||
void sendAndApply(CPackForClient * info) const override;
|
void sendAndApply(CPackForClient * info) const override;
|
||||||
CRandomGenerator & getRandomGenerator() const override;
|
CRandomGenerator & getRandomGenerator() const override;
|
||||||
void complain(const std::string & problem) const override;
|
void complain(const std::string & problem) const override;
|
||||||
const CMap * getMap() const override;
|
const CMap * getMap() const override;
|
||||||
const CGameInfoCallback * getCb() const override;
|
const CGameInfoCallback * getCb() const override;
|
||||||
bool moveHero(ObjectInstanceID hid, int3 dst, ui8 teleporting, PlayerColor asker = PlayerColor::NEUTRAL) const override;
|
bool moveHero(ObjectInstanceID hid, int3 dst, ui8 teleporting, PlayerColor asker = PlayerColor::NEUTRAL) const override;
|
||||||
private:
|
private:
|
||||||
mutable CGameHandler * gh;
|
mutable CGameHandler * gh;
|
||||||
};
|
};
|
||||||
|
|
||||||
CondSh<bool> battleMadeAction;
|
CondSh<bool> battleMadeAction;
|
||||||
@ -102,7 +102,7 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
class CApplyOnGH<CPack> : public CBaseForGHApply
|
class CApplyOnGH<CPack> : public CBaseForGHApply
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@ -799,15 +799,15 @@ void CGameHandler::prepareAttack(BattleAttack &bat, const CStack *att, const CSt
|
|||||||
|
|
||||||
const Bonus * bonus = att->getBonusLocalFirst(Selector::type(Bonus::SPELL_LIKE_ATTACK));
|
const Bonus * bonus = att->getBonusLocalFirst(Selector::type(Bonus::SPELL_LIKE_ATTACK));
|
||||||
if (bonus && (bat.shot())) //TODO: make it work in melee?
|
if (bonus && (bat.shot())) //TODO: make it work in melee?
|
||||||
{
|
{
|
||||||
//this is need for displaying hit animation
|
//this is need for displaying hit animation
|
||||||
bat.flags |= BattleAttack::SPELL_LIKE;
|
bat.flags |= BattleAttack::SPELL_LIKE;
|
||||||
bat.spellID = SpellID(bonus->subtype);
|
bat.spellID = SpellID(bonus->subtype);
|
||||||
|
|
||||||
//TODO: should spell override creature`s projectile?
|
//TODO: should spell override creature`s projectile?
|
||||||
|
|
||||||
std::set<const CStack*> attackedCreatures = SpellID(bonus->subtype).toSpell()->getAffectedStacks(gs->curB, ECastingMode::SPELL_LIKE_ATTACK, att->owner, bonus->val, targetHex, att);
|
std::set<const CStack*> attackedCreatures = SpellID(bonus->subtype).toSpell()->getAffectedStacks(gs->curB, ECastingMode::SPELL_LIKE_ATTACK, att->owner, bonus->val, targetHex, att);
|
||||||
|
|
||||||
//TODO: get exact attacked hex for defender
|
//TODO: get exact attacked hex for defender
|
||||||
|
|
||||||
for(const CStack * stack : attackedCreatures)
|
for(const CStack * stack : attackedCreatures)
|
||||||
@ -817,7 +817,7 @@ void CGameHandler::prepareAttack(BattleAttack &bat, const CStack *att, const CSt
|
|||||||
applyBattleEffects(bat, att, stack, distance, true);
|
applyBattleEffects(bat, att, stack, distance, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//now add effect info for all attacked stacks
|
//now add effect info for all attacked stacks
|
||||||
for(BattleStackAttacked & bsa : bat.bsa)
|
for(BattleStackAttacked & bsa : bat.bsa)
|
||||||
{
|
{
|
||||||
@ -828,7 +828,7 @@ void CGameHandler::prepareAttack(BattleAttack &bat, const CStack *att, const CSt
|
|||||||
bsa.spellID = SpellID(bonus->subtype);
|
bsa.spellID = SpellID(bonus->subtype);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void CGameHandler::applyBattleEffects(BattleAttack &bat, const CStack *att, const CStack *def, int distance, bool secondary) //helper function for prepareAttack
|
void CGameHandler::applyBattleEffects(BattleAttack &bat, const CStack *att, const CStack *def, int distance, bool secondary) //helper function for prepareAttack
|
||||||
@ -917,7 +917,7 @@ void CGameHandler::handleConnection(std::set<PlayerColor> players, CConnection &
|
|||||||
c << &applied;
|
c << &applied;
|
||||||
};
|
};
|
||||||
|
|
||||||
CBaseForGHApply *apply = applier->apps[packType]; //and appropriae applier object
|
CBaseForGHApply *apply = applier->apps[packType]; //and appropriate applier object
|
||||||
if(isBlockedByQueries(pack, player))
|
if(isBlockedByQueries(pack, player))
|
||||||
{
|
{
|
||||||
sendPackageResponse(false);
|
sendPackageResponse(false);
|
||||||
@ -1026,7 +1026,7 @@ int CGameHandler::moveStack(int stack, BattleHex dest)
|
|||||||
int v = path.first.size()-1;
|
int v = path.first.size()-1;
|
||||||
|
|
||||||
bool stackIsMoving = true;
|
bool stackIsMoving = true;
|
||||||
|
|
||||||
while(stackIsMoving)
|
while(stackIsMoving)
|
||||||
{
|
{
|
||||||
if(v<tilesToMove)
|
if(v<tilesToMove)
|
||||||
@ -1079,10 +1079,10 @@ int CGameHandler::moveStack(int stack, BattleHex dest)
|
|||||||
if(obs->stopsMovement() || !curStack->alive())
|
if(obs->stopsMovement() || !curStack->alive())
|
||||||
stackIsMoving = false;
|
stackIsMoving = false;
|
||||||
|
|
||||||
obs.reset();
|
obs.reset();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
processObstacle(obstacle);
|
processObstacle(obstacle);
|
||||||
if(curStack->alive())
|
if(curStack->alive())
|
||||||
processObstacle(obstacle2);
|
processObstacle(obstacle2);
|
||||||
@ -1105,14 +1105,14 @@ int CGameHandler::moveStack(int stack, BattleHex dest)
|
|||||||
if(curStack->alive() && curStack->doubleWide())
|
if(curStack->alive() && curStack->doubleWide())
|
||||||
{
|
{
|
||||||
BattleHex otherHex = curStack->occupiedHex(curStack->position);
|
BattleHex otherHex = curStack->occupiedHex(curStack->position);
|
||||||
|
|
||||||
if(otherHex.isValid())
|
if(otherHex.isValid())
|
||||||
if(auto theLastObstacle = battleGetObstacleOnPos(otherHex, false))
|
if(auto theLastObstacle = battleGetObstacleOnPos(otherHex, false))
|
||||||
{
|
{
|
||||||
//two hex creature hit obstacle by backside
|
//two hex creature hit obstacle by backside
|
||||||
handleDamageFromObstacle(*theLastObstacle, curStack);
|
handleDamageFromObstacle(*theLastObstacle, curStack);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1125,7 +1125,7 @@ CGameHandler::CGameHandler(void)
|
|||||||
registerTypesServerPacks(*applier);
|
registerTypesServerPacks(*applier);
|
||||||
visitObjectAfterVictory = false;
|
visitObjectAfterVictory = false;
|
||||||
queries.gh = this;
|
queries.gh = this;
|
||||||
|
|
||||||
spellEnv = new ServerSpellCastEnvironment(this);
|
spellEnv = new ServerSpellCastEnvironment(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3907,8 +3907,8 @@ bool CGameHandler::makeBattleAction( BattleAction &ba )
|
|||||||
complain("That stack can't cast spells!");
|
complain("That stack can't cast spells!");
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
const CSpell * spell = SpellID(spellID).toSpell();
|
const CSpell * spell = SpellID(spellID).toSpell();
|
||||||
BattleSpellCastParameters parameters(gs->curB, stack, spell);
|
BattleSpellCastParameters parameters(gs->curB, stack, spell);
|
||||||
parameters.spellLvl = 0;
|
parameters.spellLvl = 0;
|
||||||
if (spellcaster)
|
if (spellcaster)
|
||||||
vstd::amax(parameters.spellLvl, spellcaster->val);
|
vstd::amax(parameters.spellLvl, spellcaster->val);
|
||||||
@ -3940,12 +3940,12 @@ void CGameHandler::playerMessage( PlayerColor player, const std::string &message
|
|||||||
{
|
{
|
||||||
SetMana sm;
|
SetMana sm;
|
||||||
GiveBonus giveBonus(GiveBonus::HERO);
|
GiveBonus giveBonus(GiveBonus::HERO);
|
||||||
|
|
||||||
CGHeroInstance *h = gs->getHero(currObj);
|
CGHeroInstance *h = gs->getHero(currObj);
|
||||||
if(!h && complain("Cannot realize cheat, no hero selected!")) return;
|
if(!h && complain("Cannot realize cheat, no hero selected!")) return;
|
||||||
|
|
||||||
sm.hid = h->id;
|
sm.hid = h->id;
|
||||||
|
|
||||||
giveBonus.id = h->id.getNum();
|
giveBonus.id = h->id.getNum();
|
||||||
|
|
||||||
//give all spells with bonus (to allow banned spells)
|
//give all spells with bonus (to allow banned spells)
|
||||||
@ -4107,11 +4107,11 @@ bool CGameHandler::makeCustomAction( BattleAction &ba )
|
|||||||
}
|
}
|
||||||
|
|
||||||
const CSpell * s = SpellID(ba.additionalInfo).toSpell();
|
const CSpell * s = SpellID(ba.additionalInfo).toSpell();
|
||||||
|
|
||||||
BattleSpellCastParameters parameters(gs->curB, h, s);
|
BattleSpellCastParameters parameters(gs->curB, h, s);
|
||||||
parameters.aimToHex(ba.destinationTile);//todo: allow multiple destinations
|
parameters.aimToHex(ba.destinationTile);//todo: allow multiple destinations
|
||||||
parameters.mode = ECastingMode::HERO_CASTING;
|
parameters.mode = ECastingMode::HERO_CASTING;
|
||||||
parameters.selectedStack = gs->curB->battleGetStackByID(ba.selectedStack, false);
|
parameters.selectedStack = gs->curB->battleGetStackByID(ba.selectedStack, false);
|
||||||
|
|
||||||
ESpellCastProblem::ESpellCastProblem escp = gs->curB->battleCanCastThisSpell(h, s, ECastingMode::HERO_CASTING);//todo: should we check aimed cast(battleCanCastThisSpellHere)?
|
ESpellCastProblem::ESpellCastProblem escp = gs->curB->battleCanCastThisSpell(h, s, ECastingMode::HERO_CASTING);//todo: should we check aimed cast(battleCanCastThisSpellHere)?
|
||||||
if(escp != ESpellCastProblem::OK)
|
if(escp != ESpellCastProblem::OK)
|
||||||
@ -4123,9 +4123,9 @@ bool CGameHandler::makeCustomAction( BattleAction &ba )
|
|||||||
|
|
||||||
StartAction start_action(ba);
|
StartAction start_action(ba);
|
||||||
sendAndApply(&start_action); //start spell casting
|
sendAndApply(&start_action); //start spell casting
|
||||||
|
|
||||||
s->battleCast(spellEnv, parameters);
|
s->battleCast(spellEnv, parameters);
|
||||||
|
|
||||||
sendAndApply(&end_action);
|
sendAndApply(&end_action);
|
||||||
if( !gs->curB->battleGetStackByID(gs->curB->activeStack, true))
|
if( !gs->curB->battleGetStackByID(gs->curB->activeStack, true))
|
||||||
{
|
{
|
||||||
@ -4255,8 +4255,8 @@ void CGameHandler::stackTurnTrigger(const CStack * st)
|
|||||||
auto bonus = *RandomGeneratorUtil::nextItem(bl, gs->getRandomGenerator());
|
auto bonus = *RandomGeneratorUtil::nextItem(bl, gs->getRandomGenerator());
|
||||||
auto spellID = SpellID(bonus->subtype);
|
auto spellID = SpellID(bonus->subtype);
|
||||||
const CSpell * spell = SpellID(spellID).toSpell();
|
const CSpell * spell = SpellID(spellID).toSpell();
|
||||||
bl.remove_if([&bonus](Bonus * b){return b==bonus;});
|
bl.remove_if([&bonus](Bonus * b){return b==bonus;});
|
||||||
|
|
||||||
if (gs->curB->battleCanCastThisSpell(st, spell, ECastingMode::ENCHANTER_CASTING) == ESpellCastProblem::OK)
|
if (gs->curB->battleCanCastThisSpell(st, spell, ECastingMode::ENCHANTER_CASTING) == ESpellCastProblem::OK)
|
||||||
{
|
{
|
||||||
BattleSpellCastParameters parameters(gs->curB, st, spell);
|
BattleSpellCastParameters parameters(gs->curB, st, spell);
|
||||||
@ -4265,8 +4265,8 @@ void CGameHandler::stackTurnTrigger(const CStack * st)
|
|||||||
parameters.aimToHex(BattleHex::INVALID);
|
parameters.aimToHex(BattleHex::INVALID);
|
||||||
parameters.mode = ECastingMode::ENCHANTER_CASTING;
|
parameters.mode = ECastingMode::ENCHANTER_CASTING;
|
||||||
parameters.selectedStack = nullptr;
|
parameters.selectedStack = nullptr;
|
||||||
|
|
||||||
spell->battleCast(spellEnv, parameters);
|
spell->battleCast(spellEnv, parameters);
|
||||||
|
|
||||||
//todo: move to mechanics
|
//todo: move to mechanics
|
||||||
BattleSetStackProperty ssp;
|
BattleSetStackProperty ssp;
|
||||||
@ -4275,9 +4275,9 @@ void CGameHandler::stackTurnTrigger(const CStack * st)
|
|||||||
ssp.val = bonus->additionalInfo; //increase cooldown counter
|
ssp.val = bonus->additionalInfo; //increase cooldown counter
|
||||||
ssp.stackID = st->ID;
|
ssp.stackID = st->ID;
|
||||||
sendAndApply(&ssp);
|
sendAndApply(&ssp);
|
||||||
|
|
||||||
cast = true;
|
cast = true;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
bl = *(st->getBonuses(Selector::type(Bonus::ENCHANTED)));
|
bl = *(st->getBonuses(Selector::type(Bonus::ENCHANTED)));
|
||||||
@ -4383,7 +4383,7 @@ void CGameHandler::handleTimeEvents()
|
|||||||
while(gs->map->events.size() && gs->map->events.front().firstOccurence+1 == gs->day)
|
while(gs->map->events.size() && gs->map->events.front().firstOccurence+1 == gs->day)
|
||||||
{
|
{
|
||||||
CMapEvent ev = gs->map->events.front();
|
CMapEvent ev = gs->map->events.front();
|
||||||
|
|
||||||
for (int player = 0; player < PlayerColor::PLAYER_LIMIT_I; player++)
|
for (int player = 0; player < PlayerColor::PLAYER_LIMIT_I; player++)
|
||||||
{
|
{
|
||||||
auto color = PlayerColor(player);
|
auto color = PlayerColor(player);
|
||||||
@ -4973,7 +4973,7 @@ void CGameHandler::attackCasting(const BattleAttack & bat, Bonus::BonusType atta
|
|||||||
parameters.mode = ECastingMode::AFTER_ATTACK_CASTING;
|
parameters.mode = ECastingMode::AFTER_ATTACK_CASTING;
|
||||||
parameters.selectedStack = nullptr;
|
parameters.selectedStack = nullptr;
|
||||||
|
|
||||||
spell->battleCast(spellEnv, parameters);
|
spell->battleCast(spellEnv, parameters);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -4990,7 +4990,7 @@ void CGameHandler::handleAfterAttackCasting( const BattleAttack & bat )
|
|||||||
const CStack * attacker = gs->curB->battleGetStackByID(bat.stackAttacking);
|
const CStack * attacker = gs->curB->battleGetStackByID(bat.stackAttacking);
|
||||||
if (!attacker) //could be already dead
|
if (!attacker) //could be already dead
|
||||||
return;
|
return;
|
||||||
|
|
||||||
auto cast = [=](SpellID spellID, int power)
|
auto cast = [=](SpellID spellID, int power)
|
||||||
{
|
{
|
||||||
const CSpell * spell = SpellID(spellID).toSpell();
|
const CSpell * spell = SpellID(spellID).toSpell();
|
||||||
@ -4999,13 +4999,13 @@ void CGameHandler::handleAfterAttackCasting( const BattleAttack & bat )
|
|||||||
parameters.spellLvl = 0;
|
parameters.spellLvl = 0;
|
||||||
parameters.effectLevel = 0;
|
parameters.effectLevel = 0;
|
||||||
parameters.aimToStack(gs->curB->battleGetStackByID(bat.bsa.at(0).stackAttacked));
|
parameters.aimToStack(gs->curB->battleGetStackByID(bat.bsa.at(0).stackAttacked));
|
||||||
parameters.effectPower = power;
|
parameters.effectPower = power;
|
||||||
parameters.mode = ECastingMode::AFTER_ATTACK_CASTING;
|
parameters.mode = ECastingMode::AFTER_ATTACK_CASTING;
|
||||||
parameters.selectedStack = nullptr;
|
parameters.selectedStack = nullptr;
|
||||||
|
|
||||||
spell->battleCast(this->spellEnv, parameters);
|
spell->battleCast(this->spellEnv, parameters);
|
||||||
};
|
};
|
||||||
|
|
||||||
attackCasting(bat, Bonus::SPELL_AFTER_ATTACK, attacker);
|
attackCasting(bat, Bonus::SPELL_AFTER_ATTACK, attacker);
|
||||||
|
|
||||||
if(bat.bsa.at(0).newAmount <= 0)
|
if(bat.bsa.at(0).newAmount <= 0)
|
||||||
@ -5056,11 +5056,11 @@ void CGameHandler::handleAfterAttackCasting( const BattleAttack & bat )
|
|||||||
bool CGameHandler::castSpell(const CGHeroInstance *h, SpellID spellID, const int3 &pos)
|
bool CGameHandler::castSpell(const CGHeroInstance *h, SpellID spellID, const int3 &pos)
|
||||||
{
|
{
|
||||||
const CSpell *s = spellID.toSpell();
|
const CSpell *s = spellID.toSpell();
|
||||||
|
|
||||||
AdventureSpellCastParameters p;
|
AdventureSpellCastParameters p;
|
||||||
p.caster = h;
|
p.caster = h;
|
||||||
p.pos = pos;
|
p.pos = pos;
|
||||||
|
|
||||||
return s->adventureCast(spellEnv, p);
|
return s->adventureCast(spellEnv, p);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -5298,8 +5298,8 @@ void CGameHandler::runBattle()
|
|||||||
auto h = gs->curB->battleGetFightingHero(i);
|
auto h = gs->curB->battleGetFightingHero(i);
|
||||||
if(h && h->hasBonusOfType(Bonus::OPENING_BATTLE_SPELL))
|
if(h && h->hasBonusOfType(Bonus::OPENING_BATTLE_SPELL))
|
||||||
{
|
{
|
||||||
TBonusListPtr bl = h->getBonuses(Selector::type(Bonus::OPENING_BATTLE_SPELL));
|
TBonusListPtr bl = h->getBonuses(Selector::type(Bonus::OPENING_BATTLE_SPELL));
|
||||||
|
|
||||||
for (Bonus *b : *bl)
|
for (Bonus *b : *bl)
|
||||||
{
|
{
|
||||||
const CSpell * spell = SpellID(b->subtype).toSpell();
|
const CSpell * spell = SpellID(b->subtype).toSpell();
|
||||||
@ -5308,7 +5308,7 @@ void CGameHandler::runBattle()
|
|||||||
parameters.effectLevel = 3;
|
parameters.effectLevel = 3;
|
||||||
parameters.aimToHex(BattleHex::INVALID);
|
parameters.aimToHex(BattleHex::INVALID);
|
||||||
parameters.mode = ECastingMode::PASSIVE_CASTING;
|
parameters.mode = ECastingMode::PASSIVE_CASTING;
|
||||||
parameters.selectedStack = nullptr;
|
parameters.selectedStack = nullptr;
|
||||||
parameters.enchantPower = b->val;
|
parameters.enchantPower = b->val;
|
||||||
spell->battleCast(spellEnv, parameters);
|
spell->battleCast(spellEnv, parameters);
|
||||||
}
|
}
|
||||||
@ -5347,7 +5347,6 @@ void CGameHandler::runBattle()
|
|||||||
const CStack *next;
|
const CStack *next;
|
||||||
while(!battleResult.get() && (next = curB.getNextStack()) && next->willMove())
|
while(!battleResult.get() && (next = curB.getNextStack()) && next->willMove())
|
||||||
{
|
{
|
||||||
|
|
||||||
//check for bad morale => freeze
|
//check for bad morale => freeze
|
||||||
int nextStackMorale = next->MoraleVal();
|
int nextStackMorale = next->MoraleVal();
|
||||||
if( nextStackMorale < 0 &&
|
if( nextStackMorale < 0 &&
|
||||||
@ -5483,7 +5482,7 @@ void CGameHandler::runBattle()
|
|||||||
{
|
{
|
||||||
logGlobal->traceStream() << "Activating " << next->nodeName();
|
logGlobal->traceStream() << "Activating " << next->nodeName();
|
||||||
auto nextId = next->ID;
|
auto nextId = next->ID;
|
||||||
BattleSetActiveStack sas;
|
BattleSetActiveStack sas;
|
||||||
sas.stack = nextId;
|
sas.stack = nextId;
|
||||||
sendAndApply(&sas);
|
sendAndApply(&sas);
|
||||||
|
|
||||||
@ -5689,7 +5688,7 @@ bool CGameHandler::isValidObject(const CGObjectInstance *obj) const
|
|||||||
|
|
||||||
bool CGameHandler::isBlockedByQueries(const CPack *pack, PlayerColor player)
|
bool CGameHandler::isBlockedByQueries(const CPack *pack, PlayerColor player)
|
||||||
{
|
{
|
||||||
if(dynamic_cast<const PlayerMessage*>(pack))
|
if(!strcmp(typeid(*pack).name(), typeid(PlayerMessage).name()))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
auto query = queries.topQuery(player);
|
auto query = queries.topQuery(player);
|
||||||
@ -5827,7 +5826,7 @@ CasualtiesAfterBattle::CasualtiesAfterBattle(const CArmedInstance *army, BattleI
|
|||||||
auto warMachine = VLC->arth->creatureToMachineID(st->type->idNumber);
|
auto warMachine = VLC->arth->creatureToMachineID(st->type->idNumber);
|
||||||
if (warMachine != ArtifactID::NONE)
|
if (warMachine != ArtifactID::NONE)
|
||||||
{
|
{
|
||||||
auto hero = dynamic_cast<const CGHeroInstance*> (army);
|
auto hero = dynamic_ptr_cast<CGHeroInstance> (army);
|
||||||
if (hero)
|
if (hero)
|
||||||
removedWarMachines.push_back (ArtifactLocation(hero, hero->getArtPos(warMachine, true)));
|
removedWarMachines.push_back (ArtifactLocation(hero, hero->getArtPos(warMachine, true)));
|
||||||
}
|
}
|
||||||
@ -5900,7 +5899,7 @@ CGameHandler::FinishingBattleHelper::FinishingBattleHelper()
|
|||||||
///ServerSpellCastEnvironment
|
///ServerSpellCastEnvironment
|
||||||
ServerSpellCastEnvironment::ServerSpellCastEnvironment(CGameHandler * gh): gh(gh)
|
ServerSpellCastEnvironment::ServerSpellCastEnvironment(CGameHandler * gh): gh(gh)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ServerSpellCastEnvironment::sendAndApply(CPackForClient * info) const
|
void ServerSpellCastEnvironment::sendAndApply(CPackForClient * info) const
|
||||||
@ -5933,4 +5932,3 @@ bool ServerSpellCastEnvironment::moveHero(ObjectInstanceID hid, int3 dst, ui8 te
|
|||||||
{
|
{
|
||||||
return gh->moveHero(hid, dst, teleporting, false, asker);
|
return gh->moveHero(hid, dst, teleporting, false, asker);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -97,11 +97,11 @@ CObjectVisitQuery::CObjectVisitQuery(const CGObjectInstance *Obj, const CGHeroIn
|
|||||||
addPlayer(Hero->tempOwner);
|
addPlayer(Hero->tempOwner);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CObjectVisitQuery::blocksPack(const CPack *pack) const
|
bool CObjectVisitQuery::blocksPack(const CPack *pack) const
|
||||||
{
|
{
|
||||||
//During the visit itself ALL actions are blocked.
|
//During the visit itself ALL actions are blocked.
|
||||||
//(However, the visit may trigger a query above that'll pass some.)
|
//(However, the visit may trigger a query above that'll pass some.)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CObjectVisitQuery::onRemoval(CGameHandler *gh, PlayerColor color)
|
void CObjectVisitQuery::onRemoval(CGameHandler *gh, PlayerColor color)
|
||||||
@ -220,7 +220,7 @@ std::vector<shared_ptr<CQuery>> Queries::allQueries()
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CBattleQuery::notifyObjectAboutRemoval(const CObjectVisitQuery &objectVisit) const
|
void CBattleQuery::notifyObjectAboutRemoval(const CObjectVisitQuery &objectVisit) const
|
||||||
{
|
{
|
||||||
assert(result);
|
assert(result);
|
||||||
objectVisit.visitedObject->battleFinished(objectVisit.visitingHero, *result);
|
objectVisit.visitedObject->battleFinished(objectVisit.visitingHero, *result);
|
||||||
@ -242,9 +242,14 @@ CBattleQuery::CBattleQuery()
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CBattleQuery::blocksPack(const CPack *pack) const
|
bool CBattleQuery::blocksPack(const CPack *pack) const
|
||||||
{
|
{
|
||||||
return !dynamic_cast<const MakeAction*>(pack) && !dynamic_cast<const MakeCustomAction*>(pack);
|
#ifndef __APPLE__
|
||||||
|
bool dynamic_success = !dynamic_cast<const MakeAction*>(pack) && !dynamic_cast<const MakeCustomAction*>(pack);
|
||||||
|
#else
|
||||||
|
const char * name = typeid(*pack).name();
|
||||||
|
return strcmp(name, typeid(MakeAction).name()) && strcmp(name, typeid(MakeCustomAction).name());
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void CBattleQuery::onRemoval(CGameHandler *gh, PlayerColor color)
|
void CBattleQuery::onRemoval(CGameHandler *gh, PlayerColor color)
|
||||||
@ -252,7 +257,7 @@ void CBattleQuery::onRemoval(CGameHandler *gh, PlayerColor color)
|
|||||||
gh->battleAfterLevelUp(*result);
|
gh->battleAfterLevelUp(*result);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CGarrisonDialogQuery::notifyObjectAboutRemoval(const CObjectVisitQuery &objectVisit) const
|
void CGarrisonDialogQuery::notifyObjectAboutRemoval(const CObjectVisitQuery &objectVisit) const
|
||||||
{
|
{
|
||||||
objectVisit.visitedObject->garrisonDialogClosed(objectVisit.visitingHero);
|
objectVisit.visitedObject->garrisonDialogClosed(objectVisit.visitingHero);
|
||||||
}
|
}
|
||||||
@ -266,18 +271,18 @@ CGarrisonDialogQuery::CGarrisonDialogQuery(const CArmedInstance *up, const CArme
|
|||||||
addPlayer(down->tempOwner);
|
addPlayer(down->tempOwner);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CGarrisonDialogQuery::blocksPack(const CPack *pack) const
|
bool CGarrisonDialogQuery::blocksPack(const CPack *pack) const
|
||||||
{
|
{
|
||||||
std::set<ObjectInstanceID> ourIds;
|
std::set<ObjectInstanceID> ourIds;
|
||||||
ourIds.insert(this->exchangingArmies[0]->id);
|
ourIds.insert(this->exchangingArmies[0]->id);
|
||||||
ourIds.insert(this->exchangingArmies[1]->id);
|
ourIds.insert(this->exchangingArmies[1]->id);
|
||||||
|
|
||||||
|
if (auto stacks = dynamic_ptr_cast<ArrangeStacks>(pack))
|
||||||
if (auto stacks = dynamic_cast<const ArrangeStacks*>(pack))
|
|
||||||
{
|
{
|
||||||
return !vstd::contains(ourIds, stacks->id1) || !vstd::contains(ourIds, stacks->id2);
|
return !vstd::contains(ourIds, stacks->id1) || !vstd::contains(ourIds, stacks->id2);
|
||||||
}
|
}
|
||||||
if (auto arts = dynamic_cast<const ExchangeArtifacts*>(pack))
|
|
||||||
|
if (auto arts = dynamic_ptr_cast<ExchangeArtifacts>(pack))
|
||||||
{
|
{
|
||||||
if(auto id1 = boost::apply_visitor(GetEngagedHeroIds(), arts->src.artHolder))
|
if(auto id1 = boost::apply_visitor(GetEngagedHeroIds(), arts->src.artHolder))
|
||||||
if(!vstd::contains(ourIds, *id1))
|
if(!vstd::contains(ourIds, *id1))
|
||||||
@ -288,24 +293,24 @@ bool CGarrisonDialogQuery::blocksPack(const CPack *pack) const
|
|||||||
return true;
|
return true;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (auto dismiss = dynamic_cast<const DisbandCreature*>(pack))
|
if (auto dismiss = dynamic_ptr_cast<DisbandCreature>(pack))
|
||||||
{
|
{
|
||||||
return !vstd::contains(ourIds, dismiss->id);
|
return !vstd::contains(ourIds, dismiss->id);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (auto dismiss = dynamic_cast<const AssembleArtifacts*>(pack))
|
if (auto dismiss = dynamic_ptr_cast<AssembleArtifacts>(pack))
|
||||||
{
|
{
|
||||||
return !vstd::contains(ourIds, dismiss->heroID);
|
return !vstd::contains(ourIds, dismiss->heroID);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(auto upgrade = dynamic_cast<const UpgradeCreature*>(pack))
|
if(auto upgrade = dynamic_ptr_cast<UpgradeCreature>(pack))
|
||||||
{
|
{
|
||||||
return !vstd::contains(ourIds, upgrade->id);
|
return !vstd::contains(ourIds, upgrade->id);
|
||||||
}
|
}
|
||||||
return CDialogQuery::blocksPack(pack);
|
return CDialogQuery::blocksPack(pack);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CBlockingDialogQuery::notifyObjectAboutRemoval(const CObjectVisitQuery &objectVisit) const
|
void CBlockingDialogQuery::notifyObjectAboutRemoval(const CObjectVisitQuery &objectVisit) const
|
||||||
{
|
{
|
||||||
assert(answer);
|
assert(answer);
|
||||||
objectVisit.visitedObject->blockingDialogAnswered(objectVisit.visitingHero, *answer);
|
objectVisit.visitedObject->blockingDialogAnswered(objectVisit.visitingHero, *answer);
|
||||||
@ -319,7 +324,7 @@ CBlockingDialogQuery::CBlockingDialogQuery(const BlockingDialog &bd)
|
|||||||
|
|
||||||
void CTeleportDialogQuery::notifyObjectAboutRemoval(const CObjectVisitQuery &objectVisit) const
|
void CTeleportDialogQuery::notifyObjectAboutRemoval(const CObjectVisitQuery &objectVisit) const
|
||||||
{
|
{
|
||||||
auto obj = dynamic_cast<const CGTeleport *>(objectVisit.visitedObject);
|
auto obj = dynamic_cast<const CGTeleport*>(objectVisit.visitedObject);
|
||||||
obj->teleportDialogAnswered(objectVisit.visitingHero, *answer, td.exits);
|
obj->teleportDialogAnswered(objectVisit.visitingHero, *answer, td.exits);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -342,7 +347,7 @@ void CHeroLevelUpDialogQuery::onRemoval(CGameHandler *gh, PlayerColor color)
|
|||||||
gh->levelUpHero(hlu.hero, hlu.skills[*answer]);
|
gh->levelUpHero(hlu.hero, hlu.skills[*answer]);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CHeroLevelUpDialogQuery::notifyObjectAboutRemoval(const CObjectVisitQuery &objectVisit) const
|
void CHeroLevelUpDialogQuery::notifyObjectAboutRemoval(const CObjectVisitQuery &objectVisit) const
|
||||||
{
|
{
|
||||||
objectVisit.visitedObject->heroLevelUpDone(objectVisit.visitingHero);
|
objectVisit.visitedObject->heroLevelUpDone(objectVisit.visitingHero);
|
||||||
}
|
}
|
||||||
@ -360,20 +365,20 @@ void CCommanderLevelUpDialogQuery::onRemoval(CGameHandler *gh, PlayerColor color
|
|||||||
gh->levelUpCommander(clu.hero->commander, clu.skills[*answer]);
|
gh->levelUpCommander(clu.hero->commander, clu.skills[*answer]);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CCommanderLevelUpDialogQuery::notifyObjectAboutRemoval(const CObjectVisitQuery &objectVisit) const
|
void CCommanderLevelUpDialogQuery::notifyObjectAboutRemoval(const CObjectVisitQuery &objectVisit) const
|
||||||
{
|
{
|
||||||
objectVisit.visitedObject->heroLevelUpDone(objectVisit.visitingHero);
|
objectVisit.visitedObject->heroLevelUpDone(objectVisit.visitingHero);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CDialogQuery::endsByPlayerAnswer() const
|
bool CDialogQuery::endsByPlayerAnswer() const
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CDialogQuery::blocksPack(const CPack *pack) const
|
bool CDialogQuery::blocksPack(const CPack *pack) const
|
||||||
{
|
{
|
||||||
//We accept only query replies from correct player
|
//We accept only query replies from correct player
|
||||||
if(auto reply = dynamic_cast<const QueryReply *>(pack))
|
if(auto reply = dynamic_ptr_cast<QueryReply>(pack))
|
||||||
{
|
{
|
||||||
return !vstd::contains(players, reply->player);
|
return !vstd::contains(players, reply->player);
|
||||||
}
|
}
|
||||||
|
@ -86,8 +86,8 @@ void CPregameServer::handleConnection(CConnection *cpc)
|
|||||||
logNetwork->infoStream() << "Got package to announce " << typeid(*cpfs).name() << " from " << *cpc;
|
logNetwork->infoStream() << "Got package to announce " << typeid(*cpfs).name() << " from " << *cpc;
|
||||||
|
|
||||||
boost::unique_lock<boost::recursive_mutex> queueLock(mx);
|
boost::unique_lock<boost::recursive_mutex> queueLock(mx);
|
||||||
bool quitting = dynamic_cast<QuitMenuWithoutStarting*>(cpfs),
|
bool quitting = dynamic_ptr_cast<QuitMenuWithoutStarting>(cpfs),
|
||||||
startingGame = dynamic_cast<StartWithCurrentSettings*>(cpfs);
|
startingGame = dynamic_ptr_cast<StartWithCurrentSettings>(cpfs);
|
||||||
if(quitting || startingGame) //host leaves main menu or wants to start game -> we end
|
if(quitting || startingGame) //host leaves main menu or wants to start game -> we end
|
||||||
{
|
{
|
||||||
cpc->receivedStop = true;
|
cpc->receivedStop = true;
|
||||||
@ -258,11 +258,11 @@ void CPregameServer::sendPack(CConnection * pc, const CPackForSelectionScreen &
|
|||||||
*pc << &pack;
|
*pc << &pack;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(dynamic_cast<const QuitMenuWithoutStarting*>(&pack))
|
if(dynamic_ptr_cast<QuitMenuWithoutStarting>(&pack))
|
||||||
{
|
{
|
||||||
pc->sendStop = true;
|
pc->sendStop = true;
|
||||||
}
|
}
|
||||||
else if(dynamic_cast<const StartWithCurrentSettings*>(&pack))
|
else if(dynamic_ptr_cast<StartWithCurrentSettings>(&pack))
|
||||||
{
|
{
|
||||||
pc->sendStop = true;
|
pc->sendStop = true;
|
||||||
}
|
}
|
||||||
@ -270,25 +270,25 @@ void CPregameServer::sendPack(CConnection * pc, const CPackForSelectionScreen &
|
|||||||
|
|
||||||
void CPregameServer::processPack(CPackForSelectionScreen * pack)
|
void CPregameServer::processPack(CPackForSelectionScreen * pack)
|
||||||
{
|
{
|
||||||
if(dynamic_cast<CPregamePackToHost*>(pack))
|
if(dynamic_ptr_cast<CPregamePackToHost>(pack))
|
||||||
{
|
{
|
||||||
sendPack(host, *pack);
|
sendPack(host, *pack);
|
||||||
}
|
}
|
||||||
else if(SelectMap *sm = dynamic_cast<SelectMap*>(pack))
|
else if(SelectMap *sm = dynamic_ptr_cast<SelectMap>(pack))
|
||||||
{
|
{
|
||||||
vstd::clear_pointer(curmap);
|
vstd::clear_pointer(curmap);
|
||||||
curmap = sm->mapInfo;
|
curmap = sm->mapInfo;
|
||||||
sm->free = false;
|
sm->free = false;
|
||||||
announcePack(*pack);
|
announcePack(*pack);
|
||||||
}
|
}
|
||||||
else if(UpdateStartOptions *uso = dynamic_cast<UpdateStartOptions*>(pack))
|
else if(UpdateStartOptions *uso = dynamic_ptr_cast<UpdateStartOptions>(pack))
|
||||||
{
|
{
|
||||||
vstd::clear_pointer(curStartInfo);
|
vstd::clear_pointer(curStartInfo);
|
||||||
curStartInfo = uso->options;
|
curStartInfo = uso->options;
|
||||||
uso->free = false;
|
uso->free = false;
|
||||||
announcePack(*pack);
|
announcePack(*pack);
|
||||||
}
|
}
|
||||||
else if(dynamic_cast<const StartWithCurrentSettings*>(pack))
|
else if(dynamic_ptr_cast<StartWithCurrentSettings>(pack))
|
||||||
{
|
{
|
||||||
state = ENDING_AND_STARTING_GAME;
|
state = ENDING_AND_STARTING_GAME;
|
||||||
announcePack(*pack);
|
announcePack(*pack);
|
||||||
@ -307,7 +307,7 @@ void CPregameServer::initConnection(CConnection *c)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void CPregameServer::startListeningThread(CConnection * pc)
|
void CPregameServer::startListeningThread(CConnection * pc)
|
||||||
{
|
{
|
||||||
listeningThreads++;
|
listeningThreads++;
|
||||||
pc->enterPregameConnectionMode();
|
pc->enterPregameConnectionMode();
|
||||||
pc->handler = new boost::thread(&CPregameServer::handleConnection, this, pc);
|
pc->handler = new boost::thread(&CPregameServer::handleConnection, this, pc);
|
||||||
@ -355,7 +355,7 @@ void CVCMIServer::newGame()
|
|||||||
{
|
{
|
||||||
CConnection &c = *firstConnection;
|
CConnection &c = *firstConnection;
|
||||||
ui8 clients;
|
ui8 clients;
|
||||||
c >> clients; //how many clients should be connected
|
c >> clients; //how many clients should be connected
|
||||||
assert(clients == 1); //multi goes now by newPregame, TODO: custom lobbies
|
assert(clients == 1); //multi goes now by newPregame, TODO: custom lobbies
|
||||||
|
|
||||||
CGameHandler *gh = initGhFromHostingConnection(c);
|
CGameHandler *gh = initGhFromHostingConnection(c);
|
||||||
@ -469,14 +469,14 @@ void CVCMIServer::loadGame()
|
|||||||
// char sig[8];
|
// char sig[8];
|
||||||
// CMapHeader dum;
|
// CMapHeader dum;
|
||||||
// StartInfo *si;
|
// StartInfo *si;
|
||||||
//
|
//
|
||||||
// CLoadFile lf(CResourceHandler::get("local")->getResourceName(ResourceID(fname, EResType::LIB_SAVEGAME)));
|
// CLoadFile lf(CResourceHandler::get("local")->getResourceName(ResourceID(fname, EResType::LIB_SAVEGAME)));
|
||||||
// lf >> sig >> dum >> si;
|
// lf >> sig >> dum >> si;
|
||||||
// logNetwork->infoStream() <<"Reading save signature";
|
// logNetwork->infoStream() <<"Reading save signature";
|
||||||
//
|
//
|
||||||
// lf >> *VLC;
|
// lf >> *VLC;
|
||||||
// logNetwork->infoStream() <<"Reading handlers";
|
// logNetwork->infoStream() <<"Reading handlers";
|
||||||
//
|
//
|
||||||
// lf >> (gh.gs);
|
// lf >> (gh.gs);
|
||||||
// c.addStdVecItems(gh.gs);
|
// c.addStdVecItems(gh.gs);
|
||||||
// logNetwork->infoStream() <<"Reading gamestate";
|
// logNetwork->infoStream() <<"Reading gamestate";
|
||||||
@ -493,7 +493,7 @@ void CVCMIServer::loadGame()
|
|||||||
CConnection* cc; //tcp::socket * ss;
|
CConnection* cc; //tcp::socket * ss;
|
||||||
for(int i=0; i<clients; i++)
|
for(int i=0; i<clients; i++)
|
||||||
{
|
{
|
||||||
if(!i)
|
if(!i)
|
||||||
{
|
{
|
||||||
cc = &c;
|
cc = &c;
|
||||||
}
|
}
|
||||||
@ -508,7 +508,7 @@ void CVCMIServer::loadGame()
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
cc = new CConnection(s,NAME);
|
cc = new CConnection(s,NAME);
|
||||||
}
|
}
|
||||||
gh.conns.insert(cc);
|
gh.conns.insert(cc);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -531,7 +531,7 @@ static void handleCommandOptions(int argc, char *argv[])
|
|||||||
{
|
{
|
||||||
po::store(po::parse_command_line(argc, argv, opts), cmdLineOptions);
|
po::store(po::parse_command_line(argc, argv, opts), cmdLineOptions);
|
||||||
}
|
}
|
||||||
catch(std::exception &e)
|
catch(std::exception &e)
|
||||||
{
|
{
|
||||||
std::cerr << "Failure during parsing command-line options:\n" << e.what() << std::endl;
|
std::cerr << "Failure during parsing command-line options:\n" << e.what() << std::endl;
|
||||||
}
|
}
|
||||||
|
@ -89,7 +89,7 @@ bool MoveHero::applyGh( CGameHandler *gh )
|
|||||||
bool CastleTeleportHero::applyGh( CGameHandler *gh )
|
bool CastleTeleportHero::applyGh( CGameHandler *gh )
|
||||||
{
|
{
|
||||||
ERROR_IF_NOT_OWNS(hid);
|
ERROR_IF_NOT_OWNS(hid);
|
||||||
|
|
||||||
return gh->teleportHero(hid,dest,source,gh->getPlayerAt(c));
|
return gh->teleportHero(hid,dest,source,gh->getPlayerAt(c));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -126,7 +126,7 @@ bool GarrisonHeroSwap::applyGh( CGameHandler *gh )
|
|||||||
{
|
{
|
||||||
const CGTownInstance * town = gh->getTown(tid);
|
const CGTownInstance * town = gh->getTown(tid);
|
||||||
if (!PLAYER_OWNS(tid) && !( town->garrisonHero && PLAYER_OWNS(town->garrisonHero->id) ) )
|
if (!PLAYER_OWNS(tid) && !( town->garrisonHero && PLAYER_OWNS(town->garrisonHero->id) ) )
|
||||||
ERROR_AND_RETURN;//neither town nor garrisoned hero (if present) is ours
|
ERROR_AND_RETURN;//neither town nor garrisoned hero (if present) is ours
|
||||||
return gh->garrisonSwap(tid);
|
return gh->garrisonSwap(tid);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -201,7 +201,7 @@ bool TradeOnMarketplace::applyGh( CGameHandler *gh )
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool SetFormation::applyGh( CGameHandler *gh )
|
bool SetFormation::applyGh( CGameHandler *gh )
|
||||||
{
|
{
|
||||||
ERROR_IF_NOT_OWNS(hid);
|
ERROR_IF_NOT_OWNS(hid);
|
||||||
return gh->setFormation(hid,formation);
|
return gh->setFormation(hid,formation);
|
||||||
}
|
}
|
||||||
@ -209,7 +209,7 @@ bool SetFormation::applyGh( CGameHandler *gh )
|
|||||||
bool HireHero::applyGh( CGameHandler *gh )
|
bool HireHero::applyGh( CGameHandler *gh )
|
||||||
{
|
{
|
||||||
const CGObjectInstance *obj = gh->getObj(tid);
|
const CGObjectInstance *obj = gh->getObj(tid);
|
||||||
const CGTownInstance *town = dynamic_cast<const CGTownInstance *>(obj);
|
const CGTownInstance *town = dynamic_ptr_cast<CGTownInstance>(obj);
|
||||||
if(town && PlayerRelations::ENEMIES == gh->getPlayerRelations(obj->tempOwner, gh->getPlayerAt(c)))
|
if(town && PlayerRelations::ENEMIES == gh->getPlayerRelations(obj->tempOwner, gh->getPlayerAt(c)))
|
||||||
COMPLAIN_AND_RETURN("Can't buy hero in enemy town!");
|
COMPLAIN_AND_RETURN("Can't buy hero in enemy town!");
|
||||||
|
|
||||||
@ -240,16 +240,16 @@ bool MakeAction::applyGh( CGameHandler *gh )
|
|||||||
{
|
{
|
||||||
const BattleInfo *b = GS(gh)->curB;
|
const BattleInfo *b = GS(gh)->curB;
|
||||||
if(!b) ERROR_AND_RETURN;
|
if(!b) ERROR_AND_RETURN;
|
||||||
|
|
||||||
if(b->tacticDistance)
|
if(b->tacticDistance)
|
||||||
{
|
{
|
||||||
if(ba.actionType != Battle::WALK && ba.actionType != Battle::END_TACTIC_PHASE
|
if(ba.actionType != Battle::WALK && ba.actionType != Battle::END_TACTIC_PHASE
|
||||||
&& ba.actionType != Battle::RETREAT && ba.actionType != Battle::SURRENDER)
|
&& ba.actionType != Battle::RETREAT && ba.actionType != Battle::SURRENDER)
|
||||||
ERROR_AND_RETURN;
|
ERROR_AND_RETURN;
|
||||||
if(gh->connections[b->sides[b->tacticsSide].color] != c)
|
if(gh->connections[b->sides[b->tacticsSide].color] != c)
|
||||||
ERROR_AND_RETURN;
|
ERROR_AND_RETURN;
|
||||||
}
|
}
|
||||||
else if(gh->connections[b->battleGetStackByID(b->activeStack)->owner] != c)
|
else if(gh->connections[b->battleGetStackByID(b->activeStack)->owner] != c)
|
||||||
ERROR_AND_RETURN;
|
ERROR_AND_RETURN;
|
||||||
|
|
||||||
return gh->makeBattleAction(ba);
|
return gh->makeBattleAction(ba);
|
||||||
|
@ -8,3 +8,31 @@
|
|||||||
#include <boost/random/mersenne_twister.hpp>
|
#include <boost/random/mersenne_twister.hpp>
|
||||||
#include <boost/random/variate_generator.hpp>
|
#include <boost/random/variate_generator.hpp>
|
||||||
#include <boost/system/system_error.hpp>
|
#include <boost/system/system_error.hpp>
|
||||||
|
|
||||||
|
template<class T, class F>
|
||||||
|
inline const T * dynamic_ptr_cast(const F * ptr)
|
||||||
|
{
|
||||||
|
#ifndef __APPLE__
|
||||||
|
return dynamic_cast<const T*>(ptr);
|
||||||
|
#else
|
||||||
|
if (!strcmp(typeid(*ptr).name(), typeid(T).name()))
|
||||||
|
{
|
||||||
|
return static_cast<const T*>(ptr);
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T, class F>
|
||||||
|
inline T * dynamic_ptr_cast(F * ptr)
|
||||||
|
{
|
||||||
|
#ifndef __APPLE__
|
||||||
|
return dynamic_cast<T*>(ptr);
|
||||||
|
#else
|
||||||
|
if (!strcmp(typeid(*ptr).name(), typeid(T).name()))
|
||||||
|
{
|
||||||
|
return static_cast<T*>(ptr);
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user