mirror of
https://github.com/vcmi/vcmi.git
synced 2024-12-24 22:14:36 +02:00
Stack artifacts - part 1
This commit is contained in:
parent
56c56f81e3
commit
b8a5d0d430
@ -127,14 +127,50 @@ bool CCallback::dismissHero(const CGHeroInstance *hero)
|
||||
// return gs->players[player].serial;
|
||||
// }
|
||||
|
||||
bool CCallback::swapArtifacts(const CGHeroInstance * hero1, ui16 pos1, const CGHeroInstance * hero2, ui16 pos2)
|
||||
bool CCallback::swapArtifacts(const IArtifactSetBase * src, ui16 pos1, const IArtifactSetBase * dest, ui16 pos2)
|
||||
{
|
||||
if(player!=hero1->tempOwner && player!=hero2->tempOwner)
|
||||
return false;
|
||||
const CStackInstance * stack1 = dynamic_cast<const CStackInstance*>(src);
|
||||
const CStackInstance * stack2 = dynamic_cast<const CStackInstance*>(dest);
|
||||
const CGHeroInstance * hero1 = dynamic_cast<const CGHeroInstance*>(src);
|
||||
const CGHeroInstance * hero2 = dynamic_cast<const CGHeroInstance*>(dest);
|
||||
|
||||
ExchangeArtifacts ea(hero1->id, hero2->id, pos1, pos2);
|
||||
sendRequest(&ea);
|
||||
return true;
|
||||
ExchangeArtifacts ea;
|
||||
|
||||
if (hero1 && hero2)
|
||||
{
|
||||
if(player!=hero1->tempOwner && player!=hero2->tempOwner) //player can exchange artifacts only between his own heroes
|
||||
return false;
|
||||
else
|
||||
{
|
||||
ExchangeArtifacts ea(hero1->id, hero2->id, pos1, pos2);
|
||||
sendRequest(&ea);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else if (hero1 && stack2) //move artifact from hero to stack
|
||||
{
|
||||
ea.hid1 = hero1->id;
|
||||
ea.s2 = StackLocation(stack2->armyObj, stack2->armyObj->findStack(stack2));
|
||||
ea.slot1 = pos1;
|
||||
ea.slot2 = pos2;
|
||||
sendRequest(&ea);
|
||||
return true;
|
||||
}
|
||||
else if (stack1 && hero2) //move artifacts from stakc to hero
|
||||
{
|
||||
ea.s1 = StackLocation(stack1->armyObj, stack1->armyObj->findStack(stack1));
|
||||
ea.hid2 = hero2->id;
|
||||
ea.slot1 = pos1;
|
||||
ea.slot2 = pos2;
|
||||
sendRequest(&ea);
|
||||
return true;
|
||||
}
|
||||
else if (stack1 && stack2)
|
||||
{
|
||||
//TODO: merge stacks?
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -13,6 +13,7 @@
|
||||
*
|
||||
*/
|
||||
|
||||
class IArtifactSetBase;
|
||||
class CGHeroInstance;
|
||||
class CGameState;
|
||||
struct CPath;
|
||||
@ -60,7 +61,8 @@ public:
|
||||
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 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 CGHeroInstance * hero1, ui16 pos1, const CGHeroInstance * hero2, ui16 pos2)=0; //swaps artifacts between two given heroes
|
||||
virtual bool swapArtifacts(const IArtifactSetBase * src, ui16 pos1, const IArtifactSetBase * dest, ui16 pos2)=0;
|
||||
virtual bool assembleArtifacts(const CGHeroInstance * hero, ui16 artifactSlot, bool assemble, ui32 assembleTo)=0;
|
||||
virtual bool dismissCreature(const CArmedInstance *obj, int stackPos)=0;
|
||||
virtual void endTurn()=0;
|
||||
@ -117,7 +119,10 @@ public:
|
||||
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);
|
||||
bool dismissHero(const CGHeroInstance * hero);
|
||||
bool swapArtifacts(const CGHeroInstance * hero1, ui16 pos1, const CGHeroInstance * hero2, ui16 pos2);
|
||||
//bool swapArtifacts(const CGHeroInstance * hero1, ui16 pos1, const CGHeroInstance * hero2, ui16 pos2);
|
||||
bool swapArtifacts(const IArtifactSetBase * src, ui16 pos1, const IArtifactSetBase * dest, ui16 pos2);
|
||||
//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 buildBuilding(const CGTownInstance *town, si32 buildingID);
|
||||
void recruitCreatures(const CGObjectInstance *obj, ui32 ID, ui32 amount, si32 level=-1);
|
||||
|
@ -262,14 +262,33 @@ void CGarrisonSlot::clickLeft(tribool down, bool previousState)
|
||||
}
|
||||
}
|
||||
}
|
||||
else //highlight
|
||||
else //drop artifact or highlight
|
||||
{
|
||||
if(creature)
|
||||
bool artSelected = false;
|
||||
if (CHeroWindow* chw = dynamic_cast<CHeroWindow*>(GH.topInt())) //dirty solution
|
||||
{
|
||||
owner->highlighted = this;
|
||||
BOOST_FOREACH(CArtifactsOfHero *aoh, chw->artSets) // why they are multiple?
|
||||
{
|
||||
if (const CArtifactInstance *art = aoh->commonInfo->src.art)
|
||||
{
|
||||
artSelected = true;
|
||||
if (art->canBePutAt(ArtifactLocation(myStack, GameConstants::CREATURE_ART)))
|
||||
{
|
||||
//TODO : move
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!artSelected)
|
||||
{
|
||||
if(creature)
|
||||
{
|
||||
owner->highlighted = this;
|
||||
|
||||
for(size_t i = 0; i<owner->splitButtons.size(); i++)
|
||||
owner->splitButtons[i]->block(false);
|
||||
for(size_t i = 0; i<owner->splitButtons.size(); i++)
|
||||
owner->splitButtons[i]->block(false);
|
||||
}
|
||||
}
|
||||
redraw();
|
||||
refr = true;
|
||||
@ -297,6 +316,7 @@ CGarrisonSlot::CGarrisonSlot(CGarrisonInt *Owner, int x, int y, int IID, int Upg
|
||||
{
|
||||
//assert(Creature == CGI->creh->creatures[Creature->idNumber]);
|
||||
active = false;
|
||||
highlight = false;
|
||||
upg = Upg;
|
||||
ID = IID;
|
||||
myStack = Creature;
|
||||
@ -334,7 +354,11 @@ void CGarrisonSlot::showAll(SDL_Surface * to)
|
||||
if((owner->highlighted==this)
|
||||
|| (owner->splitting && owner->highlighted->creature == creature))
|
||||
{
|
||||
blitAt(imgs[-1],pos,to);
|
||||
highlight = true;
|
||||
}
|
||||
{
|
||||
if (highlight)
|
||||
blitAt(imgs[-1],pos,to);
|
||||
}
|
||||
}
|
||||
else//empty slot
|
||||
@ -2700,7 +2724,7 @@ void CTradeWindow::artifactSelected(CArtPlace *slot)
|
||||
{
|
||||
assert(mode == EMarketMode::ARTIFACT_RESOURCE);
|
||||
items[1][0]->setArtInstance(slot->ourArt);
|
||||
if(slot->ourArt)
|
||||
if(slot->ourArt && slot->ourArt->id >= 0)
|
||||
hLeft = items[1][0];
|
||||
else
|
||||
hLeft = NULL;
|
||||
@ -4813,6 +4837,21 @@ void CArtifactsOfHero::markPossibleSlots(const CArtifactInstance* art)
|
||||
BOOST_FOREACH(CArtifactsOfHero *aoh, commonInfo->participants)
|
||||
BOOST_FOREACH(CArtPlace *place, aoh->artWorn)
|
||||
place->marked = art->canBePutAt(ArtifactLocation(aoh->curHero, place->slotID), true);
|
||||
|
||||
if (CHeroWindow* chw = dynamic_cast<CHeroWindow*>(GH.topInt()))
|
||||
{
|
||||
//FIXME: garrison window has two rows of cretaures :?
|
||||
BOOST_FOREACH (CGarrisonSlot *g, chw->garr->slotsDown)
|
||||
{
|
||||
if (g->myStack)
|
||||
if (art->canBePutAt(ArtifactLocation(g->myStack, GameConstants::CREATURE_ART), false));
|
||||
g->highlight = true;
|
||||
}
|
||||
}
|
||||
else if(CExchangeWindow* cew = dynamic_cast<CExchangeWindow*>(GH.topInt()))
|
||||
{
|
||||
//TODO
|
||||
}
|
||||
|
||||
safeRedraw();
|
||||
}
|
||||
@ -5012,10 +5051,10 @@ void CArtifactsOfHero::safeRedraw()
|
||||
|
||||
void CArtifactsOfHero::realizeCurrentTransaction()
|
||||
{
|
||||
assert(commonInfo->src.AOH);
|
||||
assert(commonInfo->dst.AOH);
|
||||
LOCPLINT->cb->swapArtifacts(commonInfo->src.AOH->curHero, commonInfo->src.slotID,
|
||||
commonInfo->dst.AOH->curHero, commonInfo->dst.slotID);
|
||||
assert(commonInfo->src.AOH || commonInfo->src.CAS);
|
||||
assert(commonInfo->dst.AOH || commonInfo->dst.CAS);
|
||||
LOCPLINT->cb->swapArtifacts(commonInfo->src.AOH ? (IArtifactSetBase*)commonInfo->src.AOH->curHero : commonInfo->src.CAS, commonInfo->src.slotID,
|
||||
commonInfo->dst.AOH ? (IArtifactSetBase*)commonInfo->dst.AOH->curHero : commonInfo->dst.CAS, commonInfo->dst.slotID);
|
||||
}
|
||||
|
||||
void CArtifactsOfHero::artifactMoved(const ArtifactLocation &src, const ArtifactLocation &dst)
|
||||
@ -6273,6 +6312,16 @@ void CArtifactsOfHero::SCommonPart::Artpos::setTo(const CArtPlace *place, bool d
|
||||
art = place->ourArt;
|
||||
}
|
||||
|
||||
IArtifactSetBase * CArtifactsOfHero::SCommonPart::Artpos::getArtHolder()
|
||||
{
|
||||
if (AOH)
|
||||
return (IArtifactSetBase*)AOH;
|
||||
if (CAS)
|
||||
return (IArtifactSetBase*)CAS;
|
||||
tlog2 <<"Warning! Artpos without source\n";
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bool CArtifactsOfHero::SCommonPart::Artpos::operator==(const ArtifactLocation &al) const
|
||||
{
|
||||
if(!AOH)
|
||||
|
@ -25,6 +25,7 @@
|
||||
*/
|
||||
|
||||
struct ArtifactLocation;
|
||||
class IArtifactSetBase;
|
||||
class CStackBasicDescriptor;
|
||||
class CBonusSystemNode;
|
||||
class CArtifact;
|
||||
@ -62,6 +63,7 @@ class CPlayerInterface;
|
||||
class CHeroWindow;
|
||||
class CArtifact;
|
||||
class CArtifactsOfHero;
|
||||
class CCreatureArtifactSet;
|
||||
class CResDataBar;
|
||||
struct SPuzzleInfo;
|
||||
class CGGarrison;
|
||||
@ -222,6 +224,7 @@ public:
|
||||
int count; //number of creatures
|
||||
int upg; //0 - up garrison, 1 - down garrison
|
||||
bool active; //TODO: comment me
|
||||
bool highlight;
|
||||
|
||||
virtual void hover (bool on); //call-in
|
||||
const CArmedInstance * getObj();
|
||||
@ -851,12 +854,14 @@ public:
|
||||
struct Artpos
|
||||
{
|
||||
int slotID;
|
||||
const CArtifactsOfHero * AOH;
|
||||
const CArtifactsOfHero *AOH;
|
||||
const CCreatureArtifactSet *CAS;
|
||||
const CArtifactInstance *art;
|
||||
|
||||
Artpos();
|
||||
void clear();
|
||||
void setTo(const CArtPlace *place, bool dontTakeBackpack);
|
||||
IArtifactSetBase * getArtHolder(); // returns AOH or CAS
|
||||
bool valid();
|
||||
bool operator==(const ArtifactLocation &al) const;
|
||||
} src, dst;
|
||||
|
@ -7,6 +7,7 @@
|
||||
#include "../lib/VCMI_Lib.h"
|
||||
#include "CSpellHandler.h"
|
||||
#include "CObjectHandler.h"
|
||||
//#include "CCreatureSet.h"
|
||||
#include "NetPacks.h"
|
||||
|
||||
extern CLodHandler *bitmaph;
|
||||
@ -195,7 +196,8 @@ CArtHandler::CArtHandler()
|
||||
// War machines are the default big artifacts.
|
||||
for (ui32 i = 3; i <= 6; i++)
|
||||
bigArtifacts.insert(i);
|
||||
//modableArtifacts = boost::assign::map_list_of(1, 1)(146,3)(147,3)(148,3)(150,3)(151,3)(152,3)(154,3)(156,2);
|
||||
if (GameConstants::STACK_ARTIFACT)
|
||||
creatureArtifacts += 141, 142, 143, 156; //basic Wog arts and Warlord's banner
|
||||
}
|
||||
|
||||
CArtHandler::~CArtHandler()
|
||||
@ -225,23 +227,6 @@ void CArtHandler::loadArtifacts(bool onlyTxt)
|
||||
for (int i=0; i<GameConstants::ARTIFACTS_QUANTITY; i++)
|
||||
{
|
||||
CArtifact *art = new CArtifact();
|
||||
// if ((itr = modableArtifacts.find(i)) != modableArtifacts.end())
|
||||
// {
|
||||
// switch (itr->second)
|
||||
// {
|
||||
// case 1:
|
||||
// art = new CScroll;
|
||||
// break;
|
||||
// case 2:
|
||||
// art = new CCustomizableArt;
|
||||
// break;
|
||||
// case 3:
|
||||
// art = new CCommanderArt;
|
||||
// break;
|
||||
// };
|
||||
// }
|
||||
// else
|
||||
// art = new CArtifact;
|
||||
|
||||
CArtifact &nart = *art;
|
||||
nart.id=i;
|
||||
@ -941,19 +926,24 @@ int CArtifactInstance::firstBackpackSlot(const CGHeroInstance *h) const
|
||||
|
||||
bool CArtifactInstance::canBePutAt(const ArtifactLocation &al, bool assumeDestRemoved /*= false*/) const
|
||||
{
|
||||
if(al.slot >= GameConstants::BACKPACK_START)
|
||||
if (al.hero)
|
||||
{
|
||||
if(artType->isBig())
|
||||
return false;
|
||||
if(al.slot >= GameConstants::BACKPACK_START)
|
||||
{
|
||||
if(artType->isBig())
|
||||
return false;
|
||||
|
||||
//TODO backpack limit
|
||||
return true;
|
||||
//TODO backpack limit
|
||||
return true;
|
||||
}
|
||||
|
||||
if(!vstd::contains(artType->possibleSlots, al.slot))
|
||||
return false;
|
||||
|
||||
return al.hero->isPositionFree(al.slot, assumeDestRemoved);
|
||||
}
|
||||
|
||||
if(!vstd::contains(artType->possibleSlots, al.slot))
|
||||
else
|
||||
return false;
|
||||
|
||||
return al.hero->isPositionFree(al.slot, assumeDestRemoved);
|
||||
}
|
||||
|
||||
void CArtifactInstance::putAt(CGHeroInstance *h, ui16 slot)
|
||||
@ -975,6 +965,15 @@ void CArtifactInstance::removeFrom(CGHeroInstance *h, ui16 slot)
|
||||
//TODO delete me?
|
||||
}
|
||||
|
||||
void CArtifactInstance::putAt(CStackInstance *s, ui16 slot)
|
||||
{
|
||||
tlog2 <<"Hero artifacts shouldn't be put on creatures!\n";
|
||||
}
|
||||
void CArtifactInstance::removeFrom(CStackInstance *s, ui16 slot)
|
||||
{
|
||||
tlog2 <<"Strange, we try to remove hero artifact from CStackInstance\n";
|
||||
}
|
||||
|
||||
bool CArtifactInstance::canBeDisassembled() const
|
||||
{
|
||||
return artType->constituents && artType->constituentOf->size();
|
||||
@ -1011,16 +1010,36 @@ std::vector<const CArtifact *> CArtifactInstance::assemblyPossibilities(const CG
|
||||
|
||||
void CArtifactInstance::move(ArtifactLocation &src, ArtifactLocation &dst)
|
||||
{
|
||||
removeFrom(src.hero, src.slot);
|
||||
putAt(dst.hero, dst.slot);
|
||||
if (artType->id == 135 && dst.slot == ArtifactPosition::RIGHT_HAND && !dst.hero->hasSpellbook()) //Titan's Thunder creates new spellbook on equip
|
||||
dst.hero->giveArtifact(0);
|
||||
if (src.hero)
|
||||
removeFrom(src.hero, src.slot);
|
||||
else if (src.stack)
|
||||
removeFrom(src.stack, src.slot);
|
||||
else
|
||||
tlog1 << "No source for moved artifact found!\n";
|
||||
|
||||
if (dst.hero)
|
||||
{
|
||||
putAt(dst.hero, dst.slot);
|
||||
if (artType->id == 135 && dst.slot == ArtifactPosition::RIGHT_HAND && !dst.hero->hasSpellbook()) //Titan's Thunder creates new spellbook on equip
|
||||
dst.hero->giveArtifact(0);
|
||||
}
|
||||
else if (dst.stack)
|
||||
putAt(dst.stack, dst.slot);
|
||||
else
|
||||
tlog1 << "No destination for moved artifact found!\n";
|
||||
|
||||
|
||||
}
|
||||
|
||||
CArtifactInstance * CArtifactInstance::createNewArtifactInstance(CArtifact *Art)
|
||||
{
|
||||
if(!Art->constituents)
|
||||
return new CArtifactInstance(Art);
|
||||
{
|
||||
if (vstd::contains(VLC->arth->creatureArtifacts, Art->id))
|
||||
return new CCreatureArtifactInstance(Art);
|
||||
else
|
||||
return new CArtifactInstance(Art);
|
||||
}
|
||||
else
|
||||
{
|
||||
CCombinedArtifactInstance * ret = new CCombinedArtifactInstance(Art);
|
||||
@ -1233,6 +1252,56 @@ bool CCombinedArtifactInstance::ConstituentInfo::operator==(const ConstituentInf
|
||||
{
|
||||
return art == rhs.art && slot == rhs.slot;
|
||||
}
|
||||
CCreatureArtifactInstance::CCreatureArtifactInstance()
|
||||
{
|
||||
init();
|
||||
}
|
||||
|
||||
CCreatureArtifactInstance::CCreatureArtifactInstance(CArtifact *Art)
|
||||
{
|
||||
init();
|
||||
setType(Art);
|
||||
}
|
||||
|
||||
bool CCreatureArtifactInstance::isPart(const CArtifactInstance *supposedPart) const
|
||||
{
|
||||
return false; //TODO: any other proposals?
|
||||
}
|
||||
|
||||
std::string CCreatureArtifactInstance::nodeName() const
|
||||
{
|
||||
return "Creature artifact instance of " + (artType ? artType->Name() : std::string("uninitialized")) + " type";
|
||||
}
|
||||
|
||||
bool CCreatureArtifactInstance::canBePutAt(const ArtifactLocation &al, bool assumeDestRemoved /*= false*/) const
|
||||
{
|
||||
if (al.stack)
|
||||
{
|
||||
return true; //all artifacts should fit on creature
|
||||
}
|
||||
else if(al.slot >= GameConstants::BACKPACK_START)
|
||||
{ //TODO backpack limit?
|
||||
return true;
|
||||
}
|
||||
return false; //hero can't wear creature art
|
||||
}
|
||||
|
||||
void CCreatureArtifactInstance::putAt(CStackInstance *s, ui16 slot)
|
||||
{
|
||||
assert(canBePutAt(ArtifactLocation(s, slot)));
|
||||
|
||||
s->setNewArtSlot(slot, this, false);
|
||||
if(slot == GameConstants::CREATURE_ART)
|
||||
s->attachTo(this);
|
||||
}
|
||||
|
||||
void CCreatureArtifactInstance::removeFrom(CStackInstance *s, ui16 slot)
|
||||
{
|
||||
assert(s->CCreatureArtifactSet::getArt(slot) == this);
|
||||
s->eraseArtSlot(slot);
|
||||
if(slot == GameConstants::CREATURE_ART) //we remove worn artifact
|
||||
s->detachFrom(this);
|
||||
}
|
||||
|
||||
const CArtifactInstance* IArtifactSetBase::getArt(ui16 pos, bool excludeLocked) const
|
||||
{
|
||||
|
@ -16,6 +16,8 @@
|
||||
class CDefHandler;
|
||||
class CArtifact;
|
||||
class CGHeroInstance;
|
||||
class CStackInstance;
|
||||
//class CCreatureArtifactSet;
|
||||
struct ArtifactLocation;
|
||||
|
||||
namespace ArtifactPosition
|
||||
@ -75,7 +77,7 @@ public:
|
||||
|
||||
//CArtifactInstance(int aid);
|
||||
|
||||
std::string nodeName() const OVERRIDE;
|
||||
virtual std::string nodeName() const OVERRIDE;
|
||||
void deserializationFix();
|
||||
void setType(CArtifact *Art);
|
||||
|
||||
@ -87,6 +89,8 @@ public:
|
||||
virtual bool canBeDisassembled() const;
|
||||
virtual void putAt(CGHeroInstance *h, ui16 slot);
|
||||
virtual void removeFrom(CGHeroInstance *h, ui16 slot);
|
||||
virtual void putAt(CStackInstance *s, ui16 slot);
|
||||
virtual void removeFrom(CStackInstance *s, ui16 slot);
|
||||
virtual bool isPart(const CArtifactInstance *supposedPart) const; //checks if this a part of this artifact: artifact instance is a part of itself, additionally truth is returned for consituents of combined arts
|
||||
|
||||
std::vector<const CArtifact *> assemblyPossibilities(const CGHeroInstance *h) const;
|
||||
@ -147,6 +151,30 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
class DLL_LINKAGE CCreatureArtifactInstance : public CArtifactInstance
|
||||
{
|
||||
CCreatureArtifactInstance(CArtifact *Art);
|
||||
public:
|
||||
|
||||
bool canBePutAt(const ArtifactLocation &al, bool assumeDestRemoved = false) const OVERRIDE;
|
||||
void putAt(CStackInstance *s, ui16 slot) OVERRIDE;
|
||||
void removeFrom(CStackInstance *s, ui16 slot) OVERRIDE;
|
||||
bool isPart(const CArtifactInstance *supposedPart) const OVERRIDE;
|
||||
|
||||
std::string nodeName() const OVERRIDE;
|
||||
|
||||
CCreatureArtifactInstance();
|
||||
|
||||
//void deserializationFix(); ..inherit from CArtifactInstance
|
||||
|
||||
friend class CArtifactInstance;
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{
|
||||
h & static_cast<CArtifactInstance&>(*this);
|
||||
BONUS_TREE_DESERIALIZATION_FIX
|
||||
}
|
||||
};
|
||||
|
||||
// class DLL_LINKAGE IModableArt : public CArtifact //artifact which can have different properties, such as scroll or banner
|
||||
// { //used only for dynamic cast :P
|
||||
// public:
|
||||
@ -212,7 +240,7 @@ public:
|
||||
std::vector< ConstTransitivePtr<CArtifact> > artifacts;
|
||||
std::vector<CArtifact *> allowedArtifacts;
|
||||
std::set<ui32> bigArtifacts; // Artifacts that cannot be moved to backpack, e.g. war machines.
|
||||
//std::map<ui32, ui8> modableArtifacts; //1-scroll, 2-banner, 3-commander art with progressive bonus
|
||||
std::set<ui32> creatureArtifacts; // can be held by Stacks
|
||||
|
||||
void loadArtifacts(bool onlyTxt);
|
||||
void sortArts();
|
||||
@ -235,6 +263,7 @@ public:
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{
|
||||
h & artifacts & allowedArtifacts & treasures & minors & majors & relics;
|
||||
h & creatureArtifacts;
|
||||
//if(!h.saving) sortArts();
|
||||
}
|
||||
};
|
||||
@ -299,7 +328,7 @@ public:
|
||||
class DLL_LINKAGE CCreatureArtifactSet : public IArtifactSetBase
|
||||
{ ///creature artifacts
|
||||
public:
|
||||
std::vector<ArtSlotInfo> artifactsInBackpack; //artifacts carried by creature - 4 max
|
||||
std::vector<ArtSlotInfo> artifactsInBackpack; //artifacts carried by creature - 4 max (according to WoG)
|
||||
ArtSlotInfo activeArtifact; //position 0 - Arts::CREATURE_ART
|
||||
|
||||
ArtSlotInfo &retreiveNewArtSlot(ui16 slot);
|
||||
|
@ -3,11 +3,12 @@
|
||||
|
||||
#include "HeroBonus.h"
|
||||
#include "GameConstants.h"
|
||||
#include "CArtHandler.h"
|
||||
|
||||
class CCreature;
|
||||
class CGHeroInstance;
|
||||
class CArmedInstance;
|
||||
|
||||
class CCreatureArtifactSet;
|
||||
|
||||
class DLL_LINKAGE CStackBasicDescriptor
|
||||
{
|
||||
@ -25,20 +26,20 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
class DLL_LINKAGE CStackInstance : public CBonusSystemNode, public CStackBasicDescriptor
|
||||
class DLL_LINKAGE CStackInstance : public CBonusSystemNode, public CStackBasicDescriptor, public CCreatureArtifactSet
|
||||
{
|
||||
const CArmedInstance *_armyObj; //stack must be part of some army, army must be part of some object
|
||||
public:
|
||||
int idRand; //hlp variable used during loading game -> "id" placeholder for randomization
|
||||
|
||||
const CArmedInstance * const & armyObj; //stack must be part of some army, army must be part of some object
|
||||
ui32 experience; //TODO: handle
|
||||
//TODO: stack artifacts
|
||||
ui32 experience;
|
||||
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{
|
||||
h & static_cast<CBonusSystemNode&>(*this);
|
||||
h & static_cast<CStackBasicDescriptor&>(*this);
|
||||
h & static_cast<CCreatureArtifactSet&>(*this);
|
||||
h & _armyObj & experience;
|
||||
BONUS_TREE_DESERIALIZATION_FIX
|
||||
}
|
||||
|
@ -1410,6 +1410,7 @@ void CGameState::init( StartInfo * si, ui32 checksum, int Seed )
|
||||
CGHeroInstance *hero = k->second.heroes[0];
|
||||
hero->giveArtifact(toGive->id);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
/****************************TOWNS************************************************/
|
||||
|
@ -83,13 +83,17 @@ namespace GameConstants
|
||||
const int WEEKLY_GROWTH = 10; //percent
|
||||
const int AVAILABLE_HEROES_PER_PLAYER = 2;
|
||||
const bool DWELLINGS_ACCUMULATE_CREATURES = false;
|
||||
const bool STACK_EXP = true;
|
||||
const bool STACK_ARTIFACT = true;
|
||||
const int SPELLBOOK_GOLD_COST = 500;
|
||||
|
||||
const ui16 BACKPACK_START = 19;
|
||||
const int ID_CATAPULT = 3, ID_LOCK = 145;
|
||||
const ui16 CREATURE_ART = 0;
|
||||
|
||||
//game modules
|
||||
const bool STACK_EXP = true;
|
||||
const bool STACK_ARTIFACT = true; //now toggle for testing
|
||||
const bool COMMANDERS = false;
|
||||
const bool MITHRIL = false;
|
||||
}
|
||||
|
||||
// Enum declarations
|
||||
|
@ -845,6 +845,7 @@ typedef si32 TArtPos;
|
||||
struct ArtifactLocation
|
||||
{
|
||||
ConstTransitivePtr<CGHeroInstance> hero;
|
||||
ConstTransitivePtr<CStackInstance> stack;
|
||||
TArtPos slot;
|
||||
|
||||
ArtifactLocation()
|
||||
@ -854,6 +855,13 @@ struct ArtifactLocation
|
||||
ArtifactLocation(const CGHeroInstance *Hero, TArtPos Slot)
|
||||
{
|
||||
hero = const_cast<CGHeroInstance*>(Hero); //we are allowed here to const cast -> change will go through one of our packages... do not abuse!
|
||||
stack = NULL;
|
||||
slot = Slot;
|
||||
}
|
||||
ArtifactLocation(const CStackInstance *Stack, TArtPos Slot)
|
||||
{
|
||||
stack = const_cast<CStackInstance*>(Stack); //we are allowed here to const cast -> change will go through one of our packages... do not abuse!
|
||||
hero = NULL;
|
||||
slot = Slot;
|
||||
}
|
||||
DLL_LINKAGE const CArtifactInstance *getArt() const;
|
||||
@ -861,7 +869,7 @@ struct ArtifactLocation
|
||||
DLL_LINKAGE const ArtSlotInfo *getSlot() const;
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{
|
||||
h & hero & slot;
|
||||
h & hero & stack & slot;
|
||||
}
|
||||
};
|
||||
|
||||
@ -1746,17 +1754,19 @@ struct GarrisonHeroSwap : public CPackForServer
|
||||
};
|
||||
|
||||
struct ExchangeArtifacts : public CPackForServer
|
||||
//TODO: allow exchange between heroes, stacks and commanders
|
||||
{
|
||||
ExchangeArtifacts(){};
|
||||
ExchangeArtifacts(si32 H1, si32 H2, ui16 S1, ui16 S2)
|
||||
:hid1(H1),hid2(H2),slot1(S1),slot2(S2){};
|
||||
si32 hid1, hid2;
|
||||
StackLocation s1, s2; //for creature stacks
|
||||
ui16 slot1, slot2;
|
||||
|
||||
bool applyGh(CGameHandler *gh);
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{
|
||||
h & hid1 & hid2 & slot1 & slot2;
|
||||
h & hid1 & hid2 & s1 & s2 & slot1 & slot2;
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -94,6 +94,7 @@ void registerTypes1(Serializer &s)
|
||||
s.template registerType<BattleInfo>();
|
||||
s.template registerType<CArtifactInstance>();
|
||||
s.template registerType<CCombinedArtifactInstance>();
|
||||
s.template registerType<CCreatureArtifactInstance>();
|
||||
}
|
||||
|
||||
template<typename Serializer>
|
||||
|
@ -2572,6 +2572,40 @@ bool CGameHandler::moveArtifact(si32 srcHeroID, si32 destHeroID, ui16 srcSlot, u
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CGameHandler::moveArtifact(StackLocation s1, StackLocation s2, ui16 srcSlot, ui16 destSlot)
|
||||
{
|
||||
ArtifactLocation src(s1.getStack(), srcSlot), dst(s2.getStack(), destSlot);
|
||||
moveArtifact(src, dst);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CGameHandler::moveArtifact(si32 srcHeroID, StackLocation s2, ui16 srcSlot, ui16 destSlot)
|
||||
{
|
||||
ArtifactLocation src(getHero(srcHeroID), srcSlot);
|
||||
ArtifactLocation dst(s2.getStack(), destSlot);
|
||||
moveArtifact(src, dst);
|
||||
return true;
|
||||
}
|
||||
bool CGameHandler::moveArtifact(StackLocation s1, si32 destHeroID, ui16 srcSlot, ui16 destSlot)
|
||||
{
|
||||
ArtifactLocation src(s1.getStack(), srcSlot);
|
||||
ArtifactLocation dst(getHero(destHeroID), destSlot);
|
||||
//hero should not wear stack artifact
|
||||
vstd::amin(dst.slot, GameConstants::BACKPACK_START + dst.hero->artifactsInBackpack.size()); //put on first free position
|
||||
moveArtifact(src, dst);
|
||||
return true;
|
||||
}
|
||||
|
||||
void CGameHandler::moveArtifact(const ArtifactLocation &al1, const ArtifactLocation &al2)
|
||||
{
|
||||
MoveArtifact ma;
|
||||
ma.src = al1;
|
||||
ma.dst = al2;
|
||||
sendAndApply(&ma);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Assembles or disassembles a combination artifact.
|
||||
* @param heroID ID of hero holding the artifact(s).
|
||||
@ -5501,21 +5535,20 @@ void CGameHandler::putArtifact(const ArtifactLocation &al, const CArtifactInstan
|
||||
sendAndApply(&pa);
|
||||
}
|
||||
|
||||
void CGameHandler::moveArtifact(const ArtifactLocation &al1, const ArtifactLocation &al2)
|
||||
{
|
||||
MoveArtifact ma;
|
||||
ma.src = al1;
|
||||
ma.dst = al2;
|
||||
sendAndApply(&ma);
|
||||
}
|
||||
|
||||
void CGameHandler::giveHeroNewArtifact(const CGHeroInstance *h, const CArtifact *artType, int pos)
|
||||
{
|
||||
CArtifactInstance *a = NULL;
|
||||
if(!artType->constituents)
|
||||
a = new CArtifactInstance();
|
||||
{
|
||||
if (vstd::contains(VLC->arth->creatureArtifacts, artType->id))
|
||||
a = new CCreatureArtifactInstance();
|
||||
else
|
||||
a = new CArtifactInstance();
|
||||
}
|
||||
else
|
||||
{
|
||||
a = new CCombinedArtifactInstance();
|
||||
}
|
||||
a->artType = artType; //*NOT* via settype -> all bonus-related stuff must be done by NewArtifact apply
|
||||
|
||||
NewArtifact na;
|
||||
|
@ -210,6 +210,9 @@ public:
|
||||
bool sellArtifact( const IMarket *m, const CGHeroInstance *h, int aid, int rid); //for artifact merchant selling
|
||||
bool buySecSkill( const IMarket *m, const CGHeroInstance *h, int skill);
|
||||
bool moveArtifact(si32 srcHeroID, si32 destHeroID, ui16 srcSlot, ui16 destSlot);
|
||||
bool moveArtifact(StackLocation s1, StackLocation s2, ui16 srcSlot, ui16 destSlot); //called when stacks merge
|
||||
bool moveArtifact(si32 srcHeroID, StackLocation s2, ui16 srcSlot, ui16 destSlot); //equip artifact
|
||||
bool moveArtifact(StackLocation s1, si32 destHeroID, ui16 srcSlot, ui16 destSlot); //return artifact to backpack
|
||||
bool garrisonSwap(si32 tid);
|
||||
bool upgradeCreature( ui32 objid, ui8 pos, ui32 upgID );
|
||||
bool recruitCreatures(si32 objid, ui32 crid, ui32 cram, si32 level);
|
||||
|
Loading…
Reference in New Issue
Block a user