1
0
mirror of https://github.com/vcmi/vcmi.git synced 2024-12-24 22:14:36 +02:00

* SlotID refactoring

This commit is contained in:
mateuszb 2013-02-16 14:03:47 +00:00
parent d23a5dcfdf
commit 560315bc48
33 changed files with 359 additions and 351 deletions

View File

@ -92,6 +92,7 @@
</ClCompile> </ClCompile>
<Link> <Link>
<AdditionalDependencies>VCMI_lib.lib;%(AdditionalDependencies)</AdditionalDependencies> <AdditionalDependencies>VCMI_lib.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalOptions>-Zm150 %(AdditionalOptions)</AdditionalOptions>
</Link> </Link>
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">

View File

@ -288,7 +288,7 @@ ui64 howManyReinforcementsCanGet(HeroPtr h, const CGTownInstance *t)
BOOST_FOREACH(auto const slot, t->Slots()) BOOST_FOREACH(auto const slot, t->Slots())
{ {
//can be merged woth another stack? //can be merged woth another stack?
TSlot dst = h->getSlotFor(slot.second->getCreatureID()); SlotID dst = h->getSlotFor(slot.second->getCreatureID());
if(h->hasStackAtSlot(dst)) if(h->hasStackAtSlot(dst))
ret += t->getPower(slot.first); ret += t->getPower(slot.first);
else else
@ -959,13 +959,13 @@ void makePossibleUpgrades(const CArmedInstance *obj)
for(int i = 0; i < GameConstants::ARMY_SIZE; i++) 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; 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)) 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) BOOST_FOREACH(auto armyPtr, armies)
for (int j = 0; j < GameConstants::ARMY_SIZE; j++) 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 if (!(armyPtr->needsLastStack() && armyPtr->Slots().size() == 1 && armyPtr != army)) //can't take away last creature
return true; //at least one exchange will be performed 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) BOOST_FOREACH(auto armyPtr, armies)
for (int j = 0; j < GameConstants::ARMY_SIZE; j++) 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)) 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) BOOST_FOREACH(auto c, level.second)
{ {
if (h->getSlotFor(c) != -1) if (h->getSlotFor(CreatureID(c)) != SlotID())
canRecruitCreatures = true; canRecruitCreatures = true;
} }
} }

View File

@ -79,7 +79,7 @@ void CCallback::recruitCreatures(const CGObjectInstance *obj, CreatureID ID, ui3
sendRequest(&pack); 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())) if(((player>=0) && obj->tempOwner != player) || (obj->stacksCount()<2 && obj->needsLastStack()))
return false; return false;
@ -89,7 +89,7 @@ bool CCallback::dismissCreature(const CArmedInstance *obj, int stackPos)
return true; 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); UpgradeCreature pack(stackPos,obj->id,newID);
sendRequest(&pack); sendRequest(&pack);
@ -102,20 +102,20 @@ void CCallback::endTurn()
EndTurn pack; EndTurn pack;
sendRequest(&pack); //report that we ended turn 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); ArrangeStacks pack(1,p1,p2,s1->id,s2->id,0);
sendRequest(&pack); sendRequest(&pack);
return 0; 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); ArrangeStacks pack(2,p1,p2,s1->id,s2->id,0);
sendRequest(&pack); sendRequest(&pack);
return 0; 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); ArrangeStacks pack(3,p1,p2,s1->id,s2->id,val);
sendRequest(&pack); 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 * @param assembleTo If assemble is true, this represents the artifact ID of the combination
* artifact to assemble to. Otherwise it's not used. * 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) if (player != hero->tempOwner)
return false; 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)) if(s1->getCreature(p1) == s2->getCreature(p2))
return mergeStacks(s1, s2, p1, p2); return mergeStacks(s1, s2, p1, p2);

View File

@ -51,20 +51,20 @@ public:
virtual void recruitHero(const CGObjectInstance *townOrTavern, const CGHeroInstance *hero)=0; virtual void recruitHero(const CGObjectInstance *townOrTavern, const CGHeroInstance *hero)=0;
virtual bool buildBuilding(const CGTownInstance *town, BuildingID buildingID)=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 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 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 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 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 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, int p1, int p2)=0;//joins first stack to the second (creatures must be same type) 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, int p1, int p2) =0; //first goes to the second 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, int p1, int p2, int val)=0;//split creatures from the first stack 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 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 swapArtifacts(const ArtifactLocation &l1, const ArtifactLocation &l2)=0;
virtual bool assembleArtifacts(const CGHeroInstance * hero, ArtifactPosition artifactSlot, bool assemble, ui32 assembleTo)=0; virtual bool assembleArtifacts(const CGHeroInstance * hero, ArtifactPosition artifactSlot, bool assemble, ArtifactID assembleTo)=0;
virtual bool dismissCreature(const CArmedInstance *obj, int stackPos)=0; virtual bool dismissCreature(const CArmedInstance *obj, SlotID stackPos)=0;
virtual void endTurn()=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 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; 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 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); bool teleportHero(const CGHeroInstance *who, const CGTownInstance *where);
int selectionMade(int selection, int queryID); int selectionMade(int selection, int queryID);
int swapCreatures(const CArmedInstance *s1, const CArmedInstance *s2, int p1, int p2); int swapCreatures(const CArmedInstance *s1, const CArmedInstance *s2, SlotID p1, SlotID p2);
int mergeOrSwapStacks(const CArmedInstance *s1, const CArmedInstance *s2, int p1, int p2); //first goes to the second 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, int p1, int 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, int p1, int p2, int val); int splitStack(const CArmedInstance *s1, const CArmedInstance *s2, SlotID p1, SlotID p2, int val);
bool dismissHero(const CGHeroInstance * hero); bool dismissHero(const CGHeroInstance * hero);
//bool swapArtifacts(const CGHeroInstance * hero1, ui16 pos1, const CGHeroInstance * hero2, ui16 pos2); //bool swapArtifacts(const CGHeroInstance * hero1, ui16 pos1, const CGHeroInstance * hero2, ui16 pos2);
bool swapArtifacts(const ArtifactLocation &l1, const ArtifactLocation &l2); 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 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 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; bool buildBuilding(const CGTownInstance *town, BuildingID buildingID) OVERRIDE;
void recruitCreatures(const CGObjectInstance *obj, CreatureID ID, ui32 amount, si32 level=-1); void recruitCreatures(const CGObjectInstance *obj, CreatureID ID, ui32 amount, si32 level=-1);
bool dismissCreature(const CArmedInstance *obj, int stackPos); bool dismissCreature(const CArmedInstance *obj, SlotID stackPos);
bool upgradeCreature(const CArmedInstance *obj, int stackPos, CreatureID newID=CreatureID::NONE) OVERRIDE; bool upgradeCreature(const CArmedInstance *obj, SlotID stackPos, CreatureID newID=CreatureID::NONE) OVERRIDE;
void endTurn(); void endTurn();
void swapGarrisonHero(const CGTownInstance *town); void swapGarrisonHero(const CGTownInstance *town);
void buyArtifact(const CGHeroInstance *hero, ArtifactID aid) OVERRIDE; void buyArtifact(const CGHeroInstance *hero, ArtifactID aid) OVERRIDE;

View File

@ -737,7 +737,7 @@ struct HEPerformer : StandardReceiverVisitor<const CGHeroInstance *>
{ {
if(erm->getIexp(params[0]).getInt() == 0) 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); const CStackInstance *stack = identifier->getStackPtr(slot);
if(params[2].which() == 6) //varp if(params[2].which() == 6) //varp
{ {
@ -752,7 +752,7 @@ struct HEPerformer : StandardReceiverVisitor<const CGHeroInstance *>
if(params[3].which() == 6) //varp if(params[3].which() == 6) //varp
{ {
erm->getIexp(boost::get<ERM::TVarpExp>(params[3])).setTo(identifier->getStackCount(slot)); erm->getIexp(boost::get<ERM::TVarpExp>(params[3])).setTo(identifier->getStackCount(SlotID(slot)));
} }
else else
throw EScriptExecError("Setting stack count is not implemented!"); 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 void MO_GPerformer::operator()( TVarpExp const& cmp ) const
{ {
const CGCreature *cre = erm->getObjFromAs<CGCreature>(owner.identifier); const CGCreature *cre = erm->getObjFromAs<CGCreature>(owner.identifier);
erm->getIexp(cmp).setTo(cre->getStackCount(0)); erm->getIexp(cmp).setTo(cre->getStackCount(SlotID(0)));
} }

View File

@ -280,7 +280,7 @@ void CCreatureWindow::init(const CStackInstance *Stack, const CBonusSystemNode *
} }
if (magicResistance) if (magicResistance)
{ {
std::map<TBonusType, std::pair<std::string, std::string> >::const_iterator it = CGI->creh->stackBonuses.find(Bonus::MAGIC_RESISTANCE); std::map<Bonus::BonusType, std::pair<std::string, std::string> >::const_iterator it = CGI->creh->stackBonuses.find(Bonus::MAGIC_RESISTANCE);
std::string description; std::string description;
text = it->second.first; text = it->second.first;
description = it->second.second; description = it->second.second;

View File

@ -82,13 +82,13 @@ void CArmyTooltip::init(const InfoAboutArmy &army)
BOOST_FOREACH(auto & slot, army.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; tlog3 << "Warning: " << army.name << " has stack in slot " << slot.first << std::endl;
continue; 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; std::string subtitle;
if(army.army.isDetailed) if(army.army.isDetailed)
@ -100,7 +100,7 @@ void CArmyTooltip::init(const InfoAboutArmy &army)
subtitle = CGI->generaltexth->arraytxt[171 + 3*(slot.second.count)]; 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), ID(IID),
owner(Owner), owner(Owner),
myStack(Creature), myStack(Creature),
@ -528,13 +528,13 @@ void CGarrisonInt::createSet(std::vector<CGarrisonSlot*> &ret, const CCreatureSe
{ {
for(TSlots::const_iterator i=set->Slots().begin(); i!=set->Slots().end(); i++) 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; i<ret.size(); i++) for(int i=0; i<ret.size(); i++)
if(!ret[i]) if(!ret[i])
ret[i] = new CGarrisonSlot(this, posX + (i*distance), posY,i,Upg,NULL); ret[i] = new CGarrisonSlot(this, posX + (i*distance), posY, SlotID(i), Upg, NULL);
if (twoRows) if (twoRows)
for (int i=4; i<ret.size(); i++) for (int i=4; i<ret.size(); i++)
@ -1468,9 +1468,9 @@ void CRecruitmentWindow::select(CCreatureCard *card)
void CRecruitmentWindow::buy() void CRecruitmentWindow::buy()
{ {
CreatureID crid = selected->creature->idNumber; CreatureID crid = selected->creature->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; std::string txt;
if(dst->ID == Obj::HERO) if(dst->ID == Obj::HERO)
@ -2346,7 +2346,7 @@ std::vector<int> *CTradeWindow::getItemsIds(bool Left)
ids = new std::vector<int>; ids = new std::vector<int>;
for(int i = 0; i < 7; i++) 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); ids->push_back(c->idNumber);
else else
ids->push_back(-1); ids->push_back(-1);
@ -2423,7 +2423,7 @@ void CTradeWindow::initSubs(bool Left)
switch(itemsType[1]) switch(itemsType[1])
{ {
case CREATURE: case CREATURE:
t->subtitle = boost::lexical_cast<std::string>(hero->getStackCount(t->serial)); t->subtitle = boost::lexical_cast<std::string>(hero->getStackCount(SlotID(t->serial)));
break; break;
case RESOURCE: case RESOURCE:
t->subtitle = boost::lexical_cast<std::string>(LOCPLINT->cb->getResourceAmount(static_cast<Res::ERes>(t->serial))); t->subtitle = boost::lexical_cast<std::string>(LOCPLINT->cb->getResourceAmount(static_cast<Res::ERes>(t->serial)));
@ -2494,7 +2494,7 @@ void CTradeWindow::removeItem(CTradeableItem * t)
void CTradeWindow::getEmptySlots(std::set<CTradeableItem *> &toRemove) void CTradeWindow::getEmptySlots(std::set<CTradeableItem *> &toRemove)
{ {
BOOST_FOREACH(CTradeableItem *t, items[1]) BOOST_FOREACH(CTradeableItem *t, items[1])
if(!hero->getStackCount(t->serial)) if(!hero->getStackCount(SlotID(t->serial)))
toRemove.insert(t); toRemove.insert(t);
} }
@ -2758,7 +2758,7 @@ void CMarketplaceWindow::selectionChanged(bool side)
if(itemsType[1] == RESOURCE) if(itemsType[1] == RESOURCE)
newAmount = LOCPLINT->cb->getResourceAmount(static_cast<Res::ERes>(soldItemId)); newAmount = LOCPLINT->cb->getResourceAmount(static_cast<Res::ERes>(soldItemId));
else if(itemsType[1] == CREATURE) 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 else
assert(0); assert(0);
@ -3149,7 +3149,7 @@ void CAltarWindow::SacrificeAll()
{ {
bool movedAnything = false; bool movedAnything = false;
BOOST_FOREACH(CTradeableItem *t, items[1]) 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]--; sacrificedUnits[items[1].front()->serial]--;
@ -3188,10 +3188,10 @@ void CAltarWindow::selectionChanged(bool side)
int stackCount = 0; int stackCount = 0;
for (int i = 0; i < GameConstants::ARMY_SIZE; i++) for (int i = 0; i < GameConstants::ARMY_SIZE; i++)
if(hero->getStackCount(i) > sacrificedUnits[i]) if(hero->getStackCount(SlotID(i)) > sacrificedUnits[i])
stackCount++; stackCount++;
slider->setAmount(hero->getStackCount(hLeft->serial) - (stackCount == 1)); slider->setAmount(hero->getStackCount(SlotID(hLeft->serial)) - (stackCount == 1));
slider->block(!slider->amount); slider->block(!slider->amount);
slider->value = sacrificedUnits[hLeft->serial]; slider->value = sacrificedUnits[hLeft->serial];
max->block(!slider->amount); max->block(!slider->amount);
@ -4265,7 +4265,7 @@ void CArtPlace::clickRight(tribool down, bool previousState)
ourArt->artType->id, ourArt->artType->id,
0, 0,
false, false,
boost::bind(&CCallback::assembleArtifacts, LOCPLINT->cb, ourOwner->curHero, slotID, false, 0), boost::bind(&CCallback::assembleArtifacts, LOCPLINT->cb, ourOwner->curHero, slotID, false, ArtifactID()),
0); 0);
return; return;
} }
@ -5310,7 +5310,7 @@ void CTransformerWindow::CItem::clickLeft(tribool down, bool previousState)
void CTransformerWindow::CItem::update() 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): 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.x += 45 + (id%3)*83 + id/6*83;
pos.y += 109 + (id/3)*98; 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<std::string>(size));//stack size new CLabel(28, 76,FONT_SMALL, CENTER, Colors::WHITE, boost::lexical_cast<std::string>(size));//stack size
} }
@ -5362,9 +5362,9 @@ CTransformerWindow::CTransformerWindow(const CGHeroInstance * _hero, const CGTow
else else
army = town; army = town;
for (int i=0; i<7; i++ ) for (int i=0; i<GameConstants::ARMY_SIZE; i++ )
if ( army->getCreature(i) ) if ( army->getCreature(SlotID(i)) )
items.push_back(new CItem(this, army->getStackCount(i), 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); 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); 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"; files += "APHLF1R.DEF", "APHLF1Y.DEF", "APHLF1G.DEF";
for (int i=0; i<slotsCount; i++) for (int i=0; i<slotsCount; i++)
{ {
currState[i] = getState(i); currState[i] = getState(SlotID(i));
upgrade[i] = new CAdventureMapButton(getTextForSlot(i),"",boost::bind(&CHillFortWindow::makeDeal, this, i), upgrade[i] = new CAdventureMapButton(getTextForSlot(SlotID(i)),"",boost::bind(&CHillFortWindow::makeDeal, this, SlotID(i)),
107+i*76, 171, "", SDLK_1+i, &files); 107+i*76, 171, "", SDLK_1+i, &files);
upgrade[i]->block(currState[i] == -1); upgrade[i]->block(currState[i] == -1);
} }
files.clear(); files.clear();
files += "APHLF4R.DEF", "APHLF4Y.DEF", "APHLF4G.DEF"; files += "APHLF4R.DEF", "APHLF4Y.DEF", "APHLF4G.DEF";
currState[slotsCount] = getState(slotsCount); currState[slotsCount] = getState(SlotID(slotsCount));
upgradeAll = new CAdventureMapButton(CGI->generaltexth->allTexts[432],"",boost::bind(&CHillFortWindow::makeDeal, this, slotsCount), upgradeAll = new CAdventureMapButton(CGI->generaltexth->allTexts[432],"",boost::bind(&CHillFortWindow::makeDeal, this, SlotID(slotsCount)),
30, 231, "", SDLK_0, &files); 30, 231, "", SDLK_0, &files);
quit = new CAdventureMapButton("","",boost::bind(&CHillFortWindow::close, this), 294, 275, "IOKAY.DEF", SDLK_RETURN); 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)); 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; i<slotsCount; i++) for (int i=0; i<slotsCount; i++)
{ {
costs[i].clear(); costs[i].clear();
int newState = getState(i); int newState = getState(SlotID(i));
if (newState != -1) if (newState != -1)
{ {
UpgradeInfo info; UpgradeInfo info;
LOCPLINT->cb->getUpgradeInfo(hero, i, info); LOCPLINT->cb->getUpgradeInfo(hero, SlotID(i), info);
if (info.newID.size())//we have upgrades here - update costs 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]; totalSumm += costs[i];
} }
} }
@ -5596,19 +5596,20 @@ void CHillFortWindow::updateGarrisons()
currState[i] = newState; currState[i] = newState;
upgrade[i]->setIndex(newState); upgrade[i]->setIndex(newState);
upgrade[i]->block(currState[i] == -1); 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; currState[slotsCount] = newState;
upgradeAll->setIndex(newState); upgradeAll->setIndex(newState);
garr->recreateSlots(); garr->recreateSlots();
} }
void CHillFortWindow::makeDeal(int slot) void CHillFortWindow::makeDeal(SlotID slot)
{ {
int offset = (slot == slotsCount)?2:0; assert(slot.getNum()>=0);
switch (currState[slot]) int offset = (slot.getNum() == slotsCount)?2:0;
switch (currState[slot.getNum()])
{ {
case 0: case 0:
LOCPLINT->showInfoDialog(CGI->generaltexth->allTexts[314 + offset], LOCPLINT->showInfoDialog(CGI->generaltexth->allTexts[314 + offset],
@ -5620,11 +5621,11 @@ void CHillFortWindow::makeDeal(int slot)
break; break;
case 2: case 2:
for (int i=0; i<slotsCount; i++) for (int i=0; i<slotsCount; i++)
if ( slot ==i || ( slot == slotsCount && currState[i] == 2 ) )//this is activated slot or "upgrade all" if ( slot.getNum() ==i || ( slot.getNum() == slotsCount && currState[i] == 2 ) )//this is activated slot or "upgrade all"
{ {
UpgradeInfo info; UpgradeInfo info;
LOCPLINT->cb->getUpgradeInfo(hero, i, info); LOCPLINT->cb->getUpgradeInfo(hero, SlotID(i), info);
LOCPLINT->cb->upgradeCreature(hero, i, info.newID[0]); LOCPLINT->cb->upgradeCreature(hero, SlotID(i), info.newID[0]);
} }
break; 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 if ( !hero->getCreature(slot) )//we dont have creature here
return ""; return "";
@ -5684,10 +5685,10 @@ std::string CHillFortWindow::getTextForSlot(int slot)
return str; return str;
} }
int CHillFortWindow::getState(int slot) int CHillFortWindow::getState(SlotID slot)
{ {
TResources myRes = LOCPLINT->cb->getResourceAmount(); 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? bool allUpgraded = true;//All creatures are upgraded?
for (int i=0; i<slotsCount; i++) for (int i=0; i<slotsCount; i++)

View File

@ -312,7 +312,7 @@ class CGarrisonInt;
/// A single garrison slot which holds one creature of a specific amount /// A single garrison slot which holds one creature of a specific amount
class CGarrisonSlot : public CIntObject class CGarrisonSlot : public CIntObject
{ {
int ID; //for identification SlotID ID; //for identification
CGarrisonInt *owner; CGarrisonInt *owner;
const CStackInstance *myStack; //NULL if slot is empty const CStackInstance *myStack; //NULL if slot is empty
const CCreature *creature; const CCreature *creature;
@ -330,7 +330,7 @@ public:
void clickRight(tribool down, bool previousState); void clickRight(tribool down, bool previousState);
void clickLeft(tribool down, bool previousState); void clickLeft(tribool down, bool previousState);
void update(); void update();
CGarrisonSlot(CGarrisonInt *Owner, int x, int y, int IID, int Upg=0, const CStackInstance * Creature=NULL); CGarrisonSlot(CGarrisonInt *Owner, int x, int y, SlotID IID, int Upg=0, const CStackInstance * Creature=NULL);
friend class CGarrisonInt; friend class CGarrisonInt;
}; };
@ -352,8 +352,8 @@ public:
Point garOffset; //offset between garrisons (not used if only one hero) Point garOffset; //offset between garrisons (not used if only one hero)
std::vector<CAdventureMapButton *> splitButtons; //may be empty if no buttons std::vector<CAdventureMapButton *> splitButtons; //may be empty if no buttons
int p2, //TODO: comment me SlotID p2; //TODO: comment me
shiftPos;//1st slot of the second row, set shiftPoint for effect int shiftPos;//1st slot of the second row, set shiftPoint for effect
bool pb, bool pb,
smallIcons, //true - 32x32 imgs, false - 58x64 smallIcons, //true - 32x32 imgs, false - 58x64
removableUnits,//player can remove units from up removableUnits,//player can remove units from up
@ -1172,10 +1172,10 @@ public:
CHillFortWindow(const CGHeroInstance *visitor, const CGObjectInstance *object); //c-tor CHillFortWindow(const CGHeroInstance *visitor, const CGObjectInstance *object); //c-tor
void showAll (SDL_Surface *to); void showAll (SDL_Surface *to);
std::string getDefForSlot(int slot);//return def name for this slot std::string getDefForSlot(SlotID slot);//return def name for this slot
std::string getTextForSlot(int slot);//return hover text for this slot std::string getTextForSlot(SlotID slot);//return hover text for this slot
void makeDeal(int slot);//-1 for upgrading all creatures void makeDeal(SlotID slot);//-1 for upgrading all creatures
int getState(int slot); //-1 = no creature 0=can't upgrade, 1=upgraded, 2=can upgrade int getState(SlotID slot); //-1 = no creature 0=can't upgrade, 1=upgraded, 2=can upgrade
void updateGarrisons();//update buttons after garrison changes void updateGarrisons();//update buttons after garrison changes
}; };

View File

@ -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 stackID = getIdForNewStack();
int owner = attackerOwned ? sides[0] : sides[1]; int owner = attackerOwned ? sides[0] : sides[1];
@ -151,7 +151,7 @@ CStack * BattleInfo::generateNewStack(const CStackInstance &base, bool attackerO
return ret; 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 stackID = getIdForNewStack();
int owner = attackerOwned ? sides[0] : sides[1]; 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) auto handleWarMachine= [&](int side, ArtifactPosition artslot, CreatureID cretype, BattleHex hex)
{ {
if(heroes[side] && heroes[side]->getArt(artslot)) 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); 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) 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]); creatureBank ? commanderBank[i] : commanderField[i]);
stacks.push_back(stack); 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) if (curB->siege == CGTownInstance::CITADEL || curB->siege == CGTownInstance::CASTLE)
{ {
// keep tower // 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); stacks.push_back(stack);
if (curB->siege == CGTownInstance::CASTLE) if (curB->siege == CGTownInstance::CASTLE)
{ {
// lower tower + upper tower // 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); 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); stacks.push_back(stack);
} }
@ -842,7 +842,7 @@ BattleInfo::BattleInfo()
setNodeType(BATTLE); 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), : base(Base), ID(I), owner(O), slot(S), attackerOwned(AO),
counterAttacks(1) counterAttacks(1)
{ {
@ -856,7 +856,7 @@ CStack::CStack()
init(); init();
setNodeType(STACK_BATTLE); 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) : base(NULL), ID(I), owner(O), slot(S), attackerOwned(AO), counterAttacks(1)
{ {
type = stack->type; type = stack->type;
@ -871,8 +871,8 @@ void CStack::init()
ID = -1; ID = -1;
count = baseAmount = -1; count = baseAmount = -1;
firstHPleft = -1; firstHPleft = -1;
owner = 255; owner = GameConstants::NEUTRAL_PLAYER;
slot = 255; slot = SlotID(255);
attackerOwned = false; attackerOwned = false;
position = BattleHex(); position = BattleHex();
counterAttacks = -1; counterAttacks = -1;
@ -1117,7 +1117,7 @@ std::string CStack::nodeName() const
else else
oss << "[UNDEFINED TYPE]"; oss << "[UNDEFINED TYPE]";
oss << " from slot " << (int)slot; oss << " from slot " << slot;
if(base && base->armyObj) if(base && base->armyObj)
oss << " of armyobj=" << base->armyObj->id.getNum(); oss << " of armyobj=" << base->armyObj->id.getNum();
return oss.str(); return oss.str();

View File

@ -106,8 +106,8 @@ struct DLL_LINKAGE BattleInfo : public CBonusSystemNode, public CBattleInfoCallb
//std::set<CStack*> getAttackedCreatures(const CStack* attacker, BattleHex destinationTile, BattleHex attackerPos = BattleHex::INVALID); //calculates range of multi-hex attacks //std::set<CStack*> getAttackedCreatures(const CStack* attacker, BattleHex destinationTile, BattleHex attackerPos = BattleHex::INVALID); //calculates range of multi-hex attacks
//std::set<BattleHex> getAttackedHexes(const CStack* attacker, BattleHex destinationTile, BattleHex attackerPos = BattleHex::INVALID); //calculates range of multi-hex attacks //std::set<BattleHex> 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); 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 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, int 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 int getIdForNewStack() const; //suggest a currently unused ID that'd suitable for generating a new stack
//std::pair<const CStack *, BattleHex> 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) //std::pair<const CStack *, BattleHex> 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 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 baseAmount;
ui32 firstHPleft; //HP of first creature in stack ui32 firstHPleft; //HP of first creature in stack
TPlayerColor owner; //owner - player colour (255 for neutrals) 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) 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 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) 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 //overrides
const CCreature* getCreature() const {return type;} const CCreature* getCreature() const {return type;}
CStack(const CStackInstance *base, int O, int I, bool AO, int S); //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, int S = 255); //c-tor CStack(const CStackBasicDescriptor *stack, int O, int I, bool AO, SlotID S = SlotID(255)); //c-tor
CStack(); //c-tor CStack(); //c-tor
~CStack(); ~CStack();
std::string nodeName() const OVERRIDE; std::string nodeName() const OVERRIDE;
@ -205,7 +205,7 @@ public:
& shots & casts & count; & shots & casts & count;
const CArmedInstance *army = (base ? base->armyObj : NULL); 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) if(h.saving)
{ {
@ -214,13 +214,13 @@ public:
else else
{ {
h & army & slot; h & army & slot;
if (slot == -2) //TODO if (slot == SlotID::COMMANDER_SLOT_PLACEHOLDER) //TODO
{ {
auto hero = dynamic_cast<const CGHeroInstance *>(army); auto hero = dynamic_cast<const CGHeroInstance *>(army);
assert (hero); assert (hero);
base = hero->commander; base = hero->commander;
} }
else if(!army || slot == -1 || !army->hasStackAtSlot(slot)) else if(!army || slot == SlotID() || !army->hasStackAtSlot(slot))
{ {
base = NULL; base = NULL;
tlog3 << type->nameSing << " doesn't have a base stack!\n"; tlog3 << type->nameSing << " doesn't have a base stack!\n";

View File

@ -114,7 +114,7 @@ CCreature::CCreature()
doubleWide = false; doubleWide = false;
setNodeType(CBonusSystemNode::CREATURE); 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); Bonus *added = new Bonus(Bonus::PERMANENT, type, Bonus::CREATURE_ABILITY, val, idNumber, subtype, Bonus::BASE_NUMBER);
addNewBonus(added); addNewBonus(added);
@ -149,7 +149,7 @@ static void AddAbility(CCreature *cre, const JsonVector &ability_vec)
Bonus *nsf = new Bonus(); Bonus *nsf = new Bonus();
std::string type = ability_vec[0].String(); std::string type = ability_vec[0].String();
std::map<std::string, int>::const_iterator it = bonusNameMap.find(type); std::map<std::string, Bonus::BonusType>::const_iterator it = bonusNameMap.find(type);
if (it == bonusNameMap.end()) { if (it == bonusNameMap.end()) {
if (type == "DOUBLE_WIDE") if (type == "DOUBLE_WIDE")
@ -185,7 +185,7 @@ static void RemoveAbility(CCreature *cre, const JsonNode &ability)
{ {
std::string type = ability.String(); std::string type = ability.String();
std::map<std::string, int>::const_iterator it = bonusNameMap.find(type); std::map<std::string, Bonus::BonusType>::const_iterator it = bonusNameMap.find(type);
if (it == bonusNameMap.end()) { if (it == bonusNameMap.end()) {
if (type == "DOUBLE_WIDE") if (type == "DOUBLE_WIDE")
@ -348,7 +348,7 @@ void CCreatureHandler::loadCreatures()
BOOST_FOREACH(const JsonNode &bonus, config2["bonuses"].Vector()) BOOST_FOREACH(const JsonNode &bonus, config2["bonuses"].Vector())
{ {
std::map<std::string,int>::const_iterator it_map; std::map<std::string,Bonus::BonusType>::const_iterator it_map;
std::string bonusID = bonus["id"].String(); std::string bonusID = bonus["id"].String();
it_map = bonusNameMap.find(bonusID); it_map = bonusNameMap.find(bonusID);
@ -359,7 +359,7 @@ void CCreatureHandler::loadCreatures()
} }
//handle magic resistance secondary skill premy, potentialy may be buggy //handle magic resistance secondary skill premy, potentialy may be buggy
//std::map<TBonusType, std::pair<std::string, std::string> >::iterator it = stackBonuses.find(Bonus::MAGIC_RESISTANCE); //std::map<Bonus::BonusType, std::pair<std::string, std::string> >::iterator it = stackBonuses.find(Bonus::MAGIC_RESISTANCE);
//stackBonuses[Bonus::SECONDARY_SKILL_PREMY] = std::pair<std::string, std::string>(it->second.first, it->second.second); //stackBonuses[Bonus::SECONDARY_SKILL_PREMY] = std::pair<std::string, std::string>(it->second.first, it->second.second);
if (VLC->modh->modules.STACK_EXP) //reading default stack experience bonuses if (VLC->modh->modules.STACK_EXP) //reading default stack experience bonuses

View File

@ -41,7 +41,7 @@ public:
TFaction faction; //-1 = neutral TFaction faction; //-1 = neutral
ui8 level; // 0 - unknown ui8 level; // 0 - unknown
bool doubleWide; 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 ///animation info
double timeBetweenFidgets, walkAnimationTime, attackAnimationTime, flightAnimationDistance; double timeBetweenFidgets, walkAnimationTime, attackAnimationTime, flightAnimationDistance;
@ -49,7 +49,7 @@ public:
double missleFrameAngles[12]; double missleFrameAngles[12];
int troopCountLocationOffset, attackClimaxFrame; int troopCountLocationOffset, attackClimaxFrame;
std::string projectile; 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 ///end of anim info
//sound info //sound info
@ -86,7 +86,7 @@ public:
bool valid() const; 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; std::string nodeName() const override;
//void getParents(TCNodes &out, const CBonusSystemNode *root /*= NULL*/) const; //void getParents(TCNodes &out, const CBonusSystemNode *root /*= NULL*/) const;
@ -131,12 +131,12 @@ private:
void loadCreatureJson(CCreature * creature, const JsonNode & config); void loadCreatureJson(CCreature * creature, const JsonNode & config);
public: public:
std::set<int> notUsedMonsters; std::set<CreatureID> notUsedMonsters;
std::set<CreatureID> doubledCreatures; //they get double week std::set<CreatureID> doubledCreatures; //they get double week
std::vector<ConstTransitivePtr<CCreature> > creatures; //creature ID -> creature info std::vector<ConstTransitivePtr<CCreature> > creatures; //creature ID -> creature info
//stack exp //stack exp
std::map<TBonusType, std::pair<std::string, std::string> > stackBonuses; // bonus => name, description std::map<Bonus::BonusType, std::pair<std::string, std::string> > stackBonuses; // bonus => name, description
std::vector<std::vector<ui32> > expRanks; // stack experience needed for certain rank, index 0 for other tiers (?) std::vector<std::vector<ui32> > expRanks; // stack experience needed for certain rank, index 0 for other tiers (?)
std::vector<ui32> maxExpPerBattle; //%, tiers same as above std::vector<ui32> maxExpPerBattle; //%, tiers same as above
si8 expAfterUpgrade;//multiplier in % si8 expAfterUpgrade;//multiplier in %

View File

@ -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); TSlots::const_iterator i = stacks.find(slot);
if (i != stacks.end()) if (i != stacks.end())
@ -30,7 +30,7 @@ const CStackInstance &CCreatureSet::operator[](TSlot slot) const
throw std::runtime_error("That slot is empty!"); 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); TSlots::const_iterator i = stacks.find(slot);
if (i != stacks.end()) if (i != stacks.end())
@ -39,9 +39,9 @@ const CCreature* CCreatureSet::getCreature(TSlot slot) const
return NULL; 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; tlog1 << "Cannot set slot " << slot << std::endl;
return false; return false;
@ -60,12 +60,12 @@ bool CCreatureSet::setCreature(TSlot slot, CreatureID type, TQuantity quantity)
return true; 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); 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()); assert(c->valid());
for(TSlots::const_iterator i=stacks.begin(); i!=stacks.end(); ++i) 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 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<slotsAmount; i++) for(ui32 i=0; i<slotsAmount; i++)
{ {
if(stacks.find(i) == stacks.end()) if(!vstd::contains(stacks, SlotID(i)))
{ {
return i; //return first free slot return SlotID(i); //return first free slot
} }
} }
return -1; //no slot available return SlotID(); //no slot available
} }
TSlot CCreatureSet::getFreeSlot(ui32 slotsAmount/*=ARMY_SIZE*/) const int CCreatureSet::getStackCount(SlotID slot) const
{
for (ui32 i = 0; i < slotsAmount; i++)
{
if(stacks.find(i) == stacks.end())
{
return i; //return first free slot
}
}
return -1; //no slot available
}
int CCreatureSet::getStackCount(TSlot slot) const
{ {
TSlots::const_iterator i = stacks.find(slot); TSlots::const_iterator i = stacks.find(slot);
if (i != stacks.end()) if (i != stacks.end())
@ -107,7 +100,7 @@ int CCreatureSet::getStackCount(TSlot slot) const
return 0; //TODO? consider issuing a warning return 0; //TODO? consider issuing a warning
} }
TExpType CCreatureSet::getStackExperience(TSlot slot) const TExpType CCreatureSet::getStackExperience(SlotID slot) const
{ {
TSlots::const_iterator i = stacks.find(slot); TSlots::const_iterator i = stacks.find(slot);
if (i != stacks.end()) if (i != stacks.end())
@ -117,10 +110,10 @@ TExpType CCreatureSet::getStackExperience(TSlot slot) const
} }
bool CCreatureSet::mergableStacks(std::pair<TSlot, TSlot> &out, TSlot preferable /*= -1*/) const /*looks for two same stacks, returns slot positions */ bool CCreatureSet::mergableStacks(std::pair<SlotID, SlotID> &out, SlotID preferable /*= -1*/) const /*looks for two same stacks, returns slot positions */
{ {
//try to match creature to our preferred stack //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; const CCreature *cr = stacks.find(preferable)->second->type;
for(TSlots::const_iterator j=stacks.begin(); j!=stacks.end(); ++j) 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]; 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)); assert(stack->valid(true));
@ -208,7 +201,7 @@ bool CCreatureSet::validTypes(bool allowUnrandomized /*= false*/) const
return true; return true;
} }
bool CCreatureSet::slotEmpty(TSlot slot) const bool CCreatureSet::slotEmpty(SlotID slot) const
{ {
return !hasStackAtSlot(slot); return !hasStackAtSlot(slot);
} }
@ -226,11 +219,11 @@ ui64 CCreatureSet::getArmyStrength() const
return ret; return ret;
} }
ui64 CCreatureSet::getPower (TSlot slot) const ui64 CCreatureSet::getPower (SlotID slot) const
{ {
return getStack(slot).getPower(); return getStack(slot).getPower();
} }
std::string CCreatureSet::getRoughAmount (TSlot slot) const std::string CCreatureSet::getRoughAmount (SlotID slot) const
{ {
int quantity = CCreature::getQuantityID(getStackCount(slot)); int quantity = CCreature::getQuantityID(getStackCount(slot));
if (quantity) if (quantity)
@ -248,7 +241,7 @@ void CCreatureSet::setFormation(bool tight)
formation = tight; formation = tight;
} }
void CCreatureSet::setStackCount(TSlot slot, TQuantity count) void CCreatureSet::setStackCount(SlotID slot, TQuantity count)
{ {
assert(hasStackAtSlot(slot)); assert(hasStackAtSlot(slot));
assert(stacks[slot]->count + count > 0); 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++) for(TSlots::const_iterator i = stacks.begin(); i != stacks.end(); i++)
i->second->giveStackExp(exp); i->second->giveStackExp(exp);
} }
void CCreatureSet::setStackExp(TSlot slot, TExpType exp) void CCreatureSet::setStackExp(SlotID slot, TExpType exp)
{ {
assert(hasStackAtSlot(slot)); assert(hasStackAtSlot(slot));
stacks[slot]->experience = exp; 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)); assert(hasStackAtSlot(slot));
return *getStackPtr(slot); return *getStackPtr(slot);
} }
const CStackInstance* CCreatureSet::getStackPtr(TSlot slot) const const CStackInstance* CCreatureSet::getStackPtr(SlotID slot) const
{ {
if(hasStackAtSlot(slot)) if(hasStackAtSlot(slot))
return stacks.find(slot)->second; return stacks.find(slot)->second;
else return NULL; else return NULL;
} }
void CCreatureSet::eraseStack(TSlot slot) void CCreatureSet::eraseStack(SlotID slot)
{ {
assert(hasStackAtSlot(slot)); assert(hasStackAtSlot(slot));
CStackInstance *toErase = detachStack(slot); CStackInstance *toErase = detachStack(slot);
@ -309,20 +302,20 @@ bool CCreatureSet::contains(const CStackInstance *stack) const
return false; return false;
} }
TSlot CCreatureSet::findStack(const CStackInstance *stack) const SlotID CCreatureSet::findStack(const CStackInstance *stack) const
{ {
auto h = dynamic_cast<const CGHeroInstance *>(this); auto h = dynamic_cast<const CGHeroInstance *>(this);
if (h && h->commander == stack) if (h && h->commander == stack)
return -2; return SlotID::COMMANDER_SLOT_PLACEHOLDER;
if(!stack) if(!stack)
return -1; return SlotID();
for(TSlots::const_iterator i = stacks.begin(); i != stacks.end(); ++i) for(TSlots::const_iterator i = stacks.begin(); i != stacks.end(); ++i)
if(i->second == stack) if(i->second == stack)
return i->first; return i->first;
return -1; return SlotID();
} }
CArmedInstance * CCreatureSet::castToArmyObj() CArmedInstance * CCreatureSet::castToArmyObj()
@ -330,16 +323,16 @@ CArmedInstance * CCreatureSet::castToArmyObj()
return dynamic_cast<CArmedInstance *>(this); return dynamic_cast<CArmedInstance *>(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)); assert(!hasStackAtSlot(slot));
stacks[slot] = stack; stacks[slot] = stack;
stack->setArmyObj(castToArmyObj()); stack->setArmyObj(castToArmyObj());
armyChanged(); armyChanged();
} }
void CCreatureSet::joinStack(TSlot slot, CStackInstance * stack) void CCreatureSet::joinStack(SlotID slot, CStackInstance * stack)
{ {
const CCreature *c = getCreature(slot); const CCreature *c = getCreature(slot);
assert(c == stack->type); assert(c == stack->type);
@ -350,7 +343,7 @@ void CCreatureSet::joinStack(TSlot slot, CStackInstance * stack)
vstd::clear_pointer(stack); vstd::clear_pointer(stack);
} }
void CCreatureSet::changeStackCount(TSlot slot, TQuantity toAdd) void CCreatureSet::changeStackCount(SlotID slot, TQuantity toAdd)
{ {
setStackCount(slot, getStackCount(slot) + 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)); assert(hasStackAtSlot(slot));
CStackInstance *ret = stacks[slot]; CStackInstance *ret = stacks[slot];
@ -401,7 +394,7 @@ CStackInstance * CCreatureSet::detachStack(TSlot slot)
return ret; return ret;
} }
void CCreatureSet::setStackType(TSlot slot, const CCreature *type) void CCreatureSet::setStackType(SlotID slot, const CCreature *type)
{ {
assert(hasStackAtSlot(slot)); assert(hasStackAtSlot(slot));
CStackInstance *s = stacks[slot]; CStackInstance *s = stacks[slot];
@ -417,8 +410,8 @@ bool CCreatureSet::canBeMergedWith(const CCreatureSet &cs, bool allowMergingStac
std::set<const CCreature*> cresToAdd; std::set<const CCreature*> cresToAdd;
for(TSlots::const_iterator i = cs.stacks.begin(); i != cs.stacks.end(); i++) for(TSlots::const_iterator i = cs.stacks.begin(); i != cs.stacks.end(); i++)
{ {
TSlot dest = getSlotFor(i->second->type); SlotID dest = getSlotFor(i->second->type);
if(dest < 0 || hasStackAtSlot(dest)) if(!dest.validSlot() || hasStackAtSlot(dest))
cresToAdd.insert(i->second->type); cresToAdd.insert(i->second->type);
} }
return cresToAdd.size() <= freeSlots; 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 //get types of creatures that need their own slot
for(TSlots::const_iterator i = cs.stacks.begin(); i != cs.stacks.end(); i++) for(TSlots::const_iterator i = cs.stacks.begin(); i != cs.stacks.end(); i++)
cres.addToSlot(i->first, i->second->type->idNumber, 1, true); 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++) 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 cres.addToSlot(j, i->second->type->idNumber, 1, true); //merge if possible
else else
return false; //no place found 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); 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::string CStackInstance::bonusToString(Bonus *bonus, bool description) const
{ {
std::map<TBonusType, std::pair<std::string, std::string> >::iterator it = VLC->creh->stackBonuses.find(bonus->type); std::map<Bonus::BonusType, std::pair<std::string, std::string> >::iterator it = VLC->creh->stackBonuses.find(bonus->type);
if (it != VLC->creh->stackBonuses.end()) if (it != VLC->creh->stackBonuses.end())
{ {
std::string text; std::string text;
@ -1089,7 +1082,7 @@ CSimpleArmy::operator bool() const
return army.size(); 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)); assert(!vstd::contains(army, slot));
army[slot] = CStackBasicDescriptor(cre, count); army[slot] = CStackBasicDescriptor(cre, count);

View File

@ -116,14 +116,14 @@ public:
DLL_LINKAGE std::ostream & operator<<(std::ostream & str, const CStackInstance & sth); DLL_LINKAGE std::ostream & operator<<(std::ostream & str, const CStackInstance & sth);
typedef std::map<TSlot, CStackInstance*> TSlots; typedef std::map<SlotID, CStackInstance*> TSlots;
typedef std::map<TSlot, CStackBasicDescriptor> TSimpleSlots; typedef std::map<SlotID, CStackBasicDescriptor> TSimpleSlots;
class IArmyDescriptor class IArmyDescriptor
{ {
public: public:
virtual void clear() = 0; 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 //simplified version of CCreatureSet
@ -132,7 +132,7 @@ class DLL_LINKAGE CSimpleArmy : public IArmyDescriptor
public: public:
TSimpleSlots army; TSimpleSlots army;
void clear() OVERRIDE; void clear() OVERRIDE;
bool setCreature(TSlot slot, CreatureID cre, TQuantity count) OVERRIDE; bool setCreature(SlotID slot, CreatureID cre, TQuantity count) OVERRIDE;
operator bool() const; operator bool() const;
template <typename Handler> void serialize(Handler &h, const int version) template <typename Handler> void serialize(Handler &h, const int version)
@ -153,49 +153,49 @@ public:
virtual ~CCreatureSet(); virtual ~CCreatureSet();
virtual void armyChanged(); virtual void armyChanged();
const CStackInstance &operator[](TSlot slot) const; const CStackInstance &operator[](SlotID slot) const;
const TSlots &Slots() const {return stacks;} 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(SlotID 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, CStackInstance *stack, bool allowMerging = true); //Adds stack to slot. Slot must be empty or with same type creature
void clear() OVERRIDE; void clear() OVERRIDE;
void setFormation(bool tight); void setFormation(bool tight);
CArmedInstance *castToArmyObj(); CArmedInstance *castToArmyObj();
//basic operations //basic operations
void putStack(TSlot slot, CStackInstance *stack); //adds new stack to the army, slot must be empty void putStack(SlotID slot, CStackInstance *stack); //adds new stack to the army, slot must be empty
void setStackCount(TSlot slot, TQuantity count); //stack must exist! void setStackCount(SlotID 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) 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(TSlot slot, const CCreature *type); void setStackType(SlotID slot, const CCreature *type);
void giveStackExp(TExpType exp); void giveStackExp(TExpType exp);
void setStackExp(TSlot slot, TExpType exp); void setStackExp(SlotID slot, TExpType exp);
//derivative //derivative
void eraseStack(TSlot slot); //slot must be occupied void eraseStack(SlotID slot); //slot must be occupied
void joinStack(TSlot slot, CStackInstance * stack); //adds new stack to the existing stack of the same type void joinStack(SlotID slot, CStackInstance * stack); //adds new stack to the existing stack of the same type
void changeStackCount(TSlot slot, TQuantity toAdd); //stack must exist! void changeStackCount(SlotID 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 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. 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& getStack(SlotID slot) const; //stack must exist
const CStackInstance* getStackPtr(TSlot slot) const; //if stack doesn't exist, returns NULL const CStackInstance* getStackPtr(SlotID slot) const; //if stack doesn't exist, returns NULL
const CCreature* getCreature(TSlot slot) const; //workaround of map issue; const CCreature* getCreature(SlotID slot) const; //workaround of map issue;
int getStackCount (TSlot slot) const; int getStackCount (SlotID slot) const;
TExpType getStackExperience(TSlot slot) const; TExpType getStackExperience(SlotID slot) const;
TSlot findStack(const CStackInstance *stack) const; //-1 if none SlotID findStack(const CStackInstance *stack) const; //-1 if none
TSlot getSlotFor(CreatureID creature, ui32 slotsAmount = GameConstants::ARMY_SIZE) const; //returns -1 if no slot available SlotID 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 SlotID getSlotFor(const CCreature *c, ui32 slotsAmount = GameConstants::ARMY_SIZE) const; //returns -1 if no slot available
TSlot getFreeSlot(ui32 slotsAmount = GameConstants::ARMY_SIZE) const; SlotID getFreeSlot(ui32 slotsAmount = GameConstants::ARMY_SIZE) const;
bool mergableStacks(std::pair<TSlot, TSlot> &out, TSlot preferable = -1) const; //looks for two same stacks, returns slot positions; bool mergableStacks(std::pair<SlotID, SlotID> &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 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; int stacksCount() const;
virtual bool needsLastStack() const; //true if last stack cannot be taken virtual bool needsLastStack() const; //true if last stack cannot be taken
ui64 getArmyStrength() const; //sum of AI values of creatures ui64 getArmyStrength() const; //sum of AI values of creatures
ui64 getPower (TSlot slot) const; //value of specific stack ui64 getPower (SlotID slot) const; //value of specific stack
std::string getRoughAmount (TSlot slot) const; //rough size of specific stack std::string getRoughAmount (SlotID slot) const; //rough size of specific stack
bool hasStackAtSlot(TSlot slot) const; bool hasStackAtSlot(SlotID slot) const;
bool contains(const CStackInstance *stack) const; bool contains(const CStackInstance *stack) const;
bool canBeMergedWith(const CCreatureSet &cs, bool allowMergingStacks = true) const; bool canBeMergedWith(const CCreatureSet &cs, bool allowMergingStacks = true) const;

View File

@ -806,9 +806,9 @@ void CGameState::init(StartInfo * si)
{ {
for(int i=0; i<GameConstants::ARMY_SIZE; i++) for(int i=0; i<GameConstants::ARMY_SIZE; i++)
{ {
if(hero->slotEmpty(i)) if(hero->slotEmpty(SlotID(i)))
{ {
hero->addToSlot(i, CreatureID(curBonus->info2), curBonus->info3); hero->addToSlot(SlotID(i), CreatureID(curBonus->info2), curBonus->info3);
break; break;
} }
} }
@ -1714,8 +1714,8 @@ void CGameState::initDuel()
{ {
CreatureID cre = dp.sides[i].stacks[j].type; CreatureID cre = dp.sides[i].stacks[j].type;
TQuantity count = dp.sides[i].stacks[j].count; TQuantity count = dp.sides[i].stacks[j].count;
if(count || obj->hasStackAtSlot(j)) if(count || obj->hasStackAtSlot(SlotID(j)))
obj->setCreature(j, cre, count); obj->setCreature(SlotID(j), cre, count);
} }
BOOST_FOREACH(const DuelParameters::CusomCreature &cc, dp.creatures) BOOST_FOREACH(const DuelParameters::CusomCreature &cc, dp.creatures)

View File

@ -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) //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<TSlot, CStackBasicDescriptor> struct ArmyDescriptor : public std::map<SlotID, CStackBasicDescriptor>
{ {
bool isDetailed; bool isDetailed;
DLL_LINKAGE ArmyDescriptor(const CArmedInstance *army, bool detailed); //not detailed -> quantity ids as count DLL_LINKAGE ArmyDescriptor(const CArmedInstance *army, bool detailed); //not detailed -> quantity ids as count

View File

@ -39,14 +39,14 @@ using namespace boost::assign;
#define USE_COVERAGE_MAP 0 #define USE_COVERAGE_MAP 0
std::map<int,std::map<int, std::vector<ObjectInstanceID> > > CGTeleport::objs; std::map<Obj, std::map<int, std::vector<ObjectInstanceID> > > CGTeleport::objs;
std::vector<std::pair<ObjectInstanceID, ObjectInstanceID> > CGTeleport::gates; std::vector<std::pair<ObjectInstanceID, ObjectInstanceID> > CGTeleport::gates;
IGameCallback * IObjectInterface::cb = NULL; IGameCallback * IObjectInterface::cb = NULL;
extern boost::rand48 ran; extern boost::rand48 ran;
std::map <TPlayerColor, std::set <ui8> > CGKeys::playerKeyMap; std::map <TPlayerColor, std::set <ui8> > CGKeys::playerKeyMap;
std::map <si32, std::vector<ObjectInstanceID> > CGMagi::eyelist; std::map <si32, std::vector<ObjectInstanceID> > CGMagi::eyelist;
ui8 CGObelisk::obeliskCount; //how many obelisks are on map ui8 CGObelisk::obeliskCount; //how many obelisks are on map
std::map<ui8, ui8> CGObelisk::visited; //map: team_id => how many obelisks has been visited std::map<TTeamID, ui8> CGObelisk::visited; //map: team_id => how many obelisks has been visited
std::vector<const CArtifact *> CGTownInstance::merchantArtifacts; std::vector<const CArtifact *> CGTownInstance::merchantArtifacts;
std::vector<int> CGTownInstance::universitySkills; std::vector<int> 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; tlog3 << "Hero " << name << " already has artifact at " << slot << ", omitting giving " << aid << std::endl;
} }
else else
dst->setCreature(stackNo-warMachinesGiven, stack.creature, count); dst->setCreature(SlotID(stackNo-warMachinesGiven), stack.creature, count);
} }
} }
void CGHeroInstance::initHeroDefInfo() void CGHeroInstance::initHeroDefInfo()
@ -1283,7 +1283,7 @@ void CGHeroInstance::updateSkill(SecondarySkill which, int val)
void CGHeroInstance::setPropertyDer( ui8 what, ui32 val ) void CGHeroInstance::setPropertyDer( ui8 what, ui32 val )
{ {
if(what == ObjProperty::PRIMARY_STACK_COUNT) if(what == ObjProperty::PRIMARY_STACK_COUNT)
setStackCount(0, val); setStackCount(SlotID(0), val);
} }
double CGHeroInstance::getHeroStrength() const double CGHeroInstance::getHeroStrength() const
@ -1391,8 +1391,8 @@ CStackBasicDescriptor CGHeroInstance::calculateNecromancy (const BattleResult &b
} }
// Make room for new units. // Make room for new units.
int slot = getSlotFor(raisedUnitType->idNumber); SlotID slot = getSlotFor(raisedUnitType->idNumber);
if (slot == -1) if (slot == SlotID())
{ {
// If there's no room for unit, try it's upgraded version 2/3rds the size. // If there's no room for unit, try it's upgraded version 2/3rds the size.
raisedUnitType = VLC->creh->creatures[*raisedUnitType->upgrades.begin()]; raisedUnitType = VLC->creh->creatures[*raisedUnitType->upgrades.begin()];
@ -1602,7 +1602,7 @@ void CGDwelling::initObj()
else else
hoverName = VLC->generaltexth->creGens[subID]; hoverName = VLC->generaltexth->creGens[subID];
if(crs->level > 4) 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) if (getOwner() != GameConstants::NEUTRAL_PLAYER)
cb->gameState()->players[getOwner()].dwellings.push_back (this); cb->gameState()->players[getOwner()].dwellings.push_back (this);
} }
@ -1617,8 +1617,8 @@ void CGDwelling::initObj()
creatures[2].second.push_back(CreatureID::GOLD_GOLEM); creatures[2].second.push_back(CreatureID::GOLD_GOLEM);
creatures[3].second.push_back(CreatureID::DIAMOND_GOLEM); creatures[3].second.push_back(CreatureID::DIAMOND_GOLEM);
//guards //guards
putStack(0, new CStackInstance(CreatureID::GOLD_GOLEM, 9)); putStack(SlotID(0), new CStackInstance(CreatureID::GOLD_GOLEM, 9));
putStack(1, new CStackInstance(CreatureID::DIAMOND_GOLEM, 6)); putStack(SlotID(1), new CStackInstance(CreatureID::DIAMOND_GOLEM, 6));
} }
else if(subID == 0) // Elemental Conflux else if(subID == 0) // Elemental Conflux
{ {
@ -1627,7 +1627,7 @@ void CGDwelling::initObj()
creatures[2].second.push_back(CreatureID::EARTH_ELEMENTAL); creatures[2].second.push_back(CreatureID::EARTH_ELEMENTAL);
creatures[3].second.push_back(CreatureID::WATER_ELEMENTAL); creatures[3].second.push_back(CreatureID::WATER_ELEMENTAL);
//guards //guards
putStack(0, new CStackInstance(CreatureID::EARTH_ELEMENTAL, 12)); putStack(SlotID(0), new CStackInstance(CreatureID::EARTH_ELEMENTAL, 12));
} }
else else
{ {
@ -1785,8 +1785,8 @@ void CGDwelling::heroAcceptsCreatures( const CGHeroInstance *h, ui32 answer ) co
{ {
if(count) //there are available creatures if(count) //there are available creatures
{ {
int slot = h->getSlotFor(crid); SlotID slot = h->getSlotFor(crid);
if(slot < 0) //no available slot if(!slot.validSlot()) //no available slot
{ {
InfoWindow iw; InfoWindow iw;
iw.player = h->tempOwner; iw.player = h->tempOwner;
@ -2173,7 +2173,7 @@ void CGTownInstance::newTurn() const
if (tempOwner == GameConstants::NEUTRAL_PLAYER) //garrison growth for neutral towns if (tempOwner == GameConstants::NEUTRAL_PLAYER) //garrison growth for neutral towns
{ {
std::vector<ui8> nativeCrits; //slots std::vector<SlotID> nativeCrits; //slots
for (TSlots::const_iterator it = Slots().begin(); it != Slots().end(); it++) for (TSlots::const_iterator it = Slots().begin(); it != Slots().end(); it++)
{ {
if (it->second->type->faction == subID) //native if (it->second->type->faction == subID) //native
@ -2183,7 +2183,7 @@ void CGTownInstance::newTurn() const
} }
if (nativeCrits.size()) if (nativeCrits.size())
{ {
TSlot pos = nativeCrits[rand() % nativeCrits.size()]; SlotID pos = nativeCrits[rand() % nativeCrits.size()];
StackLocation sl(this, pos); StackLocation sl(this, pos);
const CCreature *c = getCreature(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); int i = rand() % std::min (GameConstants::ARMY_SIZE, cb->getDate(Date::MONTH)<<1);
CreatureID c = town->creatures[i][0]; CreatureID c = town->creatures[i][0];
TSlot n = -1; SlotID n;
TQuantity count = creatureGrowth(i); TQuantity count = creatureGrowth(i);
if (!count) // no dwelling if (!count) // no dwelling
@ -2208,7 +2208,7 @@ void CGTownInstance::newTurn() const
{//no lower tiers or above current month {//no lower tiers or above current month
if ((n = getSlotFor(c))>=0) if ((n = getSlotFor(c)).validSlot())
{ {
StackLocation sl(this, n); StackLocation sl(this, n);
if (slotEmpty(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); 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)) if(hasBuilt(building))
{ {
@ -3045,7 +3045,7 @@ void CGCreature::onHeroVisit( const CGHeroInstance * h ) const
BlockingDialog ynd(true,false); BlockingDialog ynd(true,false);
ynd.player = h->tempOwner; ynd.player = h->tempOwner;
std::string tmp = VLC->generaltexth->advobtxt[90]; std::string tmp = VLC->generaltexth->advobtxt[90];
boost::algorithm::replace_first(tmp,"%d",boost::lexical_cast<std::string>(getStackCount(0))); boost::algorithm::replace_first(tmp,"%d",boost::lexical_cast<std::string>(getStackCount(SlotID(0))));
boost::algorithm::replace_first(tmp,"%d",boost::lexical_cast<std::string>(action)); boost::algorithm::replace_first(tmp,"%d",boost::lexical_cast<std::string>(action));
boost::algorithm::replace_first(tmp,"%s",VLC->creh->creatures[subID]->namePl); boost::algorithm::replace_first(tmp,"%s",VLC->creh->creatures[subID]->namePl);
ynd.text << tmp; 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 //first stack has to be at slot 0 -> if original one got killed, move there first remaining stack
if(!hasStackAtSlot(0)) if(!hasStackAtSlot(SlotID(0)))
cb->moveStack(StackLocation(this, stacks.begin()->first), StackLocation(this, 0), stacks.begin()->second->count); cb->moveStack(StackLocation(this, stacks.begin()->first), StackLocation(this, SlotID(0)), stacks.begin()->second->count);
while (stacks.size() > 1) //hopefully that's enough 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) // 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 = stacks.end();
i--; 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 if (slot == i->first) //no reason to move stack to its own slot
break; break;
else else
@ -3132,8 +3132,8 @@ void CGCreature::initObj()
break; break;
} }
stacks[0]->setType(CreatureID(subID)); stacks[SlotID(0)]->setType(CreatureID(subID));
TQuantity &amount = stacks[0]->count; TQuantity &amount = stacks[SlotID(0)]->count;
CCreature &c = *VLC->creh->creatures[subID]; CCreature &c = *VLC->creh->creatures[subID];
if(!amount) if(!amount)
{ {
@ -3143,7 +3143,7 @@ void CGCreature::initObj()
amount = c.ammMin + (ran() % (c.ammMax - c.ammMin)); amount = c.ammMin + (ran() % (c.ammMax - c.ammMin));
} }
temppower = stacks[0]->count * 1000; temppower = stacks[SlotID(0)]->count * 1000;
} }
void CGCreature::newTurn() const void CGCreature::newTurn() const
{//Works only for stacks of single type of size up to 2 millions {//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) switch (what)
{ {
case ObjProperty::MONSTER_COUNT: case ObjProperty::MONSTER_COUNT:
stacks[0]->count = val; stacks[SlotID(0)]->count = val;
break; break;
case ObjProperty::MONSTER_POWER: case ObjProperty::MONSTER_POWER:
temppower = val; temppower = val;
@ -3233,7 +3233,7 @@ int CGCreature::takenAction(const CGHeroInstance *h, bool allowJoin) const
return 0; //join for free return 0; //join for free
else if(h->getSecSkillLevel(SecondarySkill::DIPLOMACY) * 2 + sympathy + 1 >= character) 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 //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; stacksCount = 3;
} }
int stackSize; int stackSize;
TSlot sourceSlot = stacks.begin()->first; SlotID sourceSlot = stacks.begin()->first;
TSlot destSlot; SlotID destSlot;
for (int stacksLeft = stacksCount; stacksLeft > 1; --stacksLeft) for (int stacksLeft = stacksCount; stacksLeft > 1; --stacksLeft)
{ {
stackSize = stacks.begin()->second->count / stacksLeft; stackSize = stacks.begin()->second->count / stacksLeft;
if (stackSize) if (stackSize)
{ {
if ((destSlot = getFreeSlot()) > -1) if ((destSlot = getFreeSlot()).validSlot())
cb->moveStack(StackLocation(this, sourceSlot), StackLocation(this, destSlot), stackSize); cb->moveStack(StackLocation(this, sourceSlot), StackLocation(this, destSlot), stackSize);
else else
{ {
@ -3348,7 +3348,7 @@ void CGCreature::fight( const CGHeroInstance *h ) const
{ {
if (rand()%100 < 50) //upgrade if (rand()%100 < 50) //upgrade
{ {
TSlot slotId = (stacks.size() / 2); SlotID slotId = SlotID(stacks.size() / 2);
if(ui32 upgradesSize = getStack(slotId).type->upgrades.size()) if(ui32 upgradesSize = getStack(slotId).type->upgrades.size())
{ {
auto it = getStack(slotId).type->upgrades.cbegin(); //pick random in case there are more auto it = getStack(slotId).type->upgrades.cbegin(); //pick random in case there are more
@ -3414,7 +3414,7 @@ void CGMine::initObj()
//set guardians //set guardians
int howManyTroglodytes = 100 + ran()%100; int howManyTroglodytes = 100 + ran()%100;
CStackInstance *troglodytes = new CStackInstance(CreatureID::TROGLODYTES, howManyTroglodytes); CStackInstance *troglodytes = new CStackInstance(CreatureID::TROGLODYTES, howManyTroglodytes);
putStack(0, troglodytes); putStack(SlotID(0), troglodytes);
//after map reading tempOwner placeholds bitmask for allowed resources //after map reading tempOwner placeholds bitmask for allowed resources
std::vector<Res::ERes> possibleResources; std::vector<Res::ERes> possibleResources;
@ -3689,7 +3689,7 @@ void CGTeleport::onHeroVisit( const CGHeroInstance * h ) const
{ {
if (h->Slots().size() > 1 || h->Slots().begin()->second->count > 1) if (h->Slots().size() > 1 || h->Slots().begin()->second->count > 1)
{ //we can't remove last unit { //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++) for(TSlots::const_reverse_iterator i = h->Slots().rbegin(); i != h->Slots().rend(); i++)
{ {
if (h->getPower(targetstack) > h->getPower(i->first)) 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())); gates.push_back(std::make_pair(cur->id, ObjectInstanceID()));
} }
} }
objs.erase(103); objs.erase(Obj::SUBTERRANEAN_GATE);
} }
ObjectInstanceID CGTeleport::getMatchingGate(ObjectInstanceID id) ObjectInstanceID CGTeleport::getMatchingGate(ObjectInstanceID id)
@ -4457,7 +4457,7 @@ void CGSeerHut::setObjToKill()
{ {
if (quest->missionType == CQuest::MISSION_KILL_CREATURE) 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); assert(quest->stackToKill.type);
quest->stackToKill.count = 0; //no count in info window quest->stackToKill.count = 0; //no count in info window
quest->stackDirection = checkDirection(); quest->stackDirection = checkDirection();
@ -4757,7 +4757,7 @@ void CGSeerHut::completeQuest (const CGHeroInstance * h) const //reward
case CREATURE: case CREATURE:
{ {
CCreatureSet creatures; CCreatureSet creatures;
creatures.setCreature(0, CreatureID(rID), rVal); creatures.setCreature(SlotID(0), CreatureID(rID), rVal);
cb->giveCreatures(this, h, creatures, false); cb->giveCreatures(this, h, creatures, false);
} }
break; break;
@ -5939,8 +5939,8 @@ void CBank::setPropertyDer (ui8 what, ui32 val)
{ {
case 1: case 1:
for (int i = 0; i < 4; ++i) for (int i = 0; i < 4; ++i)
setCreature (i, bc->guards[0].first, bc->guards[0].second / 5 ); setCreature (SlotID(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(4), CreatureID(bc->guards[0].first + upgraded), bc->guards[0].second / 5 );
break; break;
case 4: case 4:
{ {
@ -5948,24 +5948,24 @@ void CBank::setPropertyDer (ui8 what, ui32 val)
{ {
for (auto it = bc->guards.begin(); it != bc->guards.end(); it++) 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 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 (SlotID(0), bc->guards[0].first, bc->guards[0].second / 2 );
setCreature (1, bc->guards[1].first, bc->guards[1].second / 2); setCreature (SlotID(1), bc->guards[1].first, bc->guards[1].second / 2);
setCreature (2, CreatureID(bc->guards[2].first + upgraded), bc->guards[2].second); setCreature (SlotID(2), CreatureID(bc->guards[2].first + upgraded), bc->guards[2].second);
setCreature (3, bc->guards[1].first, bc->guards[1].second / 2 ); setCreature (SlotID(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(4), bc->guards[0].first, bc->guards[0].second - (bc->guards[0].second / 2) );
} }
else //split both stacks else //split both stacks
{ {
for (int i = 0; i < 3; ++i) //skellies 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 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; break;
@ -6193,7 +6193,7 @@ void CBank::endBattle (const CGHeroInstance *h, const BattleResult *result) cons
CCreatureSet ourArmy; CCreatureSet ourArmy;
for (auto it = bc->creatures.cbegin(); it != bc->creatures.cend(); it++) 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); ourArmy.addToSlot(slot, it->first, it->second);
} }
for (TSlots::const_iterator i = ourArmy.Slots().begin(); i != ourArmy.Slots().end(); i++) for (TSlots::const_iterator i = ourArmy.Slots().begin(); i != ourArmy.Slots().end(); i++)

View File

@ -617,8 +617,8 @@ public:
std::string nodeName() const override; std::string nodeName() const override;
void deserializationFix(); void deserializationFix();
void recreateBuildingsBonuses(); 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, 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, int type, int val, int subtype = -1); //convienence version of above bool addBonusIfBuilt(BuildingID building, Bonus::BonusType type, int val, int subtype = -1); //convienence version of above
void setVisitingHero(CGHeroInstance *h); void setVisitingHero(CGHeroInstance *h);
void setGarrisonedHero(CGHeroInstance *h); void setGarrisonedHero(CGHeroInstance *h);
const CArmedInstance *getUpperArmy() const; //garrisoned hero if present or the town itself 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 class DLL_LINKAGE CGTeleport : public CGObjectInstance //teleports and subterranean gates
{ {
public: public:
static std::map<int,std::map<int, std::vector<ObjectInstanceID> > > objs; //teleports: map[ID][subID] => vector of ids static std::map<Obj, std::map<int, std::vector<ObjectInstanceID> > > objs; //teleports: map[ID][subID] => vector of ids
static std::vector<std::pair<ObjectInstanceID, ObjectInstanceID> > gates; //subterranean gates: pairs of ids static std::vector<std::pair<ObjectInstanceID, ObjectInstanceID> > gates; //subterranean gates: pairs of ids
void onHeroVisit(const CGHeroInstance * h) const override; void onHeroVisit(const CGHeroInstance * h) const override;
void initObj() override; void initObj() override;
@ -1291,7 +1291,7 @@ class DLL_LINKAGE CGObelisk : public CPlayersVisited
{ {
public: public:
static ui8 obeliskCount; //how many obelisks are on map static ui8 obeliskCount; //how many obelisks are on map
static std::map<ui8, ui8> visited; //map: team_id => how many obelisks has been visited static std::map<TTeamID, ui8> visited; //map: team_id => how many obelisks has been visited
void onHeroVisit(const CGHeroInstance * h) const override; void onHeroVisit(const CGHeroInstance * h) const override;
void initObj() override; void initObj() override;

View File

@ -35,7 +35,6 @@
#include "Mapping/CCampaignHandler.h" //for CCampaignState #include "Mapping/CCampaignHandler.h" //for CCampaignState
const ui32 version = 737; const ui32 version = 737;
const TSlot COMMANDER_SLOT_PLACEHOLDER = -2;
class CConnection; class CConnection;
class CGObjectInstance; class CGObjectInstance;
@ -485,14 +484,14 @@ struct SaveIfStackInstance<Ser, CStackInstance *>
static bool invoke(Ser &s, const CStackInstance* const &data) static bool invoke(Ser &s, const CStackInstance* const &data)
{ {
assert(data->armyObj); assert(data->armyObj);
TSlot slot = -1; SlotID slot;
if(data->getNodeType() == CBonusSystemNode::COMMANDER) if(data->getNodeType() == CBonusSystemNode::COMMANDER)
slot = COMMANDER_SLOT_PLACEHOLDER; slot = SlotID::COMMANDER_SLOT_PLACEHOLDER;
else else
slot = data->armyObj->findStack(data); slot = data->armyObj->findStack(data);
assert(slot != -1); assert(slot != SlotID());
s << data->armyObj << slot; s << data->armyObj << slot;
return true; return true;
} }
@ -512,9 +511,9 @@ struct LoadIfStackInstance<Ser, CStackInstance *>
static bool invoke(Ser &s, CStackInstance* &data) static bool invoke(Ser &s, CStackInstance* &data)
{ {
CArmedInstance *armedObj; CArmedInstance *armedObj;
TSlot slot; SlotID slot;
s >> armedObj >> slot; s >> armedObj >> slot;
if(slot != COMMANDER_SLOT_PLACEHOLDER) if(slot != SlotID::COMMANDER_SLOT_PLACEHOLDER)
{ {
assert(armedObj->hasStackAtSlot(slot)); assert(armedObj->hasStackAtSlot(slot));
data = armedObj->stacks[slot]; data = armedObj->stacks[slot];
@ -1172,7 +1171,7 @@ public:
if(sendStackInstanceByIds) if(sendStackInstanceByIds)
{ {
CArmedInstance *armed; CArmedInstance *armed;
TSlot slot; SlotID slot;
*this >> armed >> slot; *this >> armed >> slot;
assert(armed->hasStackAtSlot(slot)); assert(armed->hasStackAtSlot(slot));
s = armed->stacks[slot]; s = armed->stacks[slot];

View File

@ -18,6 +18,8 @@
#include "CCreatureHandler.h" #include "CCreatureHandler.h"
#include "CSpellHandler.h" #include "CSpellHandler.h"
const SlotID SlotID::COMMANDER_SLOT_PLACEHOLDER = SlotID(-2);
#define ID_LIKE_OPERATORS_INTERNAL(A, B, AN, BN) \ #define ID_LIKE_OPERATORS_INTERNAL(A, B, AN, BN) \
bool operator==(const A & a, const B & b) \ bool operator==(const A & a, const B & b) \
{ \ { \

View File

@ -223,6 +223,21 @@ class ObjectInstanceID : public BaseForID<ObjectInstanceID>
friend class CNonConstInfoCallback; friend class CNonConstInfoCallback;
}; };
class SlotID : public BaseForID<SlotID>
{
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 // #ifndef INSTANTIATE_BASE_FOR_ID_HERE
// extern template std::ostream & operator << <ArtifactInstanceID>(std::ostream & os, BaseForID<ArtifactInstanceID> id); // extern template std::ostream & operator << <ArtifactInstanceID>(std::ostream & os, BaseForID<ArtifactInstanceID> id);
// extern template std::ostream & operator << <ObjectInstanceID>(std::ostream & os, BaseForID<ObjectInstanceID> id); // extern template std::ostream & operator << <ObjectInstanceID>(std::ostream & os, BaseForID<ObjectInstanceID> id);
@ -841,11 +856,10 @@ ID_LIKE_OPERATORS_DECLS(SpellID, SpellID::ESpellID)
typedef si8 TFaction; typedef si8 TFaction;
typedef si64 TExpType; typedef si64 TExpType;
typedef std::pair<ui32, ui32> TDmgRange; typedef std::pair<ui32, ui32> TDmgRange;
typedef ui8 TBonusType;
typedef si32 TBonusSubtype; typedef si32 TBonusSubtype;
typedef si32 TSlot;
typedef si32 TQuantity; typedef si32 TQuantity;
typedef ui8 TPlayerColor; typedef ui8 TPlayerColor;
typedef ui8 TTeamID;
#undef ID_LIKE_CLASS_COMMON #undef ID_LIKE_CLASS_COMMON

View File

@ -27,20 +27,20 @@
#define FOREACH_RED_PARENT(pname) TNodes lparents; getRedParents(lparents); BOOST_FOREACH(CBonusSystemNode *pname, lparents) #define FOREACH_RED_PARENT(pname) TNodes lparents; getRedParents(lparents); BOOST_FOREACH(CBonusSystemNode *pname, lparents)
#define BONUS_NAME(x) ( #x, Bonus::x ) #define BONUS_NAME(x) ( #x, Bonus::x )
const std::map<std::string, int> bonusNameMap = boost::assign::map_list_of BONUS_LIST; const std::map<std::string, Bonus::BonusType> bonusNameMap = boost::assign::map_list_of BONUS_LIST;
#undef BONUS_NAME #undef BONUS_NAME
#define BONUS_VALUE(x) ( #x, Bonus::x ) #define BONUS_VALUE(x) ( #x, Bonus::x )
const std::map<std::string, int> bonusValueMap = boost::assign::map_list_of BONUS_VALUE_LIST; const std::map<std::string, Bonus::ValueType> bonusValueMap = boost::assign::map_list_of BONUS_VALUE_LIST;
#undef BONUS_VALUE #undef BONUS_VALUE
#define BONUS_SOURCE(x) ( #x, Bonus::x ) #define BONUS_SOURCE(x) ( #x, Bonus::x )
const std::map<std::string, int> bonusSourceMap = boost::assign::map_list_of BONUS_SOURCE_LIST; const std::map<std::string, Bonus::BonusSource> bonusSourceMap = boost::assign::map_list_of BONUS_SOURCE_LIST;
#undef BONUS_SOURCE #undef BONUS_SOURCE
#define BONUS_ITEM(x) ( #x, Bonus::x ) #define BONUS_ITEM(x) ( #x, Bonus::x )
const std::map<std::string, int> bonusDurationMap = boost::assign::map_list_of const std::map<std::string, ui16> bonusDurationMap = boost::assign::map_list_of
BONUS_ITEM(PERMANENT) BONUS_ITEM(PERMANENT)
BONUS_ITEM(ONE_BATTLE) BONUS_ITEM(ONE_BATTLE)
BONUS_ITEM(ONE_DAY) BONUS_ITEM(ONE_DAY)
@ -52,7 +52,7 @@ const std::map<std::string, int> bonusDurationMap = boost::assign::map_list_of
BONUS_ITEM(STACK_GETS_TURN) BONUS_ITEM(STACK_GETS_TURN)
BONUS_ITEM(COMMANDER_KILLED); BONUS_ITEM(COMMANDER_KILLED);
const std::map<std::string, int> bonusLimitEffect = boost::assign::map_list_of const std::map<std::string, Bonus::LimitEffect> bonusLimitEffect = boost::assign::map_list_of
BONUS_ITEM(NO_LIMIT) BONUS_ITEM(NO_LIMIT)
BONUS_ITEM(ONLY_DISTANCE_FIGHT) BONUS_ITEM(ONLY_DISTANCE_FIGHT)
BONUS_ITEM(ONLY_MELEE_FIGHT) BONUS_ITEM(ONLY_MELEE_FIGHT)
@ -1128,7 +1128,7 @@ std::string Bonus::Description() const
return str.str(); 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) : duration(Dur), type(Type), subtype(Subtype), source(Src), val(Val), sid(ID), description(Desc)
{ {
additionalInfo = -1; additionalInfo = -1;
@ -1138,7 +1138,7 @@ Bonus::Bonus(ui16 Dur, ui8 Type, BonusSource Src, si32 Val, ui32 ID, std::string
boost::algorithm::trim(description); 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) : duration(Dur), type(Type), subtype(Subtype), source(Src), val(Val), sid(ID), valType(ValType)
{ {
additionalInfo = -1; additionalInfo = -1;
@ -1176,7 +1176,7 @@ CSelector DLL_LINKAGE operator||(const CSelector &first, const CSelector &second
namespace Selector namespace Selector
{ {
DLL_LINKAGE CSelectFieldEqual<TBonusType> type(&Bonus::type, 0); DLL_LINKAGE CSelectFieldEqual<Bonus::BonusType> type(&Bonus::type, Bonus::NONE);
DLL_LINKAGE CSelectFieldEqual<TBonusSubtype> subtype(&Bonus::subtype, 0); DLL_LINKAGE CSelectFieldEqual<TBonusSubtype> subtype(&Bonus::subtype, 0);
DLL_LINKAGE CSelectFieldEqual<si32> info(&Bonus::additionalInfo, 0); DLL_LINKAGE CSelectFieldEqual<si32> info(&Bonus::additionalInfo, 0);
DLL_LINKAGE CSelectFieldEqual<ui16> duration(&Bonus::duration, 0); DLL_LINKAGE CSelectFieldEqual<ui16> duration(&Bonus::duration, 0);
@ -1184,14 +1184,14 @@ namespace Selector
DLL_LINKAGE CSelectFieldEqual<Bonus::LimitEffect> effectRange(&Bonus::effectRange, Bonus::NO_LIMIT); DLL_LINKAGE CSelectFieldEqual<Bonus::LimitEffect> effectRange(&Bonus::effectRange, Bonus::NO_LIMIT);
DLL_LINKAGE CWillLastTurns turns; 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); 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<TBonusType>(&Bonus::type, type) && CSelectFieldEqual<TBonusSubtype>(&Bonus::subtype, subtype) && CSelectFieldEqual<si32>(&Bonus::additionalInfo, info); return CSelectFieldEqual<Bonus::BonusType>(&Bonus::type, type) && CSelectFieldEqual<TBonusSubtype>(&Bonus::subtype, subtype) && CSelectFieldEqual<si32>(&Bonus::additionalInfo, info);
} }
CSelector DLL_LINKAGE source(Bonus::BonusSource source, ui32 sourceID) CSelector DLL_LINKAGE source(Bonus::BonusSource source, ui32 sourceID)
@ -1209,14 +1209,14 @@ namespace Selector
return CSelectFieldEqual<Bonus::BonusSource>(&Bonus::source, source); return CSelectFieldEqual<Bonus::BonusSource>(&Bonus::source, source);
} }
bool DLL_LINKAGE matchesType(const CSelector &sel, TBonusType type) bool DLL_LINKAGE matchesType(const CSelector &sel, Bonus::BonusType type)
{ {
Bonus dummy; Bonus dummy;
dummy.type = type; dummy.type = type;
return sel(&dummy); 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; Bonus dummy;
dummy.type = type; 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) DLL_LINKAGE std::ostream & operator<<(std::ostream &out, const Bonus &bonus)
{ {
for(std::map<std::string, int>::const_iterator i = bonusNameMap.begin(); i != bonusNameMap.end(); i++) for(auto i = bonusNameMap.cbegin(); i != bonusNameMap.cend(); i++)
if(i->second == bonus.type) if(i->second == bonus.type)
out << "\tType: " << i->first << " \t"; out << "\tType: " << i->first << " \t";
@ -1361,12 +1361,12 @@ void CCreatureTypeLimiter::setCreature (CreatureID id)
creature = VLC->creh->creatures[id]; creature = VLC->creh->creatures[id];
} }
HasAnotherBonusLimiter::HasAnotherBonusLimiter( TBonusType bonus ) HasAnotherBonusLimiter::HasAnotherBonusLimiter( Bonus::BonusType bonus )
: type(bonus), subtype(0), isSubtypeRelevant(false) : 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) : type(bonus), subtype(_subtype), isSubtypeRelevant(true)
{ {
} }

View File

@ -252,7 +252,7 @@ struct DLL_LINKAGE Bonus
ui16 duration; //uses BonusDuration values ui16 duration; //uses BonusDuration values
si16 turnsRemain; //used if duration is N_TURNS or N_DAYS 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 TBonusSubtype subtype; //-1 if not applicable - 4 bytes
BonusSource source;//source type" uses BonusSource values - what gave that bonus BonusSource source;//source type" uses BonusSource values - what gave that bonus
@ -268,8 +268,8 @@ struct DLL_LINKAGE Bonus
std::string description; std::string description;
Bonus(ui16 Dur, ui8 Type, BonusSource Src, si32 Val, ui32 ID, std::string Desc, si32 Subtype=-1); Bonus(ui16 Dur, BonusType 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, si32 Subtype=-1, ValueType ValType = ADDITIVE_VALUE);
Bonus(); Bonus();
~Bonus(); ~Bonus();
@ -780,12 +780,12 @@ public:
class DLL_LINKAGE HasAnotherBonusLimiter : public ILimiter //applies only to nodes that have another bonus working class DLL_LINKAGE HasAnotherBonusLimiter : public ILimiter //applies only to nodes that have another bonus working
{ {
public: public:
TBonusType type; Bonus::BonusType type;
TBonusSubtype subtype; TBonusSubtype subtype;
bool isSubtypeRelevant; //check for subtype only if this is true bool isSubtypeRelevant; //check for subtype only if this is true
HasAnotherBonusLimiter(TBonusType bonus = Bonus::NONE); HasAnotherBonusLimiter(Bonus::BonusType bonus = Bonus::NONE);
HasAnotherBonusLimiter(TBonusType bonus, TBonusSubtype _subtype); HasAnotherBonusLimiter(Bonus::BonusType bonus, TBonusSubtype _subtype);
int limit(const BonusLimitationContext &context) const OVERRIDE; int limit(const BonusLimitationContext &context) const OVERRIDE;
@ -880,7 +880,7 @@ const CCreature *retrieveCreature(const CBonusSystemNode *node);
namespace Selector namespace Selector
{ {
extern DLL_LINKAGE CSelectFieldEqual<TBonusType> type; extern DLL_LINKAGE CSelectFieldEqual<Bonus::BonusType> type;
extern DLL_LINKAGE CSelectFieldEqual<TBonusSubtype> subtype; extern DLL_LINKAGE CSelectFieldEqual<TBonusSubtype> subtype;
extern DLL_LINKAGE CSelectFieldEqual<si32> info; extern DLL_LINKAGE CSelectFieldEqual<si32> info;
extern DLL_LINKAGE CSelectFieldEqual<ui16> duration; extern DLL_LINKAGE CSelectFieldEqual<ui16> duration;
@ -888,18 +888,22 @@ namespace Selector
extern DLL_LINKAGE CSelectFieldEqual<Bonus::LimitEffect> effectRange; extern DLL_LINKAGE CSelectFieldEqual<Bonus::LimitEffect> effectRange;
extern DLL_LINKAGE CWillLastTurns turns; extern DLL_LINKAGE CWillLastTurns turns;
CSelector DLL_LINKAGE typeSubtype(TBonusType Type, TBonusSubtype Subtype); CSelector DLL_LINKAGE typeSubtype(Bonus::BonusType Type, TBonusSubtype Subtype);
CSelector DLL_LINKAGE typeSubtypeInfo(TBonusType type, TBonusSubtype subtype, si32 info); CSelector DLL_LINKAGE typeSubtypeInfo(Bonus::BonusType type, TBonusSubtype subtype, si32 info);
CSelector DLL_LINKAGE source(Bonus::BonusSource source, ui32 sourceID); CSelector DLL_LINKAGE source(Bonus::BonusSource source, ui32 sourceID);
CSelector DLL_LINKAGE durationType(ui16 duration); CSelector DLL_LINKAGE durationType(ui16 duration);
CSelector DLL_LINKAGE sourceTypeSel(Bonus::BonusSource source); CSelector DLL_LINKAGE sourceTypeSel(Bonus::BonusSource source);
bool DLL_LINKAGE matchesType(const CSelector &sel, TBonusType type); bool DLL_LINKAGE matchesType(const CSelector &sel, Bonus::BonusType type);
bool DLL_LINKAGE matchesTypeSubtype(const CSelector &sel, TBonusType type, TBonusSubtype subtype); bool DLL_LINKAGE matchesTypeSubtype(const CSelector &sel, Bonus::BonusType type, TBonusSubtype subtype);
bool DLL_LINKAGE positiveSpellEffects(const Bonus *b); bool DLL_LINKAGE positiveSpellEffects(const Bonus *b);
} }
extern DLL_LINKAGE const std::map<std::string, int> bonusNameMap, bonusValueMap, bonusSourceMap, bonusDurationMap, bonusLimitEffect; extern DLL_LINKAGE const std::map<std::string, Bonus::BonusType> bonusNameMap;
extern DLL_LINKAGE const std::map<std::string, Bonus::ValueType> bonusValueMap;
extern DLL_LINKAGE const std::map<std::string, Bonus::BonusSource> bonusSourceMap;
extern DLL_LINKAGE const std::map<std::string, ui16> bonusDurationMap;
extern DLL_LINKAGE const std::map<std::string, Bonus::LimitEffect> bonusLimitEffect;
extern DLL_LINKAGE const bmap<std::string, TLimiterPtr> bonusLimiterMap; extern DLL_LINKAGE const bmap<std::string, TLimiterPtr> bonusLimiterMap;
extern DLL_LINKAGE const bmap<std::string, TPropagatorPtr> bonusPropagatorMap; extern DLL_LINKAGE const bmap<std::string, TPropagatorPtr> bonusPropagatorMap;

View File

@ -286,7 +286,7 @@ const CGTownInstance* CGameInfoCallback::getTown(ObjectInstanceID objid) const
return NULL; 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<boost::shared_mutex> lock(*gs->mx); //boost::shared_lock<boost::shared_mutex> lock(*gs->mx);
ERROR_RET_IF(!canGetFullInfo(obj), "Cannot get info about not owned object!"); ERROR_RET_IF(!canGetFullInfo(obj), "Cannot get info about not owned object!");

View File

@ -92,7 +92,7 @@ public:
//armed object //armed object
void getUpgradeInfo(const CArmedInstance *obj, int stackPos, UpgradeInfo &out)const; void getUpgradeInfo(const CArmedInstance *obj, SlotID stackPos, UpgradeInfo &out)const;
//hero //hero
const CGHeroInstance* getHero(ObjectInstanceID objid) const; const CGHeroInstance* getHero(ObjectInstanceID objid) const;

View File

@ -1118,17 +1118,17 @@ Key reverseMapFirst(const Val & val, const std::map<Key, Val> map)
void JsonUtils::unparseBonus( JsonNode &node, const Bonus * bonus ) void JsonUtils::unparseBonus( JsonNode &node, const Bonus * bonus )
{ {
node["type"].String() = reverseMapFirst<std::string, int>(bonus->type, bonusNameMap); node["type"].String() = reverseMapFirst<std::string, Bonus::BonusType>(bonus->type, bonusNameMap);
node["subtype"].Float() = bonus->subtype; node["subtype"].Float() = bonus->subtype;
node["val"].Float() = bonus->val; node["val"].Float() = bonus->val;
node["valueType"].String() = reverseMapFirst<std::string, int>(bonus->valType, bonusValueMap); node["valueType"].String() = reverseMapFirst<std::string, Bonus::ValueType>(bonus->valType, bonusValueMap);
node["additionalInfo"].Float() = bonus->additionalInfo; node["additionalInfo"].Float() = bonus->additionalInfo;
node["turns"].Float() = bonus->turnsRemain; node["turns"].Float() = bonus->turnsRemain;
node["sourceID"].Float() = bonus->source; node["sourceID"].Float() = bonus->source;
node["description"].String() = bonus->description; node["description"].String() = bonus->description;
node["effectRange"].String() = reverseMapFirst<std::string, int>(bonus->effectRange, bonusLimitEffect); node["effectRange"].String() = reverseMapFirst<std::string, Bonus::LimitEffect>(bonus->effectRange, bonusLimitEffect);
node["duration"].String() = reverseMapFirst<std::string, int>(bonus->duration, bonusDurationMap); node["duration"].String() = reverseMapFirst<std::string, ui16>(bonus->duration, bonusDurationMap);
node["source"].String() = reverseMapFirst<std::string, int>(bonus->source, bonusSourceMap); node["source"].String() = reverseMapFirst<std::string, Bonus::BonusSource>(bonus->source, bonusSourceMap);
if(bonus->limiter) if(bonus->limiter)
{ {
node["limiter"].String() = reverseMapFirst<std::string, TLimiterPtr>(bonus->limiter, bonusLimiterMap); node["limiter"].String() = reverseMapFirst<std::string, TLimiterPtr>(bonus->limiter, bonusLimiterMap);

View File

@ -393,9 +393,10 @@ void CCampaignScenario::prepareCrossoverHeroes( std::vector<CGHeroInstance *> he
//trimming creatures //trimming creatures
BOOST_FOREACH(CGHeroInstance * cgh, crossoverHeroes) BOOST_FOREACH(CGHeroInstance * cgh, crossoverHeroes)
{ {
vstd::erase_if(cgh->stacks, [&](const std::pair<TSlot, CStackInstance *> & j) vstd::erase_if(cgh->stacks, [&](const std::pair<SlotID, CStackInstance *> & 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)) );
}); });
} }
} }

View File

@ -960,7 +960,7 @@ void CMapLoaderH3M::readObjects()
hlp->count = reader.readUInt16(); hlp->count = reader.readUInt16();
//type will be set during initialization //type will be set during initialization
cre->putStack(0, hlp); cre->putStack(SlotID(0), hlp);
cre->character = reader.readUInt8(); cre->character = reader.readUInt8();
@ -1515,7 +1515,7 @@ void CMapLoaderH3M::readCreatureSet(CCreatureSet * out, int number)
hlp->setType(creID); hlp->setType(creID);
} }
out->putStack(ir, hlp); out->putStack(SlotID(ir), hlp);
} }
out->validTypes(true); out->validTypes(true);

View File

@ -174,23 +174,16 @@ public:
struct StackLocation struct StackLocation
{ {
ConstTransitivePtr<CArmedInstance> army; ConstTransitivePtr<CArmedInstance> army;
TSlot slot; SlotID slot;
StackLocation() StackLocation()
{ {}
slot = -1; StackLocation(const CArmedInstance *Army, SlotID Slot)
}
StackLocation(const CArmedInstance *Army, TSlot Slot)
{ {
army = const_cast<CArmedInstance*>(Army); //we are allowed here to const cast -> change will go through one of our packages... do not abuse! army = const_cast<CArmedInstance*>(Army); //we are allowed here to const cast -> change will go through one of our packages... do not abuse!
slot = Slot; slot = Slot;
} }
bool validSlot() const
{
return slot >= 0 && slot < GameConstants::ARMY_SIZE;
}
DLL_LINKAGE const CStackInstance *getStack(); DLL_LINKAGE const CStackInstance *getStack();
template <typename Handler> void serialize(Handler &h, const int version) template <typename Handler> void serialize(Handler &h, const int version)
{ {
@ -1816,11 +1809,11 @@ struct CastleTeleportHero : public CPackForServer
struct ArrangeStacks : public CPackForServer struct ArrangeStacks : public CPackForServer
{ {
ArrangeStacks(){}; 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) {}; :what(W),p1(P1),p2(P2),id1(ID1),id2(ID2),val(VAL) {};
ui8 what; //1 - swap; 2 - merge; 3 - split 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 ObjectInstanceID id1, id2; //ids of objects with garrison
si32 val; si32 val;
bool applyGh(CGameHandler *gh); bool applyGh(CGameHandler *gh);
@ -1833,8 +1826,8 @@ struct ArrangeStacks : public CPackForServer
struct DisbandCreature : public CPackForServer struct DisbandCreature : public CPackForServer
{ {
DisbandCreature(){}; DisbandCreature(){};
DisbandCreature(ui8 Pos, ObjectInstanceID ID):pos(Pos),id(ID){}; DisbandCreature(SlotID Pos, ObjectInstanceID ID):pos(Pos),id(ID){};
ui8 pos; //stack pos SlotID pos; //stack pos
ObjectInstanceID id; //object id ObjectInstanceID id; //object id
bool applyGh(CGameHandler *gh); bool applyGh(CGameHandler *gh);
@ -1882,8 +1875,8 @@ struct RecruitCreatures : public CPackForServer
struct UpgradeCreature : public CPackForServer struct UpgradeCreature : public CPackForServer
{ {
UpgradeCreature(){}; UpgradeCreature(){};
UpgradeCreature(ui8 Pos, ObjectInstanceID ID, CreatureID CRID):pos(Pos),id(ID), cid(CRID){}; UpgradeCreature(SlotID Pos, ObjectInstanceID ID, CreatureID CRID):pos(Pos),id(ID), cid(CRID){};
ui8 pos; //stack pos SlotID pos; //stack pos
ObjectInstanceID id; //object id ObjectInstanceID id; //object id
CreatureID cid; //id of type to which we want make upgrade CreatureID cid; //id of type to which we want make upgrade
@ -1923,12 +1916,12 @@ struct ExchangeArtifacts : public CPackForServer
struct AssembleArtifacts : public CPackForServer struct AssembleArtifacts : public CPackForServer
{ {
AssembleArtifacts(){}; 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){}; : heroID(_heroID), artifactSlot(_artifactSlot), assemble(_assemble), assembleTo(_assembleTo){};
ObjectInstanceID heroID; ObjectInstanceID heroID;
ArtifactPosition artifactSlot; ArtifactPosition artifactSlot;
bool assemble; // True to assemble artifact, false to disassemble. 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); bool applyGh(CGameHandler *gh);
template <typename Handler> void serialize(Handler &h, const int version) template <typename Handler> void serialize(Handler &h, const int version)

View File

@ -537,7 +537,7 @@ DLL_LINKAGE void NewObject::applyGs( CGameState *gs )
cre->character = 2; cre->character = 2;
cre->gainedArtifact = ArtifactID::NONE; cre->gainedArtifact = ArtifactID::NONE;
cre->identifier = -1; 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; break;
default: default:
@ -1460,7 +1460,7 @@ DLL_LINKAGE void BattleStackAdded::applyGs(CGameState *gs)
} }
CStackBasicDescriptor csbd(creID, amount); 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) if (summoned)
addedStack->state.insert(EBattleStackState::SUMMONED); addedStack->state.insert(EBattleStackState::SUMMONED);

View File

@ -693,7 +693,7 @@ void CGameHandler::endBattle(int3 tile, const CGHeroInstance *hero1, const CGHer
const CStackBasicDescriptor raisedStack = winnerHero ? winnerHero->calculateNecromancy(*battleResult.data) : CStackBasicDescriptor(); const CStackBasicDescriptor raisedStack = winnerHero ? winnerHero->calculateNecromancy(*battleResult.data) : CStackBasicDescriptor();
// Give raised units to winner and show dialog, if any were raised, // Give raised units to winner and show dialog, if any were raised,
// units will be given after casualities are taken // 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) if(!duel)
{ {
@ -720,7 +720,7 @@ void CGameHandler::endBattle(int3 tile, const CGHeroInstance *hero1, const CGHer
afterBattleCallback(); afterBattleCallback();
} }
if (necroSlot != -1) if (necroSlot != SlotID())
{ {
winnerHero->showNecromancyDialog(raisedStack); winnerHero->showNecromancyDialog(raisedStack);
addToSlot(StackLocation(winnerHero, necroSlot), raisedStack.type, raisedStack.count); 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 if(result == 1) //retreat
{ {
sah.army[0].clear(); 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]) if(const CGHeroInstance *another = getPlayer(loser)->availableHeroes[1])
@ -2341,13 +2341,13 @@ void CGameHandler::close()
//exit(0); //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<CArmedInstance*>(gs->getObjInstance(id1)), const CArmedInstance *s1 = static_cast<CArmedInstance*>(gs->getObjInstance(id1)),
*s2 = static_cast<CArmedInstance*>(gs->getObjInstance(id2)); *s2 = static_cast<CArmedInstance*>(gs->getObjInstance(id2));
const CCreatureSet &S1 = *s1, &S2 = *s2; const CCreatureSet &S1 = *s1, &S2 = *s2;
StackLocation sl1(s1, p1), sl2(s2, p2); StackLocation sl1(s1, p1), sl2(s2, p2);
if(!sl1.validSlot() || !sl2.validSlot()) if(!sl1.slot.validSlot() || !sl2.slot.validSlot())
{ {
complain("Invalid slot accessed!"); complain("Invalid slot accessed!");
return false; 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<CArmedInstance*>(gs->getObjInstance(id)); CArmedInstance *s1 = static_cast<CArmedInstance*>(gs->getObjInstance(id));
if(!vstd::contains(s1->stacks,pos)) if(!vstd::contains(s1->stacks,pos))
@ -2645,12 +2645,12 @@ bool CGameHandler::recruitCreatures( ObjectInstanceID objid, CreatureID crid, ui
break; break;
} }
} }
int slot = dst->getSlotFor(crid); SlotID slot = dst->getSlotFor(crid);
if( (!found && complain("Cannot recruit: no such creatures!")) 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 > VLC->creh->creatures[crid]->maxAmount(gs->getPlayer(dst->tempOwner)->resources) && complain("Cannot recruit: lack of resources!"))
|| (cram<=0 && complain("Cannot recruit: cram <= 0!")) || (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; return false;
} }
@ -2697,7 +2697,7 @@ bool CGameHandler::recruitCreatures( ObjectInstanceID objid, CreatureID crid, ui
return true; return true;
} }
bool CGameHandler::upgradeCreature( ObjectInstanceID objid, ui8 pos, CreatureID upgID ) bool CGameHandler::upgradeCreature( ObjectInstanceID objid, SlotID pos, CreatureID upgID )
{ {
CArmedInstance *obj = static_cast<CArmedInstance*>(gs->getObjInstance(objid)); CArmedInstance *obj = static_cast<CArmedInstance*>(gs->getObjInstance(objid));
assert(obj->hasStackAtSlot(pos)); 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 TSlots::const_iterator i = src->Slots().begin(); //iterator to stack to move
StackLocation sl(src, i->first); //location of stack to move StackLocation sl(src, i->first); //location of stack to move
TSlot pos = dst->getSlotFor(i->second->type); SlotID pos = dst->getSlotFor(i->second->type);
if(pos < 0) if(!pos.validSlot())
{ {
//try to merge two other stacks to make place //try to merge two other stacks to make place
std::pair<TSlot, TSlot> toMerge; std::pair<SlotID, SlotID> toMerge;
if(dst->mergableStacks(toMerge, i->first) && allowMerging) if(dst->mergableStacks(toMerge, i->first) && allowMerging)
{ {
moveStack(StackLocation(dst, toMerge.first), StackLocation(dst, toMerge.second)); //merge toMerge.first into toMerge.second 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 * @param assembleTo If assemble is true, this represents the artifact ID of the combination
* artifact to assemble to. Otherwise it's not used. * 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); CGHeroInstance *hero = gs->getHero(heroID);
@ -3099,7 +3099,7 @@ bool CGameHandler::tradeResources(const IMarket *market, ui32 val, TPlayerColor
return true; 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)) if(!vstd::contains(hero->Slots(), slot))
COMPLAIN_RET("Hero doesn't have any creature in that 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; 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; const CArmedInstance *army = NULL;
if (hero) if (hero)
@ -3242,7 +3242,7 @@ bool CGameHandler::hireHero(const CGObjectInstance *obj, ui8 hid, TPlayerColor p
{ {
sah.hid[hid] = newHero->subID; sah.hid[hid] = newHero->subID;
sah.army[hid].clear(); 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 else
sah.hid[hid] = -1; sah.hid[hid] = -1;
@ -3820,8 +3820,8 @@ void CGameHandler::playerMessage( TPlayerColor player, const std::string &messag
if(!hero) return; if(!hero) return;
for(int i = 0; i < GameConstants::ARMY_SIZE; i++) for(int i = 0; i < GameConstants::ARMY_SIZE; i++)
if(!hero->hasStackAtSlot(i)) if(!hero->hasStackAtSlot(SlotID(i)))
insertNewStack(StackLocation(hero, i), archangel, 5); insertNewStack(StackLocation(hero, SlotID(i)), archangel, 5);
} }
else if(message == "vcmiangband") //gives 10 black knight into each slot 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; if(!hero) return;
for(int i = 0; i < GameConstants::ARMY_SIZE; i++) for(int i = 0; i < GameConstants::ARMY_SIZE; i++)
if(!hero->hasStackAtSlot(i)) if(!hero->hasStackAtSlot(SlotID(i)))
insertNewStack(StackLocation(hero, i), blackKnight, 10); insertNewStack(StackLocation(hero, SlotID(i)), blackKnight, 10);
} }
else if(message == "vcminoldor") //all war machines else if(message == "vcminoldor") //all war machines
{ {
@ -5622,7 +5622,7 @@ bool CGameHandler::tryAttackingGuard(const int3 &guardPos, const CGHeroInstance
return true; 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); 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)) if(sl.army->hasStackAtSlot(sl.slot))
COMPLAIN_RET("Slot is already taken!"); COMPLAIN_RET("Slot is already taken!");
if(!sl.validSlot()) if(!sl.slot.validSlot())
COMPLAIN_RET("Cannot insert stack to that slot!"); COMPLAIN_RET("Cannot insert stack to that slot!");
InsertNewStack ins; 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 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); SlotID pos = dst->getSlotFor(i->second->type);
if(pos > -1) if(pos.validSlot())
{ {
moveStack(StackLocation(src, i->first), StackLocation(dst, pos)); moveStack(StackLocation(src, i->first), StackLocation(dst, pos));
cont = true; 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)) 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!"); 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!"); COMPLAIN_RET("Cannot move stack to that slot!");
if(count == -1) if(count == -1)

View File

@ -209,23 +209,23 @@ public:
bool buildBoat( ObjectInstanceID objid ); bool buildBoat( ObjectInstanceID objid );
bool setFormation( ObjectInstanceID hid, ui8 formation ); bool setFormation( ObjectInstanceID hid, ui8 formation );
bool tradeResources(const IMarket *market, ui32 val, TPlayerColor player, ui32 id1, ui32 id2); 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 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 sellCreatures(ui32 count, const IMarket *market, const CGHeroInstance * hero, SlotID slot, Res::ERes resourceID);
bool transformInUndead(const IMarket *market, const CGHeroInstance * hero, ui32 slot); bool transformInUndead(const IMarket *market, const CGHeroInstance * hero, SlotID slot);
bool assembleArtifacts (ObjectInstanceID heroID, ArtifactPosition artifactSlot, bool assemble, ui32 assembleTo); 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( 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 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 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<ui32> &arts); //after battle - move al arts to winer //void lootArtifacts (TArtHolder source, TArtHolder dest, std::vector<ui32> &arts); //after battle - move al arts to winer
bool buySecSkill( const IMarket *m, const CGHeroInstance *h, SecondarySkill skill); bool buySecSkill( const IMarket *m, const CGHeroInstance *h, SecondarySkill skill);
bool garrisonSwap(ObjectInstanceID tid); 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 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 buildStructure(ObjectInstanceID tid, BuildingID bid, bool force=false);//force - for events: no cost, no checkings
bool razeStructure(ObjectInstanceID tid, BuildingID bid); bool razeStructure(ObjectInstanceID tid, BuildingID bid);
bool disbandCreature( ObjectInstanceID id, ui8 pos ); bool disbandCreature( ObjectInstanceID id, SlotID pos );
bool arrangeStacks( ObjectInstanceID id1, ObjectInstanceID id2, ui8 what, ui8 p1, ui8 p2, si32 val, TPlayerColor player); bool arrangeStacks( ObjectInstanceID id1, ObjectInstanceID id2, ui8 what, SlotID p1, SlotID p2, si32 val, TPlayerColor player);
void save(const std::string &fname); void save(const std::string &fname);
void close(); void close();
void handleTimeEvents(); void handleTimeEvents();

View File

@ -180,7 +180,7 @@ bool TradeOnMarketplace::applyGh( CGameHandler *gh )
case EMarketMode::CREATURE_RESOURCE: case EMarketMode::CREATURE_RESOURCE:
if(!hero) if(!hero)
COMPLAIN_AND_RETURN("Only hero can sell creatures!"); COMPLAIN_AND_RETURN("Only hero can sell creatures!");
return gh->sellCreatures(val, m, hero, r1, static_cast<Res::ERes>(r2)); return gh->sellCreatures(val, m, hero, SlotID(r1), static_cast<Res::ERes>(r2));
case EMarketMode::RESOURCE_ARTIFACT: case EMarketMode::RESOURCE_ARTIFACT:
if(!hero) if(!hero)
COMPLAIN_AND_RETURN("Only hero can buy artifacts!"); 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!"); COMPLAIN_AND_RETURN("Only hero can sell artifacts!");
return gh->sellArtifact(m, hero, ArtifactInstanceID(r1), static_cast<Res::ERes>(r2)); return gh->sellArtifact(m, hero, ArtifactInstanceID(r1), static_cast<Res::ERes>(r2));
case EMarketMode::CREATURE_UNDEAD: case EMarketMode::CREATURE_UNDEAD:
return gh->transformInUndead(m, hero, r1); return gh->transformInUndead(m, hero, SlotID(r1));
case EMarketMode::RESOURCE_SKILL: case EMarketMode::RESOURCE_SKILL:
return gh->buySecSkill(m, hero, SecondarySkill(r2)); return gh->buySecSkill(m, hero, SecondarySkill(r2));
case EMarketMode::CREATURE_EXP: case EMarketMode::CREATURE_EXP:
return gh->sacrificeCreatures(m, hero, r1, val); return gh->sacrificeCreatures(m, hero, SlotID(r1), val);
case EMarketMode::ARTIFACT_EXP: case EMarketMode::ARTIFACT_EXP:
return gh->sacrificeArtifact(m, hero, ArtifactPosition(r1)); return gh->sacrificeArtifact(m, hero, ArtifactPosition(r1));
default: default: