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: