diff --git a/global.h b/global.h index 83e57ed24..53ee12948 100644 --- a/global.h +++ b/global.h @@ -361,6 +361,7 @@ namespace Arts }; const ui16 BACKPACK_START = 19; const int ID_CATAPULT = 3, ID_LOCK = 145; + const ui16 CREATURE_ART = 0; } enum EAlignment diff --git a/lib/CArtHandler.cpp b/lib/CArtHandler.cpp index 2ea24dcea..9e990373f 100644 --- a/lib/CArtHandler.cpp +++ b/lib/CArtHandler.cpp @@ -1231,7 +1231,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* IArtifactSetBase::getArt(ui16 pos, bool excludeLocked) const { if(const ArtSlotInfo *si = getSlot(pos)) { @@ -1242,9 +1242,29 @@ const CArtifactInstance* CArtifactSet::getArt(ui16 pos, bool excludeLocked /*= t return NULL; } -CArtifactInstance* CArtifactSet::getArt(ui16 pos, bool excludeLocked /*= true*/) +bool IArtifactSetBase::hasArt(ui32 aid, bool onlyWorn) const { - return const_cast((const_cast(this))->getArt(pos, excludeLocked)); + return getArtPos(aid, onlyWorn) != -1; +} + +bool IArtifactSetBase::isPositionFree(ui16 pos, bool onlyLockCheck) const +{ + if(const ArtSlotInfo *s = getSlot(pos)) + return (onlyLockCheck || !s->artifact) && !s->locked; + + return true; //no slot means not used +} + +void IArtifactSetBase::setNewArtSlot(ui16 slot, CArtifactInstance *art, bool locked) +{ + ArtSlotInfo &asi = retreiveNewArtSlot(slot); + asi.artifact = art; + asi.locked = locked; +} + +CArtifactInstance* IArtifactSetBase::getArt(ui16 pos, bool excludeLocked /*= true*/) +{ + return const_cast((const_cast(this))->getArt(pos, excludeLocked)); } si32 CArtifactSet::getArtPos(int aid, bool onlyWorn /*= true*/) const @@ -1289,11 +1309,6 @@ const CArtifactInstance * CArtifactSet::getArtByInstanceId(int artInstId) const return NULL; } -bool CArtifactSet::hasArt(ui32 aid, bool onlyWorn /*= false*/) const -{ - return getArtPos(aid, onlyWorn) != -1; -} - const ArtSlotInfo * CArtifactSet::getSlot(ui16 pos) const { if(vstd::contains(artifactsWorn, pos)) @@ -1310,14 +1325,6 @@ const ArtSlotInfo * CArtifactSet::getSlot(ui16 pos) const return NULL; } -bool CArtifactSet::isPositionFree(ui16 pos, bool onlyLockCheck /*= false*/) const -{ - if(const ArtSlotInfo *s = getSlot(pos)) - return (onlyLockCheck || !s->artifact) && !s->locked; - - return true; //no slot means not used -} - si32 CArtifactSet::getArtTypeId(ui16 pos) const { const CArtifactInstance * const a = getArt(pos); @@ -1344,13 +1351,6 @@ ArtSlotInfo & CArtifactSet::retreiveNewArtSlot(ui16 slot) return ret; } -void CArtifactSet::setNewArtSlot(ui16 slot, CArtifactInstance *art, bool locked) -{ - ArtSlotInfo &asi = retreiveNewArtSlot(slot); - asi.artifact = art; - asi.locked = locked; -} - void CArtifactSet::eraseArtSlot(ui16 slot) { if(slot < Arts::BACKPACK_START) @@ -1362,4 +1362,94 @@ void CArtifactSet::eraseArtSlot(ui16 slot) slot -= Arts::BACKPACK_START; artifactsInBackpack.erase(artifactsInBackpack.begin() + slot); } +} + +ArtSlotInfo & CCreatureArtifactSet::retreiveNewArtSlot(ui16 slot) +{ + assert(slot); //ke? + ArtSlotInfo &ret = slot <= Arts::CREATURE_ART + ? activeArtifact + : *artifactsInBackpack.insert(artifactsInBackpack.begin() + (slot - 1), ArtSlotInfo()); + + return ret; +} + +void CCreatureArtifactSet::eraseArtSlot(ui16 slot) +{ + if(slot == Arts::CREATURE_ART) + { + activeArtifact.artifact = NULL; //hmm? + } + else + { + slot -= 1; + artifactsInBackpack.erase(artifactsInBackpack.begin() + slot); + } +} + +const ArtSlotInfo * CCreatureArtifactSet::getSlot(ui16 pos) const +{ + if (pos == Arts::CREATURE_ART) + return &activeArtifact; + else if(pos > Arts::CREATURE_ART) + { + int backpackPos = (int)pos - 1; + if(backpackPos < 0 || backpackPos >= artifactsInBackpack.size()) + return NULL; + else + return &artifactsInBackpack[backpackPos]; + } + return NULL; +} + +si32 CCreatureArtifactSet::getArtPos(int aid, bool onlyWorn) const +{ + if (aid == activeArtifact.artifact->artType->id ) + return Arts::CREATURE_ART; + + if(onlyWorn) + return -1; + + for(int i = 0; i < artifactsInBackpack.size(); i++) + { + if(artifactsInBackpack[i].artifact->artType->id == aid) + return i + 1; + } + + return -1; +} + +si32 CCreatureArtifactSet::getArtPos(const CArtifactInstance *art) const +{ + if (activeArtifact.artifact == art) + return Arts::CREATURE_ART; + + for(int i = 0; i < artifactsInBackpack.size(); i++) + if(artifactsInBackpack[i].artifact == art) + return Arts::BACKPACK_START + i; + + return -1; +} + +const CArtifactInstance * CCreatureArtifactSet::getArtByInstanceId(int artInstId) const +{ + if (activeArtifact.artifact->id == artInstId) + return activeArtifact.artifact; + + for(int i = 0; i < artifactsInBackpack.size(); i++) + if(artifactsInBackpack[i].artifact->id == artInstId) + return artifactsInBackpack[i].artifact; + + return NULL; +} + +si32 CCreatureArtifactSet::getArtTypeId(ui16 pos) const +{ + const CArtifactInstance * const a = getArt(pos); + if(!a) + { + tlog2 << "Stack has no artifact at " << pos << " (getArtTypeId)\n"; + return -1; + } + return a->artType->id; } \ No newline at end of file diff --git a/lib/CArtHandler.h b/lib/CArtHandler.h index d24667462..cb8ac929c 100644 --- a/lib/CArtHandler.h +++ b/lib/CArtHandler.h @@ -245,27 +245,40 @@ struct DLL_EXPORT ArtSlotInfo } }; -class DLL_EXPORT CArtifactSet -{ +class DLL_EXPORT IArtifactSetBase +{ ///artifacts container +public: + virtual void setNewArtSlot(ui16 slot, CArtifactInstance *art, bool locked); //redundant inheritance + virtual const CArtifactInstance* getArt(ui16 pos, bool excludeLocked = true) const; //redundant inheritance + virtual CArtifactInstance* getArt(ui16 pos, bool excludeLocked = true); //NULL - no artifact + virtual bool hasArt(ui32 aid, bool onlyWorn = false) const; //redundant inheritance + virtual bool isPositionFree(ui16 pos, bool onlyLockCheck = false) const; //redundant inheritance + + virtual ArtSlotInfo &retreiveNewArtSlot(ui16 slot)=0; + virtual void eraseArtSlot(ui16 slot)=0; + + virtual const ArtSlotInfo *getSlot(ui16 pos) const=0; + virtual si32 getArtPos(int aid, bool onlyWorn = true) const=0; //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) + virtual si32 getArtPos(const CArtifactInstance *art) const=0; + virtual const CArtifactInstance *getArtByInstanceId(int artInstId) const=0; + virtual si32 getArtTypeId(ui16 pos) const=0; +}; + +class DLL_EXPORT CArtifactSet : public IArtifactSetBase +{ ///hero artifacts public: std::vector artifactsInBackpack; //hero's artifacts from bag bmap artifactsWorn; //map; 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); 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 CArtifactInstance *getArtByInstanceId(int 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; - virtual ~CArtifactSet(); template void serialize(Handler &h, const int version) @@ -274,5 +287,27 @@ public: } }; +class DLL_EXPORT CCreatureArtifactSet : public IArtifactSetBase +{ ///creature artifacts +public: + std::vector artifactsInBackpack; //artifacts carried by creature - 4 max + ArtSlotInfo activeArtifact; //position 0 - Arts::CREATURE_ART + + ArtSlotInfo &retreiveNewArtSlot(ui16 slot); + void eraseArtSlot(ui16 slot); + + const ArtSlotInfo *getSlot(ui16 pos)const; + si32 getArtPos(int aid, bool onlyWorn = true) const; + si32 getArtPos(const CArtifactInstance *art) const; + const CArtifactInstance *getArtByInstanceId(int artInstId) const; + si32 getArtTypeId(ui16 pos) const; + + virtual ~CCreatureArtifactSet(){}; + + template void serialize(Handler &h, const int version) + { + h & artifactsInBackpack & activeArtifact; + } +}; #endif // __CARTHANDLER_H__ diff --git a/lib/NetPacksLib.cpp b/lib/NetPacksLib.cpp index 70a219930..bdd9563e7 100644 --- a/lib/NetPacksLib.cpp +++ b/lib/NetPacksLib.cpp @@ -1150,7 +1150,8 @@ DLL_EXPORT void BattleSpellCast::applyGs( CGameState *gs ) } } - CStackInstance *csi = new CStackInstance(creID, h->getPrimSkillLevel(2) * VLC->spellh->spells[id]->powers[skill]); //deleted by d-tor of summoned stack + int summonedElementals = h->getPrimSkillLevel(2) * VLC->spellh->spells[id]->powers[skill] * (100 + h->valOfBonuses(Bonus::SPECIFIC_SPELL_DAMAGE, id) / 100.0f); //new feature - percentage bonus + CStackInstance *csi = new CStackInstance(creID, summonedElementals); //deleted by d-tor of summoned stack csi->setArmyObj(h); CStack * summonedStack = gs->curB->generateNewStack(*csi, gs->curB->stacks.size(), !side, 255, pos); summonedStack->state.insert(SUMMONED);