1
0
mirror of https://github.com/vcmi/vcmi.git synced 2024-12-24 22:14:36 +02:00

Fixed 563 & 701.

It's not nice to write same piece of code twice.
This commit is contained in:
DjWarmonger 2011-03-08 13:27:32 +00:00
parent 2fc2fa539d
commit f7bd5e75cb
4 changed files with 38 additions and 19 deletions

View File

@ -374,15 +374,20 @@ bool CCreatureSet::canBeMergedWith(const CCreatureSet &cs, bool allowMergingStac
} }
else else
{ {
std::set<const CCreature*> cres; CCreatureSet cres;
//get types of creatures that need their own slot //get types of creatures that need their own slot
for(TSlots::const_iterator i = cs.stacks.begin(); i != cs.stacks.end(); i++) for(TSlots::const_iterator i = cs.stacks.begin(); i != cs.stacks.end(); i++)
cres.insert(i->second->type); cres.addToSlot(i->first, i->second->type->idNumber, 1, true);
TSlot j;
for(TSlots::const_iterator i = stacks.begin(); i != stacks.end(); i++) for(TSlots::const_iterator i = stacks.begin(); i != stacks.end(); i++)
cres.insert(i->second->type); {
if ((j = cres.getSlotFor(i->second->type)) >= 0)
return cres.size() <= ARMY_SIZE; cres.addToSlot(j, i->second->type->idNumber, 1, true); //merge if possible
else
return false; //no place found
}
return true; //all stacks found their slots
} }
} }

View File

@ -4873,6 +4873,7 @@ void CGPandoraBox::giveContents( const CGHeroInstance *h, bool afterBattle ) con
{ {
InfoWindow iw; InfoWindow iw;
iw.player = h->getOwner(); iw.player = h->getOwner();
std::string msg = message; //in case box is removed in the meantime
bool changesPrimSkill = false; bool changesPrimSkill = false;
for (int i = 0; i < primskills.size(); i++) for (int i = 0; i < primskills.size(); i++)
@ -5044,11 +5045,10 @@ void CGPandoraBox::giveContents( const CGHeroInstance *h, bool afterBattle ) con
cb->showInfoDialog(&iw); cb->showInfoDialog(&iw);
cb->giveCreatures(this, h, creatures, true); cb->giveCreatures(this, h, creatures, true);
//boost::bind(&CGPandoraBox::endBattle, this, h, _1)
} }
if(!afterBattle && message.size()) if(!afterBattle && msg.size())
{ {
iw.text << message; iw.text << msg;
cb->showInfoDialog(&iw); cb->showInfoDialog(&iw);
} }
if (!creatures.Slots().size()) if (!creatures.Slots().size())

View File

@ -654,7 +654,6 @@ class DLL_EXPORT CGPandoraBox : public CArmedInstance
{ {
public: public:
std::string message; std::string message;
ui8 removeAfterVisit; //true if event is removed after occurring
//gained things: //gained things:
ui32 gainedExp; ui32 gainedExp;
@ -688,17 +687,15 @@ public:
class DLL_EXPORT CGEvent : public CGPandoraBox //event objects class DLL_EXPORT CGEvent : public CGPandoraBox //event objects
{ {
public: public:
ui8 removeAfterVisit; //true if event is removed after occurring
ui8 availableFor; //players whom this event is available for ui8 availableFor; //players whom this event is available for
ui8 computerActivate; //true if computre player can activate this event ui8 computerActivate; //true if computre player can activate this event
ui8 humanActivate; //true if human player can activate this event ui8 humanActivate; //true if human player can activate this event
template <typename Handler> void serialize(Handler &h, const int version) template <typename Handler> void serialize(Handler &h, const int version)
{ {
h & static_cast<CArmedInstance&>(*this); h & static_cast<CGPandoraBox &>(*this);
h & message & gainedExp & manaDiff & moraleDiff & luckDiff & resources & primskills h & removeAfterVisit & availableFor & computerActivate & humanActivate;
& abilities & abilityLevels & artifacts & spells & creatures & availableFor
& computerActivate & humanActivate;
} }
void onHeroVisit(const CGHeroInstance * h) const; void onHeroVisit(const CGHeroInstance * h) const;

View File

@ -1586,13 +1586,12 @@ void CGameHandler::giveCreatures(const CArmedInstance *obj, const CGHeroInstance
COMPLAIN_RET_IF(creatures.stacksCount() > ARMY_SIZE, "Too many stacks to give!"); COMPLAIN_RET_IF(creatures.stacksCount() > ARMY_SIZE, "Too many stacks to give!");
//first we move creatures to give to make them army of object-source //first we move creatures to give to make them army of object-source
for(int i = 0; i != creatures.stacksCount(); i++) for (TSlots::const_iterator stack = creatures.Slots().begin(); stack != creatures.Slots().end(); stack++)
{ {
TSlots::const_iterator stack = creatures.Slots().begin(); addToSlot(StackLocation(obj, obj->getSlotFor(stack->second->type)), stack->second->type, stack->second->count);
addToSlot(StackLocation(obj, i), stack->second->type, stack->second->count);
} }
tryJoiningArmy(obj, h, remove, false); tryJoiningArmy(obj, h, remove, true);
} }
void CGameHandler::takeCreatures(int objid, std::vector<CStackBasicDescriptor> creatures) void CGameHandler::takeCreatures(int objid, std::vector<CStackBasicDescriptor> creatures)
@ -4522,6 +4521,24 @@ void CGameHandler::tryJoiningArmy(const CArmedInstance *src, const CArmedInstanc
{ {
if(!dst->canBeMergedWith(*src, allowMerging)) if(!dst->canBeMergedWith(*src, allowMerging))
{ {
if (allowMerging) //do that, add all matching creatures.
{
bool cont = true;
while (cont)
{
for(TSlots::const_iterator i = src->stacks.begin(); i != src->stacks.end(); i++)//while there are unmoved creatures
{
TSlot pos = dst->getSlotFor(i->second->type);
if(pos > -1)
{
moveStack(StackLocation(src, i->first), StackLocation(dst, pos));
cont = true;
break; //or iterator crashes
}
cont = false;
}
}
}
boost::function<void()> removeOrNot = 0; boost::function<void()> removeOrNot = 0;
if(removeObjWhenFinished) if(removeObjWhenFinished)
removeOrNot = boost::bind(&IGameCallback::removeObject,this,src->id); removeOrNot = boost::bind(&IGameCallback::removeObject,this,src->id);