1
0
mirror of https://github.com/vcmi/vcmi.git synced 2024-11-24 08:32:34 +02:00

Correct handling of merging & moving stacks with experience.

This commit is contained in:
DjWarmonger 2011-03-27 09:31:14 +00:00
parent caf50fc278
commit 15d80d040f
3 changed files with 46 additions and 7 deletions

View File

@ -86,6 +86,16 @@ int CCreatureSet::getStackCount(TSlot slot) const
return 0; //TODO? consider issuing a warning
}
expType CCreatureSet::getStackExperience(TSlot slot) const
{
TSlots::const_iterator i = stacks.find(slot);
if (i != stacks.end())
return i->second->experience;
else
return 0; //TODO? consider issuing a warning
}
bool CCreatureSet::mergableStacks(std::pair<TSlot, TSlot> &out, TSlot preferable /*= -1*/) const /*looks for two same stacks, returns slot positions */
{
//try to match creature to our preferred stack
@ -218,8 +228,8 @@ void CCreatureSet::setStackCount(TSlot slot, TQuantity count)
{
assert(hasStackAtSlot(slot));
assert(count > 0);
if (STACK_EXP)
stacks[slot]->experience *= ((stacks[slot]->count + count)/(float)stacks[slot]->count);
if (STACK_EXP && count > stacks[slot]->count)
stacks[slot]->experience *= (count/(float)stacks[slot]->count);
stacks[slot]->count = count;
armyChanged();
}
@ -229,6 +239,11 @@ void CCreatureSet::giveStackExp(expType exp)
for(TSlots::const_iterator i = stacks.begin(); i != stacks.end(); i++)
i->second->giveStackExp(exp);
}
void CCreatureSet::setStackExp(TSlot slot, expType exp)
{
assert(hasStackAtSlot(slot));
stacks[slot]->experience = exp;
}
void CCreatureSet::clear()
{

View File

@ -122,6 +122,7 @@ public:
CStackInstance *detachStack(TSlot slot); //removes stack from army but doesn't destroy it (so it can be moved somewhere else or safely deleted)
void setStackType(TSlot slot, const CCreature *type);
void giveStackExp(expType exp);
void setStackExp(TSlot slot, expType exp);
//derivative
void eraseStack(TSlot slot); //slot must be occupied
@ -133,6 +134,7 @@ public:
const CStackInstance& getStack(TSlot slot) const;
const CCreature* getCreature(TSlot slot) const; //workaround of map issue;
int getStackCount (TSlot slot) const;
expType getStackExperience(TSlot slot) const;
TSlot findStack(const CStackInstance *stack) const; //-1 if none
TSlot getSlotFor(TCreature creature, ui32 slotsAmount=ARMY_SIZE) const; //returns -1 if no slot available
TSlot getSlotFor(const CCreature *c, ui32 slotsAmount=ARMY_SIZE) const; //returns -1 if no slot available

View File

@ -597,10 +597,20 @@ DLL_EXPORT void RebalanceStacks::applyGs( CGameState *gs )
if(const CCreature *c = dst.army->getCreature(dst.slot)) //stack at dest -> merge
{
assert(c == srcType);
src.army->eraseStack(src.slot);
dst.army->changeStackCount(dst.slot, count);
if (STACK_EXP)
{
ui64 totalExp = srcCount * src.army->getStackExperience(src.slot) + dst.army->getStackCount(dst.slot) * dst.army->getStackExperience(dst.slot);
src.army->eraseStack(src.slot);
dst.army->changeStackCount(dst.slot, count);
dst.army->setStackExp(dst.slot, totalExp /(dst.army->getStackCount(dst.slot))); //mean
}
else
{
src.army->eraseStack(src.slot);
dst.army->changeStackCount(dst.slot, count);
}
}
else //move stack to an empty slot
else //move stack to an empty slot, no exp change needed
{
CStackInstance *stackDetached = src.army->detachStack(src.slot);
dst.army->putStack(dst.slot, stackDetached);
@ -611,13 +621,25 @@ DLL_EXPORT void RebalanceStacks::applyGs( CGameState *gs )
if(const CCreature *c = dst.army->getCreature(dst.slot)) //stack at dest -> rebalance
{
assert(c == srcType);
src.army->changeStackCount(src.slot, -count);
dst.army->changeStackCount(dst.slot, count);
if (STACK_EXP)
{
ui64 totalExp = srcCount * src.army->getStackExperience(src.slot) + dst.army->getStackCount(dst.slot) * dst.army->getStackExperience(dst.slot);
src.army->changeStackCount(src.slot, -count);
dst.army->changeStackCount(dst.slot, count);
dst.army->setStackExp(dst.slot, totalExp /(src.army->getStackCount(src.slot) + dst.army->getStackCount(dst.slot))); //mean
}
else
{
src.army->changeStackCount(src.slot, -count);
dst.army->changeStackCount(dst.slot, count);
}
}
else //split stack to an empty slot
{
src.army->changeStackCount(src.slot, -count);
dst.army->addToSlot(dst.slot, srcType->idNumber, count, false);
if (STACK_EXP)
dst.army->setStackExp(dst.slot, src.army->getStackExperience(src.slot));
}
}
}