1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-01-12 02:28:11 +02:00

It is possible to set on visit query that object is to be removed after visit is over.

Fixes #1263.
This commit is contained in:
Michał W. Urbańczyk 2013-05-14 13:42:52 +00:00
parent 42c2c29976
commit f95e6c233b
7 changed files with 42 additions and 17 deletions

View File

@ -170,7 +170,7 @@ public:
void changeSecSkill(const CGHeroInstance * hero, SecondarySkill which, int val, bool abs=false) OVERRIDE {};
void showBlockingDialog(BlockingDialog *iw) OVERRIDE {};
void showGarrisonDialog(ObjectInstanceID upobj, ObjectInstanceID hid, bool removableUnits, const boost::function<void()> &cb) OVERRIDE {};
void showGarrisonDialog(ObjectInstanceID upobj, ObjectInstanceID hid, bool removableUnits) OVERRIDE {};
void showThievesGuildWindow(PlayerColor player, ObjectInstanceID requestingObjId) OVERRIDE {};
void giveResource(PlayerColor player, Res::ERes which, int val) OVERRIDE {};
virtual void giveResources(PlayerColor player, TResources resources) OVERRIDE {};
@ -185,6 +185,8 @@ public:
bool addToSlot(const StackLocation &sl, const CCreature *c, TQuantity count) OVERRIDE {return false;}
void tryJoiningArmy(const CArmedInstance *src, const CArmedInstance *dst, bool removeObjWhenFinished, bool allowMerging) OVERRIDE {}
bool moveStack(const StackLocation &src, const StackLocation &dst, TQuantity count = -1) OVERRIDE {return false;}
void removeAfterVisit(const CGObjectInstance *object) OVERRIDE {};
void giveHeroNewArtifact(const CGHeroInstance *h, const CArtifact *artType, ArtifactPosition pos) OVERRIDE {};
void giveHeroArtifact(const CGHeroInstance *h, const CArtifactInstance *a, ArtifactPosition pos) OVERRIDE {};

View File

@ -3556,7 +3556,7 @@ void CGMine::onHeroVisit( const CGHeroInstance * h ) const
if(relations == 2) //we're visiting our mine
{
cb->showGarrisonDialog(id,h->id,true,0);
cb->showGarrisonDialog(id,h->id,true);
return;
}
else if (relations == 1)//ally
@ -5833,7 +5833,7 @@ void CGGarrison::onHeroVisit (const CGHeroInstance *h) const
if (!ally)
cb->setOwner(this, h->tempOwner);
cb->showGarrisonDialog(id, h->id, removableUnits, 0);
cb->showGarrisonDialog(id, h->id, removableUnits);
}
ui8 CGGarrison::getPassableness() const

View File

@ -221,7 +221,7 @@ public:
virtual void changePrimSkill(const CGHeroInstance * hero, PrimarySkill::PrimarySkill which, si64 val, bool abs=false)=0;
virtual void changeSecSkill(const CGHeroInstance * hero, SecondarySkill which, int val, bool abs=false)=0;
virtual void showBlockingDialog(BlockingDialog *iw) =0;
virtual void showGarrisonDialog(ObjectInstanceID upobj, ObjectInstanceID hid, bool removableUnits, const boost::function<void()> &cb) =0; //cb will be called when player closes garrison window
virtual void showGarrisonDialog(ObjectInstanceID upobj, ObjectInstanceID hid, bool removableUnits) =0; //cb will be called when player closes garrison window
virtual void showThievesGuildWindow(PlayerColor player, ObjectInstanceID requestingObjId) =0;
virtual void giveResource(PlayerColor player, Res::ERes which, int val)=0;
virtual void giveResources(PlayerColor player, TResources resources)=0;
@ -237,6 +237,8 @@ public:
virtual void tryJoiningArmy(const CArmedInstance *src, const CArmedInstance *dst, bool removeObjWhenFinished, bool allowMerging) =0; //merges army from src do dst or opens a garrison window
virtual bool moveStack(const StackLocation &src, const StackLocation &dst, TQuantity count) = 0;
virtual void removeAfterVisit(const CGObjectInstance *object) = 0; //object will be destroyed when interaction is over. Do not call when interaction is not ongoing!
virtual void giveHeroNewArtifact(const CGHeroInstance *h, const CArtifact *artType, ArtifactPosition pos) = 0;
virtual void giveHeroArtifact(const CGHeroInstance *h, const CArtifactInstance *a, ArtifactPosition pos) = 0; //pos==-1 - first free slot in backpack=0; pos==-2 - default if available or backpack
virtual void putArtifact(const ArtifactLocation &al, const CArtifactInstance *a) = 0;

View File

@ -1853,10 +1853,6 @@ void CGameHandler::giveResources(PlayerColor player, TResources resources)
void CGameHandler::giveCreatures(const CArmedInstance *obj, const CGHeroInstance * h, const CCreatureSet &creatures, bool remove)
{
boost::function<void()> removeOrNot = 0;
if(remove)
removeOrNot = boost::bind(&CGameHandler::removeObject, this, obj);
COMPLAIN_RET_IF(!creatures.stacksCount(), "Strange, giveCreatures called without args!");
COMPLAIN_RET_IF(obj->stacksCount(), "Cannot give creatures from not-cleared object!");
COMPLAIN_RET_IF(creatures.stacksCount() > GameConstants::ARMY_SIZE, "Too many stacks to give!");
@ -4743,7 +4739,7 @@ bool CGameHandler::complain( const std::string &problem )
return true;
}
void CGameHandler::showGarrisonDialog( ObjectInstanceID upobj, ObjectInstanceID hid, bool removableUnits, const boost::function<void()> &cb )
void CGameHandler::showGarrisonDialog( ObjectInstanceID upobj, ObjectInstanceID hid, bool removableUnits)
{
//PlayerColor player = getOwner(hid);
auto upperArmy = dynamic_cast<const CArmedInstance*>(getObj(upobj));
@ -5639,6 +5635,9 @@ bool CGameHandler::addToSlot(const StackLocation &sl, const CCreature *c, TQuant
void CGameHandler::tryJoiningArmy(const CArmedInstance *src, const CArmedInstance *dst, bool removeObjWhenFinished, bool allowMerging)
{
if(removeObjWhenFinished)
removeAfterVisit(src);
if(!src->canBeMergedWith(*dst, allowMerging))
{
if (allowMerging) //do that, add all matching creatures.
@ -5659,16 +5658,11 @@ void CGameHandler::tryJoiningArmy(const CArmedInstance *src, const CArmedInstanc
}
}
}
boost::function<void()> removeOrNot = 0;
if(removeObjWhenFinished)
removeOrNot = boost::bind(&IGameCallback::removeObject,this,src);
showGarrisonDialog(src->id, dst->id, true, removeOrNot); //show garrison window and optionally remove ourselves from map when player ends
showGarrisonDialog(src->id, dst->id, true); //show garrison window and optionally remove ourselves from map when player ends
}
else //merge
{
moveArmy(src, dst, allowMerging);
if(removeObjWhenFinished)
removeObject(src);
}
}
@ -6094,6 +6088,25 @@ bool CGameHandler::isBlockedByQueries(const CPack *pack, PlayerColor player)
return false;
}
void CGameHandler::removeAfterVisit(const CGObjectInstance *object)
{
//If the object is being visited, there must be a matching query
BOOST_FOREACH(const auto &query, queries.allQueries())
{
if(auto someVistQuery = std::dynamic_pointer_cast<CObjectVisitQuery>(query))
{
if(someVistQuery->visitedObject == object)
{
someVistQuery->removeObjectAfterVisit = true;
return;
}
}
};
//If we haven't returned so far, there is no query and no visit, call was wrong
assert("This function needs to be called during the object visit!");
}
CasualtiesAfterBattle::CasualtiesAfterBattle(const CArmedInstance *army, BattleInfo *bat)
{
heroWithDeadCommander = ObjectInstanceID();

View File

@ -138,7 +138,7 @@ public:
//void showInfoDialog(InfoWindow *iw) OVERRIDE;
void showBlockingDialog(BlockingDialog *iw) OVERRIDE;
void showGarrisonDialog(ObjectInstanceID upobj, ObjectInstanceID hid, bool removableUnits, const boost::function<void()> &cb) OVERRIDE;
void showGarrisonDialog(ObjectInstanceID upobj, ObjectInstanceID hid, bool removableUnits) OVERRIDE;
void showThievesGuildWindow(PlayerColor player, ObjectInstanceID requestingObjId) OVERRIDE;
void giveResource(PlayerColor player, Res::ERes which, int val) OVERRIDE;
void giveResources(PlayerColor player, TResources resources) OVERRIDE;
@ -153,6 +153,8 @@ public:
bool addToSlot(const StackLocation &sl, const CCreature *c, TQuantity count) OVERRIDE;
void tryJoiningArmy(const CArmedInstance *src, const CArmedInstance *dst, bool removeObjWhenFinished, bool allowMerging) OVERRIDE;
bool moveStack(const StackLocation &src, const StackLocation &dst, TQuantity count = -1) OVERRIDE;
void removeAfterVisit(const CGObjectInstance *object) OVERRIDE;
void giveHeroNewArtifact(const CGHeroInstance *h, const CArtifact *artType, ArtifactPosition pos) OVERRIDE;
void giveHeroArtifact(const CGHeroInstance *h, const CArtifactInstance *a, ArtifactPosition pos) OVERRIDE;

View File

@ -87,7 +87,7 @@ void CQuery::onExposure(CGameHandler *gh, QueryPtr topQuery)
}
CObjectVisitQuery::CObjectVisitQuery(const CGObjectInstance *Obj, const CGHeroInstance *Hero, int3 Tile)
: visitedObject(Obj), visitingHero(Hero), tile(Tile)
: visitedObject(Obj), visitingHero(Hero), tile(Tile), removeObjectAfterVisit(false)
{
addPlayer(Hero->tempOwner);
}
@ -102,6 +102,11 @@ bool CObjectVisitQuery::blocksPack(const CPack *pack) const
void CObjectVisitQuery::onRemoval(CGameHandler *gh, PlayerColor color)
{
gh->objectVisitEnded(*this);
//TODO or should it be destructor?
//Can object visit affect 2 players and what would be desired behavior?
if(removeObjectAfterVisit)
gh->removeObject(visitedObject);
}
void CObjectVisitQuery::onExposure(CGameHandler *gh, QueryPtr topQuery)

View File

@ -63,6 +63,7 @@ public:
const CGObjectInstance *visitedObject;
const CGHeroInstance *visitingHero;
int3 tile; //may be different than hero pos -> eg. visit via teleport
bool removeObjectAfterVisit;
CObjectVisitQuery(const CGObjectInstance *Obj, const CGHeroInstance *Hero, int3 Tile);