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

* fixed opening custom campaign selection window

* artifact positions refactored
* vstd::advance allows moving between enum values
This commit is contained in:
mateuszb 2013-02-06 23:24:43 +00:00
parent c3a1d10988
commit af5287c193
26 changed files with 201 additions and 188 deletions

View File

@ -153,7 +153,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, ui16 artifactSlot, bool assemble, ui32 assembleTo)
bool CCallback::assembleArtifacts (const CGHeroInstance * hero, ArtifactPosition::ArtifactPosition artifactSlot, bool assemble, ui32 assembleTo)
{
if (player != hero->tempOwner)
return false;

View File

@ -63,7 +63,7 @@ public:
virtual int splitStack(const CArmedInstance *s1, const CArmedInstance *s2, int p1, int 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, ui16 artifactSlot, bool assemble, ui32 assembleTo)=0;
virtual bool assembleArtifacts(const CGHeroInstance * hero, ArtifactPosition::ArtifactPosition artifactSlot, bool assemble, ui32 assembleTo)=0;
virtual bool dismissCreature(const CArmedInstance *obj, int stackPos)=0;
virtual void endTurn()=0;
virtual void buyArtifact(const CGHeroInstance *hero, int aid)=0; //used to buy artifacts in towns (including spell book in the guild and war machines in blacksmith)
@ -126,7 +126,7 @@ public:
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, ui16 artifactSlot, bool assemble, ui32 assembleTo);
bool assembleArtifacts(const CGHeroInstance * hero, ArtifactPosition::ArtifactPosition artifactSlot, bool assemble, ui32 assembleTo);
bool buildBuilding(const CGTownInstance *town, si32 buildingID);
void recruitCreatures(const CGObjectInstance *obj, ui32 ID, ui32 amount, si32 level=-1);
bool dismissCreature(const CArmedInstance *obj, int stackPos);

View File

@ -494,6 +494,12 @@ namespace vstd
{
return v.at(retreiveRandNum(randGen) % v.size());
}
template<typename T>
void advance(T &obj, int change)
{
obj = (T)(((int)obj) + change);
}
}
using std::shared_ptr;

View File

@ -639,7 +639,7 @@ void CCreatureWindow::scrollArt(int dir)
{
//TODO: get next artifact
int size = stack->artifactsWorn.size();
displayedArtifact = size ? (displayedArtifact + dir) % size : ArtifactPosition::CREATURE_SLOT;
displayedArtifact = size ? static_cast<ArtifactPosition::ArtifactPosition>((displayedArtifact + dir) % size) : ArtifactPosition::CREATURE_SLOT;
setArt (stack->getArt(displayedArtifact));
}
@ -661,12 +661,12 @@ void CCreatureWindow::artifactRemoved (const ArtifactLocation &artLoc)
//align artifacts to remove holes
BOOST_FOREACH (auto al, stack->artifactsWorn)
{
int freeSlot = al.second.artifact->firstAvailableSlot(stack);
ArtifactPosition::ArtifactPosition freeSlot = al.second.artifact->firstAvailableSlot(stack);
if (freeSlot < al.first)
LOCPLINT->cb->swapArtifacts (ArtifactLocation(stack, al.first), ArtifactLocation(stack, freeSlot));
}
int size = stack->artifactsWorn.size();
displayedArtifact = size ? (displayedArtifact % size) : ArtifactPosition::CREATURE_SLOT; //0
displayedArtifact = size ? static_cast<ArtifactPosition::ArtifactPosition>(displayedArtifact % size) : ArtifactPosition::CREATURE_SLOT; //0
setArt (stack->getArt(displayedArtifact));
}
void CCreatureWindow::artifactMoved (const ArtifactLocation &artLoc, const ArtifactLocation &destLoc)

View File

@ -45,7 +45,7 @@ public:
//bool active; //TODO: comment me
CreWinType type;
int bonusRows; //height of skill window
int displayedArtifact;
ArtifactPosition::ArtifactPosition displayedArtifact;
std::string count; //creature count in text format
const CCreature *c; //related creature

View File

@ -298,7 +298,7 @@ void CHeroWindow::commanderWindow()
{
const CGHeroInstance *srcHero = commonInfo->src.AOH->getHero();
//artSelected = true;
int freeSlot = art->firstAvailableSlot (curHero->commander);
ArtifactPosition::ArtifactPosition freeSlot = art->firstAvailableSlot (curHero->commander);
if (freeSlot < ArtifactPosition::COMMANDER_AFTER_LAST) //we don't want to put it in commander's backpack!
{
ArtifactLocation src (srcHero, commonInfo->src.slotID);

View File

@ -578,7 +578,7 @@ void processCommand(const std::string &message)
{
BOOST_FOREACH(const CGHeroInstance *h, LOCPLINT->cb->getHeroesInfo())
if(h->type->ID == id1)
if(const CArtifactInstance *a = h->getArt(id2))
if(const CArtifactInstance *a = h->getArt(static_cast<ArtifactPosition::ArtifactPosition>(id2)))
tlog4 << a->nodeName();
}
}

View File

@ -1153,6 +1153,7 @@ void SelectionTab::parseGames(const std::vector<ResourceID> &files, bool multi)
void SelectionTab::parseCampaigns(const std::vector<ResourceID> & files )
{
allItems.resize(files.size());
for(int i=0; i<files.size(); i++)
{
//allItems[i].date = std::asctime(std::localtime(&files[i].date));
@ -1494,7 +1495,7 @@ void SelectionTab::showAll(SDL_Surface * to)
title = CGI->generaltexth->arraytxt[231];
break;
case CMenuScreen::campaignList:
title = CGI->generaltexth->arraytxt[726];
title = CGI->generaltexth->allTexts[726];
break;
}

View File

@ -186,8 +186,8 @@ public:
void tryJoiningArmy(const CArmedInstance *src, const CArmedInstance *dst, bool removeObjWhenFinished, bool allowMerging) OVERRIDE {}
bool moveStack(const StackLocation &src, const StackLocation &dst, TQuantity count = -1) OVERRIDE {return false;}
void giveHeroNewArtifact(const CGHeroInstance *h, const CArtifact *artType, int pos) OVERRIDE {};
void giveHeroArtifact(const CGHeroInstance *h, const CArtifactInstance *a, int pos) OVERRIDE {};
void giveHeroNewArtifact(const CGHeroInstance *h, const CArtifact *artType, ArtifactPosition::ArtifactPosition pos) OVERRIDE {};
void giveHeroArtifact(const CGHeroInstance *h, const CArtifactInstance *a, ArtifactPosition::ArtifactPosition pos) OVERRIDE {};
void putArtifact(const ArtifactLocation &al, const CArtifactInstance *a) OVERRIDE {};
void removeArtifact(const ArtifactLocation &al) OVERRIDE {};
bool moveArtifact(const ArtifactLocation &al1, const ArtifactLocation &al2) OVERRIDE {return false;};

View File

@ -3165,9 +3165,9 @@ void CAltarWindow::SacrificeAll()
}
else
{
for(std::map<ui16, ArtSlotInfo>::const_iterator i = hero->artifactsWorn.begin(); i != hero->artifactsWorn.end(); i++)
for(auto i = hero->artifactsWorn.cbegin(); i != hero->artifactsWorn.cend(); i++)
{
if(i->second.artifact->artType->id != 145) //ignore locks from assembled artifacts
if(i->second.artifact->artType->id != ArtifactID::ART_LOCK) //ignore locks from assembled artifacts
moveFromSlotToAltar(i->first, NULL, i->second.artifact);
}
@ -3385,9 +3385,9 @@ bool CAltarWindow::putOnAltar(CTradeableItem* altarSlot, const CArtifactInstance
return true;
}
void CAltarWindow::moveFromSlotToAltar(int slotID, CTradeableItem* altarSlot, const CArtifactInstance *art)
void CAltarWindow::moveFromSlotToAltar(ArtifactPosition::ArtifactPosition slotID, CTradeableItem* altarSlot, const CArtifactInstance *art)
{
int freeBackpackSlot = hero->artifactsInBackpack.size() + GameConstants::BACKPACK_START;
auto freeBackpackSlot = static_cast<ArtifactPosition::ArtifactPosition>(hero->artifactsInBackpack.size() + GameConstants::BACKPACK_START);
if(arts->commonInfo->src.art)
{
arts->commonInfo->dst.slotID = freeBackpackSlot;
@ -3771,7 +3771,7 @@ CTavernWindow::HeroPortrait::HeroPortrait(int &sel, int id, int x, int y, const
int artifs = h->artifactsWorn.size() + h->artifactsInBackpack.size();
for(int i=13; i<=17; i++) //war machines and spellbook don't count
if(vstd::contains(h->artifactsWorn,i))
if(vstd::contains(h->artifactsWorn,static_cast<ArtifactPosition::ArtifactPosition>(i)))
artifs--;
sprintf_s(descr, sizeof(descr),CGI->generaltexth->allTexts[215].c_str(),
h->name.c_str(), h->level, h->type->heroClass->name.c_str(), artifs);
@ -4182,21 +4182,22 @@ void CArtPlace::clickLeft(tribool down, bool previousState)
switch(cur->id)
{
case 3:
case ArtifactID::CATAPULT:
//should not happen, catapult cannot be selected
assert(cur->id != 3);
assert(cur->id != ArtifactID::CATAPULT);
break;
case 4: case 5: case 6: //war machines cannot go to backpack
LOCPLINT->showInfoDialog(boost::str(boost::format(CGI->generaltexth->allTexts[153]) % cur->Name()));
break;
default:
setMeAsDest();
vstd::amin(ourOwner->commonInfo->dst.slotID, ourOwner->curHero->artifactsInBackpack.size() + GameConstants::BACKPACK_START);
vstd::amin(ourOwner->commonInfo->dst.slotID, static_cast<ArtifactPosition::ArtifactPosition>(
ourOwner->curHero->artifactsInBackpack.size() + GameConstants::BACKPACK_START));
if(srcInBackpack && srcInSameHero)
{
if(!ourArt //cannot move from backpack to AFTER backpack -> combined with vstd::amin above it will guarantee that dest is at most the last artifact
|| ourOwner->commonInfo->src.slotID < ourOwner->commonInfo->dst.slotID) //rearranging arts in backpack after taking src artifact, the dest id will be shifted
ourOwner->commonInfo->dst.slotID--;
vstd::advance(ourOwner->commonInfo->dst.slotID, -1);
}
if(srcInSameHero && ourOwner->commonInfo->dst.slotID == ourOwner->commonInfo->src.slotID) //we came to src == dst
deselect();
@ -4588,7 +4589,7 @@ void CArtifactsOfHero::setHero(const CGHeroInstance * hero)
// Fill the slots for worn artifacts and backpack.
for (int g = 0; g < artWorn.size() ; g++)
setSlotData(artWorn[g], g);
setSlotData(artWorn[g], static_cast<ArtifactPosition::ArtifactPosition>(g));
scrollBackpack(0);
}
@ -4622,7 +4623,7 @@ void CArtifactsOfHero::scrollBackpack(int dir)
if (s < artsInBackpack)
{
int slotID = GameConstants::BACKPACK_START + (s + backpackPos)%artsInBackpack;
auto slotID = static_cast<ArtifactPosition::ArtifactPosition>(GameConstants::BACKPACK_START + (s + backpackPos)%artsInBackpack);
const CArtifactInstance *art = curHero->getArt(slotID);
assert(art);
if(!vstd::contains(toOmit, art))
@ -4639,7 +4640,7 @@ void CArtifactsOfHero::scrollBackpack(int dir)
}
}
for( ; s - omitedSoFar < backpack.size(); s++)
eraseSlotData(backpack[s-omitedSoFar], GameConstants::BACKPACK_START + s);
eraseSlotData(backpack[s-omitedSoFar], static_cast<ArtifactPosition::ArtifactPosition>(GameConstants::BACKPACK_START + s));
//in artifact merchant selling artifacts we may have highlight on one of backpack artifacts -> market needs update, cause artifact under highlight changed
if(highlightModeCallback)
@ -4706,7 +4707,7 @@ void CArtifactsOfHero::unmarkLocalSlots(bool withRedraw /*= true*/)
/**
* Assigns an artifacts to an artifact place depending on it's new slot ID.
*/
void CArtifactsOfHero::setSlotData(CArtPlace* artPlace, int slotID)
void CArtifactsOfHero::setSlotData(CArtPlace* artPlace, ArtifactPosition::ArtifactPosition slotID)
{
if(!artPlace && slotID >= GameConstants::BACKPACK_START) //spurious call from artifactMoved in attempt to update hidden backpack slot
{
@ -4728,7 +4729,7 @@ void CArtifactsOfHero::setSlotData(CArtPlace* artPlace, int slotID)
/**
* Makes given artifact slot appear as empty with a certain slot ID.
*/
void CArtifactsOfHero::eraseSlotData (CArtPlace* artPlace, int slotID)
void CArtifactsOfHero::eraseSlotData (CArtPlace* artPlace, ArtifactPosition::ArtifactPosition slotID)
{
artPlace->pickSlot(false);
artPlace->slotID = slotID;
@ -4754,14 +4755,14 @@ CArtifactsOfHero::CArtifactsOfHero(std::vector<CArtPlace *> ArtWorn, std::vector
for (size_t g = 0; g < artWorn.size() ; g++)
{
artWorn[g]->ourOwner = this;
eraseSlotData(artWorn[g], g);
eraseSlotData(artWorn[g], static_cast<ArtifactPosition::ArtifactPosition>(g));
}
// Init slots for the backpack.
for(size_t s=0; s<backpack.size(); ++s)
{
backpack[s]->ourOwner = this;
eraseSlotData(backpack[s], GameConstants::BACKPACK_START + s);
eraseSlotData(backpack[s], static_cast<ArtifactPosition::ArtifactPosition>(GameConstants::BACKPACK_START + s));
}
leftArtRoll->callback += boost::bind(&CArtifactsOfHero::scrollBackpack,this,-1);
@ -4791,11 +4792,11 @@ CArtifactsOfHero::CArtifactsOfHero(const Point& position, bool createCommonPart
Point(381,296);
// Create slots for worn artifacts.
for (size_t g = 0; g < 19 ; g++)
for (size_t g = 0; g < GameConstants::BACKPACK_START ; g++)
{
artWorn[g] = new CArtPlace(slotPos[g]);
artWorn[g]->ourOwner = this;
eraseSlotData(artWorn[g], g);
eraseSlotData(artWorn[g], static_cast<ArtifactPosition::ArtifactPosition>(g));
}
// Create slots for the backpack.
@ -4804,7 +4805,7 @@ CArtifactsOfHero::CArtifactsOfHero(const Point& position, bool createCommonPart
CArtPlace * add = new CArtPlace(Point(403 + 46 * s, 365));
add->ourOwner = this;
eraseSlotData(add, 19 + s);
eraseSlotData(add, static_cast<ArtifactPosition::ArtifactPosition>(GameConstants::BACKPACK_START + s));
backpack.push_back(add);
}
@ -4930,7 +4931,7 @@ void CArtifactsOfHero::artifactMoved(const ArtifactLocation &src, const Artifact
src.isHolder(commonInfo->src.AOH->curHero)) //artifact taken from before currently picked one
{
//int fixedSlot = src.hero->getArtPos(commonInfo->src.art);
commonInfo->src.slotID--;
vstd::advance(commonInfo->src.slotID, -1);
assert(commonInfo->src.valid());
}
else
@ -4998,7 +4999,7 @@ void CArtifactsOfHero::artifactDisassembled(const ArtifactLocation &al)
void CArtifactsOfHero::updateWornSlots(bool redrawParent /*= true*/)
{
for(int i = 0; i < artWorn.size(); i++)
updateSlot(i);
updateSlot(static_cast<ArtifactPosition::ArtifactPosition>(i));
if(redrawParent)
@ -5010,7 +5011,7 @@ const CGHeroInstance * CArtifactsOfHero::getHero() const
return curHero;
}
void CArtifactsOfHero::updateSlot(int slotID)
void CArtifactsOfHero::updateSlot(ArtifactPosition::ArtifactPosition slotID)
{
setSlotData(getArtPlace(slotID), slotID);
}
@ -5952,7 +5953,7 @@ void CWindowWithArtifacts::artifactAssembled(const ArtifactLocation &artLoc)
void CArtifactsOfHero::SCommonPart::Artpos::clear()
{
slotID = -1;
slotID = ArtifactPosition::PRE_FIRST;
AOH = NULL;
art = NULL;
}

View File

@ -7,6 +7,7 @@
#include "../lib/GameConstants.h"
#include "UIFramework/CIntObject.h"
#include "UIFramework/CIntObjectClasses.h"
#include "../lib/GameConstants.h"
#ifdef max
#undef max
@ -725,7 +726,7 @@ public:
void artifactPicked();
int firstFreeSlot();
void moveFromSlotToAltar(int slotID, CTradeableItem* altarSlot, const CArtifactInstance *art);
void moveFromSlotToAltar(ArtifactPosition::ArtifactPosition slotID, CTradeableItem* altarSlot, const CArtifactInstance *art);
};
class CSystemOptionsWindow : public CWindowObject
@ -897,7 +898,7 @@ public:
bool picked;
bool marked;
int slotID; //Arts::EPOS enum + backpack starting from Arts::BACKPACK_START
ArtifactPosition::ArtifactPosition slotID; //Arts::EPOS enum + backpack starting from Arts::BACKPACK_START
void lockSlot(bool on);
void pickSlot(bool on);
@ -932,7 +933,7 @@ public:
{
struct Artpos
{
int slotID;
ArtifactPosition::ArtifactPosition slotID;
const CArtifactsOfHero *AOH;
const CArtifactInstance *art;
@ -971,11 +972,11 @@ public:
void markPossibleSlots(const CArtifactInstance* art);
void unmarkSlots(bool withRedraw = true); //unmarks slots in all visible AOHs
void unmarkLocalSlots(bool withRedraw = true); //unmarks slots in that particular AOH
void setSlotData (CArtPlace* artPlace, int slotID);
void setSlotData (CArtPlace* artPlace, ArtifactPosition::ArtifactPosition slotID);
void updateWornSlots (bool redrawParent = true);
void updateSlot(int i);
void eraseSlotData (CArtPlace* artPlace, int slotID);
void updateSlot(ArtifactPosition::ArtifactPosition i);
void eraseSlotData (CArtPlace* artPlace, ArtifactPosition::ArtifactPosition slotID);
CArtifactsOfHero(const Point& position, bool createCommonPart = false);
//Alternative constructor, used if custom artifacts positioning required (Kingdom interface)

View File

@ -512,22 +512,22 @@ BattleInfo * BattleInfo::setupBattle( int3 tile, ETerrainType::ETerrainType terr
if(!creatureBank)
{
//Checks if hero has artifact and create appropriate stack
auto handleWarMachine= [&](int side, int artslot, int cretype, int hex)
auto handleWarMachine= [&](int side, ArtifactPosition::ArtifactPosition artslot, int cretype, int hex)
{
if(heroes[side] && heroes[side]->getArt(artslot))
stacks.push_back(curB->generateNewStack(CStackBasicDescriptor(cretype, 1), !side, 255, hex));
};
handleWarMachine(0, 13, 146, 52); //ballista
handleWarMachine(0, 14, 148, 18); //ammo cart
handleWarMachine(0, 15, 147, 154);//first aid tent
handleWarMachine(0, ArtifactPosition::MACH1, 146, 52); //ballista
handleWarMachine(0, ArtifactPosition::MACH2, 148, 18); //ammo cart
handleWarMachine(0, ArtifactPosition::MACH3, 147, 154);//first aid tent
if(town && town->hasFort())
handleWarMachine(0, 16, 145, 120);//catapult
handleWarMachine(0, ArtifactPosition::MACH4, 145, 120);//catapult
if(!town) //defending hero shouldn't receive ballista (bug #551)
handleWarMachine(1, 13, 146, 66); //ballista
handleWarMachine(1, 14, 148, 32); //ammo cart
handleWarMachine(1, 15, 147, 168); //first aid tent
handleWarMachine(1, ArtifactPosition::MACH1, 146, 66); //ballista
handleWarMachine(1, ArtifactPosition::MACH2, 148, 32); //ammo cart
handleWarMachine(1, ArtifactPosition::MACH3, 147, 168); //first aid tent
}
//war machines added

View File

@ -38,7 +38,7 @@ const std::map<std::string, CArtifact::EartClass> artifactClassMap = boost::assi
#define ART_POS(x) ( #x, ArtifactPosition::x )
const std::map<std::string, int> artifactPositionMap = boost::assign::map_list_of
const std::map<std::string, ArtifactPosition::ArtifactPosition> artifactPositionMap = boost::assign::map_list_of
ART_POS(HEAD)
ART_POS(SHOULDERS)
ART_POS(NECK)
@ -323,7 +323,7 @@ void CArtHandler::loadArtifacts(bool onlyTxt)
for(int j=0;j<slots.size();j++)
{
if(parser.readString() == "x")
nart.possibleSlots[ArtBearer::HERO].push_back(slots[j]);
nart.possibleSlots[ArtBearer::HERO].push_back(static_cast<ArtifactPosition::ArtifactPosition>(slots[j]));
}
nart.aClass = classes[parser.readString()[0]];
@ -692,7 +692,7 @@ void CArtHandler::makeItCommanderArt (CArtifact * a, bool onlyCommander /*= true
a->possibleSlots[ArtBearer::CREATURE].clear();
}
for (int i = ArtifactPosition::COMMANDER1; i <= ArtifactPosition::COMMANDER6; ++i)
a->possibleSlots[ArtBearer::COMMANDER].push_back(i);
a->possibleSlots[ArtBearer::COMMANDER].push_back(static_cast<ArtifactPosition::ArtifactPosition>(i));
}
void CArtHandler::makeItCommanderArt( TArtifactInstanceID aid, bool onlyCommander /*= true*/ )
@ -863,9 +863,9 @@ void CArtifactInstance::init()
setNodeType(ARTIFACT_INSTANCE);
}
int CArtifactInstance::firstAvailableSlot(const CArtifactSet *h) const
ArtifactPosition::ArtifactPosition CArtifactInstance::firstAvailableSlot(const CArtifactSet *h) const
{
BOOST_FOREACH(ui16 slot, artType->possibleSlots[h->bearerType()])
BOOST_FOREACH(auto slot, artType->possibleSlots[h->bearerType()])
{
if(canBePutAt(h, slot)) //if(artType->fitsAt(h->artifWorn, slot))
{
@ -878,12 +878,13 @@ int CArtifactInstance::firstAvailableSlot(const CArtifactSet *h) const
return firstBackpackSlot(h);
}
int CArtifactInstance::firstBackpackSlot(const CArtifactSet *h) const
ArtifactPosition::ArtifactPosition CArtifactInstance::firstBackpackSlot(const CArtifactSet *h) const
{
if(!artType->isBig()) //discard big artifact
return GameConstants::BACKPACK_START + h->artifactsInBackpack.size();
return static_cast<ArtifactPosition::ArtifactPosition>(
GameConstants::BACKPACK_START + h->artifactsInBackpack.size());
return -1;
return ArtifactPosition::PRE_FIRST;
}
bool CArtifactInstance::canBePutAt(const ArtifactLocation al, bool assumeDestRemoved /*= false*/) const
@ -891,7 +892,7 @@ bool CArtifactInstance::canBePutAt(const ArtifactLocation al, bool assumeDestRem
return canBePutAt(al.getHolderArtSet(), al.slot, assumeDestRemoved);
}
bool CArtifactInstance::canBePutAt(const CArtifactSet *artSet, int slot, bool assumeDestRemoved /*= false*/) const
bool CArtifactInstance::canBePutAt(const CArtifactSet *artSet, ArtifactPosition::ArtifactPosition slot, bool assumeDestRemoved /*= false*/) const
{
if(slot >= GameConstants::BACKPACK_START)
{
@ -1023,7 +1024,7 @@ bool CArtifactInstance::isPart(const CArtifactInstance *supposedPart) const
return supposedPart == this;
}
bool CCombinedArtifactInstance::canBePutAt(const CArtifactSet *artSet, int slot, bool assumeDestRemoved /*= false*/) const
bool CCombinedArtifactInstance::canBePutAt(const CArtifactSet *artSet, ArtifactPosition::ArtifactPosition slot, bool assumeDestRemoved /*= false*/) const
{
bool canMainArtifactBePlaced = CArtifactInstance::canBePutAt(artSet, slot, assumeDestRemoved);
if(!canMainArtifactBePlaced)
@ -1046,9 +1047,9 @@ bool CCombinedArtifactInstance::canBePutAt(const CArtifactSet *artSet, int slot,
//we iterate over all active slots and check if constituents fits them
for (int i = 0; i < GameConstants::BACKPACK_START; i++)
{
for(std::vector<ConstituentInfo>::iterator art = constituentsToBePlaced.begin(); art != constituentsToBePlaced.end(); art++)
for(auto art = constituentsToBePlaced.begin(); art != constituentsToBePlaced.end(); art++)
{
if(art->art->canBePutAt(artSet, i, i == slot)) // i == al.slot because we can remove already worn artifact only from that slot that is our main destination
if(art->art->canBePutAt(artSet, static_cast<ArtifactPosition::ArtifactPosition>(i), i == slot)) // i == al.slot because we can remove already worn artifact only from that slot that is our main destination
{
constituentsToBePlaced.erase(art);
break;
@ -1080,11 +1081,11 @@ void CCombinedArtifactInstance::createConstituents()
BOOST_FOREACH(ui32 a, *artType->constituents)
{
addAsConstituent(CArtifactInstance::createNewArtifactInstance(a), -1);
addAsConstituent(CArtifactInstance::createNewArtifactInstance(a), ArtifactPosition::PRE_FIRST);
}
}
void CCombinedArtifactInstance::addAsConstituent(CArtifactInstance *art, int slot)
void CCombinedArtifactInstance::addAsConstituent(CArtifactInstance *art, ArtifactPosition::ArtifactPosition slot)
{
assert(vstd::contains(*artType->constituents, art->artType->id));
assert(art->getParentNodes().size() == 1 && art->getParentNodes().front() == art->artType);
@ -1098,7 +1099,7 @@ void CCombinedArtifactInstance::putAt(ArtifactLocation al)
{
CArtifactInstance::putAt(al);
BOOST_FOREACH(ConstituentInfo &ci, constituentsInfo)
ci.slot = -1;
ci.slot = ArtifactPosition::PRE_FIRST;
}
else
{
@ -1113,7 +1114,7 @@ void CCombinedArtifactInstance::putAt(ArtifactLocation al)
const bool inActiveSlot = vstd::isbetween(ci.slot, 0, GameConstants::BACKPACK_START);
const bool suggestedPosValid = ci.art->canBePutAt(suggestedPos);
int pos = -1;
ArtifactPosition::ArtifactPosition pos = ArtifactPosition::PRE_FIRST;
if(inActiveSlot && suggestedPosValid) //there is a valid suggestion where to place lock
pos = ci.slot;
else
@ -1124,7 +1125,7 @@ void CCombinedArtifactInstance::putAt(ArtifactLocation al)
}
else
{
ci.slot = -1;
ci.slot = ArtifactPosition::PRE_FIRST;
}
}
}
@ -1143,7 +1144,7 @@ void CCombinedArtifactInstance::removeFrom(ArtifactLocation al)
if(ci.slot >= 0)
{
al.getHolderArtSet()->eraseArtSlot(ci.slot);
ci.slot = -1;
ci.slot = ArtifactPosition::PRE_FIRST;
}
else
{
@ -1195,7 +1196,7 @@ bool CCombinedArtifactInstance::isPart(const CArtifactInstance *supposedPart) co
return false;
}
CCombinedArtifactInstance::ConstituentInfo::ConstituentInfo(CArtifactInstance *Art /*= NULL*/, ui16 Slot /*= -1*/)
CCombinedArtifactInstance::ConstituentInfo::ConstituentInfo(CArtifactInstance *Art /*= NULL*/, ArtifactPosition::ArtifactPosition Slot /*= -1*/)
{
art = Art;
slot = Slot;
@ -1206,7 +1207,7 @@ bool CCombinedArtifactInstance::ConstituentInfo::operator==(const ConstituentInf
return art == rhs.art && slot == rhs.slot;
}
const CArtifactInstance* CArtifactSet::getArt(ui16 pos, bool excludeLocked /*= true*/) const
const CArtifactInstance* CArtifactSet::getArt(ArtifactPosition::ArtifactPosition pos, bool excludeLocked /*= true*/) const
{
if(const ArtSlotInfo *si = getSlot(pos))
{
@ -1217,59 +1218,59 @@ const CArtifactInstance* CArtifactSet::getArt(ui16 pos, bool excludeLocked /*= t
return NULL;
}
CArtifactInstance* CArtifactSet::getArt(ui16 pos, bool excludeLocked /*= true*/)
CArtifactInstance* CArtifactSet::getArt(ArtifactPosition::ArtifactPosition pos, bool excludeLocked /*= true*/)
{
return const_cast<CArtifactInstance*>((const_cast<const CArtifactSet*>(this))->getArt(pos, excludeLocked));
}
si32 CArtifactSet::getArtPos(int aid, bool onlyWorn /*= true*/) const
ArtifactPosition::ArtifactPosition CArtifactSet::getArtPos(int aid, bool onlyWorn /*= true*/) const
{
for(std::map<ui16, ArtSlotInfo>::const_iterator i = artifactsWorn.begin(); i != artifactsWorn.end(); i++)
for(auto i = artifactsWorn.cbegin(); i != artifactsWorn.cend(); i++)
if(i->second.artifact->artType->id == aid)
return i->first;
if(onlyWorn)
return -1;
return ArtifactPosition::PRE_FIRST;
for(int i = 0; i < artifactsInBackpack.size(); i++)
if(artifactsInBackpack[i].artifact->artType->id == aid)
return GameConstants::BACKPACK_START + i;
return static_cast<ArtifactPosition::ArtifactPosition>(GameConstants::BACKPACK_START + i);
return -1;
return ArtifactPosition::PRE_FIRST;
}
si32 CArtifactSet::getArtPos(const CArtifactInstance *art) const
ArtifactPosition::ArtifactPosition CArtifactSet::getArtPos(const CArtifactInstance *art) const
{
for(std::map<ui16, ArtSlotInfo>::const_iterator i = artifactsWorn.begin(); i != artifactsWorn.end(); i++)
if(i->second.artifact == art)
return i->first;
BOOST_FOREACH(auto i, artifactsWorn)
if(i.second.artifact == art)
return i.first;
for(int i = 0; i < artifactsInBackpack.size(); i++)
if(artifactsInBackpack[i].artifact == art)
return GameConstants::BACKPACK_START + i;
return static_cast<ArtifactPosition::ArtifactPosition>(GameConstants::BACKPACK_START + i);
return -1;
return ArtifactPosition::PRE_FIRST;
}
const CArtifactInstance * CArtifactSet::getArtByInstanceId( TArtifactInstanceID artInstId ) const
{
for(std::map<ui16, ArtSlotInfo>::const_iterator i = artifactsWorn.begin(); i != artifactsWorn.end(); i++)
if(i->second.artifact->id == artInstId)
return i->second.artifact;
BOOST_FOREACH(auto i, artifactsWorn)
if(i.second.artifact->id == artInstId)
return i.second.artifact;
for(int i = 0; i < artifactsInBackpack.size(); i++)
if(artifactsInBackpack[i].artifact->id == artInstId)
return artifactsInBackpack[i].artifact;
BOOST_FOREACH(auto i, artifactsInBackpack)
if(i.artifact->id == artInstId)
return i.artifact;
return NULL;
}
bool CArtifactSet::hasArt(ui32 aid, bool onlyWorn /*= false*/) const
{
return getArtPos(aid, onlyWorn) != -1;
return getArtPos(aid, onlyWorn) != ArtifactPosition::PRE_FIRST;
}
const ArtSlotInfo * CArtifactSet::getSlot(ui16 pos) const
const ArtSlotInfo * CArtifactSet::getSlot(ArtifactPosition::ArtifactPosition pos) const
{
if(vstd::contains(artifactsWorn, pos))
return &artifactsWorn[pos];
@ -1285,7 +1286,7 @@ const ArtSlotInfo * CArtifactSet::getSlot(ui16 pos) const
return NULL;
}
bool CArtifactSet::isPositionFree(ui16 pos, bool onlyLockCheck /*= false*/) const
bool CArtifactSet::isPositionFree(ArtifactPosition::ArtifactPosition pos, bool onlyLockCheck /*= false*/) const
{
if(const ArtSlotInfo *s = getSlot(pos))
return (onlyLockCheck || !s->artifact) && !s->locked;
@ -1293,7 +1294,7 @@ bool CArtifactSet::isPositionFree(ui16 pos, bool onlyLockCheck /*= false*/) cons
return true; //no slot means not used
}
si32 CArtifactSet::getArtTypeId(ui16 pos) const
si32 CArtifactSet::getArtTypeId(ArtifactPosition::ArtifactPosition pos) const
{
const CArtifactInstance * const a = getArt(pos);
if(!a)
@ -1309,7 +1310,7 @@ CArtifactSet::~CArtifactSet()
}
ArtSlotInfo & CArtifactSet::retreiveNewArtSlot(ui16 slot)
ArtSlotInfo & CArtifactSet::retreiveNewArtSlot(ArtifactPosition::ArtifactPosition slot)
{
assert(!vstd::contains(artifactsWorn, slot));
ArtSlotInfo &ret = slot < GameConstants::BACKPACK_START
@ -1319,14 +1320,14 @@ ArtSlotInfo & CArtifactSet::retreiveNewArtSlot(ui16 slot)
return ret;
}
void CArtifactSet::setNewArtSlot(ui16 slot, CArtifactInstance *art, bool locked)
void CArtifactSet::setNewArtSlot(ArtifactPosition::ArtifactPosition slot, CArtifactInstance *art, bool locked)
{
ArtSlotInfo &asi = retreiveNewArtSlot(slot);
asi.artifact = art;
asi.locked = locked;
}
void CArtifactSet::eraseArtSlot(ui16 slot)
void CArtifactSet::eraseArtSlot(ArtifactPosition::ArtifactPosition slot)
{
if(slot < GameConstants::BACKPACK_START)
{
@ -1334,14 +1335,14 @@ void CArtifactSet::eraseArtSlot(ui16 slot)
}
else
{
slot -= GameConstants::BACKPACK_START;
slot = static_cast<ArtifactPosition::ArtifactPosition>(slot - GameConstants::BACKPACK_START);
artifactsInBackpack.erase(artifactsInBackpack.begin() + slot);
}
}
void CArtifactSet::artDeserializationFix(CBonusSystemNode *node)
{
for(bmap<ui16, ArtSlotInfo>::iterator i = artifactsWorn.begin(); i != artifactsWorn.end(); i++)
for(auto i = artifactsWorn.begin(); i != artifactsWorn.end(); i++)
if(i->second.artifact && !i->second.locked)
node->attachTo(i->second.artifact);
}

View File

@ -4,6 +4,7 @@
#include "../lib/HeroBonus.h"
#include "../lib/ConstTransitivePtr.h"
#include "JsonNode.h"
#include "GameConstants.h"
/*
* CArtHandler.h, part of VCMI engine
@ -21,20 +22,6 @@ struct ArtifactLocation;
class CArtifactSet;
class CArtifactInstance;
namespace ArtifactPosition
{
enum ArtifactPosition
{
PRE_FIRST = -1,
HEAD, SHOULDERS, NECK, RIGHT_HAND, LEFT_HAND, TORSO, RIGHT_RING, LEFT_RING, FEET, MISC1, MISC2, MISC3, MISC4,
MACH1, MACH2, MACH3, MACH4, SPELLBOOK, MISC5,
AFTER_LAST,
//cres
CREATURE_SLOT = 0,
COMMANDER1 = 0, COMMANDER2, COMMANDER3, COMMANDER4, COMMANDER5, COMMANDER6, COMMANDER_AFTER_LAST
};
}
namespace ArtifactID
{
enum ArtifactID
@ -48,7 +35,8 @@ namespace ArtifactID
FIRST_AID_TENT = 6,
CENTAUR_AXE = 7,
BLACKSHARD_OF_THE_DEAD_KNIGHT = 8,
CORNUCOPIA = 140
CORNUCOPIA = 140,
ART_LOCK = 145
};
}
@ -96,7 +84,7 @@ public:
virtual void levelUpArtifact (CArtifactInstance * art){};
ui32 price;
bmap<ui8, std::vector<ui16> > possibleSlots; //Bearer Type => ids of slots where artifact can be placed
bmap<ui8, std::vector<ArtifactPosition::ArtifactPosition> > possibleSlots; //Bearer Type => ids of slots where artifact can be placed
std::vector<TArtifactID> * constituents; // Artifacts IDs a combined artifact consists of, or NULL.
std::vector<TArtifactID> * constituentOf; // Reverse map of constituents.
EartClass aClass;
@ -148,11 +136,11 @@ public:
void deserializationFix();
void setType(CArtifact *Art);
int firstAvailableSlot(const CArtifactSet *h) const;
int firstBackpackSlot(const CArtifactSet *h) const;
ArtifactPosition::ArtifactPosition firstAvailableSlot(const CArtifactSet *h) const;
ArtifactPosition::ArtifactPosition firstBackpackSlot(const CArtifactSet *h) const;
int getGivenSpellID() const; //to be used with scrolls (and similar arts), -1 if none
virtual bool canBePutAt(const CArtifactSet *artSet, int slot, bool assumeDestRemoved = false) const;
virtual bool canBePutAt(const CArtifactSet *artSet, ArtifactPosition::ArtifactPosition slot, bool assumeDestRemoved = false) const;
bool canBePutAt(const ArtifactLocation al, bool assumeDestRemoved = false) const; //forwards to the above one
virtual bool canBeDisassembled() const;
virtual void putAt(ArtifactLocation al);
@ -181,26 +169,26 @@ public:
struct ConstituentInfo
{
ConstTransitivePtr<CArtifactInstance> art;
si16 slot;
ArtifactPosition::ArtifactPosition slot;
template <typename Handler> void serialize(Handler &h, const int version)
{
h & art & slot;
}
bool operator==(const ConstituentInfo &rhs) const;
ConstituentInfo(CArtifactInstance *art = NULL, ui16 slot = -1);
ConstituentInfo(CArtifactInstance *art = NULL, ArtifactPosition::ArtifactPosition slot = ArtifactPosition::PRE_FIRST);
};
std::vector<ConstituentInfo> constituentsInfo;
bool canBePutAt(const CArtifactSet *artSet, int slot, bool assumeDestRemoved = false) const OVERRIDE;
bool canBePutAt(const CArtifactSet *artSet, ArtifactPosition::ArtifactPosition slot, bool assumeDestRemoved = false) const OVERRIDE;
bool canBeDisassembled() const OVERRIDE;
void putAt(ArtifactLocation al) OVERRIDE;
void removeFrom(ArtifactLocation al) OVERRIDE;
bool isPart(const CArtifactInstance *supposedPart) const OVERRIDE;
void createConstituents();
void addAsConstituent(CArtifactInstance *art, int slot);
void addAsConstituent(CArtifactInstance *art, ArtifactPosition::ArtifactPosition slot);
CArtifactInstance *figureMainConstituent(const ArtifactLocation al); //main constituent is replcaed with us (combined art), not lock
CCombinedArtifactInstance();
@ -291,21 +279,21 @@ class DLL_LINKAGE CArtifactSet
{
public:
std::vector<ArtSlotInfo> artifactsInBackpack; //hero's artifacts from bag
bmap<ui16, ArtSlotInfo> artifactsWorn; //map<position,artifact_id>; positions: 0 - head; 1 - shoulders; 2 - neck; 3 - right hand; 4 - left hand; 5 - torso; 6 - right ring; 7 - left ring; 8 - feet; 9 - misc1; 10 - misc2; 11 - misc3; 12 - misc4; 13 - mach1; 14 - mach2; 15 - mach3; 16 - mach4; 17 - spellbook; 18 - misc5
bmap<ArtifactPosition::ArtifactPosition, ArtSlotInfo> artifactsWorn; //map<position,artifact_id>; positions: 0 - head; 1 - shoulders; 2 - neck; 3 - right hand; 4 - left hand; 5 - torso; 6 - right ring; 7 - left ring; 8 - feet; 9 - misc1; 10 - misc2; 11 - misc3; 12 - misc4; 13 - mach1; 14 - mach2; 15 - mach3; 16 - mach4; 17 - spellbook; 18 - misc5
ArtSlotInfo &retreiveNewArtSlot(ui16 slot);
void setNewArtSlot(ui16 slot, CArtifactInstance *art, bool locked);
void eraseArtSlot(ui16 slot);
ArtSlotInfo &retreiveNewArtSlot(ArtifactPosition::ArtifactPosition slot);
void setNewArtSlot(ArtifactPosition::ArtifactPosition slot, CArtifactInstance *art, bool locked);
void eraseArtSlot(ArtifactPosition::ArtifactPosition slot);
const ArtSlotInfo *getSlot(ui16 pos) const;
const CArtifactInstance* getArt(ui16 pos, bool excludeLocked = true) const; //NULL - no artifact
CArtifactInstance* getArt(ui16 pos, bool excludeLocked = true); //NULL - no artifact
si32 getArtPos(int aid, bool onlyWorn = true) const; //looks for equipped artifact with given ID and returns its slot ID or -1 if none(if more than one such artifact lower ID is returned)
si32 getArtPos(const CArtifactInstance *art) const;
const ArtSlotInfo *getSlot(ArtifactPosition::ArtifactPosition pos) const;
const CArtifactInstance* getArt(ArtifactPosition::ArtifactPosition pos, bool excludeLocked = true) const; //NULL - no artifact
CArtifactInstance* getArt(ArtifactPosition::ArtifactPosition pos, bool excludeLocked = true); //NULL - no artifact
ArtifactPosition::ArtifactPosition getArtPos(int aid, bool onlyWorn = true) const; //looks for equipped artifact with given ID and returns its slot ID or -1 if none(if more than one such artifact lower ID is returned)
ArtifactPosition::ArtifactPosition getArtPos(const CArtifactInstance *art) const;
const CArtifactInstance *getArtByInstanceId(TArtifactInstanceID artInstId) const;
bool hasArt(ui32 aid, bool onlyWorn = false) const; //checks if hero possess artifact of given id (either in backack or worn)
bool isPositionFree(ui16 pos, bool onlyLockCheck = false) const;
si32 getArtTypeId(ui16 pos) const;
bool isPositionFree(ArtifactPosition::ArtifactPosition pos, bool onlyLockCheck = false) const;
si32 getArtTypeId(ArtifactPosition::ArtifactPosition pos) const;
virtual ui8 bearerType() const = 0;
virtual ~CArtifactSet();

View File

@ -1298,7 +1298,7 @@ void CGameState::init(StartInfo * si)
size_t totalArts = GameConstants::BACKPACK_START + oldHero->artifactsInBackpack.size();
for (size_t i=0; i<totalArts; i++ )
{
const ArtSlotInfo *info = oldHero->getSlot(i);
const ArtSlotInfo *info = oldHero->getSlot(static_cast<ArtifactPosition::ArtifactPosition>(i));
if (!info)
continue;
@ -1309,9 +1309,9 @@ void CGameState::init(StartInfo * si)
int id = art->artType->id;
assert( 8*18 > id );//number of arts that fits into h3m format
bool takeable = travelOptions.artifsKeptByHero[id / 8] & ( 1 << (id%8) );
auto slot = static_cast<ArtifactPosition::ArtifactPosition>(i);
if (takeable)
hero->setNewArtSlot(i, const_cast<CArtifactInstance*>(oldHero->getSlot(i)->artifact.get()), false);
hero->setNewArtSlot(slot, const_cast<CArtifactInstance*>(oldHero->getSlot(slot)->artifact.get()), false);
}
}
@ -1716,7 +1716,7 @@ void CGameState::initDuel()
BOOST_FOREACH(auto &parka, ss.artifacts)
{
h->putArtifact(parka.first, parka.second);
h->putArtifact(static_cast<ArtifactPosition::ArtifactPosition>(parka.first), parka.second);
}
typedef const std::pair<si32, si8> &TSecSKill;

View File

@ -841,9 +841,9 @@ void CGHeroInstance::initArmy(IArmyDescriptor *dst /*= NULL*/)
slot = 9 + aid;
break;
}
if(!getArt(slot))
putArtifact(slot, CArtifactInstance::createNewArtifactInstance(aid));
auto convSlot = static_cast<ArtifactPosition::ArtifactPosition>(slot);
if(!getArt(convSlot))
putArtifact(convSlot, CArtifactInstance::createNewArtifactInstance(aid));
else
tlog3 << "Hero " << name << " already has artifact at " << slot << ", omitting giving " << aid << std::endl;
}
@ -1335,7 +1335,7 @@ ui8 CGHeroInstance::getSpellSchoolLevel(const CSpell * spell, int *outSelectedSc
bool CGHeroInstance::canCastThisSpell(const CSpell * spell) const
{
if(!getArt(17)) //if hero has no spellbook
if(!getArt(ArtifactPosition::SPELLBOOK)) //if hero has no spellbook
return false;
if(vstd::contains(spells, spell->id) //hero has this spell in spellbook
@ -1510,7 +1510,7 @@ std::string CGHeroInstance::nodeName() const
return "Hero " + name;
}
void CGHeroInstance::putArtifact(ui16 pos, CArtifactInstance *art)
void CGHeroInstance::putArtifact(ArtifactPosition::ArtifactPosition pos, CArtifactInstance *art)
{
assert(!getArt(pos));
art->putAt(ArtifactLocation(this, pos));
@ -1828,9 +1828,9 @@ void CGDwelling::heroAcceptsCreatures( const CGHeroInstance *h, ui32 answer ) co
SetAvailableCreatures sac;
sac.tid = id;
sac.creatures = creatures;
sac.creatures[0].first = !h->getArt(13); //ballista
sac.creatures[1].first = !h->getArt(15); //first aid tent
sac.creatures[2].first = !h->getArt(14); //ammo cart
sac.creatures[0].first = !h->getArt(ArtifactPosition::MACH1); //ballista
sac.creatures[1].first = !h->getArt(ArtifactPosition::MACH3); //first aid tent
sac.creatures[2].first = !h->getArt(ArtifactPosition::MACH2); //ammo cart
cb->sendAndApply(&sac);
}
@ -3874,7 +3874,7 @@ void CGArtifact::onHeroVisit( const CGHeroInstance * h ) const
void CGArtifact::pick(const CGHeroInstance * h) const
{
cb->giveHeroArtifact(h, storedArtifact, -2);
cb->giveHeroArtifact(h, storedArtifact, ArtifactPosition::FIRST_AVAILABLE);
cb->removeObject(id);
}
@ -4032,7 +4032,7 @@ void CGPickable::onHeroVisit( const CGHeroInstance * h ) const
//TODO: what if no space in backpack?
iw.components.push_back(Component(Component::ARTIFACT, val2, 1, 0));
iw.text.addReplacement(MetaString::ART_NAMES, val2);
cb->giveHeroNewArtifact(h, VLC->arth->artifacts[val2],-2);
cb->giveHeroNewArtifact(h, VLC->arth->artifacts[val2],ArtifactPosition::FIRST_AVAILABLE);
}
cb->showInfoDialog(&iw);
break;
@ -4045,7 +4045,7 @@ void CGPickable::onHeroVisit( const CGHeroInstance * h ) const
iw.components.push_back(Component(Component::ARTIFACT,val1,1,0));
iw.text.addTxt(MetaString::ADVOB_TXT, 125);
iw.text.addReplacement(MetaString::ART_NAMES, val1);
cb->giveHeroNewArtifact(h, VLC->arth->artifacts[val1],-2);
cb->giveHeroNewArtifact(h, VLC->arth->artifacts[val1],ArtifactPosition::FIRST_AVAILABLE);
cb->showInfoDialog(&iw);
break;
}
@ -4059,7 +4059,7 @@ void CGPickable::onHeroVisit( const CGHeroInstance * h ) const
if(type) //there is an artifact
{
cb->giveHeroNewArtifact(h, VLC->arth->artifacts[val1],-2);
cb->giveHeroNewArtifact(h, VLC->arth->artifacts[val1],ArtifactPosition::FIRST_AVAILABLE);
InfoWindow iw;
iw.soundID = soundBase::treasure;
iw.player = h->tempOwner;
@ -4730,7 +4730,7 @@ void CGSeerHut::completeQuest (const CGHeroInstance * h) const //reward
cb->changeSecSkill(h->id, static_cast<SecondarySkill::SecondarySkill>(rID), rVal, false);
break;
case ARTIFACT:
cb->giveHeroNewArtifact(h, VLC->arth->artifacts[rID],-2);
cb->giveHeroNewArtifact(h, VLC->arth->artifacts[rID],ArtifactPosition::FIRST_AVAILABLE);
break;
case SPELL:
{
@ -5315,7 +5315,7 @@ void CGPandoraBox::giveContents( const CGHeroInstance *h, bool afterBattle ) con
cb->giveResource(h->getOwner(),static_cast<Res::ERes>(i),resources[i]);
for(int i=0; i<artifacts.size(); i++)
cb->giveHeroNewArtifact(h, VLC->arth->artifacts[artifacts[i]],-2);
cb->giveHeroNewArtifact(h, VLC->arth->artifacts[artifacts[i]],ArtifactPosition::FIRST_AVAILABLE);
iw.components.clear();
iw.text.clear();
@ -5554,7 +5554,7 @@ void CGScholar::onHeroVisit( const CGHeroInstance * h ) const
int ssl = h->getSecSkillLevel(static_cast<SecondarySkill::SecondarySkill>(bid)); //current sec skill level, used if bonusType == 1
if((type == SECONDARY_SKILL
&& ((ssl == 3) || (!ssl && !h->canLearnSkill()))) ////hero already has expert level in the skill or (don't know skill and doesn't have free slot)
|| (type == SPELL && (!h->getArt(17) || vstd::contains(h->spells, (ui32) bid)
|| (type == SPELL && (!h->getArt(ArtifactPosition::SPELLBOOK) || vstd::contains(h->spells, (ui32) bid)
|| (VLC->spellh->spells[bid]->level > h->getSecSkillLevel(SecondarySkill::WISDOM) + 2)
))) //hero doesn't have a spellbook or already knows the spell or doesn't have Wisdom
{
@ -5715,7 +5715,7 @@ void CGOnceVisitable::onHeroVisit( const CGHeroInstance * h ) const
break;
case 1: //art
iw.components.push_back(Component(Component::ARTIFACT,bonusType,0,0));
cb->giveHeroNewArtifact(h, VLC->arth->artifacts[bonusType],-2);
cb->giveHeroNewArtifact(h, VLC->arth->artifacts[bonusType],ArtifactPosition::FIRST_AVAILABLE);
iw.text.addTxt(MetaString::ADVOB_TXT, txtid);
if (ID == Obj::CORPSE)
{
@ -5833,7 +5833,7 @@ void CGOnceVisitable::searchTomb(const CGHeroInstance *h, ui32 accept) const
iw.components.push_back(Component(Component::ARTIFACT,bonusType,0,0));
iw.text.addReplacement(MetaString::ART_NAMES, bonusType);
cb->giveHeroNewArtifact(h, VLC->arth->artifacts[bonusType],-2);
cb->giveHeroNewArtifact(h, VLC->arth->artifacts[bonusType],ArtifactPosition::FIRST_AVAILABLE);
}
if(!h->hasBonusFrom(Bonus::OBJECT,ID)) //we don't have modifier from this object yet
@ -6162,7 +6162,7 @@ void CBank::endBattle (const CGHeroInstance *h, const BattleResult *result) cons
iw.components.push_back (Component (Component::ARTIFACT, *it, 0, 0));
loot << "%s";
loot.addReplacement(MetaString::ART_NAMES, *it);
cb->giveHeroNewArtifact (h, VLC->arth->artifacts[*it], -2);
cb->giveHeroNewArtifact (h, VLC->arth->artifacts[*it], ArtifactPosition::FIRST_AVAILABLE);
}
//display loot
if (!iw.components.empty())
@ -6262,7 +6262,7 @@ void CGPyramid::endBattle (const CGHeroInstance *h, const BattleResult *result)
iw.player = h->getOwner();
iw.text.addTxt (MetaString::ADVOB_TXT, 106);
iw.text.addTxt (MetaString::SPELL_NAME, spell);
if (!h->getArt(17))
if (!h->getArt(ArtifactPosition::SPELLBOOK))
iw.text.addTxt (MetaString::ADVOB_TXT, 109); //no spellbook
else if (h->getSecSkillLevel(SecondarySkill::WISDOM) < 3)
iw.text.addTxt (MetaString::ADVOB_TXT, 108); //no expert Wisdom

View File

@ -404,7 +404,7 @@ public:
void initHero();
void initHero(int SUBID);
void putArtifact(ui16 pos, CArtifactInstance *art);
void putArtifact(ArtifactPosition::ArtifactPosition pos, CArtifactInstance *art);
void putInBackpack(CArtifactInstance *art);
void initExp();
void initArmy(IArmyDescriptor *dst = NULL);

View File

@ -483,6 +483,20 @@ namespace PlayerRelations
enum PlayerRelations {ENEMIES, ALLIES, SAME_PLAYER};
}
namespace ArtifactPosition
{
enum ArtifactPosition
{
FIRST_AVAILABLE = -2,
PRE_FIRST = -1, //sometimes used as error, sometimes as first free in backpack
HEAD, SHOULDERS, NECK, RIGHT_HAND, LEFT_HAND, TORSO, RIGHT_RING, LEFT_RING, FEET, MISC1, MISC2, MISC3, MISC4,
MACH1, MACH2, MACH3, MACH4, SPELLBOOK, MISC5,
AFTER_LAST,
//cres
CREATURE_SLOT = 0,
COMMANDER1 = 0, COMMANDER2, COMMANDER3, COMMANDER4, COMMANDER5, COMMANDER6, COMMANDER_AFTER_LAST
};
}
// Typedef declarations
typedef si8 TFaction;

View File

@ -227,8 +227,8 @@ public:
virtual void tryJoiningArmy(const CArmedInstance *src, const CArmedInstance *dst, bool removeObjWhenFinished, bool allowMerging) =0; //merges army from src do dst or opens a garrison window
virtual bool moveStack(const StackLocation &src, const StackLocation &dst, TQuantity count) = 0;
virtual void giveHeroNewArtifact(const CGHeroInstance *h, const CArtifact *artType, int pos) = 0;
virtual void giveHeroArtifact(const CGHeroInstance *h, const CArtifactInstance *a, int pos) = 0; //pos==-1 - first free slot in backpack=0; pos==-2 - default if available or backpack
virtual void giveHeroNewArtifact(const CGHeroInstance *h, const CArtifact *artType, ArtifactPosition::ArtifactPosition pos) = 0;
virtual void giveHeroArtifact(const CGHeroInstance *h, const CArtifactInstance *a, ArtifactPosition::ArtifactPosition pos) = 0; //pos==-1 - first free slot in backpack=0; pos==-2 - default if available or backpack
virtual void putArtifact(const ArtifactLocation &al, const CArtifactInstance *a) = 0;
virtual void removeArtifact(const ArtifactLocation &al) = 0;
virtual bool moveArtifact(const ArtifactLocation &al1, const ArtifactLocation &al2) = 0;

View File

@ -369,7 +369,7 @@ void CCampaignScenario::prepareCrossoverHeroes( std::vector<CGHeroInstance *> he
size_t totalArts = GameConstants::BACKPACK_START + hero->artifactsInBackpack.size();
for (size_t i=0; i<totalArts; i++ )
{
const ArtSlotInfo *info = hero->getSlot(i);
const ArtSlotInfo *info = hero->getSlot(static_cast<ArtifactPosition::ArtifactPosition>(i));
if (!info)
continue;
@ -382,7 +382,7 @@ void CCampaignScenario::prepareCrossoverHeroes( std::vector<CGHeroInstance *> he
bool takeable = travelOptions.artifsKeptByHero[id / 8] & ( 1 << (id%8) );
if (!takeable)
hero->eraseArtSlot(i);
hero->eraseArtSlot(static_cast<ArtifactPosition::ArtifactPosition>(i));
}
}
}

View File

@ -661,7 +661,7 @@ bool CMapLoaderH3M::loadArtifactToSlot(CGHeroInstance * hero, int slot)
slot = ArtifactPosition::SPELLBOOK;
}
hero->putArtifact(slot, createArtifact(aid));
hero->putArtifact(static_cast<ArtifactPosition::ArtifactPosition>(slot), createArtifact(aid));
}
return isArt;

View File

@ -895,7 +895,6 @@ struct RebalanceStacks : CGarrisonOperationPack //526
}
};
typedef si32 TArtPos;
typedef boost::variant<ConstTransitivePtr<CGHeroInstance>, ConstTransitivePtr<CStackInstance> > TArtHolder;
//struct GetArtifactSet : boost::static_visitor<>
@ -913,20 +912,20 @@ struct ArtifactLocation
TArtHolder artHolder;
TArtPos slot;
ArtifactPosition::ArtifactPosition slot;
ArtifactLocation()
{
artHolder = ConstTransitivePtr<CGHeroInstance>();
slot = -1;
slot = ArtifactPosition::PRE_FIRST;
}
template <typename T>
ArtifactLocation(const T *ArtHolder, TArtPos Slot)
ArtifactLocation(const T *ArtHolder, ArtifactPosition::ArtifactPosition Slot)
{
artHolder = const_cast<T*>(ArtHolder); //we are allowed here to const cast -> change will go through one of our packages... do not abuse!
slot = Slot;
}
ArtifactLocation(TArtHolder ArtHolder, TArtPos Slot)
ArtifactLocation(TArtHolder ArtHolder, ArtifactPosition::ArtifactPosition Slot)
{
artHolder = ArtHolder;
slot = Slot;
@ -1902,10 +1901,10 @@ struct ExchangeArtifacts : public CPackForServer
struct AssembleArtifacts : public CPackForServer
{
AssembleArtifacts(){};
AssembleArtifacts(si32 _heroID, ui16 _artifactSlot, bool _assemble, ui32 _assembleTo)
AssembleArtifacts(si32 _heroID, ArtifactPosition::ArtifactPosition _artifactSlot, bool _assemble, ui32 _assembleTo)
: heroID(_heroID), artifactSlot(_artifactSlot), assemble(_assemble), assembleTo(_assembleTo){};
si32 heroID;
ui16 artifactSlot;
ArtifactPosition::ArtifactPosition artifactSlot;
bool assemble; // True to assemble artifact, false to disassemble.
ui32 assembleTo; // Artifact to assemble into.

View File

@ -811,7 +811,7 @@ DLL_LINKAGE void AssembledArtifact::applyGs( CGameState *gs )
//retrieve all constituents
BOOST_FOREACH(si32 constituentID, *builtArt->constituents)
{
int pos = artSet->getArtPos(constituentID);
ArtifactPosition::ArtifactPosition pos = artSet->getArtPos(constituentID);
assert(pos >= 0);
CArtifactInstance *constituentInstance = artSet->getArt(pos);

View File

@ -590,7 +590,8 @@ void CGameHandler::endBattle(int3 tile, const CGHeroInstance *hero1, const CGHer
{
//we assume that no big artifacts can be found
MoveArtifact ma;
ma.src = ArtifactLocation (loserHero, GameConstants::BACKPACK_START); //backpack automatically shifts arts to beginning
ma.src = ArtifactLocation (loserHero,
static_cast<ArtifactPosition::ArtifactPosition>(GameConstants::BACKPACK_START)); //backpack automatically shifts arts to beginning
const CArtifactInstance * art = ma.src.getArt();
arts.push_back (art->artType->id);
ma.dst = ArtifactLocation (winnerHero, art->firstAvailableSlot(winnerHero));
@ -2865,7 +2866,7 @@ bool CGameHandler::moveArtifact(const ArtifactLocation &al1, const ArtifactLocat
COMPLAIN_RET("Cannot move catapult!");
if(dst.slot >= GameConstants::BACKPACK_START)
vstd::amin(dst.slot, GameConstants::BACKPACK_START + dst.getHolderArtSet()->artifactsInBackpack.size());
vstd::amin(dst.slot, static_cast<ArtifactPosition::ArtifactPosition>(GameConstants::BACKPACK_START + dst.getHolderArtSet()->artifactsInBackpack.size()));
if (src.slot == dst.slot && src.artHolder == dst.artHolder)
COMPLAIN_RET("Won't move artifact: Dest same as source!");
@ -2873,7 +2874,8 @@ bool CGameHandler::moveArtifact(const ArtifactLocation &al1, const ArtifactLocat
if(dst.slot < GameConstants::BACKPACK_START && destArtifact) //moving art to another slot
{
//old artifact must be removed first
moveArtifact(dst, ArtifactLocation(dst.artHolder, dst.getHolderArtSet()->artifactsInBackpack.size() + GameConstants::BACKPACK_START));
moveArtifact(dst, ArtifactLocation(dst.artHolder, static_cast<ArtifactPosition::ArtifactPosition>(
dst.getHolderArtSet()->artifactsInBackpack.size() + GameConstants::BACKPACK_START)));
}
MoveArtifact ma;
@ -2891,7 +2893,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 (si32 heroID, ui16 artifactSlot, bool assemble, ui32 assembleTo)
bool CGameHandler::assembleArtifacts (si32 heroID, ArtifactPosition::ArtifactPosition artifactSlot, bool assemble, ui32 assembleTo)
{
CGHeroInstance *hero = gs->getHero(heroID);
@ -2930,7 +2932,7 @@ bool CGameHandler::buyArtifact( ui32 hid, TArtifactID aid )
{
CGHeroInstance *hero = gs->getHero(hid);
CGTownInstance *town = hero->visitedTown;
if(aid==0) //spellbook
if(aid==ArtifactID::SPELLBOOK)
{
if((!town->hasBuilt(EBuilding::MAGES_GUILD_1) && complain("Cannot buy a spellbook, no mage guild in the town!"))
|| (getResource(hero->getOwner(), Res::GOLD) < GameConstants::SPELLBOOK_GOLD_COST && complain("Cannot buy a spellbook, not enough gold!") )
@ -2948,16 +2950,16 @@ bool CGameHandler::buyArtifact( ui32 hid, TArtifactID aid )
{
int price = VLC->arth->artifacts[aid]->price;
if(( hero->getArt(9+aid) && complain("Hero already has this machine!"))
if(( hero->getArt(static_cast<ArtifactPosition::ArtifactPosition>(9+aid)) && complain("Hero already has this machine!"))
|| (gs->getPlayer(hero->getOwner())->resources[Res::GOLD] < price && complain("Not enough gold!")))
{
return false;
}
if ((town->hasBuilt(EBuilding::BLACKSMITH) && town->town->warMachine == aid )
|| ((town->hasBuilt(EBuilding::BALLISTA_YARD, ETownType::STRONGHOLD)) && aid == 4))
|| ((town->hasBuilt(EBuilding::BALLISTA_YARD, ETownType::STRONGHOLD)) && aid == ArtifactID::BALLISTA))
{
giveResource(hero->getOwner(),Res::GOLD,-price);
giveHeroNewArtifact(hero, VLC->arth->artifacts[aid], 9+aid);
giveHeroNewArtifact(hero, VLC->arth->artifacts[aid], static_cast<ArtifactPosition::ArtifactPosition>(9+aid));
return true;
}
else
@ -3014,7 +3016,7 @@ bool CGameHandler::buyArtifact(const IMarket *m, const CGHeroInstance *h, Res::E
sendAndApply(&saa);
giveHeroNewArtifact(h, VLC->arth->artifacts[aid], -2);
giveHeroNewArtifact(h, VLC->arth->artifacts[aid], ArtifactPosition::FIRST_AVAILABLE);
return true;
}
@ -3900,7 +3902,7 @@ void CGameHandler::playerMessage( TPlayerColor player, const std::string &messag
CGHeroInstance *hero = gs->getHero(gs->getPlayer(player)->currentSelection);
if(!hero) return;
for (int g=7; g<=140; ++g)
giveHeroNewArtifact(hero, VLC->arth->artifacts[g], -1);
giveHeroNewArtifact(hero, VLC->arth->artifacts[g], ArtifactPosition::PRE_FIRST);
}
else
cheated = false;
@ -5234,7 +5236,7 @@ bool CGameHandler::dig( const CGHeroInstance *h )
iw.text.addTxt(MetaString::GENERAL_TXT, 58); //"Congratulations! After spending many hours digging here, your hero has uncovered the "
iw.text.addTxt(MetaString::ART_NAMES, 2);
iw.soundID = soundBase::ULTIMATEARTIFACT;
giveHeroNewArtifact(h, VLC->arth->artifacts[2], -1); //give grail
giveHeroNewArtifact(h, VLC->arth->artifacts[2], ArtifactPosition::PRE_FIRST); //give grail
sendAndApply(&iw);
iw.soundID = soundBase::invalid;
@ -5631,7 +5633,7 @@ bool CGameHandler::sacrificeCreatures(const IMarket *market, const CGHeroInstanc
return true;
}
bool CGameHandler::sacrificeArtifact(const IMarket * m, const CGHeroInstance * hero, int slot)
bool CGameHandler::sacrificeArtifact(const IMarket * m, const CGHeroInstance * hero, ArtifactPosition::ArtifactPosition slot)
{
ArtifactLocation al(hero, slot);
const CArtifactInstance *a = al.getArt();
@ -6058,16 +6060,16 @@ bool CGameHandler::makeAutomaticAction(const CStack *stack, BattleAction &ba)
return ret;
}
void CGameHandler::giveHeroArtifact(const CGHeroInstance *h, const CArtifactInstance *a, int pos)
void CGameHandler::giveHeroArtifact(const CGHeroInstance *h, const CArtifactInstance *a, ArtifactPosition::ArtifactPosition pos)
{
assert(a->artType);
ArtifactLocation al;
al.artHolder = const_cast<CGHeroInstance*>(h);
int slot = -1;
ArtifactPosition::ArtifactPosition slot = ArtifactPosition::PRE_FIRST;
if(pos < 0)
{
if(pos == -2)
if(pos == ArtifactPosition::FIRST_AVAILABLE)
slot = a->firstAvailableSlot(h);
else
slot = a->firstBackpackSlot(h);
@ -6095,7 +6097,7 @@ void CGameHandler::putArtifact(const ArtifactLocation &al, const CArtifactInstan
sendAndApply(&pa);
}
void CGameHandler::giveHeroNewArtifact(const CGHeroInstance *h, const CArtifact *artType, int pos)
void CGameHandler::giveHeroNewArtifact(const CGHeroInstance *h, const CArtifact *artType, ArtifactPosition::ArtifactPosition pos)
{
CArtifactInstance *a = NULL;
if(!artType->constituents)

View File

@ -154,8 +154,8 @@ public:
void tryJoiningArmy(const CArmedInstance *src, const CArmedInstance *dst, bool removeObjWhenFinished, bool allowMerging) OVERRIDE;
bool moveStack(const StackLocation &src, const StackLocation &dst, TQuantity count = -1) OVERRIDE;
void giveHeroNewArtifact(const CGHeroInstance *h, const CArtifact *artType, int pos) OVERRIDE;
void giveHeroArtifact(const CGHeroInstance *h, const CArtifactInstance *a, int pos) OVERRIDE;
void giveHeroNewArtifact(const CGHeroInstance *h, const CArtifact *artType, ArtifactPosition::ArtifactPosition pos) OVERRIDE;
void giveHeroArtifact(const CGHeroInstance *h, const CArtifactInstance *a, ArtifactPosition::ArtifactPosition pos) OVERRIDE;
void putArtifact(const ArtifactLocation &al, const CArtifactInstance *a) OVERRIDE;
void removeArtifact(const ArtifactLocation &al) OVERRIDE;
bool moveArtifact(const ArtifactLocation &al1, const ArtifactLocation &al2) OVERRIDE;
@ -213,7 +213,7 @@ public:
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 (si32 heroID, ui16 artifactSlot, bool assemble, ui32 assembleTo);
bool assembleArtifacts (si32 heroID, ArtifactPosition::ArtifactPosition artifactSlot, bool assemble, ui32 assembleTo);
bool buyArtifact( ui32 hid, TArtifactID aid ); //for blacksmith and mage guild only -> buying for gold in common buildings
bool buyArtifact( const IMarket *m, const CGHeroInstance *h, Res::ERes rid, TArtifactID aid); //for artifact merchant and black market -> buying for any resource in special building / advobject
bool sellArtifact( const IMarket *m, const CGHeroInstance *h, TArtifactInstanceID aid, Res::ERes rid); //for artifact merchant selling
@ -261,7 +261,7 @@ public:
void handleAttackBeforeCasting (const BattleAttack & bat);
void handleAfterAttackCasting (const BattleAttack & bat);
void attackCasting(const BattleAttack & bat, Bonus::BonusType attackMode, const CStack * attacker);
bool sacrificeArtifact(const IMarket * m, const CGHeroInstance * hero, int slot);
bool sacrificeArtifact(const IMarket * m, const CGHeroInstance * hero, ArtifactPosition::ArtifactPosition slot);
void spawnWanderingMonsters(int creatureID);
friend class CVCMIServer;
friend class CScriptCallback;

View File

@ -196,7 +196,7 @@ bool TradeOnMarketplace::applyGh( CGameHandler *gh )
case EMarketMode::CREATURE_EXP:
return gh->sacrificeCreatures(m, hero, r1, val);
case EMarketMode::ARTIFACT_EXP:
return gh->sacrificeArtifact(m, hero, r1);
return gh->sacrificeArtifact(m, hero, static_cast<ArtifactPosition::ArtifactPosition>(r1));
default:
COMPLAIN_AND_RETURN("Unknown exchange mode!");
}