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>
<Link>
<AdditionalDependencies>VCMI_lib.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalOptions>-Zm150 %(AdditionalOptions)</AdditionalOptions>
</Link>
</ItemDefinitionGroup>
<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())
{
//can be merged woth another stack?
TSlot dst = h->getSlotFor(slot.second->getCreatureID());
SlotID dst = h->getSlotFor(slot.second->getCreatureID());
if(h->hasStackAtSlot(dst))
ret += t->getPower(slot.first);
else
@ -959,13 +959,13 @@ void makePossibleUpgrades(const CArmedInstance *obj)
for(int i = 0; i < GameConstants::ARMY_SIZE; i++)
{
if(const CStackInstance *s = obj->getStackPtr(i))
if(const CStackInstance *s = obj->getStackPtr(SlotID(i)))
{
UpgradeInfo ui;
cb->getUpgradeInfo(obj, i, ui);
cb->getUpgradeInfo(obj, SlotID(i), ui);
if(ui.oldID >= 0 && cb->getResourceAmount().canAfford(ui.cost[0] * s->count))
{
cb->upgradeCreature(obj, i, ui.newID[0]);
cb->upgradeCreature(obj, SlotID(i), ui.newID[0]);
}
}
}
@ -1176,7 +1176,7 @@ bool VCAI::canGetArmy (const CGHeroInstance * army, const CGHeroInstance * sourc
BOOST_FOREACH(auto armyPtr, armies)
for (int j = 0; j < GameConstants::ARMY_SIZE; j++)
{
if(armyPtr->getCreature(j) == bestArmy[i] && (i != j || armyPtr != army)) //it's a searched creature not in dst slot
if(armyPtr->getCreature(SlotID(j)) == bestArmy[i] && (i != j || armyPtr != army)) //it's a searched creature not in dst slot
if (!(armyPtr->needsLastStack() && armyPtr->Slots().size() == 1 && armyPtr != army)) //can't take away last creature
return true; //at least one exchange will be performed
}
@ -1220,9 +1220,9 @@ void VCAI::pickBestCreatures(const CArmedInstance * army, const CArmedInstance *
BOOST_FOREACH(auto armyPtr, armies)
for (int j = 0; j < GameConstants::ARMY_SIZE; j++)
{
if(armyPtr->getCreature(j) == bestArmy[i] && (i != j || armyPtr != army)) //it's a searched creature not in dst slot
if(armyPtr->getCreature(SlotID(j)) == bestArmy[i] && (i != j || armyPtr != army)) //it's a searched creature not in dst slot
if (!(armyPtr->needsLastStack() && armyPtr->Slots().size() == 1 && armyPtr != army))
cb->mergeOrSwapStacks(armyPtr, army, j, i);
cb->mergeOrSwapStacks(armyPtr, army, SlotID(j), SlotID(i));
}
}
@ -3630,7 +3630,7 @@ bool shouldVisit(HeroPtr h, const CGObjectInstance * obj)
{
BOOST_FOREACH(auto c, level.second)
{
if (h->getSlotFor(c) != -1)
if (h->getSlotFor(CreatureID(c)) != SlotID())
canRecruitCreatures = true;
}
}

View File

@ -79,7 +79,7 @@ void CCallback::recruitCreatures(const CGObjectInstance *obj, CreatureID ID, ui3
sendRequest(&pack);
}
bool CCallback::dismissCreature(const CArmedInstance *obj, int stackPos)
bool CCallback::dismissCreature(const CArmedInstance *obj, SlotID stackPos)
{
if(((player>=0) && obj->tempOwner != player) || (obj->stacksCount()<2 && obj->needsLastStack()))
return false;
@ -89,7 +89,7 @@ bool CCallback::dismissCreature(const CArmedInstance *obj, int stackPos)
return true;
}
bool CCallback::upgradeCreature(const CArmedInstance *obj, int stackPos, CreatureID newID)
bool CCallback::upgradeCreature(const CArmedInstance *obj, SlotID stackPos, CreatureID newID)
{
UpgradeCreature pack(stackPos,obj->id,newID);
sendRequest(&pack);
@ -102,20 +102,20 @@ void CCallback::endTurn()
EndTurn pack;
sendRequest(&pack); //report that we ended turn
}
int CCallback::swapCreatures(const CArmedInstance *s1, const CArmedInstance *s2, int p1, int p2)
int CCallback::swapCreatures(const CArmedInstance *s1, const CArmedInstance *s2, SlotID p1, SlotID p2)
{
ArrangeStacks pack(1,p1,p2,s1->id,s2->id,0);
sendRequest(&pack);
return 0;
}
int CCallback::mergeStacks(const CArmedInstance *s1, const CArmedInstance *s2, int p1, int p2)
int CCallback::mergeStacks(const CArmedInstance *s1, const CArmedInstance *s2, SlotID p1, SlotID p2)
{
ArrangeStacks pack(2,p1,p2,s1->id,s2->id,0);
sendRequest(&pack);
return 0;
}
int CCallback::splitStack(const CArmedInstance *s1, const CArmedInstance *s2, int p1, int p2, int val)
int CCallback::splitStack(const CArmedInstance *s1, const CArmedInstance *s2, SlotID p1, SlotID p2, int val)
{
ArrangeStacks pack(3,p1,p2,s1->id,s2->id,val);
sendRequest(&pack);
@ -154,7 +154,7 @@ bool CCallback::swapArtifacts(const ArtifactLocation &l1, const ArtifactLocation
* @param assembleTo If assemble is true, this represents the artifact ID of the combination
* artifact to assemble to. Otherwise it's not used.
*/
bool CCallback::assembleArtifacts (const CGHeroInstance * hero, ArtifactPosition artifactSlot, bool assemble, ui32 assembleTo)
bool CCallback::assembleArtifacts (const CGHeroInstance * hero, ArtifactPosition artifactSlot, bool assemble, ArtifactID assembleTo)
{
if (player != hero->tempOwner)
return false;
@ -366,7 +366,7 @@ void CCallback::validatePaths()
}
}
int CCallback::mergeOrSwapStacks(const CArmedInstance *s1, const CArmedInstance *s2, int p1, int p2)
int CCallback::mergeOrSwapStacks(const CArmedInstance *s1, const CArmedInstance *s2, SlotID p1, SlotID p2)
{
if(s1->getCreature(p1) == s2->getCreature(p2))
return mergeStacks(s1, s2, p1, p2);

View File

@ -51,20 +51,20 @@ public:
virtual void recruitHero(const CGObjectInstance *townOrTavern, const CGHeroInstance *hero)=0;
virtual bool buildBuilding(const CGTownInstance *town, BuildingID buildingID)=0;
virtual void recruitCreatures(const CGObjectInstance *obj, CreatureID ID, ui32 amount, si32 level=-1)=0;
virtual bool upgradeCreature(const CArmedInstance *obj, int stackPos, CreatureID newID=CreatureID::NONE)=0; //if newID==-1 then best possible upgrade will be made
virtual bool upgradeCreature(const CArmedInstance *obj, SlotID stackPos, CreatureID newID=CreatureID::NONE)=0; //if newID==-1 then best possible upgrade will be made
virtual void swapGarrisonHero(const CGTownInstance *town)=0;
virtual void trade(const CGObjectInstance *market, EMarketMode::EMarketMode mode, int id1, int id2, int val1, const CGHeroInstance *hero = NULL)=0; //mode==0: sell val1 units of id1 resource for id2 resiurce
virtual int selectionMade(int selection, int queryID) =0;
virtual int swapCreatures(const CArmedInstance *s1, const CArmedInstance *s2, int p1, int p2)=0;//swaps creatures between two possibly different garrisons // TODO: AI-unsafe code - fix it!
virtual int mergeStacks(const CArmedInstance *s1, const CArmedInstance *s2, int p1, int p2)=0;//joins first stack to the second (creatures must be same type)
virtual int mergeOrSwapStacks(const CArmedInstance *s1, const CArmedInstance *s2, int p1, int p2) =0; //first goes to the second
virtual int splitStack(const CArmedInstance *s1, const CArmedInstance *s2, int p1, int p2, int val)=0;//split creatures from the first stack
virtual int swapCreatures(const CArmedInstance *s1, const CArmedInstance *s2, SlotID p1, SlotID p2)=0;//swaps creatures between two possibly different garrisons // TODO: AI-unsafe code - fix it!
virtual int mergeStacks(const CArmedInstance *s1, const CArmedInstance *s2, SlotID p1, SlotID p2)=0;//joins first stack to the second (creatures must be same type)
virtual int mergeOrSwapStacks(const CArmedInstance *s1, const CArmedInstance *s2, SlotID p1, SlotID p2) =0; //first goes to the second
virtual int splitStack(const CArmedInstance *s1, const CArmedInstance *s2, SlotID p1, SlotID p2, int val)=0;//split creatures from the first stack
//virtual bool swapArtifacts(const CGHeroInstance * hero1, ui16 pos1, const CGHeroInstance * hero2, ui16 pos2)=0; //swaps artifacts between two given heroes
virtual bool swapArtifacts(const ArtifactLocation &l1, const ArtifactLocation &l2)=0;
virtual bool assembleArtifacts(const CGHeroInstance * hero, ArtifactPosition artifactSlot, bool assemble, ui32 assembleTo)=0;
virtual bool dismissCreature(const CArmedInstance *obj, int stackPos)=0;
virtual bool assembleArtifacts(const CGHeroInstance * hero, ArtifactPosition artifactSlot, bool assemble, ArtifactID assembleTo)=0;
virtual bool dismissCreature(const CArmedInstance *obj, SlotID stackPos)=0;
virtual void endTurn()=0;
virtual void buyArtifact(const CGHeroInstance *hero, ArtifactID aid)=0; //used to buy artifacts in towns (including spell book in the guild and war machines in blacksmith)
virtual void setFormation(const CGHeroInstance * hero, bool tight)=0;
@ -118,20 +118,20 @@ public:
bool moveHero(const CGHeroInstance *h, int3 dst); //dst must be free, neighbouring tile (this function can move hero only by one tile)
bool teleportHero(const CGHeroInstance *who, const CGTownInstance *where);
int selectionMade(int selection, int queryID);
int swapCreatures(const CArmedInstance *s1, const CArmedInstance *s2, int p1, int p2);
int mergeOrSwapStacks(const CArmedInstance *s1, const CArmedInstance *s2, int p1, int p2); //first goes to the second
int mergeStacks(const CArmedInstance *s1, const CArmedInstance *s2, int p1, int p2); //first goes to the second
int splitStack(const CArmedInstance *s1, const CArmedInstance *s2, int p1, int p2, int val);
int swapCreatures(const CArmedInstance *s1, const CArmedInstance *s2, SlotID p1, SlotID p2);
int mergeOrSwapStacks(const CArmedInstance *s1, const CArmedInstance *s2, SlotID p1, SlotID p2); //first goes to the second
int mergeStacks(const CArmedInstance *s1, const CArmedInstance *s2, SlotID p1, SlotID p2); //first goes to the second
int splitStack(const CArmedInstance *s1, const CArmedInstance *s2, SlotID p1, SlotID p2, int val);
bool dismissHero(const CGHeroInstance * hero);
//bool swapArtifacts(const CGHeroInstance * hero1, ui16 pos1, const CGHeroInstance * hero2, ui16 pos2);
bool swapArtifacts(const ArtifactLocation &l1, const ArtifactLocation &l2);
//bool moveArtifact(const CGHeroInstance * hero, ui16 src, const CStackInstance * stack, ui16 dest); // TODO: unify classes
//bool moveArtifact(const CStackInstance * stack, ui16 src , const CGHeroInstance * hero, ui16 dest); // TODO: unify classes
bool assembleArtifacts(const CGHeroInstance * hero, ArtifactPosition artifactSlot, bool assemble, ui32 assembleTo);
bool assembleArtifacts(const CGHeroInstance * hero, ArtifactPosition artifactSlot, bool assemble, ArtifactID assembleTo);
bool buildBuilding(const CGTownInstance *town, BuildingID buildingID) OVERRIDE;
void recruitCreatures(const CGObjectInstance *obj, CreatureID ID, ui32 amount, si32 level=-1);
bool dismissCreature(const CArmedInstance *obj, int stackPos);
bool upgradeCreature(const CArmedInstance *obj, int stackPos, CreatureID newID=CreatureID::NONE) OVERRIDE;
bool dismissCreature(const CArmedInstance *obj, SlotID stackPos);
bool upgradeCreature(const CArmedInstance *obj, SlotID stackPos, CreatureID newID=CreatureID::NONE) OVERRIDE;
void endTurn();
void swapGarrisonHero(const CGTownInstance *town);
void buyArtifact(const CGHeroInstance *hero, ArtifactID aid) OVERRIDE;

View File

@ -737,7 +737,7 @@ struct HEPerformer : StandardReceiverVisitor<const CGHeroInstance *>
{
if(erm->getIexp(params[0]).getInt() == 0)
{
int slot = erm->getIexp(params[1]).getInt();
SlotID slot = SlotID(erm->getIexp(params[1]).getInt());
const CStackInstance *stack = identifier->getStackPtr(slot);
if(params[2].which() == 6) //varp
{
@ -752,7 +752,7 @@ struct HEPerformer : StandardReceiverVisitor<const CGHeroInstance *>
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
throw EScriptExecError("Setting stack count is not implemented!");
@ -1016,7 +1016,7 @@ void MO_GPerformer::operator()( TIexp const& cmp ) const
void MO_GPerformer::operator()( TVarpExp const& cmp ) const
{
const CGCreature *cre = erm->getObjFromAs<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)
{
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;
text = it->second.first;
description = it->second.second;

View File

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

View File

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

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

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<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);
CStack * generateNewStack(const CStackInstance &base, bool attackerOwned, int slot, BattleHex position) const; //helper for CGameHandler::setupBattle and spells addign new stacks to the battlefield
CStack * generateNewStack(const CStackBasicDescriptor &base, bool attackerOwned, int slot, BattleHex position) const; //helper for CGameHandler::setupBattle and spells addign new stacks to the battlefield
CStack * generateNewStack(const CStackInstance &base, bool attackerOwned, SlotID slot, BattleHex position) const; //helper for CGameHandler::setupBattle and spells addign new stacks to the battlefield
CStack * generateNewStack(const CStackBasicDescriptor &base, bool attackerOwned, SlotID slot, BattleHex position) const; //helper for CGameHandler::setupBattle and spells addign new stacks to the battlefield
int getIdForNewStack() const; //suggest a currently unused ID that'd suitable for generating a new stack
//std::pair<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
@ -144,7 +144,7 @@ public:
ui32 baseAmount;
ui32 firstHPleft; //HP of first creature in stack
TPlayerColor owner; //owner - player colour (255 for neutrals)
ui8 slot; //slot - position in garrison (may be 255 for neutrals/called creatures)
SlotID slot; //slot - position in garrison (may be 255 for neutrals/called creatures)
bool attackerOwned; //if true, this stack is owned by attakcer (this one from left hand side of battle)
BattleHex position; //position on battlefield; -2 - keep, -3 - lower tower, -4 - upper tower
ui8 counterAttacks; //how many counter attacks can be performed more in this turn (by default set at the beginning of the round to 1)
@ -155,8 +155,8 @@ public:
//overrides
const CCreature* getCreature() const {return type;}
CStack(const CStackInstance *base, int O, int I, bool AO, int S); //c-tor
CStack(const CStackBasicDescriptor *stack, int O, int I, bool AO, int S = 255); //c-tor
CStack(const CStackInstance *base, int O, int I, bool AO, SlotID S); //c-tor
CStack(const CStackBasicDescriptor *stack, int O, int I, bool AO, SlotID S = SlotID(255)); //c-tor
CStack(); //c-tor
~CStack();
std::string nodeName() const OVERRIDE;
@ -205,7 +205,7 @@ public:
& shots & casts & count;
const CArmedInstance *army = (base ? base->armyObj : NULL);
TSlot slot = (base ? base->armyObj->findStack(base) : -1);
SlotID slot = (base ? base->armyObj->findStack(base) : SlotID());
if(h.saving)
{
@ -214,13 +214,13 @@ public:
else
{
h & army & slot;
if (slot == -2) //TODO
if (slot == SlotID::COMMANDER_SLOT_PLACEHOLDER) //TODO
{
auto hero = dynamic_cast<const CGHeroInstance *>(army);
assert (hero);
base = hero->commander;
}
else if(!army || slot == -1 || !army->hasStackAtSlot(slot))
else if(!army || slot == SlotID() || !army->hasStackAtSlot(slot))
{
base = NULL;
tlog3 << type->nameSing << " doesn't have a base stack!\n";

View File

@ -114,7 +114,7 @@ CCreature::CCreature()
doubleWide = false;
setNodeType(CBonusSystemNode::CREATURE);
}
void CCreature::addBonus(int val, int type, int subtype /*= -1*/)
void CCreature::addBonus(int val, Bonus::BonusType type, int subtype /*= -1*/)
{
Bonus *added = new Bonus(Bonus::PERMANENT, type, Bonus::CREATURE_ABILITY, val, idNumber, subtype, Bonus::BASE_NUMBER);
addNewBonus(added);
@ -149,7 +149,7 @@ static void AddAbility(CCreature *cre, const JsonVector &ability_vec)
Bonus *nsf = new Bonus();
std::string type = ability_vec[0].String();
std::map<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 (type == "DOUBLE_WIDE")
@ -185,7 +185,7 @@ static void RemoveAbility(CCreature *cre, const JsonNode &ability)
{
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 (type == "DOUBLE_WIDE")
@ -348,7 +348,7 @@ void CCreatureHandler::loadCreatures()
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();
it_map = bonusNameMap.find(bonusID);
@ -359,7 +359,7 @@ void CCreatureHandler::loadCreatures()
}
//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);
if (VLC->modh->modules.STACK_EXP) //reading default stack experience bonuses

View File

@ -41,7 +41,7 @@ public:
TFaction faction; //-1 = neutral
ui8 level; // 0 - unknown
bool doubleWide;
ui8 special; // Creature is not available normally (war machines, commanders, etc
bool special; // Creature is not available normally (war machines, commanders, etc
///animation info
double timeBetweenFidgets, walkAnimationTime, attackAnimationTime, flightAnimationDistance;
@ -49,7 +49,7 @@ public:
double missleFrameAngles[12];
int troopCountLocationOffset, attackClimaxFrame;
std::string projectile;
ui8 projectileSpin; //if true, appropriate projectile is spinning during flight
bool projectileSpin; //if true, appropriate projectile is spinning during flight
///end of anim info
//sound info
@ -86,7 +86,7 @@ public:
bool valid() const;
void addBonus(int val, int type, int subtype = -1);
void addBonus(int val, Bonus::BonusType type, int subtype = -1);
std::string nodeName() const override;
//void getParents(TCNodes &out, const CBonusSystemNode *root /*= NULL*/) const;
@ -131,12 +131,12 @@ private:
void loadCreatureJson(CCreature * creature, const JsonNode & config);
public:
std::set<int> notUsedMonsters;
std::set<CreatureID> notUsedMonsters;
std::set<CreatureID> doubledCreatures; //they get double week
std::vector<ConstTransitivePtr<CCreature> > creatures; //creature ID -> creature info
//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<ui32> maxExpPerBattle; //%, tiers same as above
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);
if (i != stacks.end())
@ -30,7 +30,7 @@ const CStackInstance &CCreatureSet::operator[](TSlot slot) const
throw std::runtime_error("That slot is empty!");
}
const CCreature* CCreatureSet::getCreature(TSlot slot) const
const CCreature* CCreatureSet::getCreature(SlotID slot) const
{
TSlots::const_iterator i = stacks.find(slot);
if (i != stacks.end())
@ -39,9 +39,9 @@ const CCreature* CCreatureSet::getCreature(TSlot slot) const
return NULL;
}
bool CCreatureSet::setCreature(TSlot slot, CreatureID type, TQuantity quantity) /*slots 0 to 6 */
bool CCreatureSet::setCreature(SlotID slot, CreatureID type, TQuantity quantity) /*slots 0 to 6 */
{
if(slot > 6 || slot < 0)
if(!slot.validSlot())
{
tlog1 << "Cannot set slot " << slot << std::endl;
return false;
@ -60,12 +60,12 @@ bool CCreatureSet::setCreature(TSlot slot, CreatureID type, TQuantity quantity)
return true;
}
TSlot CCreatureSet::getSlotFor(CreatureID creature, ui32 slotsAmount/*=7*/) const /*returns -1 if no slot available */
SlotID CCreatureSet::getSlotFor(CreatureID creature, ui32 slotsAmount/*=7*/) const /*returns -1 if no slot available */
{
return getSlotFor(VLC->creh->creatures[creature], slotsAmount);
}
TSlot CCreatureSet::getSlotFor(const CCreature *c, ui32 slotsAmount/*=ARMY_SIZE*/) const
SlotID CCreatureSet::getSlotFor(const CCreature *c, ui32 slotsAmount/*=ARMY_SIZE*/) const
{
assert(c->valid());
for(TSlots::const_iterator i=stacks.begin(); i!=stacks.end(); ++i)
@ -76,29 +76,22 @@ TSlot CCreatureSet::getSlotFor(const CCreature *c, ui32 slotsAmount/*=ARMY_SIZE*
return i->first; //if there is already such creature we return its slot id
}
}
for(ui32 i=0; i<slotsAmount; i++)
{
if(stacks.find(i) == stacks.end())
{
return i; //return first free slot
}
}
return -1; //no slot available
return getFreeSlot(slotsAmount);
}
TSlot CCreatureSet::getFreeSlot(ui32 slotsAmount/*=ARMY_SIZE*/) const
SlotID CCreatureSet::getFreeSlot(ui32 slotsAmount/*=ARMY_SIZE*/) const
{
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
}
int CCreatureSet::getStackCount(TSlot slot) const
int CCreatureSet::getStackCount(SlotID slot) const
{
TSlots::const_iterator i = stacks.find(slot);
if (i != stacks.end())
@ -107,7 +100,7 @@ int CCreatureSet::getStackCount(TSlot slot) const
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);
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
if(preferable >= 0 && vstd::contains(stacks, preferable))
if(preferable.validSlot() && vstd::contains(stacks, preferable))
{
const CCreature *cr = stacks.find(preferable)->second->type;
for(TSlots::const_iterator j=stacks.begin(); j!=stacks.end(); ++j)
@ -162,7 +155,7 @@ void CCreatureSet::sweep()
}
}
void CCreatureSet::addToSlot(TSlot slot, CreatureID cre, TQuantity count, bool allowMerging/* = true*/)
void CCreatureSet::addToSlot(SlotID slot, CreatureID cre, TQuantity count, bool allowMerging/* = true*/)
{
const CCreature *c = VLC->creh->creatures[cre];
@ -180,7 +173,7 @@ void CCreatureSet::addToSlot(TSlot slot, CreatureID cre, TQuantity count, bool a
}
}
void CCreatureSet::addToSlot(TSlot slot, CStackInstance *stack, bool allowMerging/* = true*/)
void CCreatureSet::addToSlot(SlotID slot, CStackInstance *stack, bool allowMerging/* = true*/)
{
assert(stack->valid(true));
@ -208,7 +201,7 @@ bool CCreatureSet::validTypes(bool allowUnrandomized /*= false*/) const
return true;
}
bool CCreatureSet::slotEmpty(TSlot slot) const
bool CCreatureSet::slotEmpty(SlotID slot) const
{
return !hasStackAtSlot(slot);
}
@ -226,11 +219,11 @@ ui64 CCreatureSet::getArmyStrength() const
return ret;
}
ui64 CCreatureSet::getPower (TSlot slot) const
ui64 CCreatureSet::getPower (SlotID slot) const
{
return getStack(slot).getPower();
}
std::string CCreatureSet::getRoughAmount (TSlot slot) const
std::string CCreatureSet::getRoughAmount (SlotID slot) const
{
int quantity = CCreature::getQuantityID(getStackCount(slot));
if (quantity)
@ -248,7 +241,7 @@ void CCreatureSet::setFormation(bool tight)
formation = tight;
}
void CCreatureSet::setStackCount(TSlot slot, TQuantity count)
void CCreatureSet::setStackCount(SlotID slot, TQuantity count)
{
assert(hasStackAtSlot(slot));
assert(stacks[slot]->count + count > 0);
@ -263,7 +256,7 @@ void CCreatureSet::giveStackExp(TExpType exp)
for(TSlots::const_iterator i = stacks.begin(); i != stacks.end(); i++)
i->second->giveStackExp(exp);
}
void CCreatureSet::setStackExp(TSlot slot, TExpType exp)
void CCreatureSet::setStackExp(SlotID slot, TExpType exp)
{
assert(hasStackAtSlot(slot));
stacks[slot]->experience = exp;
@ -277,20 +270,20 @@ void CCreatureSet::clear()
}
}
const CStackInstance& CCreatureSet::getStack(TSlot slot) const
const CStackInstance& CCreatureSet::getStack(SlotID slot) const
{
assert(hasStackAtSlot(slot));
return *getStackPtr(slot);
}
const CStackInstance* CCreatureSet::getStackPtr(TSlot slot) const
const CStackInstance* CCreatureSet::getStackPtr(SlotID slot) const
{
if(hasStackAtSlot(slot))
return stacks.find(slot)->second;
else return NULL;
}
void CCreatureSet::eraseStack(TSlot slot)
void CCreatureSet::eraseStack(SlotID slot)
{
assert(hasStackAtSlot(slot));
CStackInstance *toErase = detachStack(slot);
@ -309,20 +302,20 @@ bool CCreatureSet::contains(const CStackInstance *stack) const
return false;
}
TSlot CCreatureSet::findStack(const CStackInstance *stack) const
SlotID CCreatureSet::findStack(const CStackInstance *stack) const
{
auto h = dynamic_cast<const CGHeroInstance *>(this);
if (h && h->commander == stack)
return -2;
return SlotID::COMMANDER_SLOT_PLACEHOLDER;
if(!stack)
return -1;
return SlotID();
for(TSlots::const_iterator i = stacks.begin(); i != stacks.end(); ++i)
if(i->second == stack)
return i->first;
return -1;
return SlotID();
}
CArmedInstance * CCreatureSet::castToArmyObj()
@ -330,16 +323,16 @@ CArmedInstance * CCreatureSet::castToArmyObj()
return dynamic_cast<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));
stacks[slot] = stack;
stack->setArmyObj(castToArmyObj());
armyChanged();
}
void CCreatureSet::joinStack(TSlot slot, CStackInstance * stack)
void CCreatureSet::joinStack(SlotID slot, CStackInstance * stack)
{
const CCreature *c = getCreature(slot);
assert(c == stack->type);
@ -350,7 +343,7 @@ void CCreatureSet::joinStack(TSlot slot, CStackInstance * stack)
vstd::clear_pointer(stack);
}
void CCreatureSet::changeStackCount(TSlot slot, TQuantity toAdd)
void CCreatureSet::changeStackCount(SlotID slot, TQuantity toAdd)
{
setStackCount(slot, getStackCount(slot) + toAdd);
}
@ -385,7 +378,7 @@ void CCreatureSet::setToArmy(CSimpleArmy &src)
}
}
CStackInstance * CCreatureSet::detachStack(TSlot slot)
CStackInstance * CCreatureSet::detachStack(SlotID slot)
{
assert(hasStackAtSlot(slot));
CStackInstance *ret = stacks[slot];
@ -401,7 +394,7 @@ CStackInstance * CCreatureSet::detachStack(TSlot slot)
return ret;
}
void CCreatureSet::setStackType(TSlot slot, const CCreature *type)
void CCreatureSet::setStackType(SlotID slot, const CCreature *type)
{
assert(hasStackAtSlot(slot));
CStackInstance *s = stacks[slot];
@ -417,8 +410,8 @@ bool CCreatureSet::canBeMergedWith(const CCreatureSet &cs, bool allowMergingStac
std::set<const CCreature*> cresToAdd;
for(TSlots::const_iterator i = cs.stacks.begin(); i != cs.stacks.end(); i++)
{
TSlot dest = getSlotFor(i->second->type);
if(dest < 0 || hasStackAtSlot(dest))
SlotID dest = getSlotFor(i->second->type);
if(!dest.validSlot() || hasStackAtSlot(dest))
cresToAdd.insert(i->second->type);
}
return cresToAdd.size() <= freeSlots;
@ -430,10 +423,10 @@ bool CCreatureSet::canBeMergedWith(const CCreatureSet &cs, bool allowMergingStac
//get types of creatures that need their own slot
for(TSlots::const_iterator i = cs.stacks.begin(); i != cs.stacks.end(); i++)
cres.addToSlot(i->first, i->second->type->idNumber, 1, true);
TSlot j;
SlotID j;
for(TSlots::const_iterator i = stacks.begin(); i != stacks.end(); i++)
{
if ((j = cres.getSlotFor(i->second->type)) >= 0)
if ((j = cres.getSlotFor(i->second->type)).validSlot())
cres.addToSlot(j, i->second->type->idNumber, 1, true); //merge if possible
else
return false; //no place found
@ -442,7 +435,7 @@ bool CCreatureSet::canBeMergedWith(const CCreatureSet &cs, bool allowMergingStac
}
}
bool CCreatureSet::hasStackAtSlot(TSlot slot) const
bool CCreatureSet::hasStackAtSlot(SlotID slot) const
{
return vstd::contains(stacks, slot);
}
@ -568,7 +561,7 @@ void CStackInstance::setType(const CCreature *c)
}
std::string CStackInstance::bonusToString(Bonus *bonus, bool description) const
{
std::map<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())
{
std::string text;
@ -1089,7 +1082,7 @@ CSimpleArmy::operator bool() const
return army.size();
}
bool CSimpleArmy::setCreature(TSlot slot, CreatureID cre, TQuantity count)
bool CSimpleArmy::setCreature(SlotID slot, CreatureID cre, TQuantity count)
{
assert(!vstd::contains(army, slot));
army[slot] = CStackBasicDescriptor(cre, count);

View File

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

View File

@ -806,9 +806,9 @@ void CGameState::init(StartInfo * si)
{
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;
}
}
@ -1714,8 +1714,8 @@ void CGameState::initDuel()
{
CreatureID cre = dp.sides[i].stacks[j].type;
TQuantity count = dp.sides[i].stacks[j].count;
if(count || obj->hasStackAtSlot(j))
obj->setCreature(j, cre, count);
if(count || obj->hasStackAtSlot(SlotID(j)))
obj->setCreature(SlotID(j), cre, count);
}
BOOST_FOREACH(const DuelParameters::CusomCreature &cc, dp.creatures)

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)
struct ArmyDescriptor : public std::map<TSlot, CStackBasicDescriptor>
struct ArmyDescriptor : public std::map<SlotID, CStackBasicDescriptor>
{
bool isDetailed;
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
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;
IGameCallback * IObjectInterface::cb = NULL;
extern boost::rand48 ran;
std::map <TPlayerColor, std::set <ui8> > CGKeys::playerKeyMap;
std::map <si32, std::vector<ObjectInstanceID> > CGMagi::eyelist;
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<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;
}
else
dst->setCreature(stackNo-warMachinesGiven, stack.creature, count);
dst->setCreature(SlotID(stackNo-warMachinesGiven), stack.creature, count);
}
}
void CGHeroInstance::initHeroDefInfo()
@ -1283,7 +1283,7 @@ void CGHeroInstance::updateSkill(SecondarySkill which, int val)
void CGHeroInstance::setPropertyDer( ui8 what, ui32 val )
{
if(what == ObjProperty::PRIMARY_STACK_COUNT)
setStackCount(0, val);
setStackCount(SlotID(0), val);
}
double CGHeroInstance::getHeroStrength() const
@ -1391,8 +1391,8 @@ CStackBasicDescriptor CGHeroInstance::calculateNecromancy (const BattleResult &b
}
// Make room for new units.
int slot = getSlotFor(raisedUnitType->idNumber);
if (slot == -1)
SlotID slot = getSlotFor(raisedUnitType->idNumber);
if (slot == SlotID())
{
// If there's no room for unit, try it's upgraded version 2/3rds the size.
raisedUnitType = VLC->creh->creatures[*raisedUnitType->upgrades.begin()];
@ -1602,7 +1602,7 @@ void CGDwelling::initObj()
else
hoverName = VLC->generaltexth->creGens[subID];
if(crs->level > 4)
putStack(0, new CStackInstance(crs, (crs->growth) * 3));
putStack(SlotID(0), new CStackInstance(crs, (crs->growth) * 3));
if (getOwner() != GameConstants::NEUTRAL_PLAYER)
cb->gameState()->players[getOwner()].dwellings.push_back (this);
}
@ -1617,8 +1617,8 @@ void CGDwelling::initObj()
creatures[2].second.push_back(CreatureID::GOLD_GOLEM);
creatures[3].second.push_back(CreatureID::DIAMOND_GOLEM);
//guards
putStack(0, new CStackInstance(CreatureID::GOLD_GOLEM, 9));
putStack(1, new CStackInstance(CreatureID::DIAMOND_GOLEM, 6));
putStack(SlotID(0), new CStackInstance(CreatureID::GOLD_GOLEM, 9));
putStack(SlotID(1), new CStackInstance(CreatureID::DIAMOND_GOLEM, 6));
}
else if(subID == 0) // Elemental Conflux
{
@ -1627,7 +1627,7 @@ void CGDwelling::initObj()
creatures[2].second.push_back(CreatureID::EARTH_ELEMENTAL);
creatures[3].second.push_back(CreatureID::WATER_ELEMENTAL);
//guards
putStack(0, new CStackInstance(CreatureID::EARTH_ELEMENTAL, 12));
putStack(SlotID(0), new CStackInstance(CreatureID::EARTH_ELEMENTAL, 12));
}
else
{
@ -1785,8 +1785,8 @@ void CGDwelling::heroAcceptsCreatures( const CGHeroInstance *h, ui32 answer ) co
{
if(count) //there are available creatures
{
int slot = h->getSlotFor(crid);
if(slot < 0) //no available slot
SlotID slot = h->getSlotFor(crid);
if(!slot.validSlot()) //no available slot
{
InfoWindow iw;
iw.player = h->tempOwner;
@ -2173,7 +2173,7 @@ void CGTownInstance::newTurn() const
if (tempOwner == GameConstants::NEUTRAL_PLAYER) //garrison growth for neutral towns
{
std::vector<ui8> nativeCrits; //slots
std::vector<SlotID> nativeCrits; //slots
for (TSlots::const_iterator it = Slots().begin(); it != Slots().end(); it++)
{
if (it->second->type->faction == subID) //native
@ -2183,7 +2183,7 @@ void CGTownInstance::newTurn() const
}
if (nativeCrits.size())
{
TSlot pos = nativeCrits[rand() % nativeCrits.size()];
SlotID pos = nativeCrits[rand() % nativeCrits.size()];
StackLocation sl(this, pos);
const CCreature *c = getCreature(pos);
@ -2200,7 +2200,7 @@ void CGTownInstance::newTurn() const
{
int i = rand() % std::min (GameConstants::ARMY_SIZE, cb->getDate(Date::MONTH)<<1);
CreatureID c = town->creatures[i][0];
TSlot n = -1;
SlotID n;
TQuantity count = creatureGrowth(i);
if (!count) // no dwelling
@ -2208,7 +2208,7 @@ void CGTownInstance::newTurn() const
{//no lower tiers or above current month
if ((n = getSlotFor(c))>=0)
if ((n = getSlotFor(c)).validSlot())
{
StackLocation sl(this, n);
if (slotEmpty(n))
@ -2426,12 +2426,12 @@ void CGTownInstance::recreateBuildingsBonuses()
}
}
bool CGTownInstance::addBonusIfBuilt(BuildingID building, int type, int val, int subtype /*= -1*/)
bool CGTownInstance::addBonusIfBuilt(BuildingID building, Bonus::BonusType type, int val, int subtype /*= -1*/)
{
return addBonusIfBuilt(building, type, val, TPropagatorPtr(), subtype);
}
bool CGTownInstance::addBonusIfBuilt(BuildingID building, int type, int val, TPropagatorPtr prop, int subtype /*= -1*/)
bool CGTownInstance::addBonusIfBuilt(BuildingID building, Bonus::BonusType type, int val, TPropagatorPtr prop, int subtype /*= -1*/)
{
if(hasBuilt(building))
{
@ -3045,7 +3045,7 @@ void CGCreature::onHeroVisit( const CGHeroInstance * h ) const
BlockingDialog ynd(true,false);
ynd.player = h->tempOwner;
std::string tmp = VLC->generaltexth->advobtxt[90];
boost::algorithm::replace_first(tmp,"%d",boost::lexical_cast<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,"%s",VLC->creh->creatures[subID]->namePl);
ynd.text << tmp;
@ -3091,15 +3091,15 @@ void CGCreature::endBattle( BattleResult *result ) const
}
//first stack has to be at slot 0 -> if original one got killed, move there first remaining stack
if(!hasStackAtSlot(0))
cb->moveStack(StackLocation(this, stacks.begin()->first), StackLocation(this, 0), stacks.begin()->second->count);
if(!hasStackAtSlot(SlotID(0)))
cb->moveStack(StackLocation(this, stacks.begin()->first), StackLocation(this, SlotID(0)), stacks.begin()->second->count);
while (stacks.size() > 1) //hopefully that's enough
{
// TODO it's either overcomplicated (if we assume there'll be only one stack) or buggy (if we allow multiple stacks... but that'll also cause troubles elsewhere)
i = stacks.end();
i--;
TSlot slot = getSlotFor(i->second->type);
SlotID slot = getSlotFor(i->second->type);
if (slot == i->first) //no reason to move stack to its own slot
break;
else
@ -3132,8 +3132,8 @@ void CGCreature::initObj()
break;
}
stacks[0]->setType(CreatureID(subID));
TQuantity &amount = stacks[0]->count;
stacks[SlotID(0)]->setType(CreatureID(subID));
TQuantity &amount = stacks[SlotID(0)]->count;
CCreature &c = *VLC->creh->creatures[subID];
if(!amount)
{
@ -3143,7 +3143,7 @@ void CGCreature::initObj()
amount = c.ammMin + (ran() % (c.ammMax - c.ammMin));
}
temppower = stacks[0]->count * 1000;
temppower = stacks[SlotID(0)]->count * 1000;
}
void CGCreature::newTurn() const
{//Works only for stacks of single type of size up to 2 millions
@ -3161,7 +3161,7 @@ void CGCreature::setPropertyDer(ui8 what, ui32 val)
switch (what)
{
case ObjProperty::MONSTER_COUNT:
stacks[0]->count = val;
stacks[SlotID(0)]->count = val;
break;
case ObjProperty::MONSTER_POWER:
temppower = val;
@ -3233,7 +3233,7 @@ int CGCreature::takenAction(const CGHeroInstance *h, bool allowJoin) const
return 0; //join for free
else if(h->getSecSkillLevel(SecondarySkill::DIPLOMACY) * 2 + sympathy + 1 >= character)
return VLC->creh->creatures[subID]->cost[6] * getStackCount(0); //join for gold
return VLC->creh->creatures[subID]->cost[6] * getStackCount(SlotID(0)); //join for gold
}
//we are still here - creatures have not joined hero, flee or fight
@ -3327,14 +3327,14 @@ void CGCreature::fight( const CGHeroInstance *h ) const
stacksCount = 3;
}
int stackSize;
TSlot sourceSlot = stacks.begin()->first;
TSlot destSlot;
SlotID sourceSlot = stacks.begin()->first;
SlotID destSlot;
for (int stacksLeft = stacksCount; stacksLeft > 1; --stacksLeft)
{
stackSize = stacks.begin()->second->count / stacksLeft;
if (stackSize)
{
if ((destSlot = getFreeSlot()) > -1)
if ((destSlot = getFreeSlot()).validSlot())
cb->moveStack(StackLocation(this, sourceSlot), StackLocation(this, destSlot), stackSize);
else
{
@ -3348,7 +3348,7 @@ void CGCreature::fight( const CGHeroInstance *h ) const
{
if (rand()%100 < 50) //upgrade
{
TSlot slotId = (stacks.size() / 2);
SlotID slotId = SlotID(stacks.size() / 2);
if(ui32 upgradesSize = getStack(slotId).type->upgrades.size())
{
auto it = getStack(slotId).type->upgrades.cbegin(); //pick random in case there are more
@ -3414,7 +3414,7 @@ void CGMine::initObj()
//set guardians
int howManyTroglodytes = 100 + ran()%100;
CStackInstance *troglodytes = new CStackInstance(CreatureID::TROGLODYTES, howManyTroglodytes);
putStack(0, troglodytes);
putStack(SlotID(0), troglodytes);
//after map reading tempOwner placeholds bitmask for allowed resources
std::vector<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)
{ //we can't remove last unit
TSlot targetstack = h->Slots().begin()->first; //slot numbers may vary
SlotID targetstack = h->Slots().begin()->first; //slot numbers may vary
for(TSlots::const_reverse_iterator i = h->Slots().rbegin(); i != h->Slots().rend(); i++)
{
if (h->getPower(targetstack) > h->getPower(i->first))
@ -3800,7 +3800,7 @@ void CGTeleport::postInit() //matches subterranean gates into pairs
gates.push_back(std::make_pair(cur->id, ObjectInstanceID()));
}
}
objs.erase(103);
objs.erase(Obj::SUBTERRANEAN_GATE);
}
ObjectInstanceID CGTeleport::getMatchingGate(ObjectInstanceID id)
@ -4457,7 +4457,7 @@ void CGSeerHut::setObjToKill()
{
if (quest->missionType == CQuest::MISSION_KILL_CREATURE)
{
quest->stackToKill = getCreatureToKill(false)->getStack(0); //FIXME: stacks tend to dissapear (desync?) on server :?
quest->stackToKill = getCreatureToKill(false)->getStack(SlotID(0)); //FIXME: stacks tend to dissapear (desync?) on server :?
assert(quest->stackToKill.type);
quest->stackToKill.count = 0; //no count in info window
quest->stackDirection = checkDirection();
@ -4757,7 +4757,7 @@ void CGSeerHut::completeQuest (const CGHeroInstance * h) const //reward
case CREATURE:
{
CCreatureSet creatures;
creatures.setCreature(0, CreatureID(rID), rVal);
creatures.setCreature(SlotID(0), CreatureID(rID), rVal);
cb->giveCreatures(this, h, creatures, false);
}
break;
@ -5939,8 +5939,8 @@ void CBank::setPropertyDer (ui8 what, ui32 val)
{
case 1:
for (int i = 0; i < 4; ++i)
setCreature (i, bc->guards[0].first, bc->guards[0].second / 5 );
setCreature (4, CreatureID(bc->guards[0].first + upgraded), bc->guards[0].second / 5 );
setCreature (SlotID(i), bc->guards[0].first, bc->guards[0].second / 5 );
setCreature (SlotID(4), CreatureID(bc->guards[0].first + upgraded), bc->guards[0].second / 5 );
break;
case 4:
{
@ -5948,24 +5948,24 @@ void CBank::setPropertyDer (ui8 what, ui32 val)
{
for (auto it = bc->guards.begin(); it != bc->guards.end(); it++)
{
setCreature (stacksCount(), it->first, it->second);
setCreature (SlotID(stacksCount()), it->first, it->second);
}
}
else if (bc->guards[2].second)//Wraiths are present, split two stacks in Crypt
{
setCreature (0, bc->guards[0].first, bc->guards[0].second / 2 );
setCreature (1, bc->guards[1].first, bc->guards[1].second / 2);
setCreature (2, CreatureID(bc->guards[2].first + upgraded), bc->guards[2].second);
setCreature (3, bc->guards[1].first, bc->guards[1].second / 2 );
setCreature (4, bc->guards[0].first, bc->guards[0].second - (bc->guards[0].second / 2) );
setCreature (SlotID(0), bc->guards[0].first, bc->guards[0].second / 2 );
setCreature (SlotID(1), bc->guards[1].first, bc->guards[1].second / 2);
setCreature (SlotID(2), CreatureID(bc->guards[2].first + upgraded), bc->guards[2].second);
setCreature (SlotID(3), bc->guards[1].first, bc->guards[1].second / 2 );
setCreature (SlotID(4), bc->guards[0].first, bc->guards[0].second - (bc->guards[0].second / 2) );
}
else //split both stacks
{
for (int i = 0; i < 3; ++i) //skellies
setCreature (2*i, bc->guards[0].first, bc->guards[0].second / 3);
setCreature (SlotID(2*i), bc->guards[0].first, bc->guards[0].second / 3);
for (int i = 0; i < 2; ++i) //zombies
setCreature (2*i+1, bc->guards[1].first, bc->guards[1].second / 2);
setCreature (SlotID(2*i+1), bc->guards[1].first, bc->guards[1].second / 2);
}
}
break;
@ -6193,7 +6193,7 @@ void CBank::endBattle (const CGHeroInstance *h, const BattleResult *result) cons
CCreatureSet ourArmy;
for (auto it = bc->creatures.cbegin(); it != bc->creatures.cend(); it++)
{
int slot = ourArmy.getSlotFor(it->first);
SlotID slot = ourArmy.getSlotFor(it->first);
ourArmy.addToSlot(slot, it->first, it->second);
}
for (TSlots::const_iterator i = ourArmy.Slots().begin(); i != ourArmy.Slots().end(); i++)

View File

@ -617,8 +617,8 @@ public:
std::string nodeName() const override;
void deserializationFix();
void recreateBuildingsBonuses();
bool addBonusIfBuilt(BuildingID building, int type, int val, TPropagatorPtr prop, int subtype = -1); //returns true if building is built and bonus has been added
bool addBonusIfBuilt(BuildingID building, int type, int val, int subtype = -1); //convienence version of above
bool addBonusIfBuilt(BuildingID building, Bonus::BonusType type, int val, TPropagatorPtr prop, int subtype = -1); //returns true if building is built and bonus has been added
bool addBonusIfBuilt(BuildingID building, Bonus::BonusType type, int val, int subtype = -1); //convienence version of above
void setVisitingHero(CGHeroInstance *h);
void setGarrisonedHero(CGHeroInstance *h);
const CArmedInstance *getUpperArmy() const; //garrisoned hero if present or the town itself
@ -1015,7 +1015,7 @@ protected:
class DLL_LINKAGE CGTeleport : public CGObjectInstance //teleports and subterranean gates
{
public:
static std::map<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
void onHeroVisit(const CGHeroInstance * h) const override;
void initObj() override;
@ -1291,7 +1291,7 @@ class DLL_LINKAGE CGObelisk : public CPlayersVisited
{
public:
static ui8 obeliskCount; //how many obelisks are on map
static std::map<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 initObj() override;

View File

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

View File

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

View File

@ -223,6 +223,21 @@ class ObjectInstanceID : public BaseForID<ObjectInstanceID>
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
// extern template std::ostream & operator << <ArtifactInstanceID>(std::ostream & os, BaseForID<ArtifactInstanceID> 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 si64 TExpType;
typedef std::pair<ui32, ui32> TDmgRange;
typedef ui8 TBonusType;
typedef si32 TBonusSubtype;
typedef si32 TSlot;
typedef si32 TQuantity;
typedef ui8 TPlayerColor;
typedef ui8 TTeamID;
#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 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
#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
#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
#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(ONE_BATTLE)
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(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(ONLY_DISTANCE_FIGHT)
BONUS_ITEM(ONLY_MELEE_FIGHT)
@ -1128,7 +1128,7 @@ std::string Bonus::Description() const
return str.str();
}
Bonus::Bonus(ui16 Dur, ui8 Type, BonusSource Src, si32 Val, ui32 ID, std::string Desc, si32 Subtype/*=-1*/)
Bonus::Bonus(ui16 Dur, BonusType Type, BonusSource Src, si32 Val, ui32 ID, std::string Desc, si32 Subtype/*=-1*/)
: duration(Dur), type(Type), subtype(Subtype), source(Src), val(Val), sid(ID), description(Desc)
{
additionalInfo = -1;
@ -1138,7 +1138,7 @@ Bonus::Bonus(ui16 Dur, ui8 Type, BonusSource Src, si32 Val, ui32 ID, std::string
boost::algorithm::trim(description);
}
Bonus::Bonus(ui16 Dur, ui8 Type, BonusSource Src, si32 Val, ui32 ID, si32 Subtype/*=-1*/, ValueType ValType /*= ADDITIVE_VALUE*/)
Bonus::Bonus(ui16 Dur, BonusType Type, BonusSource Src, si32 Val, ui32 ID, si32 Subtype/*=-1*/, ValueType ValType /*= ADDITIVE_VALUE*/)
: duration(Dur), type(Type), subtype(Subtype), source(Src), val(Val), sid(ID), valType(ValType)
{
additionalInfo = -1;
@ -1176,7 +1176,7 @@ CSelector DLL_LINKAGE operator||(const CSelector &first, const CSelector &second
namespace Selector
{
DLL_LINKAGE CSelectFieldEqual<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<si32> info(&Bonus::additionalInfo, 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 CWillLastTurns turns;
CSelector DLL_LINKAGE typeSubtype(TBonusType Type, TBonusSubtype Subtype)
CSelector DLL_LINKAGE typeSubtype(Bonus::BonusType Type, TBonusSubtype Subtype)
{
return type(Type) && subtype(Subtype);
}
CSelector DLL_LINKAGE typeSubtypeInfo(TBonusType type, TBonusSubtype subtype, si32 info)
CSelector DLL_LINKAGE typeSubtypeInfo(Bonus::BonusType type, TBonusSubtype subtype, si32 info)
{
return CSelectFieldEqual<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)
@ -1209,14 +1209,14 @@ namespace Selector
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;
dummy.type = type;
return sel(&dummy);
}
bool DLL_LINKAGE matchesTypeSubtype(const CSelector &sel, TBonusType type, TBonusSubtype subtype)
bool DLL_LINKAGE matchesTypeSubtype(const CSelector &sel, Bonus::BonusType type, TBonusSubtype subtype)
{
Bonus dummy;
dummy.type = type;
@ -1285,7 +1285,7 @@ DLL_LINKAGE std::ostream & operator<<(std::ostream &out, const BonusList &bonusL
DLL_LINKAGE std::ostream & operator<<(std::ostream &out, const Bonus &bonus)
{
for(std::map<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)
out << "\tType: " << i->first << " \t";
@ -1361,12 +1361,12 @@ void CCreatureTypeLimiter::setCreature (CreatureID id)
creature = VLC->creh->creatures[id];
}
HasAnotherBonusLimiter::HasAnotherBonusLimiter( TBonusType bonus )
HasAnotherBonusLimiter::HasAnotherBonusLimiter( Bonus::BonusType bonus )
: type(bonus), subtype(0), isSubtypeRelevant(false)
{
}
HasAnotherBonusLimiter::HasAnotherBonusLimiter( TBonusType bonus, TBonusSubtype _subtype )
HasAnotherBonusLimiter::HasAnotherBonusLimiter( Bonus::BonusType bonus, TBonusSubtype _subtype )
: type(bonus), subtype(_subtype), isSubtypeRelevant(true)
{
}

View File

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

View File

@ -286,7 +286,7 @@ const CGTownInstance* CGameInfoCallback::getTown(ObjectInstanceID objid) const
return NULL;
}
void CGameInfoCallback::getUpgradeInfo(const CArmedInstance *obj, int stackPos, UpgradeInfo &out) const
void CGameInfoCallback::getUpgradeInfo(const CArmedInstance *obj, SlotID stackPos, UpgradeInfo &out) const
{
//boost::shared_lock<boost::shared_mutex> lock(*gs->mx);
ERROR_RET_IF(!canGetFullInfo(obj), "Cannot get info about not owned object!");

View File

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

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 )
{
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["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["turns"].Float() = bonus->turnsRemain;
node["sourceID"].Float() = bonus->source;
node["description"].String() = bonus->description;
node["effectRange"].String() = reverseMapFirst<std::string, int>(bonus->effectRange, bonusLimitEffect);
node["duration"].String() = reverseMapFirst<std::string, int>(bonus->duration, bonusDurationMap);
node["source"].String() = reverseMapFirst<std::string, int>(bonus->source, bonusSourceMap);
node["effectRange"].String() = reverseMapFirst<std::string, Bonus::LimitEffect>(bonus->effectRange, bonusLimitEffect);
node["duration"].String() = reverseMapFirst<std::string, ui16>(bonus->duration, bonusDurationMap);
node["source"].String() = reverseMapFirst<std::string, Bonus::BonusSource>(bonus->source, bonusSourceMap);
if(bonus->limiter)
{
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
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();
//type will be set during initialization
cre->putStack(0, hlp);
cre->putStack(SlotID(0), hlp);
cre->character = reader.readUInt8();
@ -1515,7 +1515,7 @@ void CMapLoaderH3M::readCreatureSet(CCreatureSet * out, int number)
hlp->setType(creID);
}
out->putStack(ir, hlp);
out->putStack(SlotID(ir), hlp);
}
out->validTypes(true);

View File

@ -174,23 +174,16 @@ public:
struct StackLocation
{
ConstTransitivePtr<CArmedInstance> army;
TSlot slot;
SlotID slot;
StackLocation()
{
slot = -1;
}
StackLocation(const CArmedInstance *Army, TSlot Slot)
{}
StackLocation(const CArmedInstance *Army, SlotID Slot)
{
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;
}
bool validSlot() const
{
return slot >= 0 && slot < GameConstants::ARMY_SIZE;
}
DLL_LINKAGE const CStackInstance *getStack();
template <typename Handler> void serialize(Handler &h, const int version)
{
@ -1816,11 +1809,11 @@ struct CastleTeleportHero : public CPackForServer
struct ArrangeStacks : public CPackForServer
{
ArrangeStacks(){};
ArrangeStacks(ui8 W, ui8 P1, ui8 P2, ObjectInstanceID ID1, ObjectInstanceID ID2, si32 VAL)
ArrangeStacks(ui8 W, SlotID P1, SlotID P2, ObjectInstanceID ID1, ObjectInstanceID ID2, si32 VAL)
:what(W),p1(P1),p2(P2),id1(ID1),id2(ID2),val(VAL) {};
ui8 what; //1 - swap; 2 - merge; 3 - split
ui8 p1, p2; //positions of first and second stack
SlotID p1, p2; //positions of first and second stack
ObjectInstanceID id1, id2; //ids of objects with garrison
si32 val;
bool applyGh(CGameHandler *gh);
@ -1833,8 +1826,8 @@ struct ArrangeStacks : public CPackForServer
struct DisbandCreature : public CPackForServer
{
DisbandCreature(){};
DisbandCreature(ui8 Pos, ObjectInstanceID ID):pos(Pos),id(ID){};
ui8 pos; //stack pos
DisbandCreature(SlotID Pos, ObjectInstanceID ID):pos(Pos),id(ID){};
SlotID pos; //stack pos
ObjectInstanceID id; //object id
bool applyGh(CGameHandler *gh);
@ -1882,8 +1875,8 @@ struct RecruitCreatures : public CPackForServer
struct UpgradeCreature : public CPackForServer
{
UpgradeCreature(){};
UpgradeCreature(ui8 Pos, ObjectInstanceID ID, CreatureID CRID):pos(Pos),id(ID), cid(CRID){};
ui8 pos; //stack pos
UpgradeCreature(SlotID Pos, ObjectInstanceID ID, CreatureID CRID):pos(Pos),id(ID), cid(CRID){};
SlotID pos; //stack pos
ObjectInstanceID id; //object id
CreatureID cid; //id of type to which we want make upgrade
@ -1923,12 +1916,12 @@ struct ExchangeArtifacts : public CPackForServer
struct AssembleArtifacts : public CPackForServer
{
AssembleArtifacts(){};
AssembleArtifacts(ObjectInstanceID _heroID, ArtifactPosition _artifactSlot, bool _assemble, ui32 _assembleTo)
AssembleArtifacts(ObjectInstanceID _heroID, ArtifactPosition _artifactSlot, bool _assemble, ArtifactID _assembleTo)
: heroID(_heroID), artifactSlot(_artifactSlot), assemble(_assemble), assembleTo(_assembleTo){};
ObjectInstanceID heroID;
ArtifactPosition artifactSlot;
bool assemble; // True to assemble artifact, false to disassemble.
ui32 assembleTo; // Artifact to assemble into.
ArtifactID assembleTo; // Artifact to assemble into.
bool applyGh(CGameHandler *gh);
template <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->gainedArtifact = ArtifactID::NONE;
cre->identifier = -1;
cre->addToSlot(0, new CStackInstance(CreatureID(subID), -1)); //add placeholder stack
cre->addToSlot(SlotID(0), new CStackInstance(CreatureID(subID), -1)); //add placeholder stack
}
break;
default:
@ -1460,7 +1460,7 @@ DLL_LINKAGE void BattleStackAdded::applyGs(CGameState *gs)
}
CStackBasicDescriptor csbd(creID, amount);
CStack * addedStack = gs->curB->generateNewStack(csbd, attacker, 255, pos); //TODO: netpacks?
CStack * addedStack = gs->curB->generateNewStack(csbd, attacker, SlotID(255), pos); //TODO: netpacks?
if (summoned)
addedStack->state.insert(EBattleStackState::SUMMONED);

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

View File

@ -209,23 +209,23 @@ public:
bool buildBoat( ObjectInstanceID objid );
bool setFormation( ObjectInstanceID hid, ui8 formation );
bool tradeResources(const IMarket *market, ui32 val, TPlayerColor player, ui32 id1, ui32 id2);
bool sacrificeCreatures(const IMarket *market, const CGHeroInstance *hero, TSlot slot, ui32 count);
bool sacrificeCreatures(const IMarket *market, const CGHeroInstance *hero, SlotID slot, ui32 count);
bool sendResources(ui32 val, TPlayerColor player, Res::ERes r1, TPlayerColor r2);
bool sellCreatures(ui32 count, const IMarket *market, const CGHeroInstance * hero, ui32 slot, Res::ERes resourceID);
bool transformInUndead(const IMarket *market, const CGHeroInstance * hero, ui32 slot);
bool assembleArtifacts (ObjectInstanceID heroID, ArtifactPosition artifactSlot, bool assemble, ui32 assembleTo);
bool sellCreatures(ui32 count, const IMarket *market, const CGHeroInstance * hero, SlotID slot, Res::ERes resourceID);
bool transformInUndead(const IMarket *market, const CGHeroInstance * hero, SlotID slot);
bool assembleArtifacts (ObjectInstanceID heroID, ArtifactPosition artifactSlot, bool assemble, ArtifactID assembleTo);
bool buyArtifact( ObjectInstanceID hid, ArtifactID aid ); //for blacksmith and mage guild only -> buying for gold in common buildings
bool buyArtifact( const IMarket *m, const CGHeroInstance *h, Res::ERes rid, ArtifactID aid); //for artifact merchant and black market -> buying for any resource in special building / advobject
bool sellArtifact( const IMarket *m, const CGHeroInstance *h, ArtifactInstanceID aid, Res::ERes rid); //for artifact merchant selling
//void lootArtifacts (TArtHolder source, TArtHolder dest, std::vector<ui32> &arts); //after battle - move al arts to winer
bool buySecSkill( const IMarket *m, const CGHeroInstance *h, SecondarySkill skill);
bool garrisonSwap(ObjectInstanceID tid);
bool upgradeCreature( ObjectInstanceID objid, ui8 pos, CreatureID upgID );
bool upgradeCreature( ObjectInstanceID objid, SlotID pos, CreatureID upgID );
bool recruitCreatures(ObjectInstanceID objid, CreatureID crid, ui32 cram, si32 level);
bool buildStructure(ObjectInstanceID tid, BuildingID bid, bool force=false);//force - for events: no cost, no checkings
bool razeStructure(ObjectInstanceID tid, BuildingID bid);
bool disbandCreature( ObjectInstanceID id, ui8 pos );
bool arrangeStacks( ObjectInstanceID id1, ObjectInstanceID id2, ui8 what, ui8 p1, ui8 p2, si32 val, TPlayerColor player);
bool disbandCreature( ObjectInstanceID id, SlotID pos );
bool arrangeStacks( ObjectInstanceID id1, ObjectInstanceID id2, ui8 what, SlotID p1, SlotID p2, si32 val, TPlayerColor player);
void save(const std::string &fname);
void close();
void handleTimeEvents();

View File

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