mirror of
https://github.com/vcmi/vcmi.git
synced 2024-12-24 22:14:36 +02:00
* SlotID refactoring
This commit is contained in:
parent
d23a5dcfdf
commit
560315bc48
@ -92,6 +92,7 @@
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<AdditionalDependencies>VCMI_lib.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalOptions>-Zm150 %(AdditionalOptions)</AdditionalOptions>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
|
28
CCallback.h
28
CCallback.h
@ -51,20 +51,20 @@ public:
|
||||
virtual void recruitHero(const CGObjectInstance *townOrTavern, const CGHeroInstance *hero)=0;
|
||||
virtual bool buildBuilding(const CGTownInstance *town, BuildingID buildingID)=0;
|
||||
virtual void recruitCreatures(const CGObjectInstance *obj, CreatureID ID, ui32 amount, si32 level=-1)=0;
|
||||
virtual bool upgradeCreature(const CArmedInstance *obj, int stackPos, CreatureID newID=CreatureID::NONE)=0; //if newID==-1 then best possible upgrade will be made
|
||||
virtual bool upgradeCreature(const CArmedInstance *obj, SlotID stackPos, CreatureID newID=CreatureID::NONE)=0; //if newID==-1 then best possible upgrade will be made
|
||||
virtual void swapGarrisonHero(const CGTownInstance *town)=0;
|
||||
|
||||
virtual void trade(const CGObjectInstance *market, EMarketMode::EMarketMode mode, int id1, int id2, int val1, const CGHeroInstance *hero = NULL)=0; //mode==0: sell val1 units of id1 resource for id2 resiurce
|
||||
|
||||
virtual int selectionMade(int selection, int queryID) =0;
|
||||
virtual int swapCreatures(const CArmedInstance *s1, const CArmedInstance *s2, int p1, int p2)=0;//swaps creatures between two possibly different garrisons // TODO: AI-unsafe code - fix it!
|
||||
virtual int mergeStacks(const CArmedInstance *s1, const CArmedInstance *s2, int p1, int p2)=0;//joins first stack to the second (creatures must be same type)
|
||||
virtual int mergeOrSwapStacks(const CArmedInstance *s1, const CArmedInstance *s2, int p1, int p2) =0; //first goes to the second
|
||||
virtual int splitStack(const CArmedInstance *s1, const CArmedInstance *s2, int p1, int p2, int val)=0;//split creatures from the first stack
|
||||
virtual int swapCreatures(const CArmedInstance *s1, const CArmedInstance *s2, SlotID p1, SlotID p2)=0;//swaps creatures between two possibly different garrisons // TODO: AI-unsafe code - fix it!
|
||||
virtual int mergeStacks(const CArmedInstance *s1, const CArmedInstance *s2, SlotID p1, SlotID p2)=0;//joins first stack to the second (creatures must be same type)
|
||||
virtual int mergeOrSwapStacks(const CArmedInstance *s1, const CArmedInstance *s2, SlotID p1, SlotID p2) =0; //first goes to the second
|
||||
virtual int splitStack(const CArmedInstance *s1, const CArmedInstance *s2, SlotID p1, SlotID p2, int val)=0;//split creatures from the first stack
|
||||
//virtual bool swapArtifacts(const CGHeroInstance * hero1, ui16 pos1, const CGHeroInstance * hero2, ui16 pos2)=0; //swaps artifacts between two given heroes
|
||||
virtual bool swapArtifacts(const ArtifactLocation &l1, const ArtifactLocation &l2)=0;
|
||||
virtual bool assembleArtifacts(const CGHeroInstance * hero, ArtifactPosition artifactSlot, bool assemble, ui32 assembleTo)=0;
|
||||
virtual bool dismissCreature(const CArmedInstance *obj, int stackPos)=0;
|
||||
virtual bool assembleArtifacts(const CGHeroInstance * hero, ArtifactPosition artifactSlot, bool assemble, ArtifactID assembleTo)=0;
|
||||
virtual bool dismissCreature(const CArmedInstance *obj, SlotID stackPos)=0;
|
||||
virtual void endTurn()=0;
|
||||
virtual void buyArtifact(const CGHeroInstance *hero, ArtifactID aid)=0; //used to buy artifacts in towns (including spell book in the guild and war machines in blacksmith)
|
||||
virtual void setFormation(const CGHeroInstance * hero, bool tight)=0;
|
||||
@ -118,20 +118,20 @@ public:
|
||||
bool moveHero(const CGHeroInstance *h, int3 dst); //dst must be free, neighbouring tile (this function can move hero only by one tile)
|
||||
bool teleportHero(const CGHeroInstance *who, const CGTownInstance *where);
|
||||
int selectionMade(int selection, int queryID);
|
||||
int swapCreatures(const CArmedInstance *s1, const CArmedInstance *s2, int p1, int p2);
|
||||
int mergeOrSwapStacks(const CArmedInstance *s1, const CArmedInstance *s2, int p1, int p2); //first goes to the second
|
||||
int mergeStacks(const CArmedInstance *s1, const CArmedInstance *s2, int p1, int p2); //first goes to the second
|
||||
int splitStack(const CArmedInstance *s1, const CArmedInstance *s2, int p1, int p2, int val);
|
||||
int swapCreatures(const CArmedInstance *s1, const CArmedInstance *s2, SlotID p1, SlotID p2);
|
||||
int mergeOrSwapStacks(const CArmedInstance *s1, const CArmedInstance *s2, SlotID p1, SlotID p2); //first goes to the second
|
||||
int mergeStacks(const CArmedInstance *s1, const CArmedInstance *s2, SlotID p1, SlotID p2); //first goes to the second
|
||||
int splitStack(const CArmedInstance *s1, const CArmedInstance *s2, SlotID p1, SlotID p2, int val);
|
||||
bool dismissHero(const CGHeroInstance * hero);
|
||||
//bool swapArtifacts(const CGHeroInstance * hero1, ui16 pos1, const CGHeroInstance * hero2, ui16 pos2);
|
||||
bool swapArtifacts(const ArtifactLocation &l1, const ArtifactLocation &l2);
|
||||
//bool moveArtifact(const CGHeroInstance * hero, ui16 src, const CStackInstance * stack, ui16 dest); // TODO: unify classes
|
||||
//bool moveArtifact(const CStackInstance * stack, ui16 src , const CGHeroInstance * hero, ui16 dest); // TODO: unify classes
|
||||
bool assembleArtifacts(const CGHeroInstance * hero, ArtifactPosition artifactSlot, bool assemble, ui32 assembleTo);
|
||||
bool assembleArtifacts(const CGHeroInstance * hero, ArtifactPosition artifactSlot, bool assemble, ArtifactID assembleTo);
|
||||
bool buildBuilding(const CGTownInstance *town, BuildingID buildingID) OVERRIDE;
|
||||
void recruitCreatures(const CGObjectInstance *obj, CreatureID ID, ui32 amount, si32 level=-1);
|
||||
bool dismissCreature(const CArmedInstance *obj, int stackPos);
|
||||
bool upgradeCreature(const CArmedInstance *obj, int stackPos, CreatureID newID=CreatureID::NONE) OVERRIDE;
|
||||
bool dismissCreature(const CArmedInstance *obj, SlotID stackPos);
|
||||
bool upgradeCreature(const CArmedInstance *obj, SlotID stackPos, CreatureID newID=CreatureID::NONE) OVERRIDE;
|
||||
void endTurn();
|
||||
void swapGarrisonHero(const CGTownInstance *town);
|
||||
void buyArtifact(const CGHeroInstance *hero, ArtifactID aid) OVERRIDE;
|
||||
|
@ -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)));
|
||||
}
|
||||
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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++)
|
||||
|
@ -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
|
||||
};
|
||||
|
||||
|
@ -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();
|
||||
|
@ -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";
|
||||
|
@ -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
|
||||
|
@ -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 %
|
||||
|
@ -21,7 +21,7 @@
|
||||
*
|
||||
*/
|
||||
|
||||
const CStackInstance &CCreatureSet::operator[](TSlot slot) const
|
||||
const CStackInstance &CCreatureSet::operator[](SlotID slot) const
|
||||
{
|
||||
TSlots::const_iterator i = stacks.find(slot);
|
||||
if (i != stacks.end())
|
||||
@ -30,7 +30,7 @@ const CStackInstance &CCreatureSet::operator[](TSlot slot) const
|
||||
throw std::runtime_error("That slot is empty!");
|
||||
}
|
||||
|
||||
const CCreature* CCreatureSet::getCreature(TSlot slot) const
|
||||
const CCreature* CCreatureSet::getCreature(SlotID slot) const
|
||||
{
|
||||
TSlots::const_iterator i = stacks.find(slot);
|
||||
if (i != stacks.end())
|
||||
@ -39,9 +39,9 @@ const CCreature* CCreatureSet::getCreature(TSlot slot) const
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bool CCreatureSet::setCreature(TSlot slot, CreatureID type, TQuantity quantity) /*slots 0 to 6 */
|
||||
bool CCreatureSet::setCreature(SlotID slot, CreatureID type, TQuantity quantity) /*slots 0 to 6 */
|
||||
{
|
||||
if(slot > 6 || slot < 0)
|
||||
if(!slot.validSlot())
|
||||
{
|
||||
tlog1 << "Cannot set slot " << slot << std::endl;
|
||||
return false;
|
||||
@ -60,12 +60,12 @@ bool CCreatureSet::setCreature(TSlot slot, CreatureID type, TQuantity quantity)
|
||||
return true;
|
||||
}
|
||||
|
||||
TSlot CCreatureSet::getSlotFor(CreatureID creature, ui32 slotsAmount/*=7*/) const /*returns -1 if no slot available */
|
||||
SlotID CCreatureSet::getSlotFor(CreatureID creature, ui32 slotsAmount/*=7*/) const /*returns -1 if no slot available */
|
||||
{
|
||||
return getSlotFor(VLC->creh->creatures[creature], slotsAmount);
|
||||
}
|
||||
|
||||
TSlot CCreatureSet::getSlotFor(const CCreature *c, ui32 slotsAmount/*=ARMY_SIZE*/) const
|
||||
SlotID CCreatureSet::getSlotFor(const CCreature *c, ui32 slotsAmount/*=ARMY_SIZE*/) const
|
||||
{
|
||||
assert(c->valid());
|
||||
for(TSlots::const_iterator i=stacks.begin(); i!=stacks.end(); ++i)
|
||||
@ -76,29 +76,22 @@ TSlot CCreatureSet::getSlotFor(const CCreature *c, ui32 slotsAmount/*=ARMY_SIZE*
|
||||
return i->first; //if there is already such creature we return its slot id
|
||||
}
|
||||
}
|
||||
return getFreeSlot(slotsAmount);
|
||||
}
|
||||
|
||||
SlotID CCreatureSet::getFreeSlot(ui32 slotsAmount/*=ARMY_SIZE*/) const
|
||||
{
|
||||
for(ui32 i=0; i<slotsAmount; i++)
|
||||
{
|
||||
if(stacks.find(i) == stacks.end())
|
||||
if(!vstd::contains(stacks, SlotID(i)))
|
||||
{
|
||||
return i; //return first free slot
|
||||
return SlotID(i); //return first free slot
|
||||
}
|
||||
}
|
||||
return -1; //no slot available
|
||||
return SlotID(); //no slot available
|
||||
}
|
||||
|
||||
TSlot CCreatureSet::getFreeSlot(ui32 slotsAmount/*=ARMY_SIZE*/) const
|
||||
{
|
||||
for (ui32 i = 0; i < slotsAmount; i++)
|
||||
{
|
||||
if(stacks.find(i) == stacks.end())
|
||||
{
|
||||
return i; //return first free slot
|
||||
}
|
||||
}
|
||||
return -1; //no slot available
|
||||
}
|
||||
|
||||
int CCreatureSet::getStackCount(TSlot slot) const
|
||||
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);
|
||||
|
@ -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;
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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++)
|
||||
|
@ -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;
|
||||
|
@ -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];
|
||||
|
@ -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) \
|
||||
{ \
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
{
|
||||
}
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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!");
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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)) );
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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();
|
||||
|
@ -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:
|
||||
|
Loading…
Reference in New Issue
Block a user