mirror of
https://github.com/vcmi/vcmi.git
synced 2025-01-26 03:52:01 +02:00
- Unified interface for visitable objects
- AI will manage visitable objects smarter
This commit is contained in:
parent
c8c4c5b682
commit
a3f36ccc71
@ -374,12 +374,6 @@ ui64 evaluateDanger(const CGObjectInstance *obj)
|
||||
case Obj::DERELICT_SHIP: //derelict ship
|
||||
case Obj::PYRAMID:
|
||||
return fh->estimateBankDanger (VLC->objh->bankObjToIndex(obj));
|
||||
case Obj::WHIRLPOOL: //whirlpool
|
||||
case Obj::MONOLITH1:
|
||||
case Obj::MONOLITH2:
|
||||
case Obj::MONOLITH3:
|
||||
//TODO mechanism for handling monoliths
|
||||
return 1000000000;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
@ -559,9 +553,8 @@ void VCAI::heroVisit(const CGHeroInstance *visitor, const CGObjectInstance *visi
|
||||
LOG_ENTRY;
|
||||
if (start)
|
||||
{
|
||||
visitedObject = const_cast<CGObjectInstance *>(visitedObj); // remember teh object and wait for return
|
||||
if(visitedObj->ID != Obj::MONSTER) //TODO: poll bank if it was cleared
|
||||
alreadyVisited.push_back(visitedObj);
|
||||
visitedObject = const_cast<CGObjectInstance *>(visitedObj); // remember the object and wait for return
|
||||
markObjectVisited (visitedObj);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1098,7 +1091,7 @@ std::vector<const CGObjectInstance *> VCAI::getPossibleDestinations(const CGHero
|
||||
std::vector<const CGObjectInstance *> possibleDestinations;
|
||||
BOOST_FOREACH(const CGObjectInstance *obj, visitableObjs)
|
||||
{
|
||||
if(cb->getPathInfo(obj->visitablePos())->reachable() &&
|
||||
if(cb->getPathInfo(obj->visitablePos())->reachable() && !obj->wasVisited(playerID) &&
|
||||
(obj->tempOwner != playerID || isWeeklyRevisitable(obj))) //flag or get weekly resources / creatures
|
||||
possibleDestinations.push_back(obj);
|
||||
}
|
||||
@ -1113,6 +1106,9 @@ std::vector<const CGObjectInstance *> VCAI::getPossibleDestinations(const CGHero
|
||||
if(!isSafeToVisit(h, obj->visitablePos()))
|
||||
return true;
|
||||
|
||||
if (!shouldVisit(h, obj))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}),possibleDestinations.end());
|
||||
|
||||
@ -1134,7 +1130,7 @@ void VCAI::wander(const CGHeroInstance * h)
|
||||
if(!goVisitObj(obj, h))
|
||||
{
|
||||
BNLOG("Hero %s apparently used all MPs (%d left)\n", h->name % h->movement);
|
||||
alreadyVisited.push_back(obj); //reserve that object - we predict it will be reached soon
|
||||
markObjectVisited(obj); //reserve that object - we predict it will be reached soon
|
||||
setGoal(h, CGoal(VISIT_TILE).sethero(h).settile(obj->visitablePos()));
|
||||
break;
|
||||
}
|
||||
@ -1183,6 +1179,15 @@ void VCAI::waitTillFree()
|
||||
status.waitTillFree();
|
||||
}
|
||||
|
||||
void VCAI::markObjectVisited (const CGObjectInstance *obj)
|
||||
{
|
||||
if(dynamic_cast<const CGVisitableOPH *>(obj) || //we may want to wisit it with another hero
|
||||
dynamic_cast<const CGBonusingObject *>(obj) || //or another time
|
||||
(obj->ID == Obj::MONSTER))
|
||||
return;
|
||||
alreadyVisited.push_back(obj);
|
||||
}
|
||||
|
||||
void VCAI::validateVisitableObjs()
|
||||
{
|
||||
std::vector<const CGObjectInstance *> hlp;
|
||||
@ -2476,7 +2481,9 @@ void SectorMap::write(crstring fname)
|
||||
|
||||
bool isWeeklyRevisitable (const CGObjectInstance * obj)
|
||||
{ //TODO: allow polling of remaining creatures in dwelling
|
||||
if (dynamic_cast<const CGVisitableOPW *>(obj) || dynamic_cast<const CGDwelling *>(obj)) //ensures future compatibility, unlike IDs
|
||||
if (dynamic_cast<const CGVisitableOPW *>(obj) || //ensures future compatibility, unlike IDs
|
||||
dynamic_cast<const CGDwelling *>(obj) ||
|
||||
dynamic_cast<const CBank *>(obj)) //banks tend to respawn often in mods
|
||||
return true;
|
||||
switch (obj->ID)
|
||||
{
|
||||
@ -2486,6 +2493,36 @@ bool isWeeklyRevisitable (const CGObjectInstance * obj)
|
||||
return false;
|
||||
}
|
||||
|
||||
bool shouldVisit (const CGHeroInstance * h, const CGObjectInstance * obj)
|
||||
{
|
||||
if (obj->wasVisited(h))
|
||||
return false;
|
||||
switch (obj->ID)
|
||||
{
|
||||
case Obj::CREATURE_GENERATOR1:
|
||||
{
|
||||
bool canRecruitCreatures = false;
|
||||
const CGDwelling * d = dynamic_cast<const CGDwelling *>(obj);
|
||||
BOOST_FOREACH(auto level, d->creatures)
|
||||
{
|
||||
BOOST_FOREACH(auto c, level.second)
|
||||
{
|
||||
if (h->getSlotFor(c) != -1)
|
||||
canRecruitCreatures = true;
|
||||
}
|
||||
}
|
||||
return canRecruitCreatures;
|
||||
}
|
||||
case Obj::MONOLITH1:
|
||||
case Obj::MONOLITH2:
|
||||
case Obj::MONOLITH3:
|
||||
case Obj::WHIRLPOOL:
|
||||
//TODO: mehcanism for handling monoliths
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
int3 SectorMap::firstTileToGet(const CGHeroInstance *h, crint3 dst)
|
||||
{
|
||||
int sourceSector = retreiveTile(h->visitablePos()),
|
||||
|
@ -265,6 +265,7 @@ public:
|
||||
void waitTillFree();
|
||||
|
||||
void addVisitableObj(const CGObjectInstance *obj);
|
||||
void markObjectVisited (const CGObjectInstance *obj);
|
||||
//void removeVisitableObj(const CGObjectInstance *obj);
|
||||
void validateVisitableObjs();
|
||||
void retreiveVisitableObjs(std::vector<const CGObjectInstance *> &out, bool includeOwned = false) const;
|
||||
@ -292,4 +293,5 @@ bool objWithID(const CGObjectInstance *obj)
|
||||
return obj->ID == id;
|
||||
}
|
||||
|
||||
bool isWeeklyRevisitable (const CGObjectInstance * obj);
|
||||
bool isWeeklyRevisitable (const CGObjectInstance * obj);
|
||||
bool shouldVisit (const CGHeroInstance * h, const CGObjectInstance * obj);
|
@ -74,6 +74,15 @@ void IObjectInterface::initObj()
|
||||
void IObjectInterface::setProperty( ui8 what, ui32 val )
|
||||
{}
|
||||
|
||||
bool IObjectInterface::wasVisited (ui8 player) const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
bool IObjectInterface::wasVisited (const CGHeroInstance * h) const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
void IObjectInterface::postInit()
|
||||
{}
|
||||
|
||||
@ -86,7 +95,7 @@ void CPlayersVisited::setPropertyDer( ui8 what, ui32 val )
|
||||
players.insert((ui8)val);
|
||||
}
|
||||
|
||||
bool CPlayersVisited::hasVisited( ui8 player ) const
|
||||
bool CPlayersVisited::wasVisited( ui8 player ) const
|
||||
{
|
||||
return vstd::contains(players,player);
|
||||
}
|
||||
@ -2424,6 +2433,11 @@ bool CGTownInstance::hasBuilt(int buildingID) const
|
||||
return vstd::contains(builtBuildings, buildingID);
|
||||
}
|
||||
|
||||
bool CGVisitableOPH::wasVisited (const CGHeroInstance * h) const
|
||||
{
|
||||
return vstd::contains(visitors, h->id);
|
||||
}
|
||||
|
||||
void CGVisitableOPH::onHeroVisit( const CGHeroInstance * h ) const
|
||||
{
|
||||
if(visitors.find(h->id)==visitors.end())
|
||||
@ -3479,6 +3493,10 @@ void CGVisitableOPW::newTurn() const
|
||||
cb->setHoverName(id,&ms);
|
||||
}
|
||||
}
|
||||
bool CGVisitableOPW::wasVisited(ui8 player) const
|
||||
{
|
||||
return !visited; //TODO: other players should see object as unvisited
|
||||
}
|
||||
|
||||
void CGVisitableOPW::onHeroVisit( const CGHeroInstance * h ) const
|
||||
{
|
||||
@ -4642,7 +4660,7 @@ void CGWitchHut::onHeroVisit( const CGHeroInstance * h ) const
|
||||
InfoWindow iw;
|
||||
iw.soundID = soundBase::gazebo;
|
||||
iw.player = h->getOwner();
|
||||
if(!hasVisited(h->tempOwner))
|
||||
if(!wasVisited(h->tempOwner))
|
||||
cb->setObjProperty(id,10,h->tempOwner);
|
||||
|
||||
if(h->getSecSkillLevel(static_cast<CGHeroInstance::SecondarySkill>(ability))) //you alredy know this skill
|
||||
@ -4669,7 +4687,7 @@ void CGWitchHut::onHeroVisit( const CGHeroInstance * h ) const
|
||||
const std::string & CGWitchHut::getHoverText() const
|
||||
{
|
||||
hoverName = VLC->generaltexth->names[ID];
|
||||
if(hasVisited(cb->getCurrentPlayer())) //TODO: use local player, not current
|
||||
if(wasVisited(cb->getCurrentPlayer())) //TODO: use local player, not current
|
||||
{
|
||||
hoverName += "\n" + VLC->generaltexth->allTexts[356]; // + (learn %s)
|
||||
boost::algorithm::replace_first(hoverName,"%s",VLC->generaltexth->skillName[ability]);
|
||||
@ -4680,6 +4698,11 @@ const std::string & CGWitchHut::getHoverText() const
|
||||
return hoverName;
|
||||
}
|
||||
|
||||
bool CGBonusingObject::wasVisited (const CGHeroInstance * h) const
|
||||
{
|
||||
return h->hasBonusFrom(Bonus::OBJECT, ID);
|
||||
}
|
||||
|
||||
void CGBonusingObject::onHeroVisit( const CGHeroInstance * h ) const
|
||||
{
|
||||
bool visited = h->hasBonusFrom(Bonus::OBJECT,ID);
|
||||
@ -5302,7 +5325,7 @@ void CGShrine::onHeroVisit( const CGHeroInstance * h ) const
|
||||
return;
|
||||
}
|
||||
|
||||
if(!hasVisited(h->tempOwner))
|
||||
if(!wasVisited(h->tempOwner))
|
||||
cb->setObjProperty(id,10,h->tempOwner);
|
||||
|
||||
InfoWindow iw;
|
||||
@ -5357,7 +5380,7 @@ void CGShrine::initObj()
|
||||
const std::string & CGShrine::getHoverText() const
|
||||
{
|
||||
hoverName = VLC->generaltexth->names[ID];
|
||||
if(hasVisited(cb->getCurrentPlayer())) //TODO: use local player, not current
|
||||
if(wasVisited(cb->getCurrentPlayer())) //TODO: use local player, not current
|
||||
{
|
||||
hoverName += "\n" + VLC->generaltexth->allTexts[355]; // + (learn %s)
|
||||
boost::algorithm::replace_first(hoverName,"%s",VLC->spellh->spells[spell]->name);
|
||||
@ -5597,7 +5620,7 @@ const std::string & CGOnceVisitable::getHoverText() const
|
||||
{
|
||||
hoverName = VLC->generaltexth->names[ID] + " ";
|
||||
|
||||
hoverName += (hasVisited(cb->getCurrentPlayer())
|
||||
hoverName += (wasVisited(cb->getCurrentPlayer())
|
||||
? (VLC->generaltexth->allTexts[352]) //visited
|
||||
: ( VLC->generaltexth->allTexts[353])); //not visited
|
||||
|
||||
@ -5872,6 +5895,11 @@ void CBank::newTurn() const
|
||||
cb->setObjProperty (id, 11, 1); //daycounter++
|
||||
}
|
||||
}
|
||||
bool CBank::wasVisited (ui8 player) const
|
||||
{
|
||||
return !bc;
|
||||
}
|
||||
|
||||
void CBank::onHeroVisit (const CGHeroInstance * h) const
|
||||
{
|
||||
if (bc)
|
||||
@ -6162,6 +6190,11 @@ const std::string & CGKeymasterTent::getHoverText() const
|
||||
return hoverName;
|
||||
}
|
||||
|
||||
bool CGKeymasterTent::wasVisited (ui8 player) const
|
||||
{
|
||||
return wasMyColorVisited (player);
|
||||
}
|
||||
|
||||
void CGKeymasterTent::onHeroVisit( const CGHeroInstance * h ) const
|
||||
{
|
||||
InfoWindow iw;
|
||||
@ -6492,7 +6525,7 @@ void CGShipyard::onHeroVisit( const CGHeroInstance * h ) const
|
||||
|
||||
void CCartographer::onHeroVisit( const CGHeroInstance * h ) const
|
||||
{
|
||||
if (!hasVisited (h->getOwner()) ) //if hero has not visited yet this cartographer
|
||||
if (!wasVisited (h->getOwner()) ) //if hero has not visited yet this cartographer
|
||||
{
|
||||
if (cb->getResource(h->tempOwner, 6) >= 1000) //if he can afford a map
|
||||
{
|
||||
@ -6567,7 +6600,7 @@ void CGObelisk::onHeroVisit( const CGHeroInstance * h ) const
|
||||
assert(ts);
|
||||
int team = ts->id;
|
||||
|
||||
if(!hasVisited(team))
|
||||
if(!wasVisited(team))
|
||||
{
|
||||
iw.text.addTxt(MetaString::ADVOB_TXT, 96);
|
||||
cb->sendAndApply(&iw);
|
||||
@ -6597,7 +6630,7 @@ void CGObelisk::initObj()
|
||||
const std::string & CGObelisk::getHoverText() const
|
||||
{
|
||||
hoverName = VLC->generaltexth->names[ID];
|
||||
if(hasVisited(cb->getCurrentPlayer()))
|
||||
if(wasVisited(cb->getCurrentPlayer()))
|
||||
hoverName += " " + VLC->generaltexth->allTexts[352]; //not visited
|
||||
else
|
||||
hoverName += " " + VLC->generaltexth->allTexts[353]; //visited
|
||||
|
@ -93,6 +93,9 @@ public:
|
||||
virtual void newTurn() const;
|
||||
virtual void initObj(); //synchr
|
||||
virtual void setProperty(ui8 what, ui32 val);//synchr
|
||||
//unified interface, AI helpers
|
||||
virtual bool wasVisited (ui8 player) const;
|
||||
virtual bool wasVisited (const CGHeroInstance * h) const;
|
||||
|
||||
static void preInit(); //called before objs receive their initObj
|
||||
static void postInit();//caleed after objs receive their initObj
|
||||
@ -177,6 +180,7 @@ public:
|
||||
//CGObjectInstance(const CGObjectInstance & right);
|
||||
//CGObjectInstance& operator=(const CGObjectInstance & right);
|
||||
virtual const std::string & getHoverText() const;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void initObj();
|
||||
void onHeroVisit(const CGHeroInstance * h) const;
|
||||
@ -210,7 +214,7 @@ class DLL_LINKAGE CPlayersVisited: public CGObjectInstance
|
||||
public:
|
||||
std::set<ui8> players; //players that visited this object
|
||||
|
||||
bool hasVisited(ui8 player) const;
|
||||
bool wasVisited(ui8 player) const;
|
||||
virtual void setPropertyDer( ui8 what, ui32 val );
|
||||
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
@ -464,6 +468,7 @@ public:
|
||||
void onHeroVisit(const CGHeroInstance * h) const;
|
||||
void onNAHeroVisit(int heroID, bool alreadyVisited) const;
|
||||
void initObj();
|
||||
bool wasVisited (const CGHeroInstance * h) const;
|
||||
void treeSelected(int heroID, int resType, int resVal, expType expVal, ui32 result) const; //handle player's anwer to the Tree of Knowledge dialog
|
||||
void schoolSelected(int heroID, ui32 which) const;
|
||||
void arenaSelected(int heroID, int primSkill) const;
|
||||
@ -921,7 +926,7 @@ public:
|
||||
void offerLeavingGuards(const CGHeroInstance *h) const;
|
||||
void endBattle(BattleResult *result, ui8 attackingPlayer) const;
|
||||
void fight(ui32 agreed, const CGHeroInstance *h) const;
|
||||
|
||||
|
||||
void onHeroVisit(const CGHeroInstance * h) const;
|
||||
|
||||
void flagMine(ui8 player) const;
|
||||
@ -941,6 +946,7 @@ public:
|
||||
ui8 visited; //true if object has been visited this week
|
||||
|
||||
void setPropertyDer(ui8 what, ui32 val);//synchr
|
||||
bool wasVisited(ui8 player) const;
|
||||
void onHeroVisit(const CGHeroInstance * h) const;
|
||||
void newTurn() const;
|
||||
|
||||
@ -970,6 +976,7 @@ public:
|
||||
class DLL_LINKAGE CGBonusingObject : public CGObjectInstance //objects giving bonuses to luck/morale/movement
|
||||
{
|
||||
public:
|
||||
bool wasVisited (const CGHeroInstance * h) const;
|
||||
void onHeroVisit(const CGHeroInstance * h) const;
|
||||
const std::string & getHoverText() const;
|
||||
void initObj();
|
||||
@ -1047,6 +1054,7 @@ public:
|
||||
class DLL_LINKAGE CGKeymasterTent : public CGKeys
|
||||
{
|
||||
public:
|
||||
bool wasVisited (ui8 player) const;
|
||||
void onHeroVisit(const CGHeroInstance * h) const;
|
||||
const std::string & getHoverText() const;
|
||||
|
||||
@ -1132,6 +1140,7 @@ class DLL_LINKAGE CBank : public CArmedInstance
|
||||
void initialize() const;
|
||||
void reset(ui16 var1);
|
||||
void newTurn() const;
|
||||
bool wasVisited (ui8 player) const;
|
||||
virtual void onHeroVisit (const CGHeroInstance * h) const;
|
||||
virtual void fightGuards (const CGHeroInstance *h, ui32 accept) const;
|
||||
virtual void endBattle (const CGHeroInstance *h, const BattleResult *result) const;
|
||||
|
Loading…
x
Reference in New Issue
Block a user