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:
parent
caf50fc278
commit
15d80d040f
@ -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()
|
||||
{
|
||||
|
@ -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
|
||||
|
@ -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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user