diff --git a/lib/CCreatureSet.cpp b/lib/CCreatureSet.cpp index 7ff9b94cd..271ada9ab 100644 --- a/lib/CCreatureSet.cpp +++ b/lib/CCreatureSet.cpp @@ -77,6 +77,18 @@ TSlot CCreatureSet::getSlotFor(const CCreature *c, ui32 slotsAmount/*=ARMY_SIZE* return -1; //no slot available } +TSlot CCreatureSet::getFreeSlot(ui32 slotsAmount/*=ARMY_SIZE*/) const +{ + for (ui32 i = 0; i < slotsAmount; i++) + { + if(stacks.find(i) == stacks.end()) + { + return i; //return first free slot + } + } + return -1; //no slot available +} + int CCreatureSet::getStackCount(TSlot slot) const { TSlots::const_iterator i = stacks.find(slot); @@ -227,7 +239,7 @@ void CCreatureSet::setFormation(bool tight) void CCreatureSet::setStackCount(TSlot slot, TQuantity count) { assert(hasStackAtSlot(slot)); - assert(count > 0); + assert(stacks[slot]->count + count > 0); if (STACK_EXP && count > stacks[slot]->count) stacks[slot]->experience *= (count/(float)stacks[slot]->count); stacks[slot]->count = count; diff --git a/lib/CCreatureSet.h b/lib/CCreatureSet.h index 45b30d98e..cdb961c5c 100644 --- a/lib/CCreatureSet.h +++ b/lib/CCreatureSet.h @@ -138,6 +138,7 @@ public: 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 + TSlot getFreeSlot(ui32 slotsAmount=ARMY_SIZE) const; bool mergableStacks(std::pair &out, TSlot preferable = -1) const; //looks for two same stacks, returns slot positions; bool validTypes(bool allowUnrandomized = false) const; //checks if all types of creatures are set properly bool slotEmpty(TSlot slot) const; diff --git a/lib/CObjectHandler.cpp b/lib/CObjectHandler.cpp index c2ad18afc..968046086 100644 --- a/lib/CObjectHandler.cpp +++ b/lib/CObjectHandler.cpp @@ -2852,7 +2852,7 @@ void CTownBonus::onHeroVisit (const CGHeroInstance * h) const const std::string & CGCreature::getHoverText() const { MetaString ms; - int pom = stacks.find(0)->second->getQuantityID(); + int pom = stacks.begin()->second->getQuantityID(); pom = 174 + 3*pom + 1; ms << std::pair(6,pom) << " " << std::pair(7,subID); ms.toString(hoverName); @@ -3131,7 +3131,73 @@ void CGCreature::joinDecision(const CGHeroInstance *h, int cost, ui32 accept) co void CGCreature::fight( const CGHeroInstance *h ) const { + //split stacks + int totalCount; //TODO: multiple creature types in a stack? + int basicType = stacks.begin()->second->type->idNumber; + + float relativePower = ((float)h->getTotalStrength() / getArmyStrength()); + int stacksCount; + //TODO: number depends on tile type + if (relativePower < 0.5) + { + stacksCount = 7; + } + else if (relativePower < 0.67) + { + stacksCount = 7; + } + else if (relativePower < 1) + { + stacksCount = 6; + } + else if (relativePower < 1.5) + { + stacksCount = 5; + } + else if (relativePower < 2) + { + stacksCount = 4; + } + else + { + stacksCount = 3; + } + int stackSize; + TSlot sourceSlot = stacks.begin()->first; + TSlot destSlot; + for (int stacksLeft = stacksCount; stacksLeft > 1; --stacksLeft) + { + stackSize = stacks.begin()->second->count / stacksLeft; + if (stackSize) + { + if ((destSlot = getFreeSlot()) > -1) + cb->moveStack(StackLocation(this, sourceSlot), StackLocation(this, destSlot), stackSize); + else + { + tlog2 <<"Warning! Not enough empty slots to split stack!"; + break; + } + } + else break; + } + if (stacksCount > 1) + { + if (rand()%100 > 50) //upgrade + { + TSlot slotId = (stacks.size() / 2); + if(ui32 upgradesSize = getStack(slotId).type->upgrades.size()) + { + std::set::const_iterator it = getStack(slotId).type->upgrades.begin(); //pick random in case there are more + std::advance (it, rand() % upgradesSize); + cb->changeStackType(StackLocation(this, slotId), VLC->creh->creatures[*it]); + } + } + } + cb->startBattleI(h, this, boost::bind(&CGCreature::endBattle,this,_1)); + + //stacks.clear(); + //stacks.insert( } void CGCreature::flee( const CGHeroInstance * h ) const