diff --git a/AI/StupidAI/StupidAI.vcxproj b/AI/StupidAI/StupidAI.vcxproj index a89a59d11..3b27c2597 100644 --- a/AI/StupidAI/StupidAI.vcxproj +++ b/AI/StupidAI/StupidAI.vcxproj @@ -92,6 +92,7 @@ VCMI_lib.lib;%(AdditionalDependencies) + -Zm150 %(AdditionalOptions) diff --git a/AI/VCAI/VCAI.cpp b/AI/VCAI/VCAI.cpp index 4faa103ea..a1653312f 100644 --- a/AI/VCAI/VCAI.cpp +++ b/AI/VCAI/VCAI.cpp @@ -288,7 +288,7 @@ ui64 howManyReinforcementsCanGet(HeroPtr h, const CGTownInstance *t) BOOST_FOREACH(auto const slot, t->Slots()) { //can be merged woth another stack? - TSlot dst = h->getSlotFor(slot.second->getCreatureID()); + SlotID dst = h->getSlotFor(slot.second->getCreatureID()); if(h->hasStackAtSlot(dst)) ret += t->getPower(slot.first); else @@ -959,13 +959,13 @@ void makePossibleUpgrades(const CArmedInstance *obj) for(int i = 0; i < GameConstants::ARMY_SIZE; i++) { - if(const CStackInstance *s = obj->getStackPtr(i)) + if(const CStackInstance *s = obj->getStackPtr(SlotID(i))) { UpgradeInfo ui; - cb->getUpgradeInfo(obj, i, ui); + cb->getUpgradeInfo(obj, SlotID(i), ui); if(ui.oldID >= 0 && cb->getResourceAmount().canAfford(ui.cost[0] * s->count)) { - cb->upgradeCreature(obj, i, ui.newID[0]); + cb->upgradeCreature(obj, SlotID(i), ui.newID[0]); } } } @@ -1176,7 +1176,7 @@ bool VCAI::canGetArmy (const CGHeroInstance * army, const CGHeroInstance * sourc BOOST_FOREACH(auto armyPtr, armies) for (int j = 0; j < GameConstants::ARMY_SIZE; j++) { - if(armyPtr->getCreature(j) == bestArmy[i] && (i != j || armyPtr != army)) //it's a searched creature not in dst slot + if(armyPtr->getCreature(SlotID(j)) == bestArmy[i] && (i != j || armyPtr != army)) //it's a searched creature not in dst slot if (!(armyPtr->needsLastStack() && armyPtr->Slots().size() == 1 && armyPtr != army)) //can't take away last creature return true; //at least one exchange will be performed } @@ -1220,9 +1220,9 @@ void VCAI::pickBestCreatures(const CArmedInstance * army, const CArmedInstance * BOOST_FOREACH(auto armyPtr, armies) for (int j = 0; j < GameConstants::ARMY_SIZE; j++) { - if(armyPtr->getCreature(j) == bestArmy[i] && (i != j || armyPtr != army)) //it's a searched creature not in dst slot + if(armyPtr->getCreature(SlotID(j)) == bestArmy[i] && (i != j || armyPtr != army)) //it's a searched creature not in dst slot if (!(armyPtr->needsLastStack() && armyPtr->Slots().size() == 1 && armyPtr != army)) - cb->mergeOrSwapStacks(armyPtr, army, j, i); + cb->mergeOrSwapStacks(armyPtr, army, SlotID(j), SlotID(i)); } } @@ -3630,7 +3630,7 @@ bool shouldVisit(HeroPtr h, const CGObjectInstance * obj) { BOOST_FOREACH(auto c, level.second) { - if (h->getSlotFor(c) != -1) + if (h->getSlotFor(CreatureID(c)) != SlotID()) canRecruitCreatures = true; } } diff --git a/CCallback.cpp b/CCallback.cpp index 144a29d07..672f84ef5 100644 --- a/CCallback.cpp +++ b/CCallback.cpp @@ -79,7 +79,7 @@ void CCallback::recruitCreatures(const CGObjectInstance *obj, CreatureID ID, ui3 sendRequest(&pack); } -bool CCallback::dismissCreature(const CArmedInstance *obj, int stackPos) +bool CCallback::dismissCreature(const CArmedInstance *obj, SlotID stackPos) { if(((player>=0) && obj->tempOwner != player) || (obj->stacksCount()<2 && obj->needsLastStack())) return false; @@ -89,7 +89,7 @@ bool CCallback::dismissCreature(const CArmedInstance *obj, int stackPos) return true; } -bool CCallback::upgradeCreature(const CArmedInstance *obj, int stackPos, CreatureID newID) +bool CCallback::upgradeCreature(const CArmedInstance *obj, SlotID stackPos, CreatureID newID) { UpgradeCreature pack(stackPos,obj->id,newID); sendRequest(&pack); @@ -102,20 +102,20 @@ void CCallback::endTurn() EndTurn pack; sendRequest(&pack); //report that we ended turn } -int CCallback::swapCreatures(const CArmedInstance *s1, const CArmedInstance *s2, int p1, int p2) +int CCallback::swapCreatures(const CArmedInstance *s1, const CArmedInstance *s2, SlotID p1, SlotID p2) { ArrangeStacks pack(1,p1,p2,s1->id,s2->id,0); sendRequest(&pack); return 0; } -int CCallback::mergeStacks(const CArmedInstance *s1, const CArmedInstance *s2, int p1, int p2) +int CCallback::mergeStacks(const CArmedInstance *s1, const CArmedInstance *s2, SlotID p1, SlotID p2) { ArrangeStacks pack(2,p1,p2,s1->id,s2->id,0); sendRequest(&pack); return 0; } -int CCallback::splitStack(const CArmedInstance *s1, const CArmedInstance *s2, int p1, int p2, int val) +int CCallback::splitStack(const CArmedInstance *s1, const CArmedInstance *s2, SlotID p1, SlotID p2, int val) { ArrangeStacks pack(3,p1,p2,s1->id,s2->id,val); sendRequest(&pack); @@ -154,7 +154,7 @@ bool CCallback::swapArtifacts(const ArtifactLocation &l1, const ArtifactLocation * @param assembleTo If assemble is true, this represents the artifact ID of the combination * artifact to assemble to. Otherwise it's not used. */ -bool CCallback::assembleArtifacts (const CGHeroInstance * hero, ArtifactPosition artifactSlot, bool assemble, ui32 assembleTo) +bool CCallback::assembleArtifacts (const CGHeroInstance * hero, ArtifactPosition artifactSlot, bool assemble, ArtifactID assembleTo) { if (player != hero->tempOwner) return false; @@ -366,7 +366,7 @@ void CCallback::validatePaths() } } -int CCallback::mergeOrSwapStacks(const CArmedInstance *s1, const CArmedInstance *s2, int p1, int p2) +int CCallback::mergeOrSwapStacks(const CArmedInstance *s1, const CArmedInstance *s2, SlotID p1, SlotID p2) { if(s1->getCreature(p1) == s2->getCreature(p2)) return mergeStacks(s1, s2, p1, p2); diff --git a/CCallback.h b/CCallback.h index faae832dd..bfaacb7c0 100644 --- a/CCallback.h +++ b/CCallback.h @@ -51,20 +51,20 @@ public: virtual void recruitHero(const CGObjectInstance *townOrTavern, const CGHeroInstance *hero)=0; virtual bool buildBuilding(const CGTownInstance *town, BuildingID buildingID)=0; virtual void recruitCreatures(const CGObjectInstance *obj, CreatureID ID, ui32 amount, si32 level=-1)=0; - virtual bool upgradeCreature(const CArmedInstance *obj, int stackPos, CreatureID newID=CreatureID::NONE)=0; //if newID==-1 then best possible upgrade will be made + virtual bool upgradeCreature(const CArmedInstance *obj, SlotID stackPos, CreatureID newID=CreatureID::NONE)=0; //if newID==-1 then best possible upgrade will be made virtual void swapGarrisonHero(const CGTownInstance *town)=0; virtual void trade(const CGObjectInstance *market, EMarketMode::EMarketMode mode, int id1, int id2, int val1, const CGHeroInstance *hero = NULL)=0; //mode==0: sell val1 units of id1 resource for id2 resiurce virtual int selectionMade(int selection, int queryID) =0; - virtual int swapCreatures(const CArmedInstance *s1, const CArmedInstance *s2, int p1, int p2)=0;//swaps creatures between two possibly different garrisons // TODO: AI-unsafe code - fix it! - virtual int mergeStacks(const CArmedInstance *s1, const CArmedInstance *s2, int p1, int p2)=0;//joins first stack to the second (creatures must be same type) - virtual int mergeOrSwapStacks(const CArmedInstance *s1, const CArmedInstance *s2, int p1, int p2) =0; //first goes to the second - virtual int splitStack(const CArmedInstance *s1, const CArmedInstance *s2, int p1, int p2, int val)=0;//split creatures from the first stack + virtual int swapCreatures(const CArmedInstance *s1, const CArmedInstance *s2, SlotID p1, SlotID p2)=0;//swaps creatures between two possibly different garrisons // TODO: AI-unsafe code - fix it! + virtual int mergeStacks(const CArmedInstance *s1, const CArmedInstance *s2, SlotID p1, SlotID p2)=0;//joins first stack to the second (creatures must be same type) + virtual int mergeOrSwapStacks(const CArmedInstance *s1, const CArmedInstance *s2, SlotID p1, SlotID p2) =0; //first goes to the second + virtual int splitStack(const CArmedInstance *s1, const CArmedInstance *s2, SlotID p1, SlotID p2, int val)=0;//split creatures from the first stack //virtual bool swapArtifacts(const CGHeroInstance * hero1, ui16 pos1, const CGHeroInstance * hero2, ui16 pos2)=0; //swaps artifacts between two given heroes virtual bool swapArtifacts(const ArtifactLocation &l1, const ArtifactLocation &l2)=0; - virtual bool assembleArtifacts(const CGHeroInstance * hero, ArtifactPosition artifactSlot, bool assemble, ui32 assembleTo)=0; - virtual bool dismissCreature(const CArmedInstance *obj, int stackPos)=0; + virtual bool assembleArtifacts(const CGHeroInstance * hero, ArtifactPosition artifactSlot, bool assemble, ArtifactID assembleTo)=0; + virtual bool dismissCreature(const CArmedInstance *obj, SlotID stackPos)=0; virtual void endTurn()=0; virtual void buyArtifact(const CGHeroInstance *hero, ArtifactID aid)=0; //used to buy artifacts in towns (including spell book in the guild and war machines in blacksmith) virtual void setFormation(const CGHeroInstance * hero, bool tight)=0; @@ -118,20 +118,20 @@ public: bool moveHero(const CGHeroInstance *h, int3 dst); //dst must be free, neighbouring tile (this function can move hero only by one tile) bool teleportHero(const CGHeroInstance *who, const CGTownInstance *where); int selectionMade(int selection, int queryID); - int swapCreatures(const CArmedInstance *s1, const CArmedInstance *s2, int p1, int p2); - int mergeOrSwapStacks(const CArmedInstance *s1, const CArmedInstance *s2, int p1, int p2); //first goes to the second - int mergeStacks(const CArmedInstance *s1, const CArmedInstance *s2, int p1, int p2); //first goes to the second - int splitStack(const CArmedInstance *s1, const CArmedInstance *s2, int p1, int p2, int val); + int swapCreatures(const CArmedInstance *s1, const CArmedInstance *s2, SlotID p1, SlotID p2); + int mergeOrSwapStacks(const CArmedInstance *s1, const CArmedInstance *s2, SlotID p1, SlotID p2); //first goes to the second + int mergeStacks(const CArmedInstance *s1, const CArmedInstance *s2, SlotID p1, SlotID p2); //first goes to the second + int splitStack(const CArmedInstance *s1, const CArmedInstance *s2, SlotID p1, SlotID p2, int val); bool dismissHero(const CGHeroInstance * hero); //bool swapArtifacts(const CGHeroInstance * hero1, ui16 pos1, const CGHeroInstance * hero2, ui16 pos2); bool swapArtifacts(const ArtifactLocation &l1, const ArtifactLocation &l2); //bool moveArtifact(const CGHeroInstance * hero, ui16 src, const CStackInstance * stack, ui16 dest); // TODO: unify classes //bool moveArtifact(const CStackInstance * stack, ui16 src , const CGHeroInstance * hero, ui16 dest); // TODO: unify classes - bool assembleArtifacts(const CGHeroInstance * hero, ArtifactPosition artifactSlot, bool assemble, ui32 assembleTo); + bool assembleArtifacts(const CGHeroInstance * hero, ArtifactPosition artifactSlot, bool assemble, ArtifactID assembleTo); bool buildBuilding(const CGTownInstance *town, BuildingID buildingID) OVERRIDE; void recruitCreatures(const CGObjectInstance *obj, CreatureID ID, ui32 amount, si32 level=-1); - bool dismissCreature(const CArmedInstance *obj, int stackPos); - bool upgradeCreature(const CArmedInstance *obj, int stackPos, CreatureID newID=CreatureID::NONE) OVERRIDE; + bool dismissCreature(const CArmedInstance *obj, SlotID stackPos); + bool upgradeCreature(const CArmedInstance *obj, SlotID stackPos, CreatureID newID=CreatureID::NONE) OVERRIDE; void endTurn(); void swapGarrisonHero(const CGTownInstance *town); void buyArtifact(const CGHeroInstance *hero, ArtifactID aid) OVERRIDE; diff --git a/Scripting/ERM/ERMInterpreter.cpp b/Scripting/ERM/ERMInterpreter.cpp index f92906fdc..f1bdeab8a 100644 --- a/Scripting/ERM/ERMInterpreter.cpp +++ b/Scripting/ERM/ERMInterpreter.cpp @@ -737,7 +737,7 @@ struct HEPerformer : StandardReceiverVisitor { if(erm->getIexp(params[0]).getInt() == 0) { - int slot = erm->getIexp(params[1]).getInt(); + SlotID slot = SlotID(erm->getIexp(params[1]).getInt()); const CStackInstance *stack = identifier->getStackPtr(slot); if(params[2].which() == 6) //varp { @@ -752,7 +752,7 @@ struct HEPerformer : StandardReceiverVisitor if(params[3].which() == 6) //varp { - erm->getIexp(boost::get(params[3])).setTo(identifier->getStackCount(slot)); + erm->getIexp(boost::get(params[3])).setTo(identifier->getStackCount(SlotID(slot))); } else throw EScriptExecError("Setting stack count is not implemented!"); @@ -1016,7 +1016,7 @@ void MO_GPerformer::operator()( TIexp const& cmp ) const void MO_GPerformer::operator()( TVarpExp const& cmp ) const { const CGCreature *cre = erm->getObjFromAs(owner.identifier); - erm->getIexp(cmp).setTo(cre->getStackCount(0)); + erm->getIexp(cmp).setTo(cre->getStackCount(SlotID(0))); } diff --git a/client/CCreatureWindow.cpp b/client/CCreatureWindow.cpp index f04c6214d..da89391d4 100644 --- a/client/CCreatureWindow.cpp +++ b/client/CCreatureWindow.cpp @@ -280,7 +280,7 @@ void CCreatureWindow::init(const CStackInstance *Stack, const CBonusSystemNode * } if (magicResistance) { - std::map >::const_iterator it = CGI->creh->stackBonuses.find(Bonus::MAGIC_RESISTANCE); + std::map >::const_iterator it = CGI->creh->stackBonuses.find(Bonus::MAGIC_RESISTANCE); std::string description; text = it->second.first; description = it->second.second; diff --git a/client/GUIClasses.cpp b/client/GUIClasses.cpp index 2b198bbd3..73fac8a83 100644 --- a/client/GUIClasses.cpp +++ b/client/GUIClasses.cpp @@ -82,13 +82,13 @@ void CArmyTooltip::init(const InfoAboutArmy &army) BOOST_FOREACH(auto & slot, army.army) { - if(slot.first >= GameConstants::ARMY_SIZE) + if(slot.first.getNum() >= GameConstants::ARMY_SIZE) { tlog3 << "Warning: " << army.name << " has stack in slot " << slot.first << std::endl; continue; } - new CAnimImage("CPRSMALL", slot.second.type->iconIndex, 0, slotsPos[slot.first].x, slotsPos[slot.first].y); + new CAnimImage("CPRSMALL", slot.second.type->iconIndex, 0, slotsPos[slot.first.getNum()].x, slotsPos[slot.first.getNum()].y); std::string subtitle; if(army.army.isDetailed) @@ -100,7 +100,7 @@ void CArmyTooltip::init(const InfoAboutArmy &army) subtitle = CGI->generaltexth->arraytxt[171 + 3*(slot.second.count)]; } - new CLabel(slotsPos[slot.first].x + 17, slotsPos[slot.first].y + 41, FONT_TINY, CENTER, Colors::WHITE, subtitle); + new CLabel(slotsPos[slot.first.getNum()].x + 17, slotsPos[slot.first.getNum()].y + 41, FONT_TINY, CENTER, Colors::WHITE, subtitle); } } @@ -472,7 +472,7 @@ void CGarrisonSlot::update() } } -CGarrisonSlot::CGarrisonSlot(CGarrisonInt *Owner, int x, int y, int IID, int Upg, const CStackInstance * Creature): +CGarrisonSlot::CGarrisonSlot(CGarrisonInt *Owner, int x, int y, SlotID IID, int Upg, const CStackInstance * Creature): ID(IID), owner(Owner), myStack(Creature), @@ -528,13 +528,13 @@ void CGarrisonInt::createSet(std::vector &ret, const CCreatureSe { for(TSlots::const_iterator i=set->Slots().begin(); i!=set->Slots().end(); i++) { - ret[i->first] = new CGarrisonSlot(this, posX + (i->first*distance), posY, i->first, Upg, i->second); + ret[i->first.getNum()] = new CGarrisonSlot(this, posX + (i->first.getNum()*distance), posY, i->first, Upg, i->second); } } for(int i=0; icreature->idNumber; - TSlot dstslot = dst-> getSlotFor(crid); + SlotID dstslot = dst-> getSlotFor(crid); - if(dstslot < 0 && !vstd::contains(CGI->arth->bigArtifacts,CGI->arth->creatureToMachineID(crid))) //no available slot + if(!dstslot.validSlot() && !vstd::contains(CGI->arth->bigArtifacts,CGI->arth->creatureToMachineID(crid))) //no available slot { std::string txt; if(dst->ID == Obj::HERO) @@ -2346,7 +2346,7 @@ std::vector *CTradeWindow::getItemsIds(bool Left) ids = new std::vector; for(int i = 0; i < 7; i++) { - if(const CCreature *c = hero->getCreature(i)) + if(const CCreature *c = hero->getCreature(SlotID(i))) ids->push_back(c->idNumber); else ids->push_back(-1); @@ -2423,7 +2423,7 @@ void CTradeWindow::initSubs(bool Left) switch(itemsType[1]) { case CREATURE: - t->subtitle = boost::lexical_cast(hero->getStackCount(t->serial)); + t->subtitle = boost::lexical_cast(hero->getStackCount(SlotID(t->serial))); break; case RESOURCE: t->subtitle = boost::lexical_cast(LOCPLINT->cb->getResourceAmount(static_cast(t->serial))); @@ -2494,7 +2494,7 @@ void CTradeWindow::removeItem(CTradeableItem * t) void CTradeWindow::getEmptySlots(std::set &toRemove) { BOOST_FOREACH(CTradeableItem *t, items[1]) - if(!hero->getStackCount(t->serial)) + if(!hero->getStackCount(SlotID(t->serial))) toRemove.insert(t); } @@ -2758,7 +2758,7 @@ void CMarketplaceWindow::selectionChanged(bool side) if(itemsType[1] == RESOURCE) newAmount = LOCPLINT->cb->getResourceAmount(static_cast(soldItemId)); else if(itemsType[1] == CREATURE) - newAmount = hero->getStackCount(hLeft->serial) - (hero->Slots().size() == 1 && hero->needsLastStack()); + newAmount = hero->getStackCount(SlotID(hLeft->serial)) - (hero->Slots().size() == 1 && hero->needsLastStack()); else assert(0); @@ -3149,7 +3149,7 @@ void CAltarWindow::SacrificeAll() { bool movedAnything = false; BOOST_FOREACH(CTradeableItem *t, items[1]) - sacrificedUnits[t->serial] = hero->getStackCount(t->serial); + sacrificedUnits[t->serial] = hero->getStackCount(SlotID(t->serial)); sacrificedUnits[items[1].front()->serial]--; @@ -3188,10 +3188,10 @@ void CAltarWindow::selectionChanged(bool side) int stackCount = 0; for (int i = 0; i < GameConstants::ARMY_SIZE; i++) - if(hero->getStackCount(i) > sacrificedUnits[i]) + if(hero->getStackCount(SlotID(i)) > sacrificedUnits[i]) stackCount++; - slider->setAmount(hero->getStackCount(hLeft->serial) - (stackCount == 1)); + slider->setAmount(hero->getStackCount(SlotID(hLeft->serial)) - (stackCount == 1)); slider->block(!slider->amount); slider->value = sacrificedUnits[hLeft->serial]; max->block(!slider->amount); @@ -4265,7 +4265,7 @@ void CArtPlace::clickRight(tribool down, bool previousState) ourArt->artType->id, 0, false, - boost::bind(&CCallback::assembleArtifacts, LOCPLINT->cb, ourOwner->curHero, slotID, false, 0), + boost::bind(&CCallback::assembleArtifacts, LOCPLINT->cb, ourOwner->curHero, slotID, false, ArtifactID()), 0); return; } @@ -5310,7 +5310,7 @@ void CTransformerWindow::CItem::clickLeft(tribool down, bool previousState) void CTransformerWindow::CItem::update() { - icon->setFrame(parent->army->getCreature(id)->idNumber + 2); + icon->setFrame(parent->army->getCreature(SlotID(id))->idNumber + 2); } CTransformerWindow::CItem::CItem(CTransformerWindow * parent, int size, int id): @@ -5324,7 +5324,7 @@ CTransformerWindow::CItem::CItem(CTransformerWindow * parent, int size, int id): pos.x += 45 + (id%3)*83 + id/6*83; pos.y += 109 + (id/3)*98; - icon = new CAnimImage("TWCRPORT", parent->army->getCreature(id)->idNumber + 2); + icon = new CAnimImage("TWCRPORT", parent->army->getCreature(SlotID(id))->idNumber + 2); new CLabel(28, 76,FONT_SMALL, CENTER, Colors::WHITE, boost::lexical_cast(size));//stack size } @@ -5362,9 +5362,9 @@ CTransformerWindow::CTransformerWindow(const CGHeroInstance * _hero, const CGTow else army = town; - for (int i=0; i<7; i++ ) - if ( army->getCreature(i) ) - items.push_back(new CItem(this, army->getStackCount(i), i)); + for (int i=0; igetCreature(SlotID(i)) ) + items.push_back(new CItem(this, army->getStackCount(SlotID(i)), i)); all = new CAdventureMapButton(CGI->generaltexth->zelp[590],boost::bind(&CTransformerWindow::addAll,this), 146,416,"ALTARMY.DEF",SDLK_a); convert= new CAdventureMapButton(CGI->generaltexth->zelp[591],boost::bind(&CTransformerWindow::makeDeal,this), 269,416,"ALTSACR.DEF",SDLK_RETURN); @@ -5556,15 +5556,15 @@ CHillFortWindow::CHillFortWindow(const CGHeroInstance *visitor, const CGObjectIn files += "APHLF1R.DEF", "APHLF1Y.DEF", "APHLF1G.DEF"; for (int i=0; iblock(currState[i] == -1); } files.clear(); files += "APHLF4R.DEF", "APHLF4Y.DEF", "APHLF4G.DEF"; - currState[slotsCount] = getState(slotsCount); - upgradeAll = new CAdventureMapButton(CGI->generaltexth->allTexts[432],"",boost::bind(&CHillFortWindow::makeDeal, this, slotsCount), + currState[slotsCount] = getState(SlotID(slotsCount)); + upgradeAll = new CAdventureMapButton(CGI->generaltexth->allTexts[432],"",boost::bind(&CHillFortWindow::makeDeal, this, SlotID(slotsCount)), 30, 231, "", SDLK_0, &files); quit = new CAdventureMapButton("","",boost::bind(&CHillFortWindow::close, this), 294, 275, "IOKAY.DEF", SDLK_RETURN); bar = new CGStatusBar(new CPicture(*background, Rect(8, pos.h - 26, pos.w - 16, 19), 8, pos.h - 26)); @@ -5581,14 +5581,14 @@ void CHillFortWindow::updateGarrisons() for (int i=0; icb->getUpgradeInfo(hero, i, info); + LOCPLINT->cb->getUpgradeInfo(hero, SlotID(i), info); if (info.newID.size())//we have upgrades here - update costs { - costs[i] = info.cost[0] * hero->getStackCount(i); + costs[i] = info.cost[0] * hero->getStackCount(SlotID(i)); totalSumm += costs[i]; } } @@ -5596,19 +5596,20 @@ void CHillFortWindow::updateGarrisons() currState[i] = newState; upgrade[i]->setIndex(newState); upgrade[i]->block(currState[i] == -1); - upgrade[i]->hoverTexts[0] = getTextForSlot(i); + upgrade[i]->hoverTexts[0] = getTextForSlot(SlotID(i)); } - int newState = getState(slotsCount); + int newState = getState(SlotID(slotsCount)); currState[slotsCount] = newState; upgradeAll->setIndex(newState); garr->recreateSlots(); } -void CHillFortWindow::makeDeal(int slot) +void CHillFortWindow::makeDeal(SlotID slot) { - int offset = (slot == slotsCount)?2:0; - switch (currState[slot]) + assert(slot.getNum()>=0); + int offset = (slot.getNum() == slotsCount)?2:0; + switch (currState[slot.getNum()]) { case 0: LOCPLINT->showInfoDialog(CGI->generaltexth->allTexts[314 + offset], @@ -5620,11 +5621,11 @@ void CHillFortWindow::makeDeal(int slot) break; case 2: for (int i=0; icb->getUpgradeInfo(hero, i, info); - LOCPLINT->cb->upgradeCreature(hero, i, info.newID[0]); + LOCPLINT->cb->getUpgradeInfo(hero, SlotID(i), info); + LOCPLINT->cb->upgradeCreature(hero, SlotID(i), info.newID[0]); } break; @@ -5669,7 +5670,7 @@ void CHillFortWindow::showAll (SDL_Surface *to) } } -std::string CHillFortWindow::getTextForSlot(int slot) +std::string CHillFortWindow::getTextForSlot(SlotID slot) { if ( !hero->getCreature(slot) )//we dont have creature here return ""; @@ -5684,10 +5685,10 @@ std::string CHillFortWindow::getTextForSlot(int slot) return str; } -int CHillFortWindow::getState(int slot) +int CHillFortWindow::getState(SlotID slot) { TResources myRes = LOCPLINT->cb->getResourceAmount(); - if ( slot == slotsCount )//"Upgrade all" slot + if ( slot.getNum() == slotsCount )//"Upgrade all" slot { bool allUpgraded = true;//All creatures are upgraded? for (int i=0; i splitButtons; //may be empty if no buttons - int p2, //TODO: comment me - shiftPos;//1st slot of the second row, set shiftPoint for effect + SlotID p2; //TODO: comment me + int shiftPos;//1st slot of the second row, set shiftPoint for effect bool pb, smallIcons, //true - 32x32 imgs, false - 58x64 removableUnits,//player can remove units from up @@ -1172,10 +1172,10 @@ public: CHillFortWindow(const CGHeroInstance *visitor, const CGObjectInstance *object); //c-tor void showAll (SDL_Surface *to); - std::string getDefForSlot(int slot);//return def name for this slot - std::string getTextForSlot(int slot);//return hover text for this slot - void makeDeal(int slot);//-1 for upgrading all creatures - int getState(int slot); //-1 = no creature 0=can't upgrade, 1=upgraded, 2=can upgrade + std::string getDefForSlot(SlotID slot);//return def name for this slot + std::string getTextForSlot(SlotID slot);//return hover text for this slot + void makeDeal(SlotID slot);//-1 for upgrading all creatures + int getState(SlotID slot); //-1 = no creature 0=can't upgrade, 1=upgraded, 2=can upgrade void updateGarrisons();//update buttons after garrison changes }; diff --git a/lib/BattleState.cpp b/lib/BattleState.cpp index 41e5c1af2..bab780a11 100644 --- a/lib/BattleState.cpp +++ b/lib/BattleState.cpp @@ -138,7 +138,7 @@ int BattleInfo::calculateSpellDuration( const CSpell * spell, const CGHeroInstan } } -CStack * BattleInfo::generateNewStack(const CStackInstance &base, bool attackerOwned, int slot, BattleHex position) const +CStack * BattleInfo::generateNewStack(const CStackInstance &base, bool attackerOwned, SlotID slot, BattleHex position) const { int stackID = getIdForNewStack(); int owner = attackerOwned ? sides[0] : sides[1]; @@ -151,7 +151,7 @@ CStack * BattleInfo::generateNewStack(const CStackInstance &base, bool attackerO return ret; } -CStack * BattleInfo::generateNewStack(const CStackBasicDescriptor &base, bool attackerOwned, int slot, BattleHex position) const +CStack * BattleInfo::generateNewStack(const CStackBasicDescriptor &base, bool attackerOwned, SlotID slot, BattleHex position) const { int stackID = getIdForNewStack(); int owner = attackerOwned ? sides[0] : sides[1]; @@ -515,7 +515,7 @@ BattleInfo * BattleInfo::setupBattle( int3 tile, ETerrainType terrain, BFieldTyp auto handleWarMachine= [&](int side, ArtifactPosition artslot, CreatureID cretype, BattleHex hex) { if(heroes[side] && heroes[side]->getArt(artslot)) - stacks.push_back(curB->generateNewStack(CStackBasicDescriptor(cretype, 1), !side, 255, hex)); + stacks.push_back(curB->generateNewStack(CStackBasicDescriptor(cretype, 1), !side, SlotID(255), hex)); }; handleWarMachine(0, ArtifactPosition::MACH1, CreatureID::BALLISTA, 52); @@ -562,7 +562,7 @@ BattleInfo * BattleInfo::setupBattle( int3 tile, ETerrainType terrain, BFieldTyp { if (heroes[i] && heroes[i]->commander) { - CStack * stack = curB->generateNewStack (*heroes[i]->commander, !i, -2, //TODO: use COMMANDER_SLOT_PLACEHOLDER + CStack * stack = curB->generateNewStack (*heroes[i]->commander, !i, SlotID::COMMANDER_SLOT_PLACEHOLDER, creatureBank ? commanderBank[i] : commanderField[i]); stacks.push_back(stack); } @@ -572,15 +572,15 @@ BattleInfo * BattleInfo::setupBattle( int3 tile, ETerrainType terrain, BFieldTyp if (curB->siege == CGTownInstance::CITADEL || curB->siege == CGTownInstance::CASTLE) { // keep tower - CStack * stack = curB->generateNewStack(CStackBasicDescriptor(CreatureID::ARROW_TOWERS, 1), false, 255, -2); + CStack * stack = curB->generateNewStack(CStackBasicDescriptor(CreatureID::ARROW_TOWERS, 1), false, SlotID(255), -2); stacks.push_back(stack); if (curB->siege == CGTownInstance::CASTLE) { // lower tower + upper tower - CStack * stack = curB->generateNewStack(CStackBasicDescriptor(CreatureID::ARROW_TOWERS, 1), false, 255, -4); + CStack * stack = curB->generateNewStack(CStackBasicDescriptor(CreatureID::ARROW_TOWERS, 1), false, SlotID(255), -4); stacks.push_back(stack); - stack = curB->generateNewStack(CStackBasicDescriptor(CreatureID::ARROW_TOWERS, 1), false, 255, -3); + stack = curB->generateNewStack(CStackBasicDescriptor(CreatureID::ARROW_TOWERS, 1), false, SlotID(255), -3); stacks.push_back(stack); } @@ -842,7 +842,7 @@ BattleInfo::BattleInfo() setNodeType(BATTLE); } -CStack::CStack(const CStackInstance *Base, int O, int I, bool AO, int S) +CStack::CStack(const CStackInstance *Base, int O, int I, bool AO, SlotID S) : base(Base), ID(I), owner(O), slot(S), attackerOwned(AO), counterAttacks(1) { @@ -856,7 +856,7 @@ CStack::CStack() init(); setNodeType(STACK_BATTLE); } -CStack::CStack(const CStackBasicDescriptor *stack, int O, int I, bool AO, int S) +CStack::CStack(const CStackBasicDescriptor *stack, int O, int I, bool AO, SlotID S) : base(NULL), ID(I), owner(O), slot(S), attackerOwned(AO), counterAttacks(1) { type = stack->type; @@ -871,8 +871,8 @@ void CStack::init() ID = -1; count = baseAmount = -1; firstHPleft = -1; - owner = 255; - slot = 255; + owner = GameConstants::NEUTRAL_PLAYER; + slot = SlotID(255); attackerOwned = false; position = BattleHex(); counterAttacks = -1; @@ -1117,7 +1117,7 @@ std::string CStack::nodeName() const else oss << "[UNDEFINED TYPE]"; - oss << " from slot " << (int)slot; + oss << " from slot " << slot; if(base && base->armyObj) oss << " of armyobj=" << base->armyObj->id.getNum(); return oss.str(); diff --git a/lib/BattleState.h b/lib/BattleState.h index 850d9103c..20c61bc6c 100644 --- a/lib/BattleState.h +++ b/lib/BattleState.h @@ -106,8 +106,8 @@ struct DLL_LINKAGE BattleInfo : public CBonusSystemNode, public CBattleInfoCallb //std::set getAttackedCreatures(const CStack* attacker, BattleHex destinationTile, BattleHex attackerPos = BattleHex::INVALID); //calculates range of multi-hex attacks //std::set getAttackedHexes(const CStack* attacker, BattleHex destinationTile, BattleHex attackerPos = BattleHex::INVALID); //calculates range of multi-hex attacks static int calculateSpellDuration(const CSpell * spell, const CGHeroInstance * caster, int usedSpellPower); - CStack * generateNewStack(const CStackInstance &base, bool attackerOwned, int slot, BattleHex position) const; //helper for CGameHandler::setupBattle and spells addign new stacks to the battlefield - CStack * generateNewStack(const CStackBasicDescriptor &base, bool attackerOwned, int slot, BattleHex position) const; //helper for CGameHandler::setupBattle and spells addign new stacks to the battlefield + CStack * generateNewStack(const CStackInstance &base, bool attackerOwned, SlotID slot, BattleHex position) const; //helper for CGameHandler::setupBattle and spells addign new stacks to the battlefield + CStack * generateNewStack(const CStackBasicDescriptor &base, bool attackerOwned, SlotID slot, BattleHex position) const; //helper for CGameHandler::setupBattle and spells addign new stacks to the battlefield int getIdForNewStack() const; //suggest a currently unused ID that'd suitable for generating a new stack //std::pair getNearestStack(const CStack * closest, boost::logic::tribool attackerOwned) const; //if attackerOwned is indetermnate, returened stack is of any owner; hex is the number of hex we should be looking from; returns (nerarest creature, predecessorHex) ui32 calculateHealedHP(const CGHeroInstance * caster, const CSpell * spell, const CStack * stack, const CStack * sacrificedStack = NULL) const; //Sacrifice @@ -144,7 +144,7 @@ public: ui32 baseAmount; ui32 firstHPleft; //HP of first creature in stack TPlayerColor owner; //owner - player colour (255 for neutrals) - ui8 slot; //slot - position in garrison (may be 255 for neutrals/called creatures) + SlotID slot; //slot - position in garrison (may be 255 for neutrals/called creatures) bool attackerOwned; //if true, this stack is owned by attakcer (this one from left hand side of battle) BattleHex position; //position on battlefield; -2 - keep, -3 - lower tower, -4 - upper tower ui8 counterAttacks; //how many counter attacks can be performed more in this turn (by default set at the beginning of the round to 1) @@ -155,8 +155,8 @@ public: //overrides const CCreature* getCreature() const {return type;} - CStack(const CStackInstance *base, int O, int I, bool AO, int S); //c-tor - CStack(const CStackBasicDescriptor *stack, int O, int I, bool AO, int S = 255); //c-tor + CStack(const CStackInstance *base, int O, int I, bool AO, SlotID S); //c-tor + CStack(const CStackBasicDescriptor *stack, int O, int I, bool AO, SlotID S = SlotID(255)); //c-tor CStack(); //c-tor ~CStack(); std::string nodeName() const OVERRIDE; @@ -205,7 +205,7 @@ public: & shots & casts & count; const CArmedInstance *army = (base ? base->armyObj : NULL); - TSlot slot = (base ? base->armyObj->findStack(base) : -1); + SlotID slot = (base ? base->armyObj->findStack(base) : SlotID()); if(h.saving) { @@ -214,13 +214,13 @@ public: else { h & army & slot; - if (slot == -2) //TODO + if (slot == SlotID::COMMANDER_SLOT_PLACEHOLDER) //TODO { auto hero = dynamic_cast(army); assert (hero); base = hero->commander; } - else if(!army || slot == -1 || !army->hasStackAtSlot(slot)) + else if(!army || slot == SlotID() || !army->hasStackAtSlot(slot)) { base = NULL; tlog3 << type->nameSing << " doesn't have a base stack!\n"; diff --git a/lib/CCreatureHandler.cpp b/lib/CCreatureHandler.cpp index 34f251a1f..73948d4f3 100644 --- a/lib/CCreatureHandler.cpp +++ b/lib/CCreatureHandler.cpp @@ -114,7 +114,7 @@ CCreature::CCreature() doubleWide = false; setNodeType(CBonusSystemNode::CREATURE); } -void CCreature::addBonus(int val, int type, int subtype /*= -1*/) +void CCreature::addBonus(int val, Bonus::BonusType type, int subtype /*= -1*/) { Bonus *added = new Bonus(Bonus::PERMANENT, type, Bonus::CREATURE_ABILITY, val, idNumber, subtype, Bonus::BASE_NUMBER); addNewBonus(added); @@ -149,7 +149,7 @@ static void AddAbility(CCreature *cre, const JsonVector &ability_vec) Bonus *nsf = new Bonus(); std::string type = ability_vec[0].String(); - std::map::const_iterator it = bonusNameMap.find(type); + std::map::const_iterator it = bonusNameMap.find(type); if (it == bonusNameMap.end()) { if (type == "DOUBLE_WIDE") @@ -185,7 +185,7 @@ static void RemoveAbility(CCreature *cre, const JsonNode &ability) { std::string type = ability.String(); - std::map::const_iterator it = bonusNameMap.find(type); + std::map::const_iterator it = bonusNameMap.find(type); if (it == bonusNameMap.end()) { if (type == "DOUBLE_WIDE") @@ -348,7 +348,7 @@ void CCreatureHandler::loadCreatures() BOOST_FOREACH(const JsonNode &bonus, config2["bonuses"].Vector()) { - std::map::const_iterator it_map; + std::map::const_iterator it_map; std::string bonusID = bonus["id"].String(); it_map = bonusNameMap.find(bonusID); @@ -359,7 +359,7 @@ void CCreatureHandler::loadCreatures() } //handle magic resistance secondary skill premy, potentialy may be buggy - //std::map >::iterator it = stackBonuses.find(Bonus::MAGIC_RESISTANCE); + //std::map >::iterator it = stackBonuses.find(Bonus::MAGIC_RESISTANCE); //stackBonuses[Bonus::SECONDARY_SKILL_PREMY] = std::pair(it->second.first, it->second.second); if (VLC->modh->modules.STACK_EXP) //reading default stack experience bonuses diff --git a/lib/CCreatureHandler.h b/lib/CCreatureHandler.h index 2fa9bb83d..686f9257b 100644 --- a/lib/CCreatureHandler.h +++ b/lib/CCreatureHandler.h @@ -41,7 +41,7 @@ public: TFaction faction; //-1 = neutral ui8 level; // 0 - unknown bool doubleWide; - ui8 special; // Creature is not available normally (war machines, commanders, etc + bool special; // Creature is not available normally (war machines, commanders, etc ///animation info double timeBetweenFidgets, walkAnimationTime, attackAnimationTime, flightAnimationDistance; @@ -49,7 +49,7 @@ public: double missleFrameAngles[12]; int troopCountLocationOffset, attackClimaxFrame; std::string projectile; - ui8 projectileSpin; //if true, appropriate projectile is spinning during flight + bool projectileSpin; //if true, appropriate projectile is spinning during flight ///end of anim info //sound info @@ -86,7 +86,7 @@ public: bool valid() const; - void addBonus(int val, int type, int subtype = -1); + void addBonus(int val, Bonus::BonusType type, int subtype = -1); std::string nodeName() const override; //void getParents(TCNodes &out, const CBonusSystemNode *root /*= NULL*/) const; @@ -131,12 +131,12 @@ private: void loadCreatureJson(CCreature * creature, const JsonNode & config); public: - std::set notUsedMonsters; + std::set notUsedMonsters; std::set doubledCreatures; //they get double week std::vector > creatures; //creature ID -> creature info //stack exp - std::map > stackBonuses; // bonus => name, description + std::map > stackBonuses; // bonus => name, description std::vector > expRanks; // stack experience needed for certain rank, index 0 for other tiers (?) std::vector maxExpPerBattle; //%, tiers same as above si8 expAfterUpgrade;//multiplier in % diff --git a/lib/CCreatureSet.cpp b/lib/CCreatureSet.cpp index 137a3fc1e..a651037d1 100644 --- a/lib/CCreatureSet.cpp +++ b/lib/CCreatureSet.cpp @@ -21,7 +21,7 @@ * */ -const CStackInstance &CCreatureSet::operator[](TSlot slot) const +const CStackInstance &CCreatureSet::operator[](SlotID slot) const { TSlots::const_iterator i = stacks.find(slot); if (i != stacks.end()) @@ -30,7 +30,7 @@ const CStackInstance &CCreatureSet::operator[](TSlot slot) const throw std::runtime_error("That slot is empty!"); } -const CCreature* CCreatureSet::getCreature(TSlot slot) const +const CCreature* CCreatureSet::getCreature(SlotID slot) const { TSlots::const_iterator i = stacks.find(slot); if (i != stacks.end()) @@ -39,9 +39,9 @@ const CCreature* CCreatureSet::getCreature(TSlot slot) const return NULL; } -bool CCreatureSet::setCreature(TSlot slot, CreatureID type, TQuantity quantity) /*slots 0 to 6 */ +bool CCreatureSet::setCreature(SlotID slot, CreatureID type, TQuantity quantity) /*slots 0 to 6 */ { - if(slot > 6 || slot < 0) + if(!slot.validSlot()) { tlog1 << "Cannot set slot " << slot << std::endl; return false; @@ -60,12 +60,12 @@ bool CCreatureSet::setCreature(TSlot slot, CreatureID type, TQuantity quantity) return true; } -TSlot CCreatureSet::getSlotFor(CreatureID creature, ui32 slotsAmount/*=7*/) const /*returns -1 if no slot available */ +SlotID CCreatureSet::getSlotFor(CreatureID creature, ui32 slotsAmount/*=7*/) const /*returns -1 if no slot available */ { return getSlotFor(VLC->creh->creatures[creature], slotsAmount); } -TSlot CCreatureSet::getSlotFor(const CCreature *c, ui32 slotsAmount/*=ARMY_SIZE*/) const +SlotID CCreatureSet::getSlotFor(const CCreature *c, ui32 slotsAmount/*=ARMY_SIZE*/) const { assert(c->valid()); for(TSlots::const_iterator i=stacks.begin(); i!=stacks.end(); ++i) @@ -76,29 +76,22 @@ TSlot CCreatureSet::getSlotFor(const CCreature *c, ui32 slotsAmount/*=ARMY_SIZE* return i->first; //if there is already such creature we return its slot id } } + return getFreeSlot(slotsAmount); +} + +SlotID CCreatureSet::getFreeSlot(ui32 slotsAmount/*=ARMY_SIZE*/) const +{ for(ui32 i=0; i &out, TSlot preferable /*= -1*/) const /*looks for two same stacks, returns slot positions */ +bool CCreatureSet::mergableStacks(std::pair &out, SlotID preferable /*= -1*/) const /*looks for two same stacks, returns slot positions */ { //try to match creature to our preferred stack - if(preferable >= 0 && vstd::contains(stacks, preferable)) + if(preferable.validSlot() && vstd::contains(stacks, preferable)) { const CCreature *cr = stacks.find(preferable)->second->type; for(TSlots::const_iterator j=stacks.begin(); j!=stacks.end(); ++j) @@ -162,7 +155,7 @@ void CCreatureSet::sweep() } } -void CCreatureSet::addToSlot(TSlot slot, CreatureID cre, TQuantity count, bool allowMerging/* = true*/) +void CCreatureSet::addToSlot(SlotID slot, CreatureID cre, TQuantity count, bool allowMerging/* = true*/) { const CCreature *c = VLC->creh->creatures[cre]; @@ -180,7 +173,7 @@ void CCreatureSet::addToSlot(TSlot slot, CreatureID cre, TQuantity count, bool a } } -void CCreatureSet::addToSlot(TSlot slot, CStackInstance *stack, bool allowMerging/* = true*/) +void CCreatureSet::addToSlot(SlotID slot, CStackInstance *stack, bool allowMerging/* = true*/) { assert(stack->valid(true)); @@ -208,7 +201,7 @@ bool CCreatureSet::validTypes(bool allowUnrandomized /*= false*/) const return true; } -bool CCreatureSet::slotEmpty(TSlot slot) const +bool CCreatureSet::slotEmpty(SlotID slot) const { return !hasStackAtSlot(slot); } @@ -226,11 +219,11 @@ ui64 CCreatureSet::getArmyStrength() const return ret; } -ui64 CCreatureSet::getPower (TSlot slot) const +ui64 CCreatureSet::getPower (SlotID slot) const { return getStack(slot).getPower(); } -std::string CCreatureSet::getRoughAmount (TSlot slot) const +std::string CCreatureSet::getRoughAmount (SlotID slot) const { int quantity = CCreature::getQuantityID(getStackCount(slot)); if (quantity) @@ -248,7 +241,7 @@ void CCreatureSet::setFormation(bool tight) formation = tight; } -void CCreatureSet::setStackCount(TSlot slot, TQuantity count) +void CCreatureSet::setStackCount(SlotID slot, TQuantity count) { assert(hasStackAtSlot(slot)); assert(stacks[slot]->count + count > 0); @@ -263,7 +256,7 @@ void CCreatureSet::giveStackExp(TExpType exp) for(TSlots::const_iterator i = stacks.begin(); i != stacks.end(); i++) i->second->giveStackExp(exp); } -void CCreatureSet::setStackExp(TSlot slot, TExpType exp) +void CCreatureSet::setStackExp(SlotID slot, TExpType exp) { assert(hasStackAtSlot(slot)); stacks[slot]->experience = exp; @@ -277,20 +270,20 @@ void CCreatureSet::clear() } } -const CStackInstance& CCreatureSet::getStack(TSlot slot) const +const CStackInstance& CCreatureSet::getStack(SlotID slot) const { assert(hasStackAtSlot(slot)); return *getStackPtr(slot); } -const CStackInstance* CCreatureSet::getStackPtr(TSlot slot) const +const CStackInstance* CCreatureSet::getStackPtr(SlotID slot) const { if(hasStackAtSlot(slot)) return stacks.find(slot)->second; else return NULL; } -void CCreatureSet::eraseStack(TSlot slot) +void CCreatureSet::eraseStack(SlotID slot) { assert(hasStackAtSlot(slot)); CStackInstance *toErase = detachStack(slot); @@ -309,20 +302,20 @@ bool CCreatureSet::contains(const CStackInstance *stack) const return false; } -TSlot CCreatureSet::findStack(const CStackInstance *stack) const +SlotID CCreatureSet::findStack(const CStackInstance *stack) const { auto h = dynamic_cast(this); if (h && h->commander == stack) - return -2; + return SlotID::COMMANDER_SLOT_PLACEHOLDER; if(!stack) - return -1; + return SlotID(); for(TSlots::const_iterator i = stacks.begin(); i != stacks.end(); ++i) if(i->second == stack) return i->first; - return -1; + return SlotID(); } CArmedInstance * CCreatureSet::castToArmyObj() @@ -330,16 +323,16 @@ CArmedInstance * CCreatureSet::castToArmyObj() return dynamic_cast(this); } -void CCreatureSet::putStack(TSlot slot, CStackInstance *stack) +void CCreatureSet::putStack(SlotID slot, CStackInstance *stack) { - assert(slot < GameConstants::ARMY_SIZE); + assert(slot.getNum() < GameConstants::ARMY_SIZE); assert(!hasStackAtSlot(slot)); stacks[slot] = stack; stack->setArmyObj(castToArmyObj()); armyChanged(); } -void CCreatureSet::joinStack(TSlot slot, CStackInstance * stack) +void CCreatureSet::joinStack(SlotID slot, CStackInstance * stack) { const CCreature *c = getCreature(slot); assert(c == stack->type); @@ -350,7 +343,7 @@ void CCreatureSet::joinStack(TSlot slot, CStackInstance * stack) vstd::clear_pointer(stack); } -void CCreatureSet::changeStackCount(TSlot slot, TQuantity toAdd) +void CCreatureSet::changeStackCount(SlotID slot, TQuantity toAdd) { setStackCount(slot, getStackCount(slot) + toAdd); } @@ -385,7 +378,7 @@ void CCreatureSet::setToArmy(CSimpleArmy &src) } } -CStackInstance * CCreatureSet::detachStack(TSlot slot) +CStackInstance * CCreatureSet::detachStack(SlotID slot) { assert(hasStackAtSlot(slot)); CStackInstance *ret = stacks[slot]; @@ -401,7 +394,7 @@ CStackInstance * CCreatureSet::detachStack(TSlot slot) return ret; } -void CCreatureSet::setStackType(TSlot slot, const CCreature *type) +void CCreatureSet::setStackType(SlotID slot, const CCreature *type) { assert(hasStackAtSlot(slot)); CStackInstance *s = stacks[slot]; @@ -417,8 +410,8 @@ bool CCreatureSet::canBeMergedWith(const CCreatureSet &cs, bool allowMergingStac std::set cresToAdd; for(TSlots::const_iterator i = cs.stacks.begin(); i != cs.stacks.end(); i++) { - TSlot dest = getSlotFor(i->second->type); - if(dest < 0 || hasStackAtSlot(dest)) + SlotID dest = getSlotFor(i->second->type); + if(!dest.validSlot() || hasStackAtSlot(dest)) cresToAdd.insert(i->second->type); } return cresToAdd.size() <= freeSlots; @@ -430,10 +423,10 @@ bool CCreatureSet::canBeMergedWith(const CCreatureSet &cs, bool allowMergingStac //get types of creatures that need their own slot for(TSlots::const_iterator i = cs.stacks.begin(); i != cs.stacks.end(); i++) cres.addToSlot(i->first, i->second->type->idNumber, 1, true); - TSlot j; + SlotID j; for(TSlots::const_iterator i = stacks.begin(); i != stacks.end(); i++) { - if ((j = cres.getSlotFor(i->second->type)) >= 0) + if ((j = cres.getSlotFor(i->second->type)).validSlot()) cres.addToSlot(j, i->second->type->idNumber, 1, true); //merge if possible else return false; //no place found @@ -442,7 +435,7 @@ bool CCreatureSet::canBeMergedWith(const CCreatureSet &cs, bool allowMergingStac } } -bool CCreatureSet::hasStackAtSlot(TSlot slot) const +bool CCreatureSet::hasStackAtSlot(SlotID slot) const { return vstd::contains(stacks, slot); } @@ -568,7 +561,7 @@ void CStackInstance::setType(const CCreature *c) } std::string CStackInstance::bonusToString(Bonus *bonus, bool description) const { - std::map >::iterator it = VLC->creh->stackBonuses.find(bonus->type); + std::map >::iterator it = VLC->creh->stackBonuses.find(bonus->type); if (it != VLC->creh->stackBonuses.end()) { std::string text; @@ -1089,7 +1082,7 @@ CSimpleArmy::operator bool() const return army.size(); } -bool CSimpleArmy::setCreature(TSlot slot, CreatureID cre, TQuantity count) +bool CSimpleArmy::setCreature(SlotID slot, CreatureID cre, TQuantity count) { assert(!vstd::contains(army, slot)); army[slot] = CStackBasicDescriptor(cre, count); diff --git a/lib/CCreatureSet.h b/lib/CCreatureSet.h index 534794770..d097bf717 100644 --- a/lib/CCreatureSet.h +++ b/lib/CCreatureSet.h @@ -116,14 +116,14 @@ public: DLL_LINKAGE std::ostream & operator<<(std::ostream & str, const CStackInstance & sth); -typedef std::map TSlots; -typedef std::map TSimpleSlots; +typedef std::map TSlots; +typedef std::map TSimpleSlots; class IArmyDescriptor { public: virtual void clear() = 0; - virtual bool setCreature(TSlot slot, CreatureID cre, TQuantity count) = 0; + virtual bool setCreature(SlotID slot, CreatureID cre, TQuantity count) = 0; }; //simplified version of CCreatureSet @@ -132,7 +132,7 @@ class DLL_LINKAGE CSimpleArmy : public IArmyDescriptor public: TSimpleSlots army; void clear() OVERRIDE; - bool setCreature(TSlot slot, CreatureID cre, TQuantity count) OVERRIDE; + bool setCreature(SlotID slot, CreatureID cre, TQuantity count) OVERRIDE; operator bool() const; template void serialize(Handler &h, const int version) @@ -153,49 +153,49 @@ public: virtual ~CCreatureSet(); virtual void armyChanged(); - const CStackInstance &operator[](TSlot slot) const; + const CStackInstance &operator[](SlotID slot) const; const TSlots &Slots() const {return stacks;} - void addToSlot(TSlot slot, CreatureID cre, TQuantity count, bool allowMerging = true); //Adds stack to slot. Slot must be empty or with same type creature - void addToSlot(TSlot slot, CStackInstance *stack, bool allowMerging = true); //Adds stack to slot. Slot must be empty or with same type creature + void addToSlot(SlotID slot, CreatureID cre, TQuantity count, bool allowMerging = true); //Adds stack to slot. Slot must be empty or with same type creature + void addToSlot(SlotID slot, CStackInstance *stack, bool allowMerging = true); //Adds stack to slot. Slot must be empty or with same type creature void clear() OVERRIDE; void setFormation(bool tight); CArmedInstance *castToArmyObj(); //basic operations - void putStack(TSlot slot, CStackInstance *stack); //adds new stack to the army, slot must be empty - void setStackCount(TSlot slot, TQuantity count); //stack must exist! - 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 putStack(SlotID slot, CStackInstance *stack); //adds new stack to the army, slot must be empty + void setStackCount(SlotID slot, TQuantity count); //stack must exist! + CStackInstance *detachStack(SlotID slot); //removes stack from army but doesn't destroy it (so it can be moved somewhere else or safely deleted) + void setStackType(SlotID slot, const CCreature *type); void giveStackExp(TExpType exp); - void setStackExp(TSlot slot, TExpType exp); + void setStackExp(SlotID slot, TExpType exp); //derivative - void eraseStack(TSlot slot); //slot must be occupied - void joinStack(TSlot slot, CStackInstance * stack); //adds new stack to the existing stack of the same type - void changeStackCount(TSlot slot, TQuantity toAdd); //stack must exist! - bool setCreature (TSlot slot, CreatureID type, TQuantity quantity) OVERRIDE; //replaces creature in stack; slots 0 to 6, if quantity=0 erases stack + void eraseStack(SlotID slot); //slot must be occupied + void joinStack(SlotID slot, CStackInstance * stack); //adds new stack to the existing stack of the same type + void changeStackCount(SlotID slot, TQuantity toAdd); //stack must exist! + bool setCreature (SlotID slot, CreatureID type, TQuantity quantity) OVERRIDE; //replaces creature in stack; slots 0 to 6, if quantity=0 erases stack void setToArmy(CSimpleArmy &src); //erases all our army and moves stacks from src to us; src MUST NOT be an armed object! WARNING: use it wisely. Or better do not use at all. - const CStackInstance& getStack(TSlot slot) const; //stack must exist - const CStackInstance* getStackPtr(TSlot slot) const; //if stack doesn't exist, returns NULL - const CCreature* getCreature(TSlot slot) const; //workaround of map issue; - int getStackCount (TSlot slot) const; - TExpType getStackExperience(TSlot slot) const; - TSlot findStack(const CStackInstance *stack) const; //-1 if none - TSlot getSlotFor(CreatureID creature, ui32 slotsAmount = GameConstants::ARMY_SIZE) const; //returns -1 if no slot available - TSlot getSlotFor(const CCreature *c, ui32 slotsAmount = GameConstants::ARMY_SIZE) const; //returns -1 if no slot available - TSlot getFreeSlot(ui32 slotsAmount = GameConstants::ARMY_SIZE) const; - bool mergableStacks(std::pair &out, TSlot preferable = -1) const; //looks for two same stacks, returns slot positions; + const CStackInstance& getStack(SlotID slot) const; //stack must exist + const CStackInstance* getStackPtr(SlotID slot) const; //if stack doesn't exist, returns NULL + const CCreature* getCreature(SlotID slot) const; //workaround of map issue; + int getStackCount (SlotID slot) const; + TExpType getStackExperience(SlotID slot) const; + SlotID findStack(const CStackInstance *stack) const; //-1 if none + SlotID getSlotFor(CreatureID creature, ui32 slotsAmount = GameConstants::ARMY_SIZE) const; //returns -1 if no slot available + SlotID getSlotFor(const CCreature *c, ui32 slotsAmount = GameConstants::ARMY_SIZE) const; //returns -1 if no slot available + SlotID getFreeSlot(ui32 slotsAmount = GameConstants::ARMY_SIZE) const; + bool mergableStacks(std::pair &out, SlotID preferable = SlotID()) 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; + bool slotEmpty(SlotID slot) const; int stacksCount() const; virtual bool needsLastStack() const; //true if last stack cannot be taken ui64 getArmyStrength() const; //sum of AI values of creatures - ui64 getPower (TSlot slot) const; //value of specific stack - std::string getRoughAmount (TSlot slot) const; //rough size of specific stack - bool hasStackAtSlot(TSlot slot) const; + ui64 getPower (SlotID slot) const; //value of specific stack + std::string getRoughAmount (SlotID slot) const; //rough size of specific stack + bool hasStackAtSlot(SlotID slot) const; bool contains(const CStackInstance *stack) const; bool canBeMergedWith(const CCreatureSet &cs, bool allowMergingStacks = true) const; diff --git a/lib/CGameState.cpp b/lib/CGameState.cpp index 7c7e92d7e..36b23efbb 100644 --- a/lib/CGameState.cpp +++ b/lib/CGameState.cpp @@ -806,9 +806,9 @@ void CGameState::init(StartInfo * si) { for(int i=0; islotEmpty(i)) + if(hero->slotEmpty(SlotID(i))) { - hero->addToSlot(i, CreatureID(curBonus->info2), curBonus->info3); + hero->addToSlot(SlotID(i), CreatureID(curBonus->info2), curBonus->info3); break; } } @@ -1714,8 +1714,8 @@ void CGameState::initDuel() { CreatureID cre = dp.sides[i].stacks[j].type; TQuantity count = dp.sides[i].stacks[j].count; - if(count || obj->hasStackAtSlot(j)) - obj->setCreature(j, cre, count); + if(count || obj->hasStackAtSlot(SlotID(j))) + obj->setCreature(SlotID(j), cre, count); } BOOST_FOREACH(const DuelParameters::CusomCreature &cc, dp.creatures) diff --git a/lib/CGameState.h b/lib/CGameState.h index 1823a6098..d786890e4 100644 --- a/lib/CGameState.h +++ b/lib/CGameState.h @@ -69,7 +69,7 @@ namespace boost } //numbers of creatures are exact numbers if detailed else they are quantity ids (0 - a few, 1 - several and so on; additionally -1 - unknown) -struct ArmyDescriptor : public std::map +struct ArmyDescriptor : public std::map { bool isDetailed; DLL_LINKAGE ArmyDescriptor(const CArmedInstance *army, bool detailed); //not detailed -> quantity ids as count diff --git a/lib/CObjectHandler.cpp b/lib/CObjectHandler.cpp index d35e43cf3..7ebe369b8 100644 --- a/lib/CObjectHandler.cpp +++ b/lib/CObjectHandler.cpp @@ -39,14 +39,14 @@ using namespace boost::assign; #define USE_COVERAGE_MAP 0 -std::map > > CGTeleport::objs; +std::map > > CGTeleport::objs; std::vector > CGTeleport::gates; IGameCallback * IObjectInterface::cb = NULL; extern boost::rand48 ran; std::map > CGKeys::playerKeyMap; std::map > CGMagi::eyelist; ui8 CGObelisk::obeliskCount; //how many obelisks are on map -std::map CGObelisk::visited; //map: team_id => how many obelisks has been visited +std::map CGObelisk::visited; //map: team_id => how many obelisks has been visited std::vector CGTownInstance::merchantArtifacts; std::vector CGTownInstance::universitySkills; @@ -850,7 +850,7 @@ void CGHeroInstance::initArmy(IArmyDescriptor *dst /*= NULL*/) tlog3 << "Hero " << name << " already has artifact at " << slot << ", omitting giving " << aid << std::endl; } else - dst->setCreature(stackNo-warMachinesGiven, stack.creature, count); + dst->setCreature(SlotID(stackNo-warMachinesGiven), stack.creature, count); } } void CGHeroInstance::initHeroDefInfo() @@ -1283,7 +1283,7 @@ void CGHeroInstance::updateSkill(SecondarySkill which, int val) void CGHeroInstance::setPropertyDer( ui8 what, ui32 val ) { if(what == ObjProperty::PRIMARY_STACK_COUNT) - setStackCount(0, val); + setStackCount(SlotID(0), val); } double CGHeroInstance::getHeroStrength() const @@ -1391,8 +1391,8 @@ CStackBasicDescriptor CGHeroInstance::calculateNecromancy (const BattleResult &b } // Make room for new units. - int slot = getSlotFor(raisedUnitType->idNumber); - if (slot == -1) + SlotID slot = getSlotFor(raisedUnitType->idNumber); + if (slot == SlotID()) { // If there's no room for unit, try it's upgraded version 2/3rds the size. raisedUnitType = VLC->creh->creatures[*raisedUnitType->upgrades.begin()]; @@ -1602,7 +1602,7 @@ void CGDwelling::initObj() else hoverName = VLC->generaltexth->creGens[subID]; if(crs->level > 4) - putStack(0, new CStackInstance(crs, (crs->growth) * 3)); + putStack(SlotID(0), new CStackInstance(crs, (crs->growth) * 3)); if (getOwner() != GameConstants::NEUTRAL_PLAYER) cb->gameState()->players[getOwner()].dwellings.push_back (this); } @@ -1617,8 +1617,8 @@ void CGDwelling::initObj() creatures[2].second.push_back(CreatureID::GOLD_GOLEM); creatures[3].second.push_back(CreatureID::DIAMOND_GOLEM); //guards - putStack(0, new CStackInstance(CreatureID::GOLD_GOLEM, 9)); - putStack(1, new CStackInstance(CreatureID::DIAMOND_GOLEM, 6)); + putStack(SlotID(0), new CStackInstance(CreatureID::GOLD_GOLEM, 9)); + putStack(SlotID(1), new CStackInstance(CreatureID::DIAMOND_GOLEM, 6)); } else if(subID == 0) // Elemental Conflux { @@ -1627,7 +1627,7 @@ void CGDwelling::initObj() creatures[2].second.push_back(CreatureID::EARTH_ELEMENTAL); creatures[3].second.push_back(CreatureID::WATER_ELEMENTAL); //guards - putStack(0, new CStackInstance(CreatureID::EARTH_ELEMENTAL, 12)); + putStack(SlotID(0), new CStackInstance(CreatureID::EARTH_ELEMENTAL, 12)); } else { @@ -1785,8 +1785,8 @@ void CGDwelling::heroAcceptsCreatures( const CGHeroInstance *h, ui32 answer ) co { if(count) //there are available creatures { - int slot = h->getSlotFor(crid); - if(slot < 0) //no available slot + SlotID slot = h->getSlotFor(crid); + if(!slot.validSlot()) //no available slot { InfoWindow iw; iw.player = h->tempOwner; @@ -2173,7 +2173,7 @@ void CGTownInstance::newTurn() const if (tempOwner == GameConstants::NEUTRAL_PLAYER) //garrison growth for neutral towns { - std::vector nativeCrits; //slots + std::vector nativeCrits; //slots for (TSlots::const_iterator it = Slots().begin(); it != Slots().end(); it++) { if (it->second->type->faction == subID) //native @@ -2183,7 +2183,7 @@ void CGTownInstance::newTurn() const } if (nativeCrits.size()) { - TSlot pos = nativeCrits[rand() % nativeCrits.size()]; + SlotID pos = nativeCrits[rand() % nativeCrits.size()]; StackLocation sl(this, pos); const CCreature *c = getCreature(pos); @@ -2200,7 +2200,7 @@ void CGTownInstance::newTurn() const { int i = rand() % std::min (GameConstants::ARMY_SIZE, cb->getDate(Date::MONTH)<<1); CreatureID c = town->creatures[i][0]; - TSlot n = -1; + SlotID n; TQuantity count = creatureGrowth(i); if (!count) // no dwelling @@ -2208,7 +2208,7 @@ void CGTownInstance::newTurn() const {//no lower tiers or above current month - if ((n = getSlotFor(c))>=0) + if ((n = getSlotFor(c)).validSlot()) { StackLocation sl(this, n); if (slotEmpty(n)) @@ -2426,12 +2426,12 @@ void CGTownInstance::recreateBuildingsBonuses() } } -bool CGTownInstance::addBonusIfBuilt(BuildingID building, int type, int val, int subtype /*= -1*/) +bool CGTownInstance::addBonusIfBuilt(BuildingID building, Bonus::BonusType type, int val, int subtype /*= -1*/) { return addBonusIfBuilt(building, type, val, TPropagatorPtr(), subtype); } -bool CGTownInstance::addBonusIfBuilt(BuildingID building, int type, int val, TPropagatorPtr prop, int subtype /*= -1*/) +bool CGTownInstance::addBonusIfBuilt(BuildingID building, Bonus::BonusType type, int val, TPropagatorPtr prop, int subtype /*= -1*/) { if(hasBuilt(building)) { @@ -3045,7 +3045,7 @@ void CGCreature::onHeroVisit( const CGHeroInstance * h ) const BlockingDialog ynd(true,false); ynd.player = h->tempOwner; std::string tmp = VLC->generaltexth->advobtxt[90]; - boost::algorithm::replace_first(tmp,"%d",boost::lexical_cast(getStackCount(0))); + boost::algorithm::replace_first(tmp,"%d",boost::lexical_cast(getStackCount(SlotID(0)))); boost::algorithm::replace_first(tmp,"%d",boost::lexical_cast(action)); boost::algorithm::replace_first(tmp,"%s",VLC->creh->creatures[subID]->namePl); ynd.text << tmp; @@ -3091,15 +3091,15 @@ void CGCreature::endBattle( BattleResult *result ) const } //first stack has to be at slot 0 -> if original one got killed, move there first remaining stack - if(!hasStackAtSlot(0)) - cb->moveStack(StackLocation(this, stacks.begin()->first), StackLocation(this, 0), stacks.begin()->second->count); + if(!hasStackAtSlot(SlotID(0))) + cb->moveStack(StackLocation(this, stacks.begin()->first), StackLocation(this, SlotID(0)), stacks.begin()->second->count); while (stacks.size() > 1) //hopefully that's enough { // TODO it's either overcomplicated (if we assume there'll be only one stack) or buggy (if we allow multiple stacks... but that'll also cause troubles elsewhere) i = stacks.end(); i--; - TSlot slot = getSlotFor(i->second->type); + SlotID slot = getSlotFor(i->second->type); if (slot == i->first) //no reason to move stack to its own slot break; else @@ -3132,8 +3132,8 @@ void CGCreature::initObj() break; } - stacks[0]->setType(CreatureID(subID)); - TQuantity &amount = stacks[0]->count; + stacks[SlotID(0)]->setType(CreatureID(subID)); + TQuantity &amount = stacks[SlotID(0)]->count; CCreature &c = *VLC->creh->creatures[subID]; if(!amount) { @@ -3143,7 +3143,7 @@ void CGCreature::initObj() amount = c.ammMin + (ran() % (c.ammMax - c.ammMin)); } - temppower = stacks[0]->count * 1000; + temppower = stacks[SlotID(0)]->count * 1000; } void CGCreature::newTurn() const {//Works only for stacks of single type of size up to 2 millions @@ -3161,7 +3161,7 @@ void CGCreature::setPropertyDer(ui8 what, ui32 val) switch (what) { case ObjProperty::MONSTER_COUNT: - stacks[0]->count = val; + stacks[SlotID(0)]->count = val; break; case ObjProperty::MONSTER_POWER: temppower = val; @@ -3233,7 +3233,7 @@ int CGCreature::takenAction(const CGHeroInstance *h, bool allowJoin) const return 0; //join for free else if(h->getSecSkillLevel(SecondarySkill::DIPLOMACY) * 2 + sympathy + 1 >= character) - return VLC->creh->creatures[subID]->cost[6] * getStackCount(0); //join for gold + return VLC->creh->creatures[subID]->cost[6] * getStackCount(SlotID(0)); //join for gold } //we are still here - creatures have not joined hero, flee or fight @@ -3327,14 +3327,14 @@ void CGCreature::fight( const CGHeroInstance *h ) const stacksCount = 3; } int stackSize; - TSlot sourceSlot = stacks.begin()->first; - TSlot destSlot; + SlotID sourceSlot = stacks.begin()->first; + SlotID destSlot; for (int stacksLeft = stacksCount; stacksLeft > 1; --stacksLeft) { stackSize = stacks.begin()->second->count / stacksLeft; if (stackSize) { - if ((destSlot = getFreeSlot()) > -1) + if ((destSlot = getFreeSlot()).validSlot()) cb->moveStack(StackLocation(this, sourceSlot), StackLocation(this, destSlot), stackSize); else { @@ -3348,7 +3348,7 @@ void CGCreature::fight( const CGHeroInstance *h ) const { if (rand()%100 < 50) //upgrade { - TSlot slotId = (stacks.size() / 2); + SlotID slotId = SlotID(stacks.size() / 2); if(ui32 upgradesSize = getStack(slotId).type->upgrades.size()) { auto it = getStack(slotId).type->upgrades.cbegin(); //pick random in case there are more @@ -3414,7 +3414,7 @@ void CGMine::initObj() //set guardians int howManyTroglodytes = 100 + ran()%100; CStackInstance *troglodytes = new CStackInstance(CreatureID::TROGLODYTES, howManyTroglodytes); - putStack(0, troglodytes); + putStack(SlotID(0), troglodytes); //after map reading tempOwner placeholds bitmask for allowed resources std::vector possibleResources; @@ -3689,7 +3689,7 @@ void CGTeleport::onHeroVisit( const CGHeroInstance * h ) const { if (h->Slots().size() > 1 || h->Slots().begin()->second->count > 1) { //we can't remove last unit - TSlot targetstack = h->Slots().begin()->first; //slot numbers may vary + SlotID targetstack = h->Slots().begin()->first; //slot numbers may vary for(TSlots::const_reverse_iterator i = h->Slots().rbegin(); i != h->Slots().rend(); i++) { if (h->getPower(targetstack) > h->getPower(i->first)) @@ -3800,7 +3800,7 @@ void CGTeleport::postInit() //matches subterranean gates into pairs gates.push_back(std::make_pair(cur->id, ObjectInstanceID())); } } - objs.erase(103); + objs.erase(Obj::SUBTERRANEAN_GATE); } ObjectInstanceID CGTeleport::getMatchingGate(ObjectInstanceID id) @@ -4457,7 +4457,7 @@ void CGSeerHut::setObjToKill() { if (quest->missionType == CQuest::MISSION_KILL_CREATURE) { - quest->stackToKill = getCreatureToKill(false)->getStack(0); //FIXME: stacks tend to dissapear (desync?) on server :? + quest->stackToKill = getCreatureToKill(false)->getStack(SlotID(0)); //FIXME: stacks tend to dissapear (desync?) on server :? assert(quest->stackToKill.type); quest->stackToKill.count = 0; //no count in info window quest->stackDirection = checkDirection(); @@ -4757,7 +4757,7 @@ void CGSeerHut::completeQuest (const CGHeroInstance * h) const //reward case CREATURE: { CCreatureSet creatures; - creatures.setCreature(0, CreatureID(rID), rVal); + creatures.setCreature(SlotID(0), CreatureID(rID), rVal); cb->giveCreatures(this, h, creatures, false); } break; @@ -5939,8 +5939,8 @@ void CBank::setPropertyDer (ui8 what, ui32 val) { case 1: for (int i = 0; i < 4; ++i) - setCreature (i, bc->guards[0].first, bc->guards[0].second / 5 ); - setCreature (4, CreatureID(bc->guards[0].first + upgraded), bc->guards[0].second / 5 ); + setCreature (SlotID(i), bc->guards[0].first, bc->guards[0].second / 5 ); + setCreature (SlotID(4), CreatureID(bc->guards[0].first + upgraded), bc->guards[0].second / 5 ); break; case 4: { @@ -5948,24 +5948,24 @@ void CBank::setPropertyDer (ui8 what, ui32 val) { for (auto it = bc->guards.begin(); it != bc->guards.end(); it++) { - setCreature (stacksCount(), it->first, it->second); + setCreature (SlotID(stacksCount()), it->first, it->second); } } else if (bc->guards[2].second)//Wraiths are present, split two stacks in Crypt { - setCreature (0, bc->guards[0].first, bc->guards[0].second / 2 ); - setCreature (1, bc->guards[1].first, bc->guards[1].second / 2); - setCreature (2, CreatureID(bc->guards[2].first + upgraded), bc->guards[2].second); - setCreature (3, bc->guards[1].first, bc->guards[1].second / 2 ); - setCreature (4, bc->guards[0].first, bc->guards[0].second - (bc->guards[0].second / 2) ); + setCreature (SlotID(0), bc->guards[0].first, bc->guards[0].second / 2 ); + setCreature (SlotID(1), bc->guards[1].first, bc->guards[1].second / 2); + setCreature (SlotID(2), CreatureID(bc->guards[2].first + upgraded), bc->guards[2].second); + setCreature (SlotID(3), bc->guards[1].first, bc->guards[1].second / 2 ); + setCreature (SlotID(4), bc->guards[0].first, bc->guards[0].second - (bc->guards[0].second / 2) ); } else //split both stacks { for (int i = 0; i < 3; ++i) //skellies - setCreature (2*i, bc->guards[0].first, bc->guards[0].second / 3); + setCreature (SlotID(2*i), bc->guards[0].first, bc->guards[0].second / 3); for (int i = 0; i < 2; ++i) //zombies - setCreature (2*i+1, bc->guards[1].first, bc->guards[1].second / 2); + setCreature (SlotID(2*i+1), bc->guards[1].first, bc->guards[1].second / 2); } } break; @@ -6193,7 +6193,7 @@ void CBank::endBattle (const CGHeroInstance *h, const BattleResult *result) cons CCreatureSet ourArmy; for (auto it = bc->creatures.cbegin(); it != bc->creatures.cend(); it++) { - int slot = ourArmy.getSlotFor(it->first); + SlotID slot = ourArmy.getSlotFor(it->first); ourArmy.addToSlot(slot, it->first, it->second); } for (TSlots::const_iterator i = ourArmy.Slots().begin(); i != ourArmy.Slots().end(); i++) diff --git a/lib/CObjectHandler.h b/lib/CObjectHandler.h index f68ac4a04..0ecd8f25f 100644 --- a/lib/CObjectHandler.h +++ b/lib/CObjectHandler.h @@ -617,8 +617,8 @@ public: std::string nodeName() const override; void deserializationFix(); void recreateBuildingsBonuses(); - bool addBonusIfBuilt(BuildingID building, int type, int val, TPropagatorPtr prop, int subtype = -1); //returns true if building is built and bonus has been added - bool addBonusIfBuilt(BuildingID building, int type, int val, int subtype = -1); //convienence version of above + bool addBonusIfBuilt(BuildingID building, Bonus::BonusType type, int val, TPropagatorPtr prop, int subtype = -1); //returns true if building is built and bonus has been added + bool addBonusIfBuilt(BuildingID building, Bonus::BonusType type, int val, int subtype = -1); //convienence version of above void setVisitingHero(CGHeroInstance *h); void setGarrisonedHero(CGHeroInstance *h); const CArmedInstance *getUpperArmy() const; //garrisoned hero if present or the town itself @@ -1015,7 +1015,7 @@ protected: class DLL_LINKAGE CGTeleport : public CGObjectInstance //teleports and subterranean gates { public: - static std::map > > objs; //teleports: map[ID][subID] => vector of ids + static std::map > > objs; //teleports: map[ID][subID] => vector of ids static std::vector > gates; //subterranean gates: pairs of ids void onHeroVisit(const CGHeroInstance * h) const override; void initObj() override; @@ -1291,7 +1291,7 @@ class DLL_LINKAGE CGObelisk : public CPlayersVisited { public: static ui8 obeliskCount; //how many obelisks are on map - static std::map visited; //map: team_id => how many obelisks has been visited + static std::map visited; //map: team_id => how many obelisks has been visited void onHeroVisit(const CGHeroInstance * h) const override; void initObj() override; diff --git a/lib/Connection.h b/lib/Connection.h index 798bbaada..08b81bdcd 100644 --- a/lib/Connection.h +++ b/lib/Connection.h @@ -35,7 +35,6 @@ #include "Mapping/CCampaignHandler.h" //for CCampaignState const ui32 version = 737; -const TSlot COMMANDER_SLOT_PLACEHOLDER = -2; class CConnection; class CGObjectInstance; @@ -485,14 +484,14 @@ struct SaveIfStackInstance static bool invoke(Ser &s, const CStackInstance* const &data) { assert(data->armyObj); - TSlot slot = -1; + SlotID slot; if(data->getNodeType() == CBonusSystemNode::COMMANDER) - slot = COMMANDER_SLOT_PLACEHOLDER; + slot = SlotID::COMMANDER_SLOT_PLACEHOLDER; else slot = data->armyObj->findStack(data); - assert(slot != -1); + assert(slot != SlotID()); s << data->armyObj << slot; return true; } @@ -512,9 +511,9 @@ struct LoadIfStackInstance static bool invoke(Ser &s, CStackInstance* &data) { CArmedInstance *armedObj; - TSlot slot; + SlotID slot; s >> armedObj >> slot; - if(slot != COMMANDER_SLOT_PLACEHOLDER) + if(slot != SlotID::COMMANDER_SLOT_PLACEHOLDER) { assert(armedObj->hasStackAtSlot(slot)); data = armedObj->stacks[slot]; @@ -1172,7 +1171,7 @@ public: if(sendStackInstanceByIds) { CArmedInstance *armed; - TSlot slot; + SlotID slot; *this >> armed >> slot; assert(armed->hasStackAtSlot(slot)); s = armed->stacks[slot]; diff --git a/lib/GameConstants.cpp b/lib/GameConstants.cpp index 90d9974ca..9d15752ed 100644 --- a/lib/GameConstants.cpp +++ b/lib/GameConstants.cpp @@ -18,6 +18,8 @@ #include "CCreatureHandler.h" #include "CSpellHandler.h" +const SlotID SlotID::COMMANDER_SLOT_PLACEHOLDER = SlotID(-2); + #define ID_LIKE_OPERATORS_INTERNAL(A, B, AN, BN) \ bool operator==(const A & a, const B & b) \ { \ diff --git a/lib/GameConstants.h b/lib/GameConstants.h index 1e4e824fb..88058c044 100644 --- a/lib/GameConstants.h +++ b/lib/GameConstants.h @@ -223,6 +223,21 @@ class ObjectInstanceID : public BaseForID friend class CNonConstInfoCallback; }; +class SlotID : public BaseForID +{ + INSTID_LIKE_CLASS_COMMON(SlotID) + + friend class CGameInfoCallback; + friend class CNonConstInfoCallback; + + DLL_LINKAGE static const SlotID COMMANDER_SLOT_PLACEHOLDER; + + bool validSlot() const + { + return getNum() >= 0 && getNum() < GameConstants::ARMY_SIZE; + } +}; + // #ifndef INSTANTIATE_BASE_FOR_ID_HERE // extern template std::ostream & operator << (std::ostream & os, BaseForID id); // extern template std::ostream & operator << (std::ostream & os, BaseForID id); @@ -841,11 +856,10 @@ ID_LIKE_OPERATORS_DECLS(SpellID, SpellID::ESpellID) typedef si8 TFaction; typedef si64 TExpType; typedef std::pair TDmgRange; -typedef ui8 TBonusType; typedef si32 TBonusSubtype; -typedef si32 TSlot; typedef si32 TQuantity; typedef ui8 TPlayerColor; +typedef ui8 TTeamID; #undef ID_LIKE_CLASS_COMMON diff --git a/lib/HeroBonus.cpp b/lib/HeroBonus.cpp index 4c789ee25..a001eb377 100644 --- a/lib/HeroBonus.cpp +++ b/lib/HeroBonus.cpp @@ -27,20 +27,20 @@ #define FOREACH_RED_PARENT(pname) TNodes lparents; getRedParents(lparents); BOOST_FOREACH(CBonusSystemNode *pname, lparents) #define BONUS_NAME(x) ( #x, Bonus::x ) - const std::map bonusNameMap = boost::assign::map_list_of BONUS_LIST; + const std::map bonusNameMap = boost::assign::map_list_of BONUS_LIST; #undef BONUS_NAME #define BONUS_VALUE(x) ( #x, Bonus::x ) - const std::map bonusValueMap = boost::assign::map_list_of BONUS_VALUE_LIST; + const std::map bonusValueMap = boost::assign::map_list_of BONUS_VALUE_LIST; #undef BONUS_VALUE #define BONUS_SOURCE(x) ( #x, Bonus::x ) - const std::map bonusSourceMap = boost::assign::map_list_of BONUS_SOURCE_LIST; + const std::map bonusSourceMap = boost::assign::map_list_of BONUS_SOURCE_LIST; #undef BONUS_SOURCE #define BONUS_ITEM(x) ( #x, Bonus::x ) -const std::map bonusDurationMap = boost::assign::map_list_of +const std::map bonusDurationMap = boost::assign::map_list_of BONUS_ITEM(PERMANENT) BONUS_ITEM(ONE_BATTLE) BONUS_ITEM(ONE_DAY) @@ -52,7 +52,7 @@ const std::map bonusDurationMap = boost::assign::map_list_of BONUS_ITEM(STACK_GETS_TURN) BONUS_ITEM(COMMANDER_KILLED); -const std::map bonusLimitEffect = boost::assign::map_list_of +const std::map bonusLimitEffect = boost::assign::map_list_of BONUS_ITEM(NO_LIMIT) BONUS_ITEM(ONLY_DISTANCE_FIGHT) BONUS_ITEM(ONLY_MELEE_FIGHT) @@ -1128,7 +1128,7 @@ std::string Bonus::Description() const return str.str(); } -Bonus::Bonus(ui16 Dur, ui8 Type, BonusSource Src, si32 Val, ui32 ID, std::string Desc, si32 Subtype/*=-1*/) +Bonus::Bonus(ui16 Dur, BonusType Type, BonusSource Src, si32 Val, ui32 ID, std::string Desc, si32 Subtype/*=-1*/) : duration(Dur), type(Type), subtype(Subtype), source(Src), val(Val), sid(ID), description(Desc) { additionalInfo = -1; @@ -1138,7 +1138,7 @@ Bonus::Bonus(ui16 Dur, ui8 Type, BonusSource Src, si32 Val, ui32 ID, std::string boost::algorithm::trim(description); } -Bonus::Bonus(ui16 Dur, ui8 Type, BonusSource Src, si32 Val, ui32 ID, si32 Subtype/*=-1*/, ValueType ValType /*= ADDITIVE_VALUE*/) +Bonus::Bonus(ui16 Dur, BonusType Type, BonusSource Src, si32 Val, ui32 ID, si32 Subtype/*=-1*/, ValueType ValType /*= ADDITIVE_VALUE*/) : duration(Dur), type(Type), subtype(Subtype), source(Src), val(Val), sid(ID), valType(ValType) { additionalInfo = -1; @@ -1176,7 +1176,7 @@ CSelector DLL_LINKAGE operator||(const CSelector &first, const CSelector &second namespace Selector { - DLL_LINKAGE CSelectFieldEqual type(&Bonus::type, 0); + DLL_LINKAGE CSelectFieldEqual type(&Bonus::type, Bonus::NONE); DLL_LINKAGE CSelectFieldEqual subtype(&Bonus::subtype, 0); DLL_LINKAGE CSelectFieldEqual info(&Bonus::additionalInfo, 0); DLL_LINKAGE CSelectFieldEqual duration(&Bonus::duration, 0); @@ -1184,14 +1184,14 @@ namespace Selector DLL_LINKAGE CSelectFieldEqual effectRange(&Bonus::effectRange, Bonus::NO_LIMIT); DLL_LINKAGE CWillLastTurns turns; - CSelector DLL_LINKAGE typeSubtype(TBonusType Type, TBonusSubtype Subtype) + CSelector DLL_LINKAGE typeSubtype(Bonus::BonusType Type, TBonusSubtype Subtype) { return type(Type) && subtype(Subtype); } - CSelector DLL_LINKAGE typeSubtypeInfo(TBonusType type, TBonusSubtype subtype, si32 info) + CSelector DLL_LINKAGE typeSubtypeInfo(Bonus::BonusType type, TBonusSubtype subtype, si32 info) { - return CSelectFieldEqual(&Bonus::type, type) && CSelectFieldEqual(&Bonus::subtype, subtype) && CSelectFieldEqual(&Bonus::additionalInfo, info); + return CSelectFieldEqual(&Bonus::type, type) && CSelectFieldEqual(&Bonus::subtype, subtype) && CSelectFieldEqual(&Bonus::additionalInfo, info); } CSelector DLL_LINKAGE source(Bonus::BonusSource source, ui32 sourceID) @@ -1209,14 +1209,14 @@ namespace Selector return CSelectFieldEqual(&Bonus::source, source); } - bool DLL_LINKAGE matchesType(const CSelector &sel, TBonusType type) + bool DLL_LINKAGE matchesType(const CSelector &sel, Bonus::BonusType type) { Bonus dummy; dummy.type = type; return sel(&dummy); } - bool DLL_LINKAGE matchesTypeSubtype(const CSelector &sel, TBonusType type, TBonusSubtype subtype) + bool DLL_LINKAGE matchesTypeSubtype(const CSelector &sel, Bonus::BonusType type, TBonusSubtype subtype) { Bonus dummy; dummy.type = type; @@ -1285,7 +1285,7 @@ DLL_LINKAGE std::ostream & operator<<(std::ostream &out, const BonusList &bonusL DLL_LINKAGE std::ostream & operator<<(std::ostream &out, const Bonus &bonus) { - for(std::map::const_iterator i = bonusNameMap.begin(); i != bonusNameMap.end(); i++) + for(auto i = bonusNameMap.cbegin(); i != bonusNameMap.cend(); i++) if(i->second == bonus.type) out << "\tType: " << i->first << " \t"; @@ -1361,12 +1361,12 @@ void CCreatureTypeLimiter::setCreature (CreatureID id) creature = VLC->creh->creatures[id]; } -HasAnotherBonusLimiter::HasAnotherBonusLimiter( TBonusType bonus ) +HasAnotherBonusLimiter::HasAnotherBonusLimiter( Bonus::BonusType bonus ) : type(bonus), subtype(0), isSubtypeRelevant(false) { } -HasAnotherBonusLimiter::HasAnotherBonusLimiter( TBonusType bonus, TBonusSubtype _subtype ) +HasAnotherBonusLimiter::HasAnotherBonusLimiter( Bonus::BonusType bonus, TBonusSubtype _subtype ) : type(bonus), subtype(_subtype), isSubtypeRelevant(true) { } diff --git a/lib/HeroBonus.h b/lib/HeroBonus.h index 153098466..7d7d11fc6 100644 --- a/lib/HeroBonus.h +++ b/lib/HeroBonus.h @@ -252,7 +252,7 @@ struct DLL_LINKAGE Bonus ui16 duration; //uses BonusDuration values si16 turnsRemain; //used if duration is N_TURNS or N_DAYS - TBonusType type; //uses BonusType values - says to what is this bonus - 1 byte + BonusType type; //uses BonusType values - says to what is this bonus - 1 byte TBonusSubtype subtype; //-1 if not applicable - 4 bytes BonusSource source;//source type" uses BonusSource values - what gave that bonus @@ -268,8 +268,8 @@ struct DLL_LINKAGE Bonus std::string description; - Bonus(ui16 Dur, ui8 Type, BonusSource Src, si32 Val, ui32 ID, std::string Desc, si32 Subtype=-1); - Bonus(ui16 Dur, ui8 Type, BonusSource Src, si32 Val, ui32 ID, si32 Subtype=-1, ValueType ValType = ADDITIVE_VALUE); + Bonus(ui16 Dur, BonusType Type, BonusSource Src, si32 Val, ui32 ID, std::string Desc, si32 Subtype=-1); + Bonus(ui16 Dur, BonusType Type, BonusSource Src, si32 Val, ui32 ID, si32 Subtype=-1, ValueType ValType = ADDITIVE_VALUE); Bonus(); ~Bonus(); @@ -780,12 +780,12 @@ public: class DLL_LINKAGE HasAnotherBonusLimiter : public ILimiter //applies only to nodes that have another bonus working { public: - TBonusType type; + Bonus::BonusType type; TBonusSubtype subtype; bool isSubtypeRelevant; //check for subtype only if this is true - HasAnotherBonusLimiter(TBonusType bonus = Bonus::NONE); - HasAnotherBonusLimiter(TBonusType bonus, TBonusSubtype _subtype); + HasAnotherBonusLimiter(Bonus::BonusType bonus = Bonus::NONE); + HasAnotherBonusLimiter(Bonus::BonusType bonus, TBonusSubtype _subtype); int limit(const BonusLimitationContext &context) const OVERRIDE; @@ -880,7 +880,7 @@ const CCreature *retrieveCreature(const CBonusSystemNode *node); namespace Selector { - extern DLL_LINKAGE CSelectFieldEqual type; + extern DLL_LINKAGE CSelectFieldEqual type; extern DLL_LINKAGE CSelectFieldEqual subtype; extern DLL_LINKAGE CSelectFieldEqual info; extern DLL_LINKAGE CSelectFieldEqual duration; @@ -888,18 +888,22 @@ namespace Selector extern DLL_LINKAGE CSelectFieldEqual effectRange; extern DLL_LINKAGE CWillLastTurns turns; - CSelector DLL_LINKAGE typeSubtype(TBonusType Type, TBonusSubtype Subtype); - CSelector DLL_LINKAGE typeSubtypeInfo(TBonusType type, TBonusSubtype subtype, si32 info); + CSelector DLL_LINKAGE typeSubtype(Bonus::BonusType Type, TBonusSubtype Subtype); + CSelector DLL_LINKAGE typeSubtypeInfo(Bonus::BonusType type, TBonusSubtype subtype, si32 info); CSelector DLL_LINKAGE source(Bonus::BonusSource source, ui32 sourceID); CSelector DLL_LINKAGE durationType(ui16 duration); CSelector DLL_LINKAGE sourceTypeSel(Bonus::BonusSource source); - bool DLL_LINKAGE matchesType(const CSelector &sel, TBonusType type); - bool DLL_LINKAGE matchesTypeSubtype(const CSelector &sel, TBonusType type, TBonusSubtype subtype); + bool DLL_LINKAGE matchesType(const CSelector &sel, Bonus::BonusType type); + bool DLL_LINKAGE matchesTypeSubtype(const CSelector &sel, Bonus::BonusType type, TBonusSubtype subtype); bool DLL_LINKAGE positiveSpellEffects(const Bonus *b); } -extern DLL_LINKAGE const std::map bonusNameMap, bonusValueMap, bonusSourceMap, bonusDurationMap, bonusLimitEffect; +extern DLL_LINKAGE const std::map bonusNameMap; +extern DLL_LINKAGE const std::map bonusValueMap; +extern DLL_LINKAGE const std::map bonusSourceMap; +extern DLL_LINKAGE const std::map bonusDurationMap; +extern DLL_LINKAGE const std::map bonusLimitEffect; extern DLL_LINKAGE const bmap bonusLimiterMap; extern DLL_LINKAGE const bmap bonusPropagatorMap; diff --git a/lib/IGameCallback.cpp b/lib/IGameCallback.cpp index 53c3b082f..bacb83f06 100644 --- a/lib/IGameCallback.cpp +++ b/lib/IGameCallback.cpp @@ -286,7 +286,7 @@ const CGTownInstance* CGameInfoCallback::getTown(ObjectInstanceID objid) const return NULL; } -void CGameInfoCallback::getUpgradeInfo(const CArmedInstance *obj, int stackPos, UpgradeInfo &out) const +void CGameInfoCallback::getUpgradeInfo(const CArmedInstance *obj, SlotID stackPos, UpgradeInfo &out) const { //boost::shared_lock lock(*gs->mx); ERROR_RET_IF(!canGetFullInfo(obj), "Cannot get info about not owned object!"); diff --git a/lib/IGameCallback.h b/lib/IGameCallback.h index ddd5df773..ea66fd89a 100644 --- a/lib/IGameCallback.h +++ b/lib/IGameCallback.h @@ -92,7 +92,7 @@ public: //armed object - void getUpgradeInfo(const CArmedInstance *obj, int stackPos, UpgradeInfo &out)const; + void getUpgradeInfo(const CArmedInstance *obj, SlotID stackPos, UpgradeInfo &out)const; //hero const CGHeroInstance* getHero(ObjectInstanceID objid) const; diff --git a/lib/JsonNode.cpp b/lib/JsonNode.cpp index d7958ef56..acbe57f76 100644 --- a/lib/JsonNode.cpp +++ b/lib/JsonNode.cpp @@ -1118,17 +1118,17 @@ Key reverseMapFirst(const Val & val, const std::map map) void JsonUtils::unparseBonus( JsonNode &node, const Bonus * bonus ) { - node["type"].String() = reverseMapFirst(bonus->type, bonusNameMap); + node["type"].String() = reverseMapFirst(bonus->type, bonusNameMap); node["subtype"].Float() = bonus->subtype; node["val"].Float() = bonus->val; - node["valueType"].String() = reverseMapFirst(bonus->valType, bonusValueMap); + node["valueType"].String() = reverseMapFirst(bonus->valType, bonusValueMap); node["additionalInfo"].Float() = bonus->additionalInfo; node["turns"].Float() = bonus->turnsRemain; node["sourceID"].Float() = bonus->source; node["description"].String() = bonus->description; - node["effectRange"].String() = reverseMapFirst(bonus->effectRange, bonusLimitEffect); - node["duration"].String() = reverseMapFirst(bonus->duration, bonusDurationMap); - node["source"].String() = reverseMapFirst(bonus->source, bonusSourceMap); + node["effectRange"].String() = reverseMapFirst(bonus->effectRange, bonusLimitEffect); + node["duration"].String() = reverseMapFirst(bonus->duration, bonusDurationMap); + node["source"].String() = reverseMapFirst(bonus->source, bonusSourceMap); if(bonus->limiter) { node["limiter"].String() = reverseMapFirst(bonus->limiter, bonusLimiterMap); diff --git a/lib/Mapping/CCampaignHandler.cpp b/lib/Mapping/CCampaignHandler.cpp index ad694abfd..b3a8517b9 100644 --- a/lib/Mapping/CCampaignHandler.cpp +++ b/lib/Mapping/CCampaignHandler.cpp @@ -393,9 +393,10 @@ void CCampaignScenario::prepareCrossoverHeroes( std::vector he //trimming creatures BOOST_FOREACH(CGHeroInstance * cgh, crossoverHeroes) { - vstd::erase_if(cgh->stacks, [&](const std::pair & j) + vstd::erase_if(cgh->stacks, [&](const std::pair & j) { - return !(travelOptions.monstersKeptByHero[j.first / 8] & (1 << (j.first%8)) ); + CreatureID::ECreatureID crid = j.second->getCreatureID().toEnum(); + return !(travelOptions.monstersKeptByHero[crid / 8] & (1 << (crid % 8)) ); }); } } diff --git a/lib/Mapping/MapFormatH3M.cpp b/lib/Mapping/MapFormatH3M.cpp index 2f79c07e4..eafcca810 100644 --- a/lib/Mapping/MapFormatH3M.cpp +++ b/lib/Mapping/MapFormatH3M.cpp @@ -960,7 +960,7 @@ void CMapLoaderH3M::readObjects() hlp->count = reader.readUInt16(); //type will be set during initialization - cre->putStack(0, hlp); + cre->putStack(SlotID(0), hlp); cre->character = reader.readUInt8(); @@ -1515,7 +1515,7 @@ void CMapLoaderH3M::readCreatureSet(CCreatureSet * out, int number) hlp->setType(creID); } - out->putStack(ir, hlp); + out->putStack(SlotID(ir), hlp); } out->validTypes(true); diff --git a/lib/NetPacks.h b/lib/NetPacks.h index fa3e17a2a..5aebfe5b8 100644 --- a/lib/NetPacks.h +++ b/lib/NetPacks.h @@ -174,23 +174,16 @@ public: struct StackLocation { ConstTransitivePtr army; - TSlot slot; + SlotID slot; StackLocation() - { - slot = -1; - } - StackLocation(const CArmedInstance *Army, TSlot Slot) + {} + StackLocation(const CArmedInstance *Army, SlotID Slot) { army = const_cast(Army); //we are allowed here to const cast -> change will go through one of our packages... do not abuse! slot = Slot; } - bool validSlot() const - { - return slot >= 0 && slot < GameConstants::ARMY_SIZE; - } - DLL_LINKAGE const CStackInstance *getStack(); template void serialize(Handler &h, const int version) { @@ -1816,11 +1809,11 @@ struct CastleTeleportHero : public CPackForServer struct ArrangeStacks : public CPackForServer { ArrangeStacks(){}; - ArrangeStacks(ui8 W, ui8 P1, ui8 P2, ObjectInstanceID ID1, ObjectInstanceID ID2, si32 VAL) + ArrangeStacks(ui8 W, SlotID P1, SlotID P2, ObjectInstanceID ID1, ObjectInstanceID ID2, si32 VAL) :what(W),p1(P1),p2(P2),id1(ID1),id2(ID2),val(VAL) {}; ui8 what; //1 - swap; 2 - merge; 3 - split - ui8 p1, p2; //positions of first and second stack + SlotID p1, p2; //positions of first and second stack ObjectInstanceID id1, id2; //ids of objects with garrison si32 val; bool applyGh(CGameHandler *gh); @@ -1833,8 +1826,8 @@ struct ArrangeStacks : public CPackForServer struct DisbandCreature : public CPackForServer { DisbandCreature(){}; - DisbandCreature(ui8 Pos, ObjectInstanceID ID):pos(Pos),id(ID){}; - ui8 pos; //stack pos + DisbandCreature(SlotID Pos, ObjectInstanceID ID):pos(Pos),id(ID){}; + SlotID pos; //stack pos ObjectInstanceID id; //object id bool applyGh(CGameHandler *gh); @@ -1882,8 +1875,8 @@ struct RecruitCreatures : public CPackForServer struct UpgradeCreature : public CPackForServer { UpgradeCreature(){}; - UpgradeCreature(ui8 Pos, ObjectInstanceID ID, CreatureID CRID):pos(Pos),id(ID), cid(CRID){}; - ui8 pos; //stack pos + UpgradeCreature(SlotID Pos, ObjectInstanceID ID, CreatureID CRID):pos(Pos),id(ID), cid(CRID){}; + SlotID pos; //stack pos ObjectInstanceID id; //object id CreatureID cid; //id of type to which we want make upgrade @@ -1923,12 +1916,12 @@ struct ExchangeArtifacts : public CPackForServer struct AssembleArtifacts : public CPackForServer { AssembleArtifacts(){}; - AssembleArtifacts(ObjectInstanceID _heroID, ArtifactPosition _artifactSlot, bool _assemble, ui32 _assembleTo) + AssembleArtifacts(ObjectInstanceID _heroID, ArtifactPosition _artifactSlot, bool _assemble, ArtifactID _assembleTo) : heroID(_heroID), artifactSlot(_artifactSlot), assemble(_assemble), assembleTo(_assembleTo){}; ObjectInstanceID heroID; ArtifactPosition artifactSlot; bool assemble; // True to assemble artifact, false to disassemble. - ui32 assembleTo; // Artifact to assemble into. + ArtifactID assembleTo; // Artifact to assemble into. bool applyGh(CGameHandler *gh); template void serialize(Handler &h, const int version) diff --git a/lib/NetPacksLib.cpp b/lib/NetPacksLib.cpp index 5c0da340c..f8c771831 100644 --- a/lib/NetPacksLib.cpp +++ b/lib/NetPacksLib.cpp @@ -537,7 +537,7 @@ DLL_LINKAGE void NewObject::applyGs( CGameState *gs ) cre->character = 2; cre->gainedArtifact = ArtifactID::NONE; cre->identifier = -1; - cre->addToSlot(0, new CStackInstance(CreatureID(subID), -1)); //add placeholder stack + cre->addToSlot(SlotID(0), new CStackInstance(CreatureID(subID), -1)); //add placeholder stack } break; default: @@ -1460,7 +1460,7 @@ DLL_LINKAGE void BattleStackAdded::applyGs(CGameState *gs) } CStackBasicDescriptor csbd(creID, amount); - CStack * addedStack = gs->curB->generateNewStack(csbd, attacker, 255, pos); //TODO: netpacks? + CStack * addedStack = gs->curB->generateNewStack(csbd, attacker, SlotID(255), pos); //TODO: netpacks? if (summoned) addedStack->state.insert(EBattleStackState::SUMMONED); diff --git a/server/CGameHandler.cpp b/server/CGameHandler.cpp index e39976b37..bc48741e4 100644 --- a/server/CGameHandler.cpp +++ b/server/CGameHandler.cpp @@ -693,7 +693,7 @@ void CGameHandler::endBattle(int3 tile, const CGHeroInstance *hero1, const CGHer const CStackBasicDescriptor raisedStack = winnerHero ? winnerHero->calculateNecromancy(*battleResult.data) : CStackBasicDescriptor(); // Give raised units to winner and show dialog, if any were raised, // units will be given after casualities are taken - const TSlot necroSlot = raisedStack.type ? winnerHero->getSlotFor(raisedStack.type) : -1; + const SlotID necroSlot = raisedStack.type ? winnerHero->getSlotFor(raisedStack.type) : SlotID(); if(!duel) { @@ -720,7 +720,7 @@ void CGameHandler::endBattle(int3 tile, const CGHeroInstance *hero1, const CGHer afterBattleCallback(); } - if (necroSlot != -1) + if (necroSlot != SlotID()) { winnerHero->showNecromancyDialog(raisedStack); addToSlot(StackLocation(winnerHero, necroSlot), raisedStack.type, raisedStack.count); @@ -751,7 +751,7 @@ void CGameHandler::endBattle(int3 tile, const CGHeroInstance *hero1, const CGHer if(result == 1) //retreat { sah.army[0].clear(); - sah.army[0].setCreature(0, loserHero->type->initialArmy[0].creature, 1); + sah.army[0].setCreature(SlotID(0), loserHero->type->initialArmy[0].creature, 1); } if(const CGHeroInstance *another = getPlayer(loser)->availableHeroes[1]) @@ -2341,13 +2341,13 @@ void CGameHandler::close() //exit(0); } -bool CGameHandler::arrangeStacks( ObjectInstanceID id1, ObjectInstanceID id2, ui8 what, ui8 p1, ui8 p2, si32 val, TPlayerColor player ) +bool CGameHandler::arrangeStacks( ObjectInstanceID id1, ObjectInstanceID id2, ui8 what, SlotID p1, SlotID p2, si32 val, TPlayerColor player ) { const CArmedInstance *s1 = static_cast(gs->getObjInstance(id1)), *s2 = static_cast(gs->getObjInstance(id2)); const CCreatureSet &S1 = *s1, &S2 = *s2; StackLocation sl1(s1, p1), sl2(s2, p2); - if(!sl1.validSlot() || !sl2.validSlot()) + if(!sl1.slot.validSlot() || !sl2.slot.validSlot()) { complain("Invalid slot accessed!"); return false; @@ -2449,7 +2449,7 @@ TPlayerColor CGameHandler::getPlayerAt( CConnection *c ) const } } -bool CGameHandler::disbandCreature( ObjectInstanceID id, ui8 pos ) +bool CGameHandler::disbandCreature( ObjectInstanceID id, SlotID pos ) { CArmedInstance *s1 = static_cast(gs->getObjInstance(id)); if(!vstd::contains(s1->stacks,pos)) @@ -2645,12 +2645,12 @@ bool CGameHandler::recruitCreatures( ObjectInstanceID objid, CreatureID crid, ui break; } } - int slot = dst->getSlotFor(crid); + SlotID slot = dst->getSlotFor(crid); if( (!found && complain("Cannot recruit: no such creatures!")) || (cram > VLC->creh->creatures[crid]->maxAmount(gs->getPlayer(dst->tempOwner)->resources) && complain("Cannot recruit: lack of resources!")) || (cram<=0 && complain("Cannot recruit: cram <= 0!")) - || (slot<0 && !warMachine && complain("Cannot recruit: no available slot!"))) + || (!slot.validSlot() && !warMachine && complain("Cannot recruit: no available slot!"))) { return false; } @@ -2697,7 +2697,7 @@ bool CGameHandler::recruitCreatures( ObjectInstanceID objid, CreatureID crid, ui return true; } -bool CGameHandler::upgradeCreature( ObjectInstanceID objid, ui8 pos, CreatureID upgID ) +bool CGameHandler::upgradeCreature( ObjectInstanceID objid, SlotID pos, CreatureID upgID ) { CArmedInstance *obj = static_cast(gs->getObjInstance(objid)); assert(obj->hasStackAtSlot(pos)); @@ -2749,11 +2749,11 @@ void CGameHandler::moveArmy(const CArmedInstance *src, const CArmedInstance *dst TSlots::const_iterator i = src->Slots().begin(); //iterator to stack to move StackLocation sl(src, i->first); //location of stack to move - TSlot pos = dst->getSlotFor(i->second->type); - if(pos < 0) + SlotID pos = dst->getSlotFor(i->second->type); + if(!pos.validSlot()) { //try to merge two other stacks to make place - std::pair toMerge; + std::pair toMerge; if(dst->mergableStacks(toMerge, i->first) && allowMerging) { moveStack(StackLocation(dst, toMerge.first), StackLocation(dst, toMerge.second)); //merge toMerge.first into toMerge.second @@ -2888,7 +2888,7 @@ bool CGameHandler::moveArtifact(const ArtifactLocation &al1, const ArtifactLocat * @param assembleTo If assemble is true, this represents the artifact ID of the combination * artifact to assemble to. Otherwise it's not used. */ -bool CGameHandler::assembleArtifacts (ObjectInstanceID heroID, ArtifactPosition artifactSlot, bool assemble, ui32 assembleTo) +bool CGameHandler::assembleArtifacts (ObjectInstanceID heroID, ArtifactPosition artifactSlot, bool assemble, ArtifactID assembleTo) { CGHeroInstance *hero = gs->getHero(heroID); @@ -3099,7 +3099,7 @@ bool CGameHandler::tradeResources(const IMarket *market, ui32 val, TPlayerColor return true; } -bool CGameHandler::sellCreatures(ui32 count, const IMarket *market, const CGHeroInstance * hero, ui32 slot, Res::ERes resourceID) +bool CGameHandler::sellCreatures(ui32 count, const IMarket *market, const CGHeroInstance * hero, SlotID slot, Res::ERes resourceID) { if(!vstd::contains(hero->Slots(), slot)) COMPLAIN_RET("Hero doesn't have any creature in that slot!"); @@ -3133,7 +3133,7 @@ bool CGameHandler::sellCreatures(ui32 count, const IMarket *market, const CGHero return true; } -bool CGameHandler::transformInUndead(const IMarket *market, const CGHeroInstance * hero, ui32 slot) +bool CGameHandler::transformInUndead(const IMarket *market, const CGHeroInstance * hero, SlotID slot) { const CArmedInstance *army = NULL; if (hero) @@ -3242,7 +3242,7 @@ bool CGameHandler::hireHero(const CGObjectInstance *obj, ui8 hid, TPlayerColor p { sah.hid[hid] = newHero->subID; sah.army[hid].clear(); - sah.army[hid].setCreature(0, newHero->type->initialArmy[0].creature, 1); + sah.army[hid].setCreature(SlotID(0), newHero->type->initialArmy[0].creature, 1); } else sah.hid[hid] = -1; @@ -3820,8 +3820,8 @@ void CGameHandler::playerMessage( TPlayerColor player, const std::string &messag if(!hero) return; for(int i = 0; i < GameConstants::ARMY_SIZE; i++) - if(!hero->hasStackAtSlot(i)) - insertNewStack(StackLocation(hero, i), archangel, 5); + if(!hero->hasStackAtSlot(SlotID(i))) + insertNewStack(StackLocation(hero, SlotID(i)), archangel, 5); } else if(message == "vcmiangband") //gives 10 black knight into each slot { @@ -3830,8 +3830,8 @@ void CGameHandler::playerMessage( TPlayerColor player, const std::string &messag if(!hero) return; for(int i = 0; i < GameConstants::ARMY_SIZE; i++) - if(!hero->hasStackAtSlot(i)) - insertNewStack(StackLocation(hero, i), blackKnight, 10); + if(!hero->hasStackAtSlot(SlotID(i))) + insertNewStack(StackLocation(hero, SlotID(i)), blackKnight, 10); } else if(message == "vcminoldor") //all war machines { @@ -5622,7 +5622,7 @@ bool CGameHandler::tryAttackingGuard(const int3 &guardPos, const CGHeroInstance return true; } -bool CGameHandler::sacrificeCreatures(const IMarket *market, const CGHeroInstance *hero, TSlot slot, ui32 count) +bool CGameHandler::sacrificeCreatures(const IMarket *market, const CGHeroInstance *hero, SlotID slot, ui32 count) { int oldCount = hero->getStackCount(slot); @@ -5677,7 +5677,7 @@ bool CGameHandler::insertNewStack(const StackLocation &sl, const CCreature *c, T if(sl.army->hasStackAtSlot(sl.slot)) COMPLAIN_RET("Slot is already taken!"); - if(!sl.validSlot()) + if(!sl.slot.validSlot()) COMPLAIN_RET("Cannot insert stack to that slot!"); InsertNewStack ins; @@ -5755,8 +5755,8 @@ void CGameHandler::tryJoiningArmy(const CArmedInstance *src, const CArmedInstanc { 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) + SlotID pos = dst->getSlotFor(i->second->type); + if(pos.validSlot()) { moveStack(StackLocation(src, i->first), StackLocation(dst, pos)); cont = true; @@ -5787,7 +5787,7 @@ bool CGameHandler::moveStack(const StackLocation &src, const StackLocation &dst, if(dst.army->hasStackAtSlot(dst.slot) && dst.army->getCreature(dst.slot) != src.army->getCreature(src.slot)) COMPLAIN_RET("Cannot move: stack of different type at destination pos!"); - if(!dst.validSlot()) + if(!dst.slot.validSlot()) COMPLAIN_RET("Cannot move stack to that slot!"); if(count == -1) diff --git a/server/CGameHandler.h b/server/CGameHandler.h index 8c3a4fb10..07d6ad96e 100644 --- a/server/CGameHandler.h +++ b/server/CGameHandler.h @@ -209,23 +209,23 @@ public: bool buildBoat( ObjectInstanceID objid ); bool setFormation( ObjectInstanceID hid, ui8 formation ); bool tradeResources(const IMarket *market, ui32 val, TPlayerColor player, ui32 id1, ui32 id2); - bool sacrificeCreatures(const IMarket *market, const CGHeroInstance *hero, TSlot slot, ui32 count); + bool sacrificeCreatures(const IMarket *market, const CGHeroInstance *hero, SlotID slot, ui32 count); bool sendResources(ui32 val, TPlayerColor player, Res::ERes r1, TPlayerColor r2); - bool sellCreatures(ui32 count, const IMarket *market, const CGHeroInstance * hero, ui32 slot, Res::ERes resourceID); - bool transformInUndead(const IMarket *market, const CGHeroInstance * hero, ui32 slot); - bool assembleArtifacts (ObjectInstanceID heroID, ArtifactPosition artifactSlot, bool assemble, ui32 assembleTo); + bool sellCreatures(ui32 count, const IMarket *market, const CGHeroInstance * hero, SlotID slot, Res::ERes resourceID); + bool transformInUndead(const IMarket *market, const CGHeroInstance * hero, SlotID slot); + bool assembleArtifacts (ObjectInstanceID heroID, ArtifactPosition artifactSlot, bool assemble, ArtifactID assembleTo); bool buyArtifact( ObjectInstanceID hid, ArtifactID aid ); //for blacksmith and mage guild only -> buying for gold in common buildings bool buyArtifact( const IMarket *m, const CGHeroInstance *h, Res::ERes rid, ArtifactID aid); //for artifact merchant and black market -> buying for any resource in special building / advobject bool sellArtifact( const IMarket *m, const CGHeroInstance *h, ArtifactInstanceID aid, Res::ERes rid); //for artifact merchant selling //void lootArtifacts (TArtHolder source, TArtHolder dest, std::vector &arts); //after battle - move al arts to winer bool buySecSkill( const IMarket *m, const CGHeroInstance *h, SecondarySkill skill); bool garrisonSwap(ObjectInstanceID tid); - bool upgradeCreature( ObjectInstanceID objid, ui8 pos, CreatureID upgID ); + bool upgradeCreature( ObjectInstanceID objid, SlotID pos, CreatureID upgID ); bool recruitCreatures(ObjectInstanceID objid, CreatureID crid, ui32 cram, si32 level); bool buildStructure(ObjectInstanceID tid, BuildingID bid, bool force=false);//force - for events: no cost, no checkings bool razeStructure(ObjectInstanceID tid, BuildingID bid); - bool disbandCreature( ObjectInstanceID id, ui8 pos ); - bool arrangeStacks( ObjectInstanceID id1, ObjectInstanceID id2, ui8 what, ui8 p1, ui8 p2, si32 val, TPlayerColor player); + bool disbandCreature( ObjectInstanceID id, SlotID pos ); + bool arrangeStacks( ObjectInstanceID id1, ObjectInstanceID id2, ui8 what, SlotID p1, SlotID p2, si32 val, TPlayerColor player); void save(const std::string &fname); void close(); void handleTimeEvents(); diff --git a/server/NetPacksServer.cpp b/server/NetPacksServer.cpp index f8aa80635..d14078450 100644 --- a/server/NetPacksServer.cpp +++ b/server/NetPacksServer.cpp @@ -180,7 +180,7 @@ bool TradeOnMarketplace::applyGh( CGameHandler *gh ) case EMarketMode::CREATURE_RESOURCE: if(!hero) COMPLAIN_AND_RETURN("Only hero can sell creatures!"); - return gh->sellCreatures(val, m, hero, r1, static_cast(r2)); + return gh->sellCreatures(val, m, hero, SlotID(r1), static_cast(r2)); case EMarketMode::RESOURCE_ARTIFACT: if(!hero) COMPLAIN_AND_RETURN("Only hero can buy artifacts!"); @@ -190,11 +190,11 @@ bool TradeOnMarketplace::applyGh( CGameHandler *gh ) COMPLAIN_AND_RETURN("Only hero can sell artifacts!"); return gh->sellArtifact(m, hero, ArtifactInstanceID(r1), static_cast(r2)); case EMarketMode::CREATURE_UNDEAD: - return gh->transformInUndead(m, hero, r1); + return gh->transformInUndead(m, hero, SlotID(r1)); case EMarketMode::RESOURCE_SKILL: return gh->buySecSkill(m, hero, SecondarySkill(r2)); case EMarketMode::CREATURE_EXP: - return gh->sacrificeCreatures(m, hero, r1, val); + return gh->sacrificeCreatures(m, hero, SlotID(r1), val); case EMarketMode::ARTIFACT_EXP: return gh->sacrificeArtifact(m, hero, ArtifactPosition(r1)); default: