mirror of
https://github.com/vcmi/vcmi.git
synced 2024-12-24 22:14:36 +02:00
Refactoing of pathfinder <-> client/AI interaction to remove dependency on selected hero
- finished removal of server-side setSelection - disabled some broken code (AI & cheats). TODO: fix
This commit is contained in:
parent
78709e223b
commit
6c0c03d74b
@ -175,9 +175,11 @@ std::string strFromInt3(int3 pos)
|
|||||||
return oss.str();
|
return oss.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isCloser(const CGObjectInstance *lhs, const CGObjectInstance *rhs)
|
bool CDistanceSorter::operator ()(const CGObjectInstance *lhs, const CGObjectInstance *rhs)
|
||||||
{
|
{
|
||||||
const CGPathNode *ln = cb->getPathInfo(lhs->visitablePos()), *rn = cb->getPathInfo(rhs->visitablePos());
|
const CGPathNode *ln = ai->myCb->getPathsInfo(hero)->getPathInfo(lhs->visitablePos()),
|
||||||
|
*rn = ai->myCb->getPathsInfo(hero)->getPathInfo(rhs->visitablePos());
|
||||||
|
|
||||||
if(ln->turns != rn->turns)
|
if(ln->turns != rn->turns)
|
||||||
return ln->turns < rn->turns;
|
return ln->turns < rn->turns;
|
||||||
|
|
||||||
@ -340,11 +342,6 @@ bool isSafeToVisit(HeroPtr h, crint3 tile)
|
|||||||
return true; //there's no danger
|
return true; //there's no danger
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isReachable(const CGObjectInstance *obj)
|
|
||||||
{
|
|
||||||
return cb->getPathInfo(obj->visitablePos())->turns < 255;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool canBeEmbarkmentPoint(const TerrainTile *t, bool fromWater)
|
bool canBeEmbarkmentPoint(const TerrainTile *t, bool fromWater)
|
||||||
{
|
{
|
||||||
//tile must be free of with unoccupied boat
|
//tile must be free of with unoccupied boat
|
||||||
@ -356,7 +353,7 @@ bool canBeEmbarkmentPoint(const TerrainTile *t, bool fromWater)
|
|||||||
int3 whereToExplore(HeroPtr h)
|
int3 whereToExplore(HeroPtr h)
|
||||||
{
|
{
|
||||||
TimeCheck tc ("where to explore");
|
TimeCheck tc ("where to explore");
|
||||||
cb->setSelection(*h);
|
ai->setSelection(*h);
|
||||||
int radius = h->getSightRadious();
|
int radius = h->getSightRadious();
|
||||||
int3 hpos = h->visitablePos();
|
int3 hpos = h->visitablePos();
|
||||||
|
|
||||||
@ -371,7 +368,7 @@ int3 whereToExplore(HeroPtr h)
|
|||||||
{
|
{
|
||||||
int3 op = obj->visitablePos();
|
int3 op = obj->visitablePos();
|
||||||
CGPath p;
|
CGPath p;
|
||||||
cb->getPath2(op, p);
|
ai->myCb->getPathsInfo(h.get())->getPath(op, p);
|
||||||
if (p.nodes.size() && p.endPos() == op && p.nodes.size() <= DIST_LIMIT)
|
if (p.nodes.size() && p.endPos() == op && p.nodes.size() <= DIST_LIMIT)
|
||||||
if (ai->isGoodForVisit(obj, h))
|
if (ai->isGoodForVisit(obj, h))
|
||||||
nearbyVisitableObjs.push_back(obj);
|
nearbyVisitableObjs.push_back(obj);
|
||||||
@ -379,7 +376,7 @@ int3 whereToExplore(HeroPtr h)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
vstd::removeDuplicates (nearbyVisitableObjs); //one object may occupy multiple tiles
|
vstd::removeDuplicates (nearbyVisitableObjs); //one object may occupy multiple tiles
|
||||||
boost::sort(nearbyVisitableObjs, isCloser);
|
boost::sort(nearbyVisitableObjs, CDistanceSorter(h.get()));
|
||||||
if(nearbyVisitableObjs.size())
|
if(nearbyVisitableObjs.size())
|
||||||
return nearbyVisitableObjs.back()->visitablePos();
|
return nearbyVisitableObjs.back()->visitablePos();
|
||||||
|
|
||||||
@ -396,8 +393,8 @@ int3 whereToExplore(HeroPtr h)
|
|||||||
|
|
||||||
bool isBlockedBorderGate(int3 tileToHit)
|
bool isBlockedBorderGate(int3 tileToHit)
|
||||||
{
|
{
|
||||||
return cb->getTile(tileToHit)->topVisitableId() == Obj::BORDER_GATE
|
return cb->getTile(tileToHit)->topVisitableId() == Obj::BORDER_GATE &&
|
||||||
&& cb->getPathInfo(tileToHit)->accessible != CGPathNode::ACCESSIBLE;
|
(dynamic_cast <const CGKeys *>(cb->getTile(tileToHit)->visitableObjects.back()))->wasMyColorVisited (ai->playerID);
|
||||||
}
|
}
|
||||||
|
|
||||||
int howManyTilesWillBeDiscovered(const int3 &pos, int radious, CCallback * cbp)
|
int howManyTilesWillBeDiscovered(const int3 &pos, int radious, CCallback * cbp)
|
||||||
|
@ -146,8 +146,6 @@ void getVisibleNeighbours(const std::vector<int3> &tiles, std::vector<int3> &out
|
|||||||
|
|
||||||
bool canBeEmbarkmentPoint(const TerrainTile *t, bool fromWater);
|
bool canBeEmbarkmentPoint(const TerrainTile *t, bool fromWater);
|
||||||
bool isBlockedBorderGate(int3 tileToHit);
|
bool isBlockedBorderGate(int3 tileToHit);
|
||||||
bool isReachable(const CGObjectInstance *obj);
|
|
||||||
bool isCloser(const CGObjectInstance *lhs, const CGObjectInstance *rhs);
|
|
||||||
|
|
||||||
bool isWeeklyRevisitable (const CGObjectInstance * obj);
|
bool isWeeklyRevisitable (const CGObjectInstance * obj);
|
||||||
bool shouldVisit (HeroPtr h, const CGObjectInstance * obj);
|
bool shouldVisit (HeroPtr h, const CGObjectInstance * obj);
|
||||||
@ -162,3 +160,12 @@ bool compareHeroStrength(HeroPtr h1, HeroPtr h2);
|
|||||||
bool compareArmyStrength(const CArmedInstance *a1, const CArmedInstance *a2);
|
bool compareArmyStrength(const CArmedInstance *a1, const CArmedInstance *a2);
|
||||||
ui64 howManyReinforcementsCanGet(HeroPtr h, const CGTownInstance *t);
|
ui64 howManyReinforcementsCanGet(HeroPtr h, const CGTownInstance *t);
|
||||||
int3 whereToExplore(HeroPtr h);
|
int3 whereToExplore(HeroPtr h);
|
||||||
|
|
||||||
|
class CDistanceSorter
|
||||||
|
{
|
||||||
|
const CGHeroInstance * hero;
|
||||||
|
public:
|
||||||
|
CDistanceSorter(const CGHeroInstance * hero): hero(hero) {}
|
||||||
|
|
||||||
|
bool operator ()(const CGObjectInstance *lhs, const CGObjectInstance *rhs);
|
||||||
|
};
|
||||||
|
@ -405,7 +405,7 @@ float FuzzyHelper::evaluate (Goals::VisitTile & g)
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
//assert(cb->isInTheMap(g.tile));
|
//assert(cb->isInTheMap(g.tile));
|
||||||
cb->setSelection (g.hero.h);
|
ai->setSelection (g.hero.h);
|
||||||
float turns = 0;
|
float turns = 0;
|
||||||
float distance = cb->getMovementCost(g.hero.h, g.tile);
|
float distance = cb->getMovementCost(g.hero.h, g.tile);
|
||||||
if (!distance) //we stand on that tile
|
if (!distance) //we stand on that tile
|
||||||
|
@ -256,7 +256,7 @@ TSubgoal Win::whatToDoToAchieve()
|
|||||||
return vstd::contains(t->forbiddenBuildings, BuildingID::GRAIL);
|
return vstd::contains(t->forbiddenBuildings, BuildingID::GRAIL);
|
||||||
}),
|
}),
|
||||||
towns.end());
|
towns.end());
|
||||||
boost::sort(towns, isCloser);
|
boost::sort(towns, CDistanceSorter(h.get()));
|
||||||
if(towns.size())
|
if(towns.size())
|
||||||
{
|
{
|
||||||
return sptr (Goals::VisitTile(towns.front()->visitablePos()).sethero(h));
|
return sptr (Goals::VisitTile(towns.front()->visitablePos()).sethero(h));
|
||||||
@ -353,7 +353,7 @@ TSubgoal FindObj::whatToDoToAchieve()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (o && isReachable(o)) //we don't use isAccessibleForHero as we don't know which hero it is
|
if (o)// FIXME: re-enable with *some* hero && isReachable(o)) //we don't use isAccessibleForHero as we don't know which hero it is
|
||||||
return sptr (Goals::GetObj(o->id.getNum()));
|
return sptr (Goals::GetObj(o->id.getNum()));
|
||||||
else
|
else
|
||||||
return sptr (Goals::Explore());
|
return sptr (Goals::Explore());
|
||||||
@ -377,7 +377,7 @@ TSubgoal GetObj::whatToDoToAchieve()
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (isReachable(obj))
|
//if (isReachable(obj)) //FIXME: re-enable with some hero
|
||||||
return sptr (Goals::VisitTile(pos).sethero(hero)); //we must visit object with same hero, if any
|
return sptr (Goals::VisitTile(pos).sethero(hero)); //we must visit object with same hero, if any
|
||||||
}
|
}
|
||||||
return sptr (Goals::ClearWayTo(pos).sethero(hero));
|
return sptr (Goals::ClearWayTo(pos).sethero(hero));
|
||||||
@ -853,7 +853,8 @@ TSubgoal GatherTroops::whatToDoToAchieve()
|
|||||||
}
|
}
|
||||||
if (dwellings.size())
|
if (dwellings.size())
|
||||||
{
|
{
|
||||||
boost::sort(dwellings, isCloser);
|
//FIXME: we need hero to sort dwellings by distance
|
||||||
|
//boost::sort(dwellings, CDistanceSorter(h.get()));
|
||||||
return sptr (Goals::GetObj(dwellings.front()->id.getNum()));
|
return sptr (Goals::GetObj(dwellings.front()->id.getNum()));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -95,6 +95,7 @@ VCAI::VCAI(void)
|
|||||||
{
|
{
|
||||||
LOG_TRACE(logAi);
|
LOG_TRACE(logAi);
|
||||||
makingTurn = nullptr;
|
makingTurn = nullptr;
|
||||||
|
currentSelection = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
VCAI::~VCAI(void)
|
VCAI::~VCAI(void)
|
||||||
@ -664,9 +665,6 @@ void VCAI::makeTurn()
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
//FIXME: necessary? How to re-enable?
|
|
||||||
//cb->recalculatePaths(cb->getSelectedHero());
|
|
||||||
|
|
||||||
markHeroAbleToExplore (primaryHero());
|
markHeroAbleToExplore (primaryHero());
|
||||||
|
|
||||||
makeTurnInternal();
|
makeTurnInternal();
|
||||||
@ -697,9 +695,9 @@ void VCAI::makeTurnInternal()
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
cb->setSelection(hero.first.get());
|
setSelection(hero.first.get());
|
||||||
std::vector<const CGObjectInstance *> vec(hero.second.begin(), hero.second.end());
|
std::vector<const CGObjectInstance *> vec(hero.second.begin(), hero.second.end());
|
||||||
boost::sort (vec, isCloser);
|
boost::sort (vec, CDistanceSorter(hero.first.get()));
|
||||||
for (auto obj : vec)
|
for (auto obj : vec)
|
||||||
{
|
{
|
||||||
if(!obj || !cb->getObj(obj->id))
|
if(!obj || !cb->getObj(obj->id))
|
||||||
@ -1222,7 +1220,7 @@ std::vector<const CGObjectInstance *> VCAI::getPossibleDestinations(HeroPtr h)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
boost::sort(possibleDestinations, isCloser);
|
boost::sort(possibleDestinations, CDistanceSorter(h.get()));
|
||||||
|
|
||||||
return possibleDestinations;
|
return possibleDestinations;
|
||||||
}
|
}
|
||||||
@ -1256,7 +1254,7 @@ bool VCAI::canRecruitAnyHero (const CGTownInstance * t) const
|
|||||||
|
|
||||||
void VCAI::wander(HeroPtr h)
|
void VCAI::wander(HeroPtr h)
|
||||||
{
|
{
|
||||||
cb->setSelection(*h);
|
setSelection(*h);
|
||||||
//unclaim objects that are now dangerous for us
|
//unclaim objects that are now dangerous for us
|
||||||
auto reservedObjsSetCopy = reservedHeroesMap[h];
|
auto reservedObjsSetCopy = reservedHeroesMap[h];
|
||||||
for (auto obj : reservedObjsSetCopy)
|
for (auto obj : reservedObjsSetCopy)
|
||||||
@ -1381,7 +1379,7 @@ void VCAI::wander(HeroPtr h)
|
|||||||
erase_if(dests, shouldBeErased);
|
erase_if(dests, shouldBeErased);
|
||||||
|
|
||||||
erase_if_present(dests, dest); //why that fails sometimes when removing monsters?
|
erase_if_present(dests, dest); //why that fails sometimes when removing monsters?
|
||||||
boost::sort(dests, isCloser); //find next closest one
|
boost::sort(dests, CDistanceSorter(h.get())); //find next closest one
|
||||||
}
|
}
|
||||||
|
|
||||||
if (h->visitedTown)
|
if (h->visitedTown)
|
||||||
@ -1618,7 +1616,6 @@ const CGObjectInstance * VCAI::getUnvisitedObj(const std::function<bool(const CG
|
|||||||
|
|
||||||
bool VCAI::isAccessibleForHero(const int3 & pos, HeroPtr h, bool includeAllies /*= false*/) const
|
bool VCAI::isAccessibleForHero(const int3 & pos, HeroPtr h, bool includeAllies /*= false*/) const
|
||||||
{
|
{
|
||||||
cb->setSelection(*h);
|
|
||||||
if (!includeAllies)
|
if (!includeAllies)
|
||||||
{ //don't visit tile occupied by allied hero
|
{ //don't visit tile occupied by allied hero
|
||||||
for (auto obj : cb->getVisitableObjs(pos))
|
for (auto obj : cb->getVisitableObjs(pos))
|
||||||
@ -1629,12 +1626,12 @@ bool VCAI::isAccessibleForHero(const int3 & pos, HeroPtr h, bool includeAllies /
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return cb->getPathInfo(pos)->reachable();
|
return cb->getPathsInfo(h.get())->getPathInfo(pos)->reachable();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool VCAI::moveHeroToTile(int3 dst, HeroPtr h)
|
bool VCAI::moveHeroToTile(int3 dst, HeroPtr h)
|
||||||
{
|
{
|
||||||
cb->setSelection(h.h); //make sure we are using the RIGHT pathfinder
|
setSelection(h.h); //make sure we are using the RIGHT pathfinder
|
||||||
logAi->debugStream() << boost::format("Moving hero %s to tile %s") % h->name % dst;
|
logAi->debugStream() << boost::format("Moving hero %s to tile %s") % h->name % dst;
|
||||||
int3 startHpos = h->visitablePos();
|
int3 startHpos = h->visitablePos();
|
||||||
bool ret = false;
|
bool ret = false;
|
||||||
@ -1649,11 +1646,10 @@ bool VCAI::moveHeroToTile(int3 dst, HeroPtr h)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
CGPath path;
|
CGPath path;
|
||||||
cb->getPath2(dst, path);
|
cb->getPathsInfo(h.get())->getPath(dst, path);
|
||||||
if(path.nodes.empty())
|
if(path.nodes.empty())
|
||||||
{
|
{
|
||||||
logAi->errorStream() << "Hero " << h->name << " cannot reach " << dst;
|
logAi->errorStream() << "Hero " << h->name << " cannot reach " << dst;
|
||||||
cb->recalculatePaths(h.get());
|
|
||||||
throw goalFulfilledException (sptr(Goals::VisitTile(dst).sethero(h)));
|
throw goalFulfilledException (sptr(Goals::VisitTile(dst).sethero(h)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1702,7 +1698,6 @@ bool VCAI::moveHeroToTile(int3 dst, HeroPtr h)
|
|||||||
reserveObject(h, obj);
|
reserveObject(h, obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
cb->recalculatePaths(h.get());
|
|
||||||
if (startHpos == h->visitablePos() && !ret) //we didn't move and didn't reach the target
|
if (startHpos == h->visitablePos() && !ret) //we didn't move and didn't reach the target
|
||||||
{
|
{
|
||||||
erase_if_present (lockedHeroes, h); //hero seemingly is confused
|
erase_if_present (lockedHeroes, h); //hero seemingly is confused
|
||||||
@ -2190,6 +2185,16 @@ void VCAI::striveToQuest (const QuestInfo &q)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const CArmedInstance * VCAI::getSelection()
|
||||||
|
{
|
||||||
|
return currentSelection;
|
||||||
|
}
|
||||||
|
|
||||||
|
void VCAI::setSelection(const CArmedInstance * obj)
|
||||||
|
{
|
||||||
|
currentSelection = obj;
|
||||||
|
}
|
||||||
|
|
||||||
void VCAI::performTypicalActions()
|
void VCAI::performTypicalActions()
|
||||||
{
|
{
|
||||||
for(auto h : getUnblockedHeroes())
|
for(auto h : getUnblockedHeroes())
|
||||||
@ -2230,7 +2235,7 @@ int3 VCAI::explorationBestNeighbour(int3 hpos, int radius, HeroPtr h)
|
|||||||
auto best = dstToRevealedTiles.begin();
|
auto best = dstToRevealedTiles.begin();
|
||||||
for (auto i = dstToRevealedTiles.begin(); i != dstToRevealedTiles.end(); i++)
|
for (auto i = dstToRevealedTiles.begin(); i != dstToRevealedTiles.end(); i++)
|
||||||
{
|
{
|
||||||
const CGPathNode *pn = cb->getPathInfo(i->first);
|
const CGPathNode *pn = cb->getPathsInfo(h.get())->getPathInfo(i->first);
|
||||||
//const TerrainTile *t = cb->getTile(i->first);
|
//const TerrainTile *t = cb->getTile(i->first);
|
||||||
if(best->second < i->second && pn->reachable() && pn->accessible == CGPathNode::ACCESSIBLE)
|
if(best->second < i->second && pn->reachable() && pn->accessible == CGPathNode::ACCESSIBLE)
|
||||||
best = i;
|
best = i;
|
||||||
@ -2245,7 +2250,7 @@ int3 VCAI::explorationBestNeighbour(int3 hpos, int radius, HeroPtr h)
|
|||||||
int3 VCAI::explorationNewPoint(HeroPtr h)
|
int3 VCAI::explorationNewPoint(HeroPtr h)
|
||||||
{
|
{
|
||||||
//logAi->debugStream() << "Looking for an another place for exploration...";
|
//logAi->debugStream() << "Looking for an another place for exploration...";
|
||||||
cb->setSelection(h.h);
|
setSelection(h.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]
|
||||||
@ -2269,13 +2274,11 @@ int3 VCAI::explorationNewPoint(HeroPtr h)
|
|||||||
|
|
||||||
for(const int3 &tile : tiles[i])
|
for(const int3 &tile : tiles[i])
|
||||||
{
|
{
|
||||||
if (cbp->getTile(tile)->blocked) //does it shorten the time?
|
if (!cb->getPathsInfo(h.get())->getPathInfo(tile)->reachable()) //this will remove tiles that are guarded by monsters (or removable objects)
|
||||||
continue;
|
|
||||||
if (!cbp->getPathInfo(tile)->reachable()) //this will remove tiles that are guarded by monsters (or removable objects)
|
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
CGPath path;
|
CGPath path;
|
||||||
cbp->getPath2(tile, path);
|
cb->getPathsInfo(h.get())->getPath(tile, path);
|
||||||
float ourValue = (float)howManyTilesWillBeDiscovered(tile, radius, cbp) / (path.nodes.size() + 1); //+1 prevents erratic jumps
|
float ourValue = (float)howManyTilesWillBeDiscovered(tile, radius, cbp) / (path.nodes.size() + 1); //+1 prevents erratic jumps
|
||||||
|
|
||||||
if (ourValue > bestValue) //avoid costly checks of tiles that don't reveal much
|
if (ourValue > bestValue) //avoid costly checks of tiles that don't reveal much
|
||||||
@ -2655,7 +2658,7 @@ SectorMap::SectorMap()
|
|||||||
|
|
||||||
SectorMap::SectorMap(HeroPtr h)
|
SectorMap::SectorMap(HeroPtr h)
|
||||||
{
|
{
|
||||||
cb->setSelection(h.h);
|
ai->setSelection(h.h);
|
||||||
update();
|
update();
|
||||||
makeParentBFS(h->visitablePos());
|
makeParentBFS(h->visitablePos());
|
||||||
}
|
}
|
||||||
@ -3104,7 +3107,7 @@ int3 SectorMap::findFirstVisitableTile (HeroPtr h, crint3 dst)
|
|||||||
logAi->warnStream() << ("Another allied hero stands in our way");
|
logAi->warnStream() << ("Another allied hero stands in our way");
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
if(cb->getPathInfo(curtile)->reachable())
|
if(ai->myCb->getPathsInfo(h.get())->getPathInfo(curtile)->reachable())
|
||||||
{
|
{
|
||||||
return curtile;
|
return curtile;
|
||||||
}
|
}
|
||||||
|
@ -124,6 +124,7 @@ const BuildingID extra[] = {BuildingID::RESOURCE_SILO, BuildingID::SPECIAL_1, Bu
|
|||||||
|
|
||||||
class VCAI : public CAdventureAI
|
class VCAI : public CAdventureAI
|
||||||
{
|
{
|
||||||
|
const CArmedInstance * currentSelection;
|
||||||
public:
|
public:
|
||||||
//internal methods for town development
|
//internal methods for town development
|
||||||
|
|
||||||
@ -258,6 +259,9 @@ public:
|
|||||||
void completeGoal (Goals::TSubgoal goal); //safely removes goal from reserved hero
|
void completeGoal (Goals::TSubgoal goal); //safely removes goal from reserved hero
|
||||||
void striveToQuest (const QuestInfo &q);
|
void striveToQuest (const QuestInfo &q);
|
||||||
|
|
||||||
|
const CArmedInstance * getSelection();
|
||||||
|
void setSelection(const CArmedInstance * obj);
|
||||||
|
|
||||||
void recruitHero(const CGTownInstance * t, bool throwing = false);
|
void recruitHero(const CGTownInstance * t, bool throwing = false);
|
||||||
bool isGoodForVisit(const CGObjectInstance *obj, HeroPtr h);
|
bool isGoodForVisit(const CGObjectInstance *obj, HeroPtr h);
|
||||||
std::vector<const CGObjectInstance *> getPossibleDestinations(HeroPtr h);
|
std::vector<const CGObjectInstance *> getPossibleDestinations(HeroPtr h);
|
||||||
|
@ -235,31 +235,6 @@ void CCallback::setFormation(const CGHeroInstance * hero, bool tight)
|
|||||||
sendRequest(&pack);
|
sendRequest(&pack);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CCallback::setSelection(const CArmedInstance * obj)
|
|
||||||
{/*
|
|
||||||
if(!player || obj->getOwner() != *player)
|
|
||||||
{
|
|
||||||
logGlobal->errorStream() << boost::format("Cannot set selection to the object that is not owned. Object owner is %s, callback player %s") % obj->getOwner() % player;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(obj->getOwner() != *player)
|
|
||||||
{
|
|
||||||
// Cf. bug #1679 http://bugs.vcmi.eu/view.php?id=1679
|
|
||||||
logGlobal->warnStream() << "The selection request became invalid because of event that occurred after it was made. Object owner is now " << obj->getOwner();
|
|
||||||
throw std::runtime_error("setSelection not allowed");
|
|
||||||
}
|
|
||||||
|
|
||||||
if(obj->ID == Obj::HERO)
|
|
||||||
{
|
|
||||||
if(cl->pathInfo->hero != obj) //calculate new paths only if we selected a different hero
|
|
||||||
cl->calculatePaths(static_cast<const CGHeroInstance *>(obj));
|
|
||||||
|
|
||||||
//nasty workaround. TODO: nice workaround
|
|
||||||
cl->gs->getPlayer(*player)->currentSelection = obj->id;
|
|
||||||
}*/
|
|
||||||
}
|
|
||||||
|
|
||||||
void CCallback::recruitHero(const CGObjectInstance *townOrTavern, const CGHeroInstance *hero)
|
void CCallback::recruitHero(const CGObjectInstance *townOrTavern, const CGHeroInstance *hero)
|
||||||
{
|
{
|
||||||
assert(townOrTavern);
|
assert(townOrTavern);
|
||||||
@ -309,47 +284,22 @@ CCallback::~CCallback()
|
|||||||
//trivial, but required. Don`t remove.
|
//trivial, but required. Don`t remove.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const CGPathNode * CCallback::getPathInfo( int3 tile )
|
|
||||||
{
|
|
||||||
if (!gs->map->isInTheMap(tile))
|
|
||||||
return nullptr;
|
|
||||||
|
|
||||||
validatePaths();
|
|
||||||
return &cl->pathInfo->nodes[tile.x][tile.y][tile.z];
|
|
||||||
}
|
|
||||||
|
|
||||||
int CCallback::getDistance( int3 tile )
|
|
||||||
{
|
|
||||||
CGPath ret;
|
|
||||||
if (getPath2 (tile, ret))
|
|
||||||
return ret.nodes.size();
|
|
||||||
else
|
|
||||||
return 255;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CCallback::canMoveBetween(const int3 &a, const int3 &b)
|
bool CCallback::canMoveBetween(const int3 &a, const int3 &b)
|
||||||
{
|
{
|
||||||
//TODO: merge with Pathfinder::canMoveBetween
|
//TODO: merge with Pathfinder::canMoveBetween
|
||||||
return gs->checkForVisitableDir(a, b) && gs->checkForVisitableDir(b, a);
|
return gs->checkForVisitableDir(a, b) && gs->checkForVisitableDir(b, a);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CCallback::getPath2( int3 dest, CGPath &ret )
|
|
||||||
{
|
|
||||||
if (!gs->map->isInTheMap(dest))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
validatePaths();
|
|
||||||
|
|
||||||
boost::unique_lock<boost::mutex> pathLock(cl->pathMx);
|
|
||||||
return cl->pathInfo->getPath(dest, ret);
|
|
||||||
}
|
|
||||||
|
|
||||||
int CCallback::getMovementCost(const CGHeroInstance * hero, int3 dest)
|
int CCallback::getMovementCost(const CGHeroInstance * hero, int3 dest)
|
||||||
{
|
{
|
||||||
return gs->getMovementCost(hero, hero->visitablePos(), dest, hero->hasBonusOfType (Bonus::FLYING_MOVEMENT), hero->movement);
|
return gs->getMovementCost(hero, hero->visitablePos(), dest, hero->hasBonusOfType (Bonus::FLYING_MOVEMENT), hero->movement);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const CPathsInfo * CCallback::getPathsInfo(const CGHeroInstance *h)
|
||||||
|
{
|
||||||
|
return cl->getPathsInfo(h);
|
||||||
|
}
|
||||||
|
|
||||||
int3 CCallback::getGuardingCreaturePosition(int3 tile)
|
int3 CCallback::getGuardingCreaturePosition(int3 tile)
|
||||||
{
|
{
|
||||||
if (!gs->map->isInTheMap(tile))
|
if (!gs->map->isInTheMap(tile))
|
||||||
@ -358,15 +308,9 @@ int3 CCallback::getGuardingCreaturePosition(int3 tile)
|
|||||||
return gs->map->guardingCreaturePositions[tile.x][tile.y][tile.z];
|
return gs->map->guardingCreaturePositions[tile.x][tile.y][tile.z];
|
||||||
}
|
}
|
||||||
|
|
||||||
void CCallback::recalculatePaths(const CGHeroInstance * hero)
|
void CCallback::calculatePaths( const CGHeroInstance *hero, CPathsInfo &out)
|
||||||
{
|
{
|
||||||
if (hero)
|
gs->calculatePaths(hero, out);
|
||||||
cl->calculatePaths(hero);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CCallback::calculatePaths( const CGHeroInstance *hero, CPathsInfo &out, int3 src /*= int3(-1,-1,-1)*/, int movement /*= -1*/ )
|
|
||||||
{
|
|
||||||
gs->calculatePaths(hero, out, src, movement);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CCallback::dig( const CGObjectInstance *hero )
|
void CCallback::dig( const CGObjectInstance *hero )
|
||||||
|
16
CCallback.h
16
CCallback.h
@ -72,8 +72,6 @@ public:
|
|||||||
virtual void endTurn()=0;
|
virtual void endTurn()=0;
|
||||||
virtual void buyArtifact(const CGHeroInstance *hero, ArtifactID aid)=0; //used to buy artifacts in towns (including spell book in the guild and war machines in blacksmith)
|
virtual void buyArtifact(const CGHeroInstance *hero, ArtifactID aid)=0; //used to buy artifacts in towns (including spell book in the guild and war machines in blacksmith)
|
||||||
virtual void setFormation(const CGHeroInstance * hero, bool tight)=0;
|
virtual void setFormation(const CGHeroInstance * hero, bool tight)=0;
|
||||||
virtual void setSelection(const CArmedInstance * obj)=0;
|
|
||||||
|
|
||||||
|
|
||||||
virtual void save(const std::string &fname) = 0;
|
virtual void save(const std::string &fname) = 0;
|
||||||
virtual void sendMessage(const std::string &mess) = 0;
|
virtual void sendMessage(const std::string &mess) = 0;
|
||||||
@ -100,24 +98,17 @@ public:
|
|||||||
|
|
||||||
class CCallback : public CPlayerSpecificInfoCallback, public IGameActionCallback, public CBattleCallback
|
class CCallback : public CPlayerSpecificInfoCallback, public IGameActionCallback, public CBattleCallback
|
||||||
{
|
{
|
||||||
private:
|
|
||||||
|
|
||||||
void validatePaths(); //recalcualte paths if necessary
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CCallback(CGameState * GS, boost::optional<PlayerColor> Player, CClient *C);
|
CCallback(CGameState * GS, boost::optional<PlayerColor> Player, CClient *C);
|
||||||
virtual ~CCallback();
|
virtual ~CCallback();
|
||||||
|
|
||||||
//client-specific functionalities (pathfinding)
|
//client-specific functionalities (pathfinding)
|
||||||
virtual const CGPathNode *getPathInfo(int3 tile); //uses main, client pathfinder info
|
|
||||||
virtual int getDistance(int3 tile);
|
|
||||||
virtual bool getPath2(int3 dest, CGPath &ret); //uses main, client pathfinder info
|
|
||||||
virtual bool canMoveBetween(const int3 &a, const int3 &b);
|
virtual bool canMoveBetween(const int3 &a, const int3 &b);
|
||||||
virtual int getMovementCost(const CGHeroInstance * hero, int3 dest);
|
virtual int getMovementCost(const CGHeroInstance * hero, int3 dest);
|
||||||
virtual int3 getGuardingCreaturePosition(int3 tile); //uses main, client pathfinder info
|
virtual int3 getGuardingCreaturePosition(int3 tile);
|
||||||
|
virtual const CPathsInfo * getPathsInfo(const CGHeroInstance *h);
|
||||||
|
|
||||||
virtual void calculatePaths(const CGHeroInstance *hero, CPathsInfo &out, int3 src = int3(-1,-1,-1), int movement = -1);
|
virtual void calculatePaths(const CGHeroInstance *hero, CPathsInfo &out);
|
||||||
virtual void recalculatePaths(const CGHeroInstance * hero); //updates main, client pathfinder info (should be called when moving hero is over)
|
|
||||||
|
|
||||||
//Set of metrhods that allows adding more interfaces for this player that'll receive game event call-ins.
|
//Set of metrhods that allows adding more interfaces for this player that'll receive game event call-ins.
|
||||||
void registerGameInterface(shared_ptr<IGameEventsReceiver> gameEvents);
|
void registerGameInterface(shared_ptr<IGameEventsReceiver> gameEvents);
|
||||||
@ -150,7 +141,6 @@ public:
|
|||||||
void buyArtifact(const CGHeroInstance *hero, ArtifactID aid) override;
|
void buyArtifact(const CGHeroInstance *hero, ArtifactID aid) override;
|
||||||
void trade(const CGObjectInstance *market, EMarketMode::EMarketMode mode, int id1, int id2, int val1, const CGHeroInstance *hero = nullptr);
|
void trade(const CGObjectInstance *market, EMarketMode::EMarketMode mode, int id1, int id2, int val1, const CGHeroInstance *hero = nullptr);
|
||||||
void setFormation(const CGHeroInstance * hero, bool tight);
|
void setFormation(const CGHeroInstance * hero, bool tight);
|
||||||
void setSelection(const CArmedInstance * obj);
|
|
||||||
void recruitHero(const CGObjectInstance *townOrTavern, const CGHeroInstance *hero);
|
void recruitHero(const CGObjectInstance *townOrTavern, const CGHeroInstance *hero);
|
||||||
void save(const std::string &fname);
|
void save(const std::string &fname);
|
||||||
void sendMessage(const std::string &mess);
|
void sendMessage(const std::string &mess);
|
||||||
|
@ -105,6 +105,7 @@ CPlayerInterface::CPlayerInterface(PlayerColor Player)
|
|||||||
curAction = nullptr;
|
curAction = nullptr;
|
||||||
playerID=Player;
|
playerID=Player;
|
||||||
human=true;
|
human=true;
|
||||||
|
currentSelection = nullptr;
|
||||||
castleInt = nullptr;
|
castleInt = nullptr;
|
||||||
battleInt = nullptr;
|
battleInt = nullptr;
|
||||||
//pim = new boost::recursive_mutex;
|
//pim = new boost::recursive_mutex;
|
||||||
@ -1256,12 +1257,10 @@ template <typename Handler> void CPlayerInterface::serializeTempl( Handler &h, c
|
|||||||
{
|
{
|
||||||
h & pathsMap;
|
h & pathsMap;
|
||||||
|
|
||||||
CPathsInfo pathsInfo(cb->getMapSize());
|
|
||||||
for(auto &p : pathsMap)
|
for(auto &p : pathsMap)
|
||||||
{
|
{
|
||||||
cb->calculatePaths(p.first, pathsInfo);
|
|
||||||
CGPath path;
|
CGPath path;
|
||||||
pathsInfo.getPath(p.second, path);
|
cb->getPathsInfo(p.first)->getPath(p.second, path);
|
||||||
paths[p.first] = path;
|
paths[p.first] = path;
|
||||||
logGlobal->traceStream() << boost::format("Restored path for hero %s leading to %s with %d nodes")
|
logGlobal->traceStream() << boost::format("Restored path for hero %s leading to %s with %d nodes")
|
||||||
% p.first->nodeName() % p.second % path.nodes.size();
|
% p.first->nodeName() % p.second % path.nodes.size();
|
||||||
@ -1552,6 +1551,16 @@ bool CPlayerInterface::ctrlPressed() const
|
|||||||
return isCtrlKeyDown();
|
return isCtrlKeyDown();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const CArmedInstance * CPlayerInterface::getSelection()
|
||||||
|
{
|
||||||
|
return currentSelection;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CPlayerInterface::setSelection(const CArmedInstance * obj)
|
||||||
|
{
|
||||||
|
currentSelection = obj;
|
||||||
|
}
|
||||||
|
|
||||||
void CPlayerInterface::update()
|
void CPlayerInterface::update()
|
||||||
{
|
{
|
||||||
if (!locked)
|
if (!locked)
|
||||||
@ -2185,13 +2194,6 @@ void CPlayerInterface::eraseCurrentPathOf( const CGHeroInstance * ho, bool check
|
|||||||
adventureInt->updateMoveHero(ho, false);
|
adventureInt->updateMoveHero(ho, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CPlayerInterface::updateCurrentHeroPath()
|
|
||||||
{
|
|
||||||
//TODO? lazy evaluation? paths now can get recalculated multiple times upon various game events
|
|
||||||
if (currentSelection)//if we have selected hero...
|
|
||||||
calculatePaths(currentSelection);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CPlayerInterface::removeLastNodeFromPath(const CGHeroInstance *ho)
|
void CPlayerInterface::removeLastNodeFromPath(const CGHeroInstance *ho)
|
||||||
{
|
{
|
||||||
adventureInt->terrain.currentPath->nodes.erase(adventureInt->terrain.currentPath->nodes.end()-1);
|
adventureInt->terrain.currentPath->nodes.erase(adventureInt->terrain.currentPath->nodes.end()-1);
|
||||||
@ -2213,7 +2215,7 @@ CGPath * CPlayerInterface::getAndVerifyPath(const CGHeroInstance * h)
|
|||||||
{
|
{
|
||||||
assert(h->getPosition(false) == path.startPos());
|
assert(h->getPosition(false) == path.startPos());
|
||||||
//update the hero path in case of something has changed on map
|
//update the hero path in case of something has changed on map
|
||||||
if(LOCPLINT->cb->getPath2(path.endPos(), path))
|
if(LOCPLINT->cb->getPathsInfo(h)->getPath(path.endPos(), path))
|
||||||
return &path;
|
return &path;
|
||||||
else
|
else
|
||||||
paths.erase(h);
|
paths.erase(h);
|
||||||
|
@ -86,7 +86,7 @@ enum
|
|||||||
/// Central class for managing user interface logic
|
/// Central class for managing user interface logic
|
||||||
class CPlayerInterface : public CGameInterface, public ILockedUpdatable
|
class CPlayerInterface : public CGameInterface, public ILockedUpdatable
|
||||||
{
|
{
|
||||||
const CGObjectInstance * currentSelection;
|
const CArmedInstance * currentSelection;
|
||||||
public:
|
public:
|
||||||
bool observerInDuelMode;
|
bool observerInDuelMode;
|
||||||
|
|
||||||
@ -118,6 +118,8 @@ public:
|
|||||||
shared_ptr<CBattleGameInterface> autofightingAI; //AI that makes decisions
|
shared_ptr<CBattleGameInterface> autofightingAI; //AI that makes decisions
|
||||||
bool isAutoFightOn; //Flag, switch it to stop quick combat. Don't touch if there is no battle interface.
|
bool isAutoFightOn; //Flag, switch it to stop quick combat. Don't touch if there is no battle interface.
|
||||||
|
|
||||||
|
const CArmedInstance * getSelection();
|
||||||
|
void setSelection(const CArmedInstance * obj);
|
||||||
|
|
||||||
struct SpellbookLastSetting
|
struct SpellbookLastSetting
|
||||||
{
|
{
|
||||||
@ -247,7 +249,6 @@ public:
|
|||||||
void movementPxStep( const TryMoveHero &details, int i, const int3 &hp, const CGHeroInstance * ho );//performing step of movement
|
void movementPxStep( const TryMoveHero &details, int i, const int3 &hp, const CGHeroInstance * ho );//performing step of movement
|
||||||
void finishMovement( const TryMoveHero &details, const int3 &hp, const CGHeroInstance * ho ); //finish movement
|
void finishMovement( const TryMoveHero &details, const int3 &hp, const CGHeroInstance * ho ); //finish movement
|
||||||
void eraseCurrentPathOf( const CGHeroInstance * ho, bool checkForExistanceOfPath = true );
|
void eraseCurrentPathOf( const CGHeroInstance * ho, bool checkForExistanceOfPath = true );
|
||||||
void updateCurrentHeroPath();
|
|
||||||
|
|
||||||
void removeLastNodeFromPath(const CGHeroInstance *ho);
|
void removeLastNodeFromPath(const CGHeroInstance *ho);
|
||||||
CGPath *getAndVerifyPath( const CGHeroInstance * h );
|
CGPath *getAndVerifyPath( const CGHeroInstance * h );
|
||||||
|
@ -664,13 +664,6 @@ PlayerColor CClient::getLocalPlayer() const
|
|||||||
return getCurrentPlayer();
|
return getCurrentPlayer();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CClient::calculatePaths(const CGHeroInstance *h)
|
|
||||||
{
|
|
||||||
assert(h);
|
|
||||||
boost::unique_lock<boost::mutex> pathLock(pathMx);
|
|
||||||
gs->calculatePaths(h, *pathInfo);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CClient::commenceTacticPhaseForInt(shared_ptr<CBattleGameInterface> battleInt)
|
void CClient::commenceTacticPhaseForInt(shared_ptr<CBattleGameInterface> battleInt)
|
||||||
{
|
{
|
||||||
setThreadName("CClient::commenceTacticPhaseForInt");
|
setThreadName("CClient::commenceTacticPhaseForInt");
|
||||||
@ -685,10 +678,22 @@ void CClient::commenceTacticPhaseForInt(shared_ptr<CBattleGameInterface> battleI
|
|||||||
} HANDLE_EXCEPTION
|
} HANDLE_EXCEPTION
|
||||||
}
|
}
|
||||||
|
|
||||||
void CClient::invalidatePaths(const CGHeroInstance *h /*= nullptr*/)
|
void CClient::invalidatePaths()
|
||||||
{
|
{
|
||||||
if(!h || pathInfo->hero == h)
|
// turn pathfinding info into invalid. It will be regenerated later
|
||||||
pathInfo->isValid = false;
|
boost::unique_lock<boost::mutex> pathLock(pathInfo->pathMx);
|
||||||
|
pathInfo->hero = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
const CPathsInfo * CClient::getPathsInfo(const CGHeroInstance *h)
|
||||||
|
{
|
||||||
|
assert(h);
|
||||||
|
boost::unique_lock<boost::mutex> pathLock(pathInfo->pathMx);
|
||||||
|
if (pathInfo->hero != h)
|
||||||
|
{
|
||||||
|
gs->calculatePaths(h, *pathInfo.get());
|
||||||
|
}
|
||||||
|
return pathInfo.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
int CClient::sendRequest(const CPack *request, PlayerColor player)
|
int CClient::sendRequest(const CPack *request, PlayerColor player)
|
||||||
|
@ -113,6 +113,7 @@ public:
|
|||||||
/// Class which handles client - server logic
|
/// Class which handles client - server logic
|
||||||
class CClient : public IGameCallback
|
class CClient : public IGameCallback
|
||||||
{
|
{
|
||||||
|
unique_ptr<CPathsInfo> pathInfo;
|
||||||
public:
|
public:
|
||||||
std::map<PlayerColor,shared_ptr<CCallback> > callbacks; //callbacks given to player interfaces
|
std::map<PlayerColor,shared_ptr<CCallback> > callbacks; //callbacks given to player interfaces
|
||||||
std::map<PlayerColor,shared_ptr<CBattleCallback> > battleCallbacks; //callbacks given to player interfaces
|
std::map<PlayerColor,shared_ptr<CBattleCallback> > battleCallbacks; //callbacks given to player interfaces
|
||||||
@ -129,9 +130,6 @@ public:
|
|||||||
|
|
||||||
boost::optional<BattleAction> curbaction;
|
boost::optional<BattleAction> curbaction;
|
||||||
|
|
||||||
unique_ptr<CPathsInfo> pathInfo;
|
|
||||||
boost::mutex pathMx; //protects the variable above
|
|
||||||
|
|
||||||
CScriptingModule *erm;
|
CScriptingModule *erm;
|
||||||
|
|
||||||
ThreadSafeVector<int> waitingRequest;
|
ThreadSafeVector<int> waitingRequest;
|
||||||
@ -158,8 +156,9 @@ public:
|
|||||||
void campaignMapFinished( shared_ptr<CCampaignState> camp );
|
void campaignMapFinished( shared_ptr<CCampaignState> camp );
|
||||||
void finishCampaign( shared_ptr<CCampaignState> camp );
|
void finishCampaign( shared_ptr<CCampaignState> camp );
|
||||||
void proposeNextMission(shared_ptr<CCampaignState> camp);
|
void proposeNextMission(shared_ptr<CCampaignState> camp);
|
||||||
void invalidatePaths(const CGHeroInstance *h = nullptr); //invalidates paths for hero h or for any hero if h is nullptr => they'll got recalculated when the next query comes
|
|
||||||
void calculatePaths(const CGHeroInstance *h);
|
void invalidatePaths();
|
||||||
|
const CPathsInfo * getPathsInfo(const CGHeroInstance *h);
|
||||||
|
|
||||||
bool terminate; // tell to terminate
|
bool terminate; // tell to terminate
|
||||||
boost::thread *connectionHandler; //thread running run() method
|
boost::thread *connectionHandler; //thread running run() method
|
||||||
|
@ -160,7 +160,7 @@ void SetMana::applyCl( CClient *cl )
|
|||||||
void SetMovePoints::applyCl( CClient *cl )
|
void SetMovePoints::applyCl( CClient *cl )
|
||||||
{
|
{
|
||||||
const CGHeroInstance *h = cl->getHero(hid);
|
const CGHeroInstance *h = cl->getHero(hid);
|
||||||
cl->invalidatePaths(h);
|
cl->invalidatePaths();
|
||||||
INTERFACE_CALL_IF_PRESENT(h->tempOwner, heroMovePointsChanged, h);
|
INTERFACE_CALL_IF_PRESENT(h->tempOwner, heroMovePointsChanged, h);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -905,7 +905,7 @@ void CenterView::applyCl(CClient *cl)
|
|||||||
|
|
||||||
void NewObject::applyCl(CClient *cl)
|
void NewObject::applyCl(CClient *cl)
|
||||||
{
|
{
|
||||||
INTERFACE_CALL_IF_PRESENT(player, updateCurrentHeroPath);
|
cl->invalidatePaths();
|
||||||
|
|
||||||
const CGObjectInstance *obj = cl->getObj(id);
|
const CGObjectInstance *obj = cl->getObj(id);
|
||||||
CGI->mh->printObject(obj);
|
CGI->mh->printObject(obj);
|
||||||
|
@ -948,7 +948,7 @@ void CAdvMapInt::keyPressed(const SDL_KeyboardEvent & key)
|
|||||||
|
|
||||||
CGPath &path = LOCPLINT->paths[h];
|
CGPath &path = LOCPLINT->paths[h];
|
||||||
terrain.currentPath = &path;
|
terrain.currentPath = &path;
|
||||||
if(!LOCPLINT->cb->getPath2(h->getPosition(false) + dir, path))
|
if(!LOCPLINT->cb->getPathsInfo(h)->getPath(h->getPosition(false) + dir, path))
|
||||||
{
|
{
|
||||||
terrain.currentPath = nullptr;
|
terrain.currentPath = nullptr;
|
||||||
return;
|
return;
|
||||||
@ -997,7 +997,7 @@ int3 CAdvMapInt::verifyPos(int3 ver)
|
|||||||
void CAdvMapInt::select(const CArmedInstance *sel, bool centerView /*= true*/)
|
void CAdvMapInt::select(const CArmedInstance *sel, bool centerView /*= true*/)
|
||||||
{
|
{
|
||||||
assert(sel);
|
assert(sel);
|
||||||
LOCPLINT->cb->setSelection(sel);
|
LOCPLINT->setSelection(sel);
|
||||||
selection = sel;
|
selection = sel;
|
||||||
if (LOCPLINT->battleInt == nullptr && LOCPLINT->makingTurn)
|
if (LOCPLINT->battleInt == nullptr && LOCPLINT->makingTurn)
|
||||||
{
|
{
|
||||||
@ -1184,7 +1184,7 @@ void CAdvMapInt::tileLClicked(const int3 &mapPos)
|
|||||||
}
|
}
|
||||||
else if(const CGHeroInstance * currentHero = curHero()) //hero is selected
|
else if(const CGHeroInstance * currentHero = curHero()) //hero is selected
|
||||||
{
|
{
|
||||||
const CGPathNode *pn = LOCPLINT->cb->getPathInfo(mapPos);
|
const CGPathNode *pn = LOCPLINT->cb->getPathsInfo(currentHero)->getPathInfo(mapPos);
|
||||||
if(currentHero == topBlocking) //clicked selected hero
|
if(currentHero == topBlocking) //clicked selected hero
|
||||||
{
|
{
|
||||||
LOCPLINT->openHeroWindow(currentHero);
|
LOCPLINT->openHeroWindow(currentHero);
|
||||||
@ -1206,7 +1206,7 @@ void CAdvMapInt::tileLClicked(const int3 &mapPos)
|
|||||||
{
|
{
|
||||||
CGPath &path = LOCPLINT->paths[currentHero];
|
CGPath &path = LOCPLINT->paths[currentHero];
|
||||||
terrain.currentPath = &path;
|
terrain.currentPath = &path;
|
||||||
bool gotPath = LOCPLINT->cb->getPath2(mapPos, path); //try getting path, erase if failed
|
bool gotPath = LOCPLINT->cb->getPathsInfo(currentHero)->getPath(mapPos, path); //try getting path, erase if failed
|
||||||
updateMoveHero(currentHero);
|
updateMoveHero(currentHero);
|
||||||
if (!gotPath)
|
if (!gotPath)
|
||||||
LOCPLINT->eraseCurrentPathOf(currentHero);
|
LOCPLINT->eraseCurrentPathOf(currentHero);
|
||||||
@ -1249,11 +1249,6 @@ void CAdvMapInt::tileHovered(const int3 &mapPos)
|
|||||||
statusbar.setText(hlp);
|
statusbar.setText(hlp);
|
||||||
}
|
}
|
||||||
|
|
||||||
const CGPathNode *pnode = LOCPLINT->cb->getPathInfo(mapPos);
|
|
||||||
|
|
||||||
int turns = pnode->turns;
|
|
||||||
vstd::amin(turns, 3);
|
|
||||||
|
|
||||||
if(!selection) //may occur just at the start of game (fake move before full intiialization)
|
if(!selection) //may occur just at the start of game (fake move before full intiialization)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -1298,6 +1293,10 @@ 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);
|
||||||
|
|
||||||
|
int turns = pnode->turns;
|
||||||
|
vstd::amin(turns, 3);
|
||||||
bool accessible = pnode->turns < 255;
|
bool accessible = pnode->turns < 255;
|
||||||
|
|
||||||
if(objAtTile)
|
if(objAtTile)
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
#include "BattleAction.h"
|
#include "BattleAction.h"
|
||||||
#include "IGameEventsReceiver.h"
|
#include "IGameEventsReceiver.h"
|
||||||
|
#include "CGameStateFwd.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* CGameInterface.h, part of VCMI engine
|
* CGameInterface.h, part of VCMI engine
|
||||||
@ -45,6 +46,7 @@ struct StackLocation;
|
|||||||
class CStackInstance;
|
class CStackInstance;
|
||||||
class CCommanderInstance;
|
class CCommanderInstance;
|
||||||
class CStack;
|
class CStack;
|
||||||
|
class CPathsInfo;
|
||||||
class CCreature;
|
class CCreature;
|
||||||
class CLoadFile;
|
class CLoadFile;
|
||||||
class CSaveFile;
|
class CSaveFile;
|
||||||
@ -73,7 +75,7 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
/// Central class for managing human player / AI interface logic
|
/// Central class for managing human player / AI interface logic
|
||||||
class CGameInterface : public CBattleGameInterface, public IGameEventsReceiver
|
class DLL_LINKAGE CGameInterface : public CBattleGameInterface, public IGameEventsReceiver
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
virtual void init(shared_ptr<CCallback> CB){};
|
virtual void init(shared_ptr<CCallback> CB){};
|
||||||
|
@ -2165,10 +2165,10 @@ void CGameState::apply(CPack *pack)
|
|||||||
applierGs->apps[typ]->applyOnGS(this,pack);
|
applierGs->apps[typ]->applyOnGS(this,pack);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CGameState::calculatePaths(const CGHeroInstance *hero, CPathsInfo &out, int3 src, int movement)
|
void CGameState::calculatePaths(const CGHeroInstance *hero, CPathsInfo &out)
|
||||||
{
|
{
|
||||||
CPathfinder pathfinder(out, this, hero);
|
CPathfinder pathfinder(out, this, hero);
|
||||||
pathfinder.calculatePaths(src, movement);
|
pathfinder.calculatePaths();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -2896,9 +2896,29 @@ bool CGPathNode::reachable() const
|
|||||||
return turns < 255;
|
return turns < 255;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CPathsInfo::getPath( const int3 &dst, CGPath &out )
|
const CGPathNode * CPathsInfo::getPathInfo( int3 tile ) const
|
||||||
{
|
{
|
||||||
assert(isValid);
|
boost::unique_lock<boost::mutex> pathLock(pathMx);
|
||||||
|
|
||||||
|
if (tile.x >= sizes.x || tile.y >= sizes.y || tile.z >= sizes.z)
|
||||||
|
return nullptr;
|
||||||
|
return &nodes[tile.x][tile.y][tile.z];
|
||||||
|
}
|
||||||
|
|
||||||
|
int CPathsInfo::getDistance( int3 tile ) const
|
||||||
|
{
|
||||||
|
boost::unique_lock<boost::mutex> pathLock(pathMx);
|
||||||
|
|
||||||
|
CGPath ret;
|
||||||
|
if (getPath(tile, ret))
|
||||||
|
return ret.nodes.size();
|
||||||
|
else
|
||||||
|
return 255;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CPathsInfo::getPath( const int3 &dst, CGPath &out ) const
|
||||||
|
{
|
||||||
|
boost::unique_lock<boost::mutex> pathLock(pathMx);
|
||||||
|
|
||||||
out.nodes.clear();
|
out.nodes.clear();
|
||||||
const CGPathNode *curnode = &nodes[dst.x][dst.y][dst.z];
|
const CGPathNode *curnode = &nodes[dst.x][dst.y][dst.z];
|
||||||
@ -3277,14 +3297,12 @@ void CPathfinder::initializeGraph()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CPathfinder::calculatePaths(int3 src /*= int3(-1,-1,-1)*/, int movement /*= -1*/)
|
void CPathfinder::calculatePaths()
|
||||||
{
|
{
|
||||||
|
int3 src = hero->getPosition(false);
|
||||||
assert(hero);
|
assert(hero);
|
||||||
assert(hero == getHero(hero->id));
|
assert(hero == getHero(hero->id));
|
||||||
if(src.x < 0)
|
|
||||||
src = hero->getPosition(false);
|
|
||||||
if(movement < 0)
|
|
||||||
movement = hero->movement;
|
|
||||||
bool flying = hero->hasBonusOfType(Bonus::FLYING_MOVEMENT);
|
bool flying = hero->hasBonusOfType(Bonus::FLYING_MOVEMENT);
|
||||||
int maxMovePointsLand = hero->maxMovePoints(true);
|
int maxMovePointsLand = hero->maxMovePoints(true);
|
||||||
int maxMovePointsWater = hero->maxMovePoints(false);
|
int maxMovePointsWater = hero->maxMovePoints(false);
|
||||||
@ -3295,9 +3313,9 @@ void CPathfinder::calculatePaths(int3 src /*= int3(-1,-1,-1)*/, int movement /*=
|
|||||||
};
|
};
|
||||||
|
|
||||||
out.hero = hero;
|
out.hero = hero;
|
||||||
out.hpos = src;
|
out.hpos = hero->getPosition(false);
|
||||||
|
|
||||||
if(!gs->map->isInTheMap(src)/* || !gs->map->isInTheMap(dest)*/) //check input
|
if(!gs->map->isInTheMap(out.hpos)/* || !gs->map->isInTheMap(dest)*/) //check input
|
||||||
{
|
{
|
||||||
logGlobal->errorStream() << "CGameState::calculatePaths: Hero outside the gs->map? How dare you...";
|
logGlobal->errorStream() << "CGameState::calculatePaths: Hero outside the gs->map? How dare you...";
|
||||||
return;
|
return;
|
||||||
@ -3307,9 +3325,9 @@ void CPathfinder::calculatePaths(int3 src /*= int3(-1,-1,-1)*/, int movement /*=
|
|||||||
|
|
||||||
|
|
||||||
//initial tile - set cost on 0 and add to the queue
|
//initial tile - set cost on 0 and add to the queue
|
||||||
CGPathNode &initialNode = *getNode(src);
|
CGPathNode &initialNode = *getNode(out.hpos);
|
||||||
initialNode.turns = 0;
|
initialNode.turns = 0;
|
||||||
initialNode.moveRemains = movement;
|
initialNode.moveRemains = hero->movement;
|
||||||
mq.push_back(&initialNode);
|
mq.push_back(&initialNode);
|
||||||
|
|
||||||
std::vector<int3> neighbours;
|
std::vector<int3> neighbours;
|
||||||
@ -3425,8 +3443,6 @@ void CPathfinder::calculatePaths(int3 src /*= int3(-1,-1,-1)*/, int movement /*=
|
|||||||
}
|
}
|
||||||
} //neighbours loop
|
} //neighbours loop
|
||||||
} //queue loop
|
} //queue loop
|
||||||
|
|
||||||
out.isValid = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CGPathNode *CPathfinder::getNode(const int3 &coord)
|
CGPathNode *CPathfinder::getNode(const int3 &coord)
|
||||||
|
@ -216,50 +216,6 @@ struct UpgradeInfo
|
|||||||
UpgradeInfo(){oldID = CreatureID::NONE;};
|
UpgradeInfo(){oldID = CreatureID::NONE;};
|
||||||
};
|
};
|
||||||
|
|
||||||
struct DLL_LINKAGE CGPathNode
|
|
||||||
{
|
|
||||||
enum EAccessibility
|
|
||||||
{
|
|
||||||
NOT_SET = 0,
|
|
||||||
ACCESSIBLE = 1, //tile can be entered and passed
|
|
||||||
VISITABLE, //tile can be entered as the last tile in path
|
|
||||||
BLOCKVIS, //visitable from neighbouring tile but not passable
|
|
||||||
BLOCKED //tile can't be entered nor visited
|
|
||||||
};
|
|
||||||
|
|
||||||
EAccessibility accessible;
|
|
||||||
ui8 land;
|
|
||||||
ui8 turns; //how many turns we have to wait before reachng the tile - 0 means current turn
|
|
||||||
ui32 moveRemains; //remaining tiles after hero reaches the tile
|
|
||||||
CGPathNode * theNodeBefore;
|
|
||||||
int3 coord; //coordinates
|
|
||||||
|
|
||||||
CGPathNode();
|
|
||||||
bool reachable() const;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct DLL_LINKAGE CGPath
|
|
||||||
{
|
|
||||||
std::vector<CGPathNode> nodes; //just get node by node
|
|
||||||
|
|
||||||
int3 startPos() const; // start point
|
|
||||||
int3 endPos() const; //destination point
|
|
||||||
void convert(ui8 mode); //mode=0 -> from 'manifest' to 'object'
|
|
||||||
};
|
|
||||||
|
|
||||||
struct DLL_LINKAGE CPathsInfo
|
|
||||||
{
|
|
||||||
bool isValid;
|
|
||||||
const CGHeroInstance *hero;
|
|
||||||
int3 hpos;
|
|
||||||
int3 sizes;
|
|
||||||
CGPathNode ***nodes; //[w][h][level]
|
|
||||||
|
|
||||||
bool getPath(const int3 &dst, CGPath &out);
|
|
||||||
CPathsInfo(const int3 &Sizes);
|
|
||||||
~CPathsInfo();
|
|
||||||
};
|
|
||||||
|
|
||||||
struct DLL_EXPORT DuelParameters
|
struct DLL_EXPORT DuelParameters
|
||||||
{
|
{
|
||||||
ETerrainType terType;
|
ETerrainType terType;
|
||||||
@ -349,7 +305,7 @@ private:
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
CPathfinder(CPathsInfo &_out, CGameState *_gs, const CGHeroInstance *_hero);
|
CPathfinder(CPathsInfo &_out, CGameState *_gs, const CGHeroInstance *_hero);
|
||||||
void calculatePaths(int3 src = int3(-1,-1,-1), int movement = -1); //calculates possible paths for hero, by default uses current hero position and movement left; returns pointer to newly allocated CPath or nullptr if path does not exists
|
void calculatePaths(); //calculates possible paths for hero, uses current hero position and movement left; returns pointer to newly allocated CPath or nullptr if path does not exists
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -397,7 +353,7 @@ public:
|
|||||||
UpgradeInfo getUpgradeInfo(const CStackInstance &stack);
|
UpgradeInfo getUpgradeInfo(const CStackInstance &stack);
|
||||||
PlayerRelations::PlayerRelations getPlayerRelations(PlayerColor color1, PlayerColor color2);
|
PlayerRelations::PlayerRelations getPlayerRelations(PlayerColor color1, PlayerColor color2);
|
||||||
bool checkForVisitableDir(const int3 & src, const int3 & dst) const; //check if src tile is visitable from dst tile
|
bool checkForVisitableDir(const int3 & src, const int3 & dst) const; //check if src tile is visitable from dst tile
|
||||||
void calculatePaths(const CGHeroInstance *hero, CPathsInfo &out, int3 src = int3(-1,-1,-1), int movement = -1); //calculates possible paths for hero, by default uses current hero position and movement left; returns pointer to newly allocated CPath or nullptr if path does not exists
|
void calculatePaths(const CGHeroInstance *hero, CPathsInfo &out); //calculates possible paths for hero, by default uses current hero position and movement left; returns pointer to newly allocated CPath or nullptr if path does not exists
|
||||||
int3 guardingCreaturePosition (int3 pos) const;
|
int3 guardingCreaturePosition (int3 pos) const;
|
||||||
std::vector<CGObjectInstance*> guardingCreatures (int3 pos) const;
|
std::vector<CGObjectInstance*> guardingCreatures (int3 pos) const;
|
||||||
|
|
||||||
|
@ -118,3 +118,49 @@ struct DLL_LINKAGE QuestInfo //universal interface for human and AI
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct DLL_LINKAGE CGPathNode
|
||||||
|
{
|
||||||
|
enum EAccessibility
|
||||||
|
{
|
||||||
|
NOT_SET = 0,
|
||||||
|
ACCESSIBLE = 1, //tile can be entered and passed
|
||||||
|
VISITABLE, //tile can be entered as the last tile in path
|
||||||
|
BLOCKVIS, //visitable from neighbouring tile but not passable
|
||||||
|
BLOCKED //tile can't be entered nor visited
|
||||||
|
};
|
||||||
|
|
||||||
|
EAccessibility accessible;
|
||||||
|
ui8 land;
|
||||||
|
ui8 turns; //how many turns we have to wait before reachng the tile - 0 means current turn
|
||||||
|
ui32 moveRemains; //remaining tiles after hero reaches the tile
|
||||||
|
CGPathNode * theNodeBefore;
|
||||||
|
int3 coord; //coordinates
|
||||||
|
|
||||||
|
CGPathNode();
|
||||||
|
bool reachable() const;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct DLL_LINKAGE CGPath
|
||||||
|
{
|
||||||
|
std::vector<CGPathNode> nodes; //just get node by node
|
||||||
|
|
||||||
|
int3 startPos() const; // start point
|
||||||
|
int3 endPos() const; //destination point
|
||||||
|
void convert(ui8 mode); //mode=0 -> from 'manifest' to 'object'
|
||||||
|
};
|
||||||
|
|
||||||
|
struct DLL_LINKAGE CPathsInfo
|
||||||
|
{
|
||||||
|
mutable boost::mutex pathMx;
|
||||||
|
|
||||||
|
const CGHeroInstance *hero;
|
||||||
|
int3 hpos;
|
||||||
|
int3 sizes;
|
||||||
|
CGPathNode ***nodes; //[w][h][level]
|
||||||
|
|
||||||
|
const CGPathNode * getPathInfo( int3 tile ) const;
|
||||||
|
bool getPath(const int3 &dst, CGPath &out) const;
|
||||||
|
int getDistance( int3 tile ) const;
|
||||||
|
CPathsInfo(const int3 &Sizes);
|
||||||
|
~CPathsInfo();
|
||||||
|
};
|
||||||
|
@ -3779,13 +3779,13 @@ bool CGameHandler::makeBattleAction( BattleAction &ba )
|
|||||||
}
|
}
|
||||||
|
|
||||||
void CGameHandler::playerMessage( PlayerColor player, const std::string &message )
|
void CGameHandler::playerMessage( PlayerColor player, const std::string &message )
|
||||||
{/*
|
{
|
||||||
bool cheated=true;
|
bool cheated=true;
|
||||||
PlayerMessage temp_message(player, message);
|
PlayerMessage temp_message(player, message);
|
||||||
|
|
||||||
sendAndApply(&temp_message);
|
sendAndApply(&temp_message);
|
||||||
if(message == "vcmiistari") //give all spells and 999 mana
|
if(message == "vcmiistari") //give all spells and 999 mana
|
||||||
{
|
{/*
|
||||||
SetMana sm;
|
SetMana sm;
|
||||||
ChangeSpells cs;
|
ChangeSpells cs;
|
||||||
|
|
||||||
@ -3866,6 +3866,18 @@ void CGameHandler::playerMessage( PlayerColor player, const std::string &message
|
|||||||
if(!hero->getArt(ArtifactPosition::MACH3))
|
if(!hero->getArt(ArtifactPosition::MACH3))
|
||||||
giveHeroNewArtifact(hero, VLC->arth->artifacts.at(6), ArtifactPosition::MACH3);
|
giveHeroNewArtifact(hero, VLC->arth->artifacts.at(6), ArtifactPosition::MACH3);
|
||||||
}
|
}
|
||||||
|
else if (message == "vcmiforgeofnoldorking") //hero gets all artifacts except war machines, spell scrolls and spell book
|
||||||
|
{
|
||||||
|
CGHeroInstance *hero = gs->getHero(gs->getPlayer(player)->currentSelection);
|
||||||
|
if(!hero) return;
|
||||||
|
for (int g = 7; g < VLC->arth->artifacts.size(); ++g) //including artifacts from mods
|
||||||
|
giveHeroNewArtifact(hero, VLC->arth->artifacts.at(g), ArtifactPosition::PRE_FIRST);
|
||||||
|
}
|
||||||
|
else if(message == "vcmiglorfindel") //selected hero gains a new level
|
||||||
|
{
|
||||||
|
CGHeroInstance *hero = gs->getHero(gs->getPlayer(player)->currentSelection);
|
||||||
|
changePrimSkill(hero, PrimarySkill::EXPERIENCE, VLC->heroh->reqExp(hero->level+1) - VLC->heroh->reqExp(hero->level));
|
||||||
|
}
|
||||||
else if(message == "vcminahar") //1000000 movement points
|
else if(message == "vcminahar") //1000000 movement points
|
||||||
{
|
{
|
||||||
CGHeroInstance *hero = gs->getHero(gs->getPlayer(player)->currentSelection);
|
CGHeroInstance *hero = gs->getHero(gs->getPlayer(player)->currentSelection);
|
||||||
@ -3873,7 +3885,7 @@ void CGameHandler::playerMessage( PlayerColor player, const std::string &message
|
|||||||
SetMovePoints smp;
|
SetMovePoints smp;
|
||||||
smp.hid = hero->id;
|
smp.hid = hero->id;
|
||||||
smp.val = 1000000;
|
smp.val = 1000000;
|
||||||
sendAndApply(&smp);
|
sendAndApply(&smp);*/
|
||||||
}
|
}
|
||||||
else if(message == "vcmiformenos") //give resources
|
else if(message == "vcmiformenos") //give resources
|
||||||
{
|
{
|
||||||
@ -3901,11 +3913,6 @@ void CGameHandler::playerMessage( PlayerColor player, const std::string &message
|
|||||||
delete [] hlp_tab;
|
delete [] hlp_tab;
|
||||||
sendAndApply(&fc);
|
sendAndApply(&fc);
|
||||||
}
|
}
|
||||||
else if(message == "vcmiglorfindel") //selected hero gains a new level
|
|
||||||
{
|
|
||||||
CGHeroInstance *hero = gs->getHero(gs->getPlayer(player)->currentSelection);
|
|
||||||
changePrimSkill(hero, PrimarySkill::EXPERIENCE, VLC->heroh->reqExp(hero->level+1) - VLC->heroh->reqExp(hero->level));
|
|
||||||
}
|
|
||||||
else if(message == "vcmisilmaril") //player wins
|
else if(message == "vcmisilmaril") //player wins
|
||||||
{
|
{
|
||||||
gs->getPlayer(player)->enteredWinningCheatCode = 1;
|
gs->getPlayer(player)->enteredWinningCheatCode = 1;
|
||||||
@ -3914,13 +3921,6 @@ void CGameHandler::playerMessage( PlayerColor player, const std::string &message
|
|||||||
{
|
{
|
||||||
gs->getPlayer(player)->enteredLosingCheatCode = 1;
|
gs->getPlayer(player)->enteredLosingCheatCode = 1;
|
||||||
}
|
}
|
||||||
else if (message == "vcmiforgeofnoldorking") //hero gets all artifacts except war machines, spell scrolls and spell book
|
|
||||||
{
|
|
||||||
CGHeroInstance *hero = gs->getHero(gs->getPlayer(player)->currentSelection);
|
|
||||||
if(!hero) return;
|
|
||||||
for (int g = 7; g < VLC->arth->artifacts.size(); ++g) //including artifacts from mods
|
|
||||||
giveHeroNewArtifact(hero, VLC->arth->artifacts.at(g), ArtifactPosition::PRE_FIRST);
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
cheated = false;
|
cheated = false;
|
||||||
if(cheated)
|
if(cheated)
|
||||||
@ -3928,7 +3928,7 @@ void CGameHandler::playerMessage( PlayerColor player, const std::string &message
|
|||||||
SystemMessage temp_message(VLC->generaltexth->allTexts.at(260));
|
SystemMessage temp_message(VLC->generaltexth->allTexts.at(260));
|
||||||
sendAndApply(&temp_message);
|
sendAndApply(&temp_message);
|
||||||
checkVictoryLossConditionsForPlayer(player);//Player enter win code or got required art\creature
|
checkVictoryLossConditionsForPlayer(player);//Player enter win code or got required art\creature
|
||||||
}*/
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CGameHandler::handleSpellCasting( SpellID spellID, int spellLvl, BattleHex destination, ui8 casterSide, PlayerColor casterColor, const CGHeroInstance * caster, const CGHeroInstance * secHero,
|
void CGameHandler::handleSpellCasting( SpellID spellID, int spellLvl, BattleHex destination, ui8 casterSide, PlayerColor casterColor, const CGHeroInstance * caster, const CGHeroInstance * secHero,
|
||||||
|
Loading…
Reference in New Issue
Block a user