mirror of
https://github.com/vcmi/vcmi.git
synced 2024-12-24 22:14:36 +02:00
Redid stack artifacts. Broken save compatibility. Added serializer support for boost::variant and sending CStackInstace* over network by implicitly passing IDs. Moved seeds and checksum to StartInfo. Various minor changes.
This commit is contained in:
parent
d55d48b978
commit
722ec55384
@ -128,51 +128,13 @@ bool CCallback::dismissHero(const CGHeroInstance *hero)
|
|||||||
// return gs->players[player].serial;
|
// return gs->players[player].serial;
|
||||||
// }
|
// }
|
||||||
|
|
||||||
bool CCallback::swapArtifacts(const IArtifactSetBase * src, ui16 pos1, const IArtifactSetBase * dest, ui16 pos2)
|
bool CCallback::swapArtifacts(const ArtifactLocation &l1, const ArtifactLocation &l2)
|
||||||
{
|
{
|
||||||
const CStackInstance * stack1 = dynamic_cast<const CStackInstance*>(src);
|
ExchangeArtifacts ea;
|
||||||
const CStackInstance * stack2 = dynamic_cast<const CStackInstance*>(dest);
|
ea.src = l1;
|
||||||
const CGHeroInstance * hero1 = dynamic_cast<const CGHeroInstance*>(src);
|
ea.dst = l2;
|
||||||
const CGHeroInstance * hero2 = dynamic_cast<const CGHeroInstance*>(dest);
|
sendRequest(&ea);
|
||||||
|
return true;
|
||||||
ExchangeArtifacts ea(0,0,0,0);
|
|
||||||
|
|
||||||
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?
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -13,7 +13,6 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
class IArtifactSetBase;
|
|
||||||
class CGHeroInstance;
|
class CGHeroInstance;
|
||||||
class CGameState;
|
class CGameState;
|
||||||
struct CPath;
|
struct CPath;
|
||||||
@ -63,7 +62,7 @@ public:
|
|||||||
virtual int mergeOrSwapStacks(const CArmedInstance *s1, const CArmedInstance *s2, int p1, int p2) =0; //first goes to the second
|
virtual int mergeOrSwapStacks(const CArmedInstance *s1, const CArmedInstance *s2, int p1, int p2) =0; //first goes to the second
|
||||||
virtual int splitStack(const CArmedInstance *s1, const CArmedInstance *s2, int p1, int p2, int val)=0;//split creatures from the first stack
|
virtual int 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 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, ui16 artifactSlot, bool assemble, ui32 assembleTo)=0;
|
||||||
virtual bool dismissCreature(const CArmedInstance *obj, int stackPos)=0;
|
virtual bool dismissCreature(const CArmedInstance *obj, int stackPos)=0;
|
||||||
virtual void endTurn()=0;
|
virtual void endTurn()=0;
|
||||||
@ -127,7 +126,7 @@ public:
|
|||||||
int splitStack(const CArmedInstance *s1, const CArmedInstance *s2, int p1, int p2, int val);
|
int splitStack(const CArmedInstance *s1, const CArmedInstance *s2, int p1, int p2, int val);
|
||||||
bool dismissHero(const CGHeroInstance * hero);
|
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 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 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 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, ui16 artifactSlot, bool assemble, ui32 assembleTo);
|
||||||
|
1
Global.h
1
Global.h
@ -68,6 +68,7 @@
|
|||||||
#include <boost/range/algorithm.hpp>
|
#include <boost/range/algorithm.hpp>
|
||||||
#include <boost/thread.hpp>
|
#include <boost/thread.hpp>
|
||||||
#include <boost/unordered_set.hpp>
|
#include <boost/unordered_set.hpp>
|
||||||
|
#include <boost/variant.hpp>
|
||||||
|
|
||||||
#ifdef ANDROID
|
#ifdef ANDROID
|
||||||
#include <android/log.h>
|
#include <android/log.h>
|
||||||
|
@ -121,6 +121,7 @@ CCreatureWindow::CCreatureWindow(const CStackInstance &st, int Type, boost::func
|
|||||||
|
|
||||||
void CCreatureWindow::init(const CStackInstance *Stack, const CBonusSystemNode *StackNode, const CGHeroInstance *HeroOwner)
|
void CCreatureWindow::init(const CStackInstance *Stack, const CBonusSystemNode *StackNode, const CGHeroInstance *HeroOwner)
|
||||||
{
|
{
|
||||||
|
creatureArtifact = NULL; //may be set later
|
||||||
stack = Stack;
|
stack = Stack;
|
||||||
c = stack->type;
|
c = stack->type;
|
||||||
if(!StackNode)
|
if(!StackNode)
|
||||||
@ -264,11 +265,9 @@ void CCreatureWindow::init(const CStackInstance *Stack, const CBonusSystemNode *
|
|||||||
if (heroOwner)
|
if (heroOwner)
|
||||||
passArtToHero = new CAdventureMapButton(std::string(), std::string(), boost::bind (&CCreatureWindow::scrollArt, this, 0), 437, 148, "OVBUTN1.DEF", SDLK_HOME);
|
passArtToHero = new CAdventureMapButton(std::string(), std::string(), boost::bind (&CCreatureWindow::scrollArt, this, 0), 437, 148, "OVBUTN1.DEF", SDLK_HOME);
|
||||||
}
|
}
|
||||||
if (const CArtifactInstance * art = stack->getArt(GameConstants::CREATURE_ART))
|
if (creatureArtifact = stack->getArt(ArtifactPosition::CREATURE_SLOT))
|
||||||
blitAt(graphics->artDefs->ourImages[art->id].bitmap, 466, 161, *bitmap);
|
blitAt(graphics->artDefs->ourImages[creatureArtifact->artType->id].bitmap, 466, 100, *bitmap);
|
||||||
}
|
}
|
||||||
else
|
|
||||||
creatureArtifact = NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (battleStack) //only during battle
|
if (battleStack) //only during battle
|
||||||
@ -398,7 +397,7 @@ void CCreatureWindow::sliderMoved(int newpos)
|
|||||||
void CCreatureWindow::scrollArt(int dir)
|
void CCreatureWindow::scrollArt(int dir)
|
||||||
{
|
{
|
||||||
//TODO: get next artifact
|
//TODO: get next artifact
|
||||||
creatureArtifact = const_cast<CArtifactInstance*>(stack->getArt(GameConstants::CREATURE_ART));
|
creatureArtifact = stack->getArt(ArtifactPosition::CREATURE_SLOT);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CCreatureWindow::passArtifactToHero()
|
void CCreatureWindow::passArtifactToHero()
|
||||||
|
@ -48,7 +48,7 @@ public:
|
|||||||
const CStackInstance *stack;
|
const CStackInstance *stack;
|
||||||
const CBonusSystemNode *stackNode;
|
const CBonusSystemNode *stackNode;
|
||||||
const CGHeroInstance *heroOwner;
|
const CGHeroInstance *heroOwner;
|
||||||
CArtifactInstance *creatureArtifact; //currently worn artifact
|
const CArtifactInstance *creatureArtifact; //currently worn artifact
|
||||||
std::vector<CComponent*> upgResCost; //cost of upgrade (if not possible then empty)
|
std::vector<CComponent*> upgResCost; //cost of upgrade (if not possible then empty)
|
||||||
std::vector<CBonusItem*> bonusItems;
|
std::vector<CBonusItem*> bonusItems;
|
||||||
std::vector<LRClickableAreaWText*> spellEffects;
|
std::vector<LRClickableAreaWText*> spellEffects;
|
||||||
|
@ -99,6 +99,12 @@ void startGameFromFile(const std::string &fname)
|
|||||||
{
|
{
|
||||||
StartInfo si;
|
StartInfo si;
|
||||||
CLoadFile out(fname);
|
CLoadFile out(fname);
|
||||||
|
if(!out.sfile || !*out.sfile)
|
||||||
|
{
|
||||||
|
tlog1 << "Failed to open startfile, falling back to the main menu!\n";
|
||||||
|
GH.curInt = new CGPreGame;
|
||||||
|
return;
|
||||||
|
}
|
||||||
out >> si;
|
out >> si;
|
||||||
while(GH.topInt())
|
while(GH.topInt())
|
||||||
GH.popIntTotally(GH.topInt());
|
GH.popIntTotally(GH.topInt());
|
||||||
|
@ -333,15 +333,12 @@ void CClient::newGame( CConnection *con, StartInfo *si )
|
|||||||
c << myPlayers;
|
c << myPlayers;
|
||||||
|
|
||||||
|
|
||||||
ui32 seed, sum;
|
c >> si;
|
||||||
si32 seedPostInit;
|
|
||||||
c >> si >> sum >> seed >> seedPostInit;
|
|
||||||
tlog0 <<"\tSending/Getting info to/from the server: "<<tmh.getDiff()<<std::endl;
|
tlog0 <<"\tSending/Getting info to/from the server: "<<tmh.getDiff()<<std::endl;
|
||||||
tlog0 << "\tUsing random seed: "<<seed << std::endl;
|
|
||||||
|
|
||||||
gs = const_cast<CGameInfo*>(CGI)->state;
|
gs = const_cast<CGameInfo*>(CGI)->state;
|
||||||
gs->scenarioOps = si;
|
gs->scenarioOps = si;
|
||||||
gs->init(si, sum, seed, seedPostInit);
|
gs->init(si);
|
||||||
tlog0 <<"Initializing GameState (together): "<<tmh.getDiff()<<std::endl;
|
tlog0 <<"Initializing GameState (together): "<<tmh.getDiff()<<std::endl;
|
||||||
|
|
||||||
if(gs->map)
|
if(gs->map)
|
||||||
|
@ -189,7 +189,7 @@ public:
|
|||||||
void giveHeroArtifact(const CGHeroInstance *h, const CArtifactInstance *a, int pos) OVERRIDE {};
|
void giveHeroArtifact(const CGHeroInstance *h, const CArtifactInstance *a, int pos) OVERRIDE {};
|
||||||
void putArtifact(const ArtifactLocation &al, const CArtifactInstance *a) OVERRIDE {};
|
void putArtifact(const ArtifactLocation &al, const CArtifactInstance *a) OVERRIDE {};
|
||||||
void removeArtifact(const ArtifactLocation &al) OVERRIDE {};
|
void removeArtifact(const ArtifactLocation &al) OVERRIDE {};
|
||||||
void moveArtifact(const ArtifactLocation &al1, const ArtifactLocation &al2) OVERRIDE {};
|
bool moveArtifact(const ArtifactLocation &al1, const ArtifactLocation &al2) OVERRIDE {return false;};
|
||||||
|
|
||||||
void showCompInfo(ShowInInfobox * comp) OVERRIDE {};
|
void showCompInfo(ShowInInfobox * comp) OVERRIDE {};
|
||||||
void heroVisitCastle(int obj, int heroID) OVERRIDE {};
|
void heroVisitCastle(int obj, int heroID) OVERRIDE {};
|
||||||
|
@ -262,25 +262,31 @@ void CGarrisonSlot::clickLeft(tribool down, bool previousState)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else //drop artifact or highlight
|
else //highlight or drop artifact
|
||||||
{
|
{
|
||||||
bool artSelected = false;
|
bool artSelected = false;
|
||||||
if (CHeroWindow* chw = dynamic_cast<CHeroWindow*>(GH.topInt())) //dirty solution
|
if (CWindowWithArtifacts* chw = dynamic_cast<CWindowWithArtifacts*>(GH.topInt())) //dirty solution
|
||||||
{
|
{
|
||||||
BOOST_FOREACH(CArtifactsOfHero *aoh, chw->artSets) // why they are multiple?
|
const CArtifactsOfHero::SCommonPart *commonInfo = chw->artSets.front()->commonInfo;
|
||||||
|
if (const CArtifactInstance *art = commonInfo->src.art)
|
||||||
{
|
{
|
||||||
if (const CArtifactInstance *art = aoh->commonInfo->src.art)
|
const CGHeroInstance *srcHero = commonInfo->src.AOH->getHero();
|
||||||
{
|
artSelected = true;
|
||||||
artSelected = true;
|
ArtifactLocation src(srcHero, commonInfo->src.slotID);
|
||||||
if (art->canBePutAt(ArtifactLocation(myStack, GameConstants::CREATURE_ART)))
|
ArtifactLocation dst(myStack, ArtifactPosition::CREATURE_SLOT);
|
||||||
{ //equip clicked stack
|
if (art->canBePutAt(dst, true))
|
||||||
LOCPLINT->cb->swapArtifacts(aoh->getHero(), aoh->commonInfo->src.slotID, myStack, GameConstants::CREATURE_ART);
|
{ //equip clicked stack
|
||||||
break;
|
if(dst.getArt())
|
||||||
|
{
|
||||||
|
//creature can wear only one active artifact
|
||||||
|
//if we are placing a new one, the old one will be returned to the hero's backpack
|
||||||
|
LOCPLINT->cb->swapArtifacts(dst, ArtifactLocation(srcHero, dst.getArt()->firstBackpackSlot(srcHero)));
|
||||||
}
|
}
|
||||||
|
LOCPLINT->cb->swapArtifacts(src, dst);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (artSelected || creature)
|
if (!artSelected && creature)
|
||||||
{
|
{
|
||||||
owner->highlighted = this;
|
owner->highlighted = this;
|
||||||
if(creature)
|
if(creature)
|
||||||
@ -315,7 +321,6 @@ CGarrisonSlot::CGarrisonSlot(CGarrisonInt *Owner, int x, int y, int IID, int Upg
|
|||||||
{
|
{
|
||||||
//assert(Creature == CGI->creh->creatures[Creature->idNumber]);
|
//assert(Creature == CGI->creh->creatures[Creature->idNumber]);
|
||||||
active = false;
|
active = false;
|
||||||
highlight = false;
|
|
||||||
upg = Upg;
|
upg = Upg;
|
||||||
ID = IID;
|
ID = IID;
|
||||||
myStack = Creature;
|
myStack = Creature;
|
||||||
@ -353,11 +358,7 @@ void CGarrisonSlot::showAll(SDL_Surface * to)
|
|||||||
if((owner->highlighted==this)
|
if((owner->highlighted==this)
|
||||||
|| (owner->splitting && owner->highlighted->creature == creature))
|
|| (owner->splitting && owner->highlighted->creature == creature))
|
||||||
{
|
{
|
||||||
highlight = true;
|
blitAt(imgs[-1],pos,to);
|
||||||
}
|
|
||||||
{
|
|
||||||
if (highlight)
|
|
||||||
blitAt(imgs[-1],pos,to);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else//empty slot
|
else//empty slot
|
||||||
@ -2738,7 +2739,7 @@ void CTradeWindow::artifactSelected(CArtPlace *slot)
|
|||||||
{
|
{
|
||||||
assert(mode == EMarketMode::ARTIFACT_RESOURCE);
|
assert(mode == EMarketMode::ARTIFACT_RESOURCE);
|
||||||
items[1][0]->setArtInstance(slot->ourArt);
|
items[1][0]->setArtInstance(slot->ourArt);
|
||||||
if(slot->ourArt && slot->ourArt->id >= 0)
|
if(slot->ourArt)
|
||||||
hLeft = items[1][0];
|
hLeft = items[1][0];
|
||||||
else
|
else
|
||||||
hLeft = NULL;
|
hLeft = NULL;
|
||||||
@ -3606,7 +3607,7 @@ void CAltarWindow::moveFromSlotToAltar(int slotID, CTradeableItem* altarSlot, co
|
|||||||
if(putOnAltar(altarSlot, art))
|
if(putOnAltar(altarSlot, art))
|
||||||
{
|
{
|
||||||
if(slotID < GameConstants::BACKPACK_START)
|
if(slotID < GameConstants::BACKPACK_START)
|
||||||
LOCPLINT->cb->swapArtifacts(hero, slotID, hero, freeBackpackSlot);
|
LOCPLINT->cb->swapArtifacts(ArtifactLocation(hero, slotID), ArtifactLocation(hero, freeBackpackSlot));
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
arts->commonInfo->src.clear();
|
arts->commonInfo->src.clear();
|
||||||
@ -4418,7 +4419,7 @@ void CArtPlace::clickRight(tribool down, bool previousState)
|
|||||||
{
|
{
|
||||||
if(down && ourArt && !locked && text.size() && !picked) //if there is no description or it's a lock, do nothing ;]
|
if(down && ourArt && !locked && text.size() && !picked) //if there is no description or it's a lock, do nothing ;]
|
||||||
{
|
{
|
||||||
if (slotID < 19)
|
if (slotID < GameConstants::BACKPACK_START)
|
||||||
{
|
{
|
||||||
if(ourOwner->allowedAssembling)
|
if(ourOwner->allowedAssembling)
|
||||||
{
|
{
|
||||||
@ -4556,7 +4557,7 @@ bool CArtPlace::fitsHere(const CArtifactInstance * art) const
|
|||||||
return true;
|
return true;
|
||||||
|
|
||||||
// Anything can but War Machines can be placed in backpack.
|
// Anything can but War Machines can be placed in backpack.
|
||||||
if (slotID >= 19)
|
if (slotID >= GameConstants::BACKPACK_START)
|
||||||
return !CGI->arth->isBigArtifact(art->id);
|
return !CGI->arth->isBigArtifact(art->id);
|
||||||
|
|
||||||
return art->canBePutAt(ArtifactLocation(ourOwner->curHero, slotID), true);
|
return art->canBePutAt(ArtifactLocation(ourOwner->curHero, slotID), true);
|
||||||
@ -4812,7 +4813,7 @@ void CArtifactsOfHero::scrollBackpack(int dir)
|
|||||||
|
|
||||||
if (s < artsInBackpack)
|
if (s < artsInBackpack)
|
||||||
{
|
{
|
||||||
int slotID = 19 + (s + backpackPos)%artsInBackpack;
|
int slotID = GameConstants::BACKPACK_START + (s + backpackPos)%artsInBackpack;
|
||||||
const CArtifactInstance *art = curHero->getArt(slotID);
|
const CArtifactInstance *art = curHero->getArt(slotID);
|
||||||
assert(art);
|
assert(art);
|
||||||
if(!vstd::contains(toOmit, art))
|
if(!vstd::contains(toOmit, art))
|
||||||
@ -4829,7 +4830,7 @@ void CArtifactsOfHero::scrollBackpack(int dir)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
for( ; s - omitedSoFar < backpack.size(); s++)
|
for( ; s - omitedSoFar < backpack.size(); s++)
|
||||||
eraseSlotData(backpack[s-omitedSoFar], 19 + s);
|
eraseSlotData(backpack[s-omitedSoFar], 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
|
//in artifact merchant selling artifacts we may have highlight on one of backpack artifacts -> market needs update, cause artifact under highlight changed
|
||||||
if(highlightModeCallback)
|
if(highlightModeCallback)
|
||||||
@ -4864,21 +4865,6 @@ void CArtifactsOfHero::markPossibleSlots(const CArtifactInstance* art)
|
|||||||
BOOST_FOREACH(CArtPlace *place, aoh->artWorn)
|
BOOST_FOREACH(CArtPlace *place, aoh->artWorn)
|
||||||
place->marked = art->canBePutAt(ArtifactLocation(aoh->curHero, place->slotID), true);
|
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();
|
safeRedraw();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4966,7 +4952,7 @@ CArtifactsOfHero::CArtifactsOfHero(std::vector<CArtPlace *> ArtWorn, std::vector
|
|||||||
for(size_t s=0; s<backpack.size(); ++s)
|
for(size_t s=0; s<backpack.size(); ++s)
|
||||||
{
|
{
|
||||||
backpack[s]->ourOwner = this;
|
backpack[s]->ourOwner = this;
|
||||||
eraseSlotData(backpack[s], 19 + s);
|
eraseSlotData(backpack[s], GameConstants::BACKPACK_START + s);
|
||||||
}
|
}
|
||||||
|
|
||||||
leftArtRoll->callback += boost::bind(&CArtifactsOfHero::scrollBackpack,this,-1);
|
leftArtRoll->callback += boost::bind(&CArtifactsOfHero::scrollBackpack,this,-1);
|
||||||
@ -5077,28 +5063,31 @@ void CArtifactsOfHero::safeRedraw()
|
|||||||
|
|
||||||
void CArtifactsOfHero::realizeCurrentTransaction()
|
void CArtifactsOfHero::realizeCurrentTransaction()
|
||||||
{
|
{
|
||||||
assert(commonInfo->src.AOH || commonInfo->src.CAS);
|
assert(commonInfo->src.AOH);
|
||||||
assert(commonInfo->dst.AOH || commonInfo->dst.CAS);
|
assert(commonInfo->dst.AOH);
|
||||||
LOCPLINT->cb->swapArtifacts(commonInfo->src.AOH ? (IArtifactSetBase*)commonInfo->src.AOH->curHero : commonInfo->src.CAS, commonInfo->src.slotID,
|
LOCPLINT->cb->swapArtifacts(ArtifactLocation(commonInfo->src.AOH->curHero, commonInfo->src.slotID),
|
||||||
commonInfo->dst.AOH ? (IArtifactSetBase*)commonInfo->dst.AOH->curHero : commonInfo->dst.CAS, commonInfo->dst.slotID);
|
ArtifactLocation(commonInfo->dst.AOH->curHero, commonInfo->dst.slotID));
|
||||||
}
|
}
|
||||||
|
|
||||||
void CArtifactsOfHero::artifactMoved(const ArtifactLocation &src, const ArtifactLocation &dst)
|
void CArtifactsOfHero::artifactMoved(const ArtifactLocation &src, const ArtifactLocation &dst)
|
||||||
{
|
{
|
||||||
if(src.hero == curHero && src.slot >= GameConstants::BACKPACK_START)
|
bool isCurHeroSrc = src.isHolder(curHero),
|
||||||
|
isCurHeroDst = dst.isHolder(curHero);
|
||||||
|
if(isCurHeroSrc && src.slot >= GameConstants::BACKPACK_START)
|
||||||
updateSlot(src.slot);
|
updateSlot(src.slot);
|
||||||
if(dst.hero == curHero && dst.slot >= GameConstants::BACKPACK_START)
|
if(isCurHeroDst && dst.slot >= GameConstants::BACKPACK_START)
|
||||||
updateSlot(dst.slot);
|
updateSlot(dst.slot);
|
||||||
if(src.hero == curHero || dst.hero == curHero) //we need to update all slots, artifact might be combined and affect more slots
|
if(isCurHeroSrc || isCurHeroDst) //we need to update all slots, artifact might be combined and affect more slots
|
||||||
updateWornSlots(false);
|
updateWornSlots(false);
|
||||||
|
|
||||||
if (src.hero != curHero && dst.hero != curHero)
|
if (!src.isHolder(curHero) && !isCurHeroDst)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if(commonInfo->src == src) //artifact was taken from us
|
if(commonInfo->src == src) //artifact was taken from us
|
||||||
{
|
{
|
||||||
//assert(commonInfo->dst == dst || dst.slot == dst.hero->artifactsInBackpack.size() + GameConstants::BACKPACK_START);
|
assert(commonInfo->dst == dst //expected movement from slot ot slot
|
||||||
//FIXME: assertion fails for stack artifacts
|
|| dst.slot == dst.getHolderArtSet()->artifactsInBackpack.size() + GameConstants::BACKPACK_START //artifact moved back to backpack (eg. to make place for art we are moving)
|
||||||
|
|| dst.getHolderArtSet()->bearerType() == ArtBearer::CREATURE);
|
||||||
commonInfo->reset();
|
commonInfo->reset();
|
||||||
unmarkSlots();
|
unmarkSlots();
|
||||||
}
|
}
|
||||||
@ -5110,7 +5099,7 @@ void CArtifactsOfHero::artifactMoved(const ArtifactLocation &src, const Artifact
|
|||||||
CArtPlace *ap = NULL;
|
CArtPlace *ap = NULL;
|
||||||
BOOST_FOREACH(CArtifactsOfHero *aoh, commonInfo->participants)
|
BOOST_FOREACH(CArtifactsOfHero *aoh, commonInfo->participants)
|
||||||
{
|
{
|
||||||
if(aoh->curHero == dst.hero)
|
if(dst.isHolder(aoh->curHero))
|
||||||
{
|
{
|
||||||
commonInfo->src.AOH = aoh;
|
commonInfo->src.AOH = aoh;
|
||||||
if((ap = aoh->getArtPlace(dst.slot)))
|
if((ap = aoh->getArtPlace(dst.slot)))
|
||||||
@ -5133,7 +5122,7 @@ void CArtifactsOfHero::artifactMoved(const ArtifactLocation &src, const Artifact
|
|||||||
}
|
}
|
||||||
else if(src.slot >= GameConstants::BACKPACK_START &&
|
else if(src.slot >= GameConstants::BACKPACK_START &&
|
||||||
src.slot < commonInfo->src.slotID &&
|
src.slot < commonInfo->src.slotID &&
|
||||||
src.hero == commonInfo->src.AOH->curHero) //artifact taken from before currently picked one
|
src.isHolder(commonInfo->src.AOH->curHero)) //artifact taken from before currently picked one
|
||||||
{
|
{
|
||||||
//int fixedSlot = src.hero->getArtPos(commonInfo->src.art);
|
//int fixedSlot = src.hero->getArtPos(commonInfo->src.art);
|
||||||
commonInfo->src.slotID--;
|
commonInfo->src.slotID--;
|
||||||
@ -5157,14 +5146,14 @@ void CArtifactsOfHero::artifactMoved(const ArtifactLocation &src, const Artifact
|
|||||||
if(dst.slot < GameConstants::BACKPACK_START && src.slot - GameConstants::BACKPACK_START < backpackPos)
|
if(dst.slot < GameConstants::BACKPACK_START && src.slot - GameConstants::BACKPACK_START < backpackPos)
|
||||||
shift--;
|
shift--;
|
||||||
|
|
||||||
if( (src.hero == curHero && src.slot >= GameConstants::BACKPACK_START)
|
if( (isCurHeroSrc && src.slot >= GameConstants::BACKPACK_START)
|
||||||
|| (dst.hero == curHero && dst.slot >= GameConstants::BACKPACK_START) )
|
|| (isCurHeroDst && dst.slot >= GameConstants::BACKPACK_START) )
|
||||||
scrollBackpack(shift); //update backpack slots
|
scrollBackpack(shift); //update backpack slots
|
||||||
}
|
}
|
||||||
|
|
||||||
void CArtifactsOfHero::artifactRemoved(const ArtifactLocation &al)
|
void CArtifactsOfHero::artifactRemoved(const ArtifactLocation &al)
|
||||||
{
|
{
|
||||||
if(al.hero == curHero)
|
if(al.isHolder(curHero))
|
||||||
{
|
{
|
||||||
if(al.slot < GameConstants::BACKPACK_START)
|
if(al.slot < GameConstants::BACKPACK_START)
|
||||||
updateWornSlots(0);
|
updateWornSlots(0);
|
||||||
@ -5191,13 +5180,13 @@ CArtPlace * CArtifactsOfHero::getArtPlace(int slot)
|
|||||||
|
|
||||||
void CArtifactsOfHero::artifactAssembled(const ArtifactLocation &al)
|
void CArtifactsOfHero::artifactAssembled(const ArtifactLocation &al)
|
||||||
{
|
{
|
||||||
if(al.hero == curHero)
|
if(al.isHolder(curHero))
|
||||||
updateWornSlots();
|
updateWornSlots();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CArtifactsOfHero::artifactDisassembled(const ArtifactLocation &al)
|
void CArtifactsOfHero::artifactDisassembled(const ArtifactLocation &al)
|
||||||
{
|
{
|
||||||
if(al.hero == curHero)
|
if(al.isHolder(curHero))
|
||||||
updateWornSlots();
|
updateWornSlots();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -6323,21 +6312,11 @@ void CArtifactsOfHero::SCommonPart::Artpos::setTo(const CArtPlace *place, bool d
|
|||||||
art = place->ourArt;
|
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
|
bool CArtifactsOfHero::SCommonPart::Artpos::operator==(const ArtifactLocation &al) const
|
||||||
{
|
{
|
||||||
if(!AOH)
|
if(!AOH)
|
||||||
return false;
|
return false;
|
||||||
bool ret = al.hero == AOH->curHero && al.slot == slotID;
|
bool ret = al.isHolder(AOH->curHero) && al.slot == slotID;
|
||||||
|
|
||||||
//assert(al.getArt() == art);
|
//assert(al.getArt() == art);
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -25,7 +25,6 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
struct ArtifactLocation;
|
struct ArtifactLocation;
|
||||||
class IArtifactSetBase;
|
|
||||||
class CStackBasicDescriptor;
|
class CStackBasicDescriptor;
|
||||||
class CBonusSystemNode;
|
class CBonusSystemNode;
|
||||||
class CArtifact;
|
class CArtifact;
|
||||||
@ -858,13 +857,11 @@ public:
|
|||||||
{
|
{
|
||||||
int slotID;
|
int slotID;
|
||||||
const CArtifactsOfHero *AOH;
|
const CArtifactsOfHero *AOH;
|
||||||
const CCreatureArtifactSet *CAS;
|
|
||||||
const CArtifactInstance *art;
|
const CArtifactInstance *art;
|
||||||
|
|
||||||
Artpos();
|
Artpos();
|
||||||
void clear();
|
void clear();
|
||||||
void setTo(const CArtPlace *place, bool dontTakeBackpack);
|
void setTo(const CArtPlace *place, bool dontTakeBackpack);
|
||||||
IArtifactSetBase * getArtHolder(); // returns AOH or CAS
|
|
||||||
bool valid();
|
bool valid();
|
||||||
bool operator==(const ArtifactLocation &al) const;
|
bool operator==(const ArtifactLocation &al) const;
|
||||||
} src, dst;
|
} src, dst;
|
||||||
|
@ -210,30 +210,29 @@ void RebalanceStacks::applyCl( CClient *cl )
|
|||||||
|
|
||||||
void PutArtifact::applyCl( CClient *cl )
|
void PutArtifact::applyCl( CClient *cl )
|
||||||
{
|
{
|
||||||
INTERFACE_CALL_IF_PRESENT(al.hero->tempOwner, artifactPut, al);
|
INTERFACE_CALL_IF_PRESENT(al.owningPlayer(), artifactPut, al);
|
||||||
}
|
}
|
||||||
|
|
||||||
void EraseArtifact::applyCl( CClient *cl )
|
void EraseArtifact::applyCl( CClient *cl )
|
||||||
{
|
{
|
||||||
INTERFACE_CALL_IF_PRESENT(al.hero->tempOwner, artifactRemoved, al);
|
INTERFACE_CALL_IF_PRESENT(al.owningPlayer(), artifactRemoved, al);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MoveArtifact::applyCl( CClient *cl )
|
void MoveArtifact::applyCl( CClient *cl )
|
||||||
{
|
{
|
||||||
INTERFACE_CALL_IF_PRESENT(src.hero->tempOwner, artifactMoved, src, dst);
|
INTERFACE_CALL_IF_PRESENT(src.owningPlayer(), artifactMoved, src, dst);
|
||||||
if (src.hero.get() && dst.hero.get())
|
if(src.owningPlayer() != dst.owningPlayer())
|
||||||
if(src.hero->tempOwner != dst.hero->tempOwner)
|
INTERFACE_CALL_IF_PRESENT(src.owningPlayer(), artifactMoved, src, dst);
|
||||||
INTERFACE_CALL_IF_PRESENT(src.hero->tempOwner, artifactMoved, src, dst);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void AssembledArtifact::applyCl( CClient *cl )
|
void AssembledArtifact::applyCl( CClient *cl )
|
||||||
{
|
{
|
||||||
INTERFACE_CALL_IF_PRESENT(al.hero->tempOwner, artifactAssembled, al);
|
INTERFACE_CALL_IF_PRESENT(al.owningPlayer(), artifactAssembled, al);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DisassembledArtifact::applyCl( CClient *cl )
|
void DisassembledArtifact::applyCl( CClient *cl )
|
||||||
{
|
{
|
||||||
INTERFACE_CALL_IF_PRESENT(al.hero->tempOwner, artifactDisassembled, al);
|
INTERFACE_CALL_IF_PRESENT(al.owningPlayer(), artifactDisassembled, al);
|
||||||
}
|
}
|
||||||
|
|
||||||
void HeroVisit::applyCl( CClient *cl )
|
void HeroVisit::applyCl( CClient *cl )
|
||||||
|
@ -7,7 +7,6 @@
|
|||||||
#include "../lib/VCMI_Lib.h"
|
#include "../lib/VCMI_Lib.h"
|
||||||
#include "CSpellHandler.h"
|
#include "CSpellHandler.h"
|
||||||
#include "CObjectHandler.h"
|
#include "CObjectHandler.h"
|
||||||
//#include "CCreatureSet.h"
|
|
||||||
#include "NetPacks.h"
|
#include "NetPacks.h"
|
||||||
|
|
||||||
extern CLodHandler *bitmaph;
|
extern CLodHandler *bitmaph;
|
||||||
@ -196,8 +195,7 @@ CArtHandler::CArtHandler()
|
|||||||
// War machines are the default big artifacts.
|
// War machines are the default big artifacts.
|
||||||
for (ui32 i = 3; i <= 6; i++)
|
for (ui32 i = 3; i <= 6; i++)
|
||||||
bigArtifacts.insert(i);
|
bigArtifacts.insert(i);
|
||||||
if (GameConstants::STACK_ARTIFACT)
|
//modableArtifacts = boost::assign::map_list_of(1, 1)(146,3)(147,3)(148,3)(150,3)(151,3)(152,3)(154,3)(156,2);
|
||||||
creatureArtifacts += 141, 142, 143, 156; //basic Wog arts and Warlord's banner
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CArtHandler::~CArtHandler()
|
CArtHandler::~CArtHandler()
|
||||||
@ -233,11 +231,13 @@ void CArtHandler::loadArtifacts(bool onlyTxt)
|
|||||||
loadToIt(VLC->generaltexth->artifNames[i],buf,it,4);
|
loadToIt(VLC->generaltexth->artifNames[i],buf,it,4);
|
||||||
loadToIt(pom,buf,it,4);
|
loadToIt(pom,buf,it,4);
|
||||||
nart.price=atoi(pom.c_str());
|
nart.price=atoi(pom.c_str());
|
||||||
|
nart.possibleSlots[ArtBearer::HERO]; //we want to generate map entry even if it will be empty
|
||||||
|
nart.possibleSlots[ArtBearer::CREATURE]; //we want to generate map entry even if it will be empty
|
||||||
for(int j=0;j<slots.size();j++)
|
for(int j=0;j<slots.size();j++)
|
||||||
{
|
{
|
||||||
loadToIt(pom,buf,it,4);
|
loadToIt(pom,buf,it,4);
|
||||||
if(pom.size() && pom[0]=='x')
|
if(pom.size() && pom[0]=='x')
|
||||||
nart.possibleSlots.push_back(slots[j]);
|
nart.possibleSlots[ArtBearer::HERO].push_back(slots[j]);
|
||||||
}
|
}
|
||||||
loadToIt(pom,buf,it,4);
|
loadToIt(pom,buf,it,4);
|
||||||
nart.aClass = classes[pom[0]];
|
nart.aClass = classes[pom[0]];
|
||||||
@ -739,9 +739,19 @@ void CArtHandler::addBonuses()
|
|||||||
giveArtBonus(140, Bonus::GENERATE_RESOURCE, +4, Res::CRYSTAL);
|
giveArtBonus(140, Bonus::GENERATE_RESOURCE, +4, Res::CRYSTAL);
|
||||||
giveArtBonus(140, Bonus::GENERATE_RESOURCE, +4, Res::GEMS);
|
giveArtBonus(140, Bonus::GENERATE_RESOURCE, +4, Res::GEMS);
|
||||||
|
|
||||||
|
|
||||||
//Stack artifact test
|
//Stack artifact test
|
||||||
if (GameConstants::STACK_ARTIFACT)
|
if (GameConstants::STACK_ARTIFACT)
|
||||||
{
|
{
|
||||||
|
auto makeItCreatureArt = [this](int aid)
|
||||||
|
{
|
||||||
|
CArtifact *a = artifacts[aid];
|
||||||
|
a->possibleSlots[ArtBearer::CREATURE].push_back(ArtifactPosition::CREATURE_SLOT);
|
||||||
|
};
|
||||||
|
makeItCreatureArt(141);
|
||||||
|
makeItCreatureArt(142);
|
||||||
|
makeItCreatureArt(143);
|
||||||
|
makeItCreatureArt(156);
|
||||||
giveArtBonus(141, Bonus::STACK_HEALTH, +400, -1, Bonus::PERCENT_TO_BASE); //Magic Wans
|
giveArtBonus(141, Bonus::STACK_HEALTH, +400, -1, Bonus::PERCENT_TO_BASE); //Magic Wans
|
||||||
giveArtBonus(142, Bonus::STACK_HEALTH, +400, -1, Bonus::PERCENT_TO_BASE); //Tower Arrow
|
giveArtBonus(142, Bonus::STACK_HEALTH, +400, -1, Bonus::PERCENT_TO_BASE); //Tower Arrow
|
||||||
giveArtBonus(143, Bonus::STACK_HEALTH, +400, -1, Bonus::PERCENT_TO_BASE); //Monster's Power
|
giveArtBonus(143, Bonus::STACK_HEALTH, +400, -1, Bonus::PERCENT_TO_BASE); //Monster's Power
|
||||||
@ -910,11 +920,11 @@ void CArtifactInstance::init()
|
|||||||
setNodeType(ARTIFACT_INSTANCE);
|
setNodeType(ARTIFACT_INSTANCE);
|
||||||
}
|
}
|
||||||
|
|
||||||
int CArtifactInstance::firstAvailableSlot(const CGHeroInstance *h) const
|
int CArtifactInstance::firstAvailableSlot(const CArtifactSet *h) const
|
||||||
{
|
{
|
||||||
BOOST_FOREACH(ui16 slot, artType->possibleSlots)
|
BOOST_FOREACH(ui16 slot, artType->possibleSlots[h->bearerType()])
|
||||||
{
|
{
|
||||||
if(canBePutAt(ArtifactLocation(h, slot))) //if(artType->fitsAt(h->artifWorn, slot))
|
if(canBePutAt(h, slot)) //if(artType->fitsAt(h->artifWorn, slot))
|
||||||
{
|
{
|
||||||
//we've found a free suitable slot.
|
//we've found a free suitable slot.
|
||||||
return slot;
|
return slot;
|
||||||
@ -925,7 +935,7 @@ int CArtifactInstance::firstAvailableSlot(const CGHeroInstance *h) const
|
|||||||
return firstBackpackSlot(h);
|
return firstBackpackSlot(h);
|
||||||
}
|
}
|
||||||
|
|
||||||
int CArtifactInstance::firstBackpackSlot(const CGHeroInstance *h) const
|
int CArtifactInstance::firstBackpackSlot(const CArtifactSet *h) const
|
||||||
{
|
{
|
||||||
if(!artType->isBig()) //discard big artifact
|
if(!artType->isBig()) //discard big artifact
|
||||||
return GameConstants::BACKPACK_START + h->artifactsInBackpack.size();
|
return GameConstants::BACKPACK_START + h->artifactsInBackpack.size();
|
||||||
@ -935,60 +945,51 @@ int CArtifactInstance::firstBackpackSlot(const CGHeroInstance *h) const
|
|||||||
|
|
||||||
bool CArtifactInstance::canBePutAt(const ArtifactLocation &al, bool assumeDestRemoved /*= false*/) const
|
bool CArtifactInstance::canBePutAt(const ArtifactLocation &al, bool assumeDestRemoved /*= false*/) const
|
||||||
{
|
{
|
||||||
if (al.hero)
|
return canBePutAt(al.getHolderArtSet(), al.slot, assumeDestRemoved);
|
||||||
{
|
}
|
||||||
if(al.slot >= GameConstants::BACKPACK_START)
|
|
||||||
{
|
|
||||||
if(artType->isBig())
|
|
||||||
return false;
|
|
||||||
|
|
||||||
//TODO backpack limit
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!vstd::contains(artType->possibleSlots, al.slot))
|
bool CArtifactInstance::canBePutAt(const CArtifactSet *artSet, int slot, bool assumeDestRemoved /*= false*/) const
|
||||||
|
{
|
||||||
|
if(slot >= GameConstants::BACKPACK_START)
|
||||||
|
{
|
||||||
|
if(artType->isBig())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return al.hero->isPositionFree(al.slot, assumeDestRemoved);
|
//TODO backpack limit
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
|
if(!vstd::contains(artType->possibleSlots[artSet->bearerType()], slot))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
return artSet->isPositionFree(slot, assumeDestRemoved);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CArtifactInstance::putAt(CGHeroInstance *h, ui16 slot)
|
void CArtifactInstance::putAt(ArtifactLocation &al)
|
||||||
{
|
{
|
||||||
assert(canBePutAt(ArtifactLocation(h, slot)));
|
assert(canBePutAt(al));
|
||||||
|
|
||||||
h->setNewArtSlot(slot, this, false);
|
al.getHolderArtSet()->setNewArtSlot(al.slot, this, false);
|
||||||
if(slot < GameConstants::BACKPACK_START)
|
if(al.slot < GameConstants::BACKPACK_START)
|
||||||
h->attachTo(this);
|
al.getHolderNode()->attachTo(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CArtifactInstance::removeFrom(CGHeroInstance *h, ui16 slot)
|
void CArtifactInstance::removeFrom(ArtifactLocation &al)
|
||||||
{
|
{
|
||||||
assert(h->CArtifactSet::getArt(slot) == this);
|
assert(al.getHolderArtSet()->getArt(al.slot) == this);
|
||||||
h->eraseArtSlot(slot);
|
al.getHolderArtSet()->eraseArtSlot(al.slot);
|
||||||
if(slot < GameConstants::BACKPACK_START)
|
if(al.slot < GameConstants::BACKPACK_START)
|
||||||
h->detachFrom(this);
|
al.getHolderNode()->detachFrom(this);
|
||||||
|
|
||||||
//TODO delete me?
|
//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
|
bool CArtifactInstance::canBeDisassembled() const
|
||||||
{
|
{
|
||||||
return artType->constituents && artType->constituentOf->size();
|
return artType->constituents && artType->constituentOf->size();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<const CArtifact *> CArtifactInstance::assemblyPossibilities(const CGHeroInstance *h) const
|
std::vector<const CArtifact *> CArtifactInstance::assemblyPossibilities(const CArtifactSet *h) const
|
||||||
{
|
{
|
||||||
std::vector<const CArtifact *> ret;
|
std::vector<const CArtifact *> ret;
|
||||||
if(!artType->constituentOf //not a part of combined artifact
|
if(!artType->constituentOf //not a part of combined artifact
|
||||||
@ -1019,30 +1020,14 @@ std::vector<const CArtifact *> CArtifactInstance::assemblyPossibilities(const CG
|
|||||||
|
|
||||||
void CArtifactInstance::move(ArtifactLocation &src, ArtifactLocation &dst)
|
void CArtifactInstance::move(ArtifactLocation &src, ArtifactLocation &dst)
|
||||||
{
|
{
|
||||||
if (src.hero)
|
removeFrom(src);
|
||||||
removeFrom(src.hero, src.slot);
|
putAt(dst);
|
||||||
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);
|
|
||||||
else if (dst.stack)
|
|
||||||
putAt(dst.stack, dst.slot);
|
|
||||||
else
|
|
||||||
tlog1 << "No destination for moved artifact found!\n";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CArtifactInstance * CArtifactInstance::createNewArtifactInstance(CArtifact *Art)
|
CArtifactInstance * CArtifactInstance::createNewArtifactInstance(CArtifact *Art)
|
||||||
{
|
{
|
||||||
if(!Art->constituents)
|
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
|
else
|
||||||
{
|
{
|
||||||
CCombinedArtifactInstance * ret = new CCombinedArtifactInstance(Art);
|
CCombinedArtifactInstance * ret = new CCombinedArtifactInstance(Art);
|
||||||
@ -1077,12 +1062,12 @@ bool CArtifactInstance::isPart(const CArtifactInstance *supposedPart) const
|
|||||||
return supposedPart == this;
|
return supposedPart == this;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CCombinedArtifactInstance::canBePutAt(const ArtifactLocation &al, bool assumeDestRemoved /*= false*/) const
|
bool CCombinedArtifactInstance::canBePutAt(const CArtifactSet *artSet, int slot, bool assumeDestRemoved /*= false*/) const
|
||||||
{
|
{
|
||||||
bool canMainArtifactBePlaced = CArtifactInstance::canBePutAt(al, assumeDestRemoved);
|
bool canMainArtifactBePlaced = CArtifactInstance::canBePutAt(artSet, slot, assumeDestRemoved);
|
||||||
if(!canMainArtifactBePlaced)
|
if(!canMainArtifactBePlaced)
|
||||||
return false; //no is no...
|
return false; //no is no...
|
||||||
if(al.slot >= GameConstants::BACKPACK_START)
|
if(slot >= GameConstants::BACKPACK_START)
|
||||||
return true; //we can always remove combined art to the backapck
|
return true; //we can always remove combined art to the backapck
|
||||||
|
|
||||||
|
|
||||||
@ -1093,16 +1078,16 @@ bool CCombinedArtifactInstance::canBePutAt(const ArtifactLocation &al, bool assu
|
|||||||
//so we remove from the list all constituents that are already present on dst hero in the form of locks
|
//so we remove from the list all constituents that are already present on dst hero in the form of locks
|
||||||
BOOST_FOREACH(const ConstituentInfo &constituent, constituentsInfo)
|
BOOST_FOREACH(const ConstituentInfo &constituent, constituentsInfo)
|
||||||
{
|
{
|
||||||
if(constituent.art == al.hero->getArt(constituent.slot, false)) //no need to worry about locked constituent
|
if(constituent.art == artSet->getArt(constituent.slot, false)) //no need to worry about locked constituent
|
||||||
constituentsToBePlaced -= constituent;
|
constituentsToBePlaced -= constituent;
|
||||||
}
|
}
|
||||||
|
|
||||||
//we iterate over all active slots and check if constituents fits them
|
//we iterate over all active slots and check if constituents fits them
|
||||||
for (int i = 0; i < GameConstants::BACKPACK_START; i++)
|
for (int i = 0; i < GameConstants::BACKPACK_START; i++)
|
||||||
{
|
{
|
||||||
for(std::vector<ConstituentInfo>::iterator art = constituentsToBePlaced.begin(); art != constituentsToBePlaced.end(); art++)
|
for(std::vector<ConstituentInfo>::iterator art = constituentsToBePlaced.begin(); art != constituentsToBePlaced.end(); art++)
|
||||||
{
|
{
|
||||||
if(art->art->canBePutAt(ArtifactLocation(al.hero, i), i == al.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, 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);
|
constituentsToBePlaced.erase(art);
|
||||||
break;
|
break;
|
||||||
@ -1146,31 +1131,35 @@ void CCombinedArtifactInstance::addAsConstituent(CArtifactInstance *art, int slo
|
|||||||
attachTo(art);
|
attachTo(art);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CCombinedArtifactInstance::putAt(CGHeroInstance *h, ui16 slot)
|
void CCombinedArtifactInstance::putAt(ArtifactLocation &al)
|
||||||
{
|
{
|
||||||
if(slot >= GameConstants::BACKPACK_START)
|
if(al.slot >= GameConstants::BACKPACK_START)
|
||||||
{
|
{
|
||||||
CArtifactInstance::putAt(h, slot);
|
CArtifactInstance::putAt(al);
|
||||||
BOOST_FOREACH(ConstituentInfo &ci, constituentsInfo)
|
BOOST_FOREACH(ConstituentInfo &ci, constituentsInfo)
|
||||||
ci.slot = -1;
|
ci.slot = -1;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
CArtifactInstance *mainConstituent = figureMainConstituent(slot); //it'll be replaced with combined artifact, not a lock
|
CArtifactInstance *mainConstituent = figureMainConstituent(al); //it'll be replaced with combined artifact, not a lock
|
||||||
CArtifactInstance::putAt(h, slot); //puts combined art (this)
|
CArtifactInstance::putAt(al); //puts combined art (this)
|
||||||
|
|
||||||
BOOST_FOREACH(ConstituentInfo &ci, constituentsInfo)
|
BOOST_FOREACH(ConstituentInfo &ci, constituentsInfo)
|
||||||
{
|
{
|
||||||
if(ci.art != mainConstituent)
|
if(ci.art != mainConstituent)
|
||||||
{
|
{
|
||||||
|
const ArtifactLocation suggestedPos(al.artHolder, ci.slot);
|
||||||
|
const bool inActiveSlot = vstd::isbetween(ci.slot, 0, GameConstants::BACKPACK_START);
|
||||||
|
const bool suggestedPosValid = ci.art->canBePutAt(suggestedPos);
|
||||||
|
|
||||||
int pos = -1;
|
int pos = -1;
|
||||||
if(vstd::isbetween(ci.slot, 0, GameConstants::BACKPACK_START) && ci.art->canBePutAt(ArtifactLocation(h, ci.slot))) //there is a valid suggestion where to place lock
|
if(inActiveSlot && suggestedPosValid) //there is a valid suggestion where to place lock
|
||||||
pos = ci.slot;
|
pos = ci.slot;
|
||||||
else
|
else
|
||||||
ci.slot = pos = ci.art->firstAvailableSlot(h);
|
ci.slot = pos = ci.art->firstAvailableSlot(al.getHolderArtSet());
|
||||||
|
|
||||||
assert(pos < GameConstants::BACKPACK_START);
|
assert(pos < GameConstants::BACKPACK_START);
|
||||||
h->setNewArtSlot(pos, ci.art, true); //sets as lock
|
al.getHolderArtSet()->setNewArtSlot(pos, ci.art, true); //sets as lock
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -1180,11 +1169,11 @@ void CCombinedArtifactInstance::putAt(CGHeroInstance *h, ui16 slot)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CCombinedArtifactInstance::removeFrom(CGHeroInstance *h, ui16 slot)
|
void CCombinedArtifactInstance::removeFrom(ArtifactLocation &al)
|
||||||
{
|
{
|
||||||
if(slot >= GameConstants::BACKPACK_START)
|
if(al.slot >= GameConstants::BACKPACK_START)
|
||||||
{
|
{
|
||||||
CArtifactInstance::removeFrom(h, slot);
|
CArtifactInstance::removeFrom(al);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -1192,30 +1181,30 @@ void CCombinedArtifactInstance::removeFrom(CGHeroInstance *h, ui16 slot)
|
|||||||
{
|
{
|
||||||
if(ci.slot >= 0)
|
if(ci.slot >= 0)
|
||||||
{
|
{
|
||||||
h->eraseArtSlot(ci.slot);
|
al.getHolderArtSet()->eraseArtSlot(ci.slot);
|
||||||
ci.slot = -1;
|
ci.slot = -1;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
//main constituent
|
//main constituent
|
||||||
CArtifactInstance::removeFrom(h, slot);
|
CArtifactInstance::removeFrom(al);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CArtifactInstance * CCombinedArtifactInstance::figureMainConstituent(ui16 slot)
|
CArtifactInstance * CCombinedArtifactInstance::figureMainConstituent(const ArtifactLocation &al)
|
||||||
{
|
{
|
||||||
CArtifactInstance *mainConstituent = NULL; //it'll be replaced with combined artifact, not a lock
|
CArtifactInstance *mainConstituent = NULL; //it'll be replaced with combined artifact, not a lock
|
||||||
BOOST_FOREACH(ConstituentInfo &ci, constituentsInfo)
|
BOOST_FOREACH(ConstituentInfo &ci, constituentsInfo)
|
||||||
if(ci.slot == slot)
|
if(ci.slot == al.slot)
|
||||||
mainConstituent = ci.art;
|
mainConstituent = ci.art;
|
||||||
|
|
||||||
if(!mainConstituent)
|
if(!mainConstituent)
|
||||||
{
|
{
|
||||||
BOOST_FOREACH(ConstituentInfo &ci, constituentsInfo)
|
BOOST_FOREACH(ConstituentInfo &ci, constituentsInfo)
|
||||||
{
|
{
|
||||||
if(vstd::contains(ci.art->artType->possibleSlots, slot))
|
if(vstd::contains(ci.art->artType->possibleSlots[al.getHolderArtSet()->bearerType()], al.slot))
|
||||||
{
|
{
|
||||||
mainConstituent = ci.art;
|
mainConstituent = ci.art;
|
||||||
}
|
}
|
||||||
@ -1255,58 +1244,8 @@ bool CCombinedArtifactInstance::ConstituentInfo::operator==(const ConstituentInf
|
|||||||
{
|
{
|
||||||
return art == rhs.art && slot == rhs.slot;
|
return art == rhs.art && slot == rhs.slot;
|
||||||
}
|
}
|
||||||
CCreatureArtifactInstance::CCreatureArtifactInstance()
|
|
||||||
{
|
|
||||||
init();
|
|
||||||
}
|
|
||||||
|
|
||||||
CCreatureArtifactInstance::CCreatureArtifactInstance(CArtifact *Art)
|
const CArtifactInstance* CArtifactSet::getArt(ui16 pos, bool excludeLocked /*= true*/) const
|
||||||
{
|
|
||||||
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 al.stack->isPositionFree(al.slot, assumeDestRemoved);
|
|
||||||
}
|
|
||||||
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
|
|
||||||
{
|
{
|
||||||
if(const ArtSlotInfo *si = getSlot(pos))
|
if(const ArtSlotInfo *si = getSlot(pos))
|
||||||
{
|
{
|
||||||
@ -1317,29 +1256,9 @@ const CArtifactInstance* IArtifactSetBase::getArt(ui16 pos, bool excludeLocked)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IArtifactSetBase::hasArt(ui32 aid, bool onlyWorn) const
|
CArtifactInstance* CArtifactSet::getArt(ui16 pos, bool excludeLocked /*= true*/)
|
||||||
{
|
{
|
||||||
return getArtPos(aid, onlyWorn) != -1;
|
return const_cast<CArtifactInstance*>((const_cast<const CArtifactSet*>(this))->getArt(pos, excludeLocked));
|
||||||
}
|
|
||||||
|
|
||||||
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<CArtifactInstance*>((const_cast<const IArtifactSetBase*>(this))->getArt(pos, excludeLocked));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
si32 CArtifactSet::getArtPos(int aid, bool onlyWorn /*= true*/) const
|
si32 CArtifactSet::getArtPos(int aid, bool onlyWorn /*= true*/) const
|
||||||
@ -1384,6 +1303,11 @@ const CArtifactInstance * CArtifactSet::getArtByInstanceId(int artInstId) const
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool CArtifactSet::hasArt(ui32 aid, bool onlyWorn /*= false*/) const
|
||||||
|
{
|
||||||
|
return getArtPos(aid, onlyWorn) != -1;
|
||||||
|
}
|
||||||
|
|
||||||
const ArtSlotInfo * CArtifactSet::getSlot(ui16 pos) const
|
const ArtSlotInfo * CArtifactSet::getSlot(ui16 pos) const
|
||||||
{
|
{
|
||||||
if(vstd::contains(artifactsWorn, pos))
|
if(vstd::contains(artifactsWorn, pos))
|
||||||
@ -1400,6 +1324,14 @@ const ArtSlotInfo * CArtifactSet::getSlot(ui16 pos) const
|
|||||||
return NULL;
|
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
|
si32 CArtifactSet::getArtTypeId(ui16 pos) const
|
||||||
{
|
{
|
||||||
const CArtifactInstance * const a = getArt(pos);
|
const CArtifactInstance * const a = getArt(pos);
|
||||||
@ -1426,6 +1358,13 @@ ArtSlotInfo & CArtifactSet::retreiveNewArtSlot(ui16 slot)
|
|||||||
return ret;
|
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)
|
void CArtifactSet::eraseArtSlot(ui16 slot)
|
||||||
{
|
{
|
||||||
if(slot < GameConstants::BACKPACK_START)
|
if(slot < GameConstants::BACKPACK_START)
|
||||||
@ -1439,88 +1378,9 @@ void CArtifactSet::eraseArtSlot(ui16 slot)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ArtSlotInfo & CCreatureArtifactSet::retreiveNewArtSlot(ui16 slot)
|
void CArtifactSet::artDeserializationFix(CBonusSystemNode *node)
|
||||||
{
|
{
|
||||||
ArtSlotInfo &ret = slot == GameConstants::CREATURE_ART
|
for(bmap<ui16, ArtSlotInfo>::iterator i = artifactsWorn.begin(); i != artifactsWorn.end(); i++)
|
||||||
? activeArtifact
|
if(i->second.artifact && !i->second.locked)
|
||||||
: *artifactsInBackpack.insert(artifactsInBackpack.begin() + (slot - GameConstants::CREATURE_ART), ArtSlotInfo());
|
node->attachTo(i->second.artifact);
|
||||||
|
}
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CCreatureArtifactSet::eraseArtSlot(ui16 slot)
|
|
||||||
{
|
|
||||||
if(slot == GameConstants::CREATURE_ART)
|
|
||||||
{
|
|
||||||
activeArtifact.artifact = NULL; //hmm?
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
slot -= 1;
|
|
||||||
artifactsInBackpack.erase(artifactsInBackpack.begin() + slot);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const ArtSlotInfo * CCreatureArtifactSet::getSlot(ui16 pos) const
|
|
||||||
{
|
|
||||||
if (pos == GameConstants::CREATURE_ART)
|
|
||||||
return &activeArtifact;
|
|
||||||
else if(pos > GameConstants::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 GameConstants::CREATURE_ART;
|
|
||||||
|
|
||||||
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 GameConstants::CREATURE_ART;
|
|
||||||
|
|
||||||
for(int i = 0; i < artifactsInBackpack.size(); i++)
|
|
||||||
if(artifactsInBackpack[i].artifact == art)
|
|
||||||
return i + 1;
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
@ -16,9 +16,8 @@
|
|||||||
class CDefHandler;
|
class CDefHandler;
|
||||||
class CArtifact;
|
class CArtifact;
|
||||||
class CGHeroInstance;
|
class CGHeroInstance;
|
||||||
class CStackInstance;
|
|
||||||
//class CCreatureArtifactSet;
|
|
||||||
struct ArtifactLocation;
|
struct ArtifactLocation;
|
||||||
|
class CArtifactSet;
|
||||||
|
|
||||||
namespace ArtifactPosition
|
namespace ArtifactPosition
|
||||||
{
|
{
|
||||||
@ -27,7 +26,17 @@ namespace ArtifactPosition
|
|||||||
PRE_FIRST = -1,
|
PRE_FIRST = -1,
|
||||||
HEAD, SHOULDERS, NECK, RIGHT_HAND, LEFT_HAND, TORSO, RIGHT_RING, LEFT_RING, FEET, MISC1, MISC2, MISC3, MISC4,
|
HEAD, SHOULDERS, NECK, RIGHT_HAND, LEFT_HAND, TORSO, RIGHT_RING, LEFT_RING, FEET, MISC1, MISC2, MISC3, MISC4,
|
||||||
MACH1, MACH2, MACH3, MACH4, SPELLBOOK, MISC5,
|
MACH1, MACH2, MACH3, MACH4, SPELLBOOK, MISC5,
|
||||||
AFTER_LAST
|
AFTER_LAST,
|
||||||
|
//cres
|
||||||
|
CREATURE_SLOT = 0
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace ArtBearer
|
||||||
|
{
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
HERO, CREATURE
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -45,7 +54,7 @@ public:
|
|||||||
std::string nodeName() const OVERRIDE;
|
std::string nodeName() const OVERRIDE;
|
||||||
|
|
||||||
ui32 price;
|
ui32 price;
|
||||||
std::vector<ui16> possibleSlots; //ids of slots where artifact can be placed
|
bmap<ui8, std::vector<ui16> > possibleSlots; //Bearer Type => ids of slots where artifact can be placed
|
||||||
std::vector<ui32> * constituents; // Artifacts IDs a combined artifact consists of, or NULL.
|
std::vector<ui32> * constituents; // Artifacts IDs a combined artifact consists of, or NULL.
|
||||||
std::vector<ui32> * constituentOf; // Reverse map of constituents.
|
std::vector<ui32> * constituentOf; // Reverse map of constituents.
|
||||||
EartClass aClass;
|
EartClass aClass;
|
||||||
@ -77,23 +86,22 @@ public:
|
|||||||
|
|
||||||
//CArtifactInstance(int aid);
|
//CArtifactInstance(int aid);
|
||||||
|
|
||||||
virtual std::string nodeName() const OVERRIDE;
|
std::string nodeName() const OVERRIDE;
|
||||||
void deserializationFix();
|
void deserializationFix();
|
||||||
void setType(CArtifact *Art);
|
void setType(CArtifact *Art);
|
||||||
|
|
||||||
int firstAvailableSlot(const CGHeroInstance *h) const;
|
int firstAvailableSlot(const CArtifactSet *h) const;
|
||||||
int firstBackpackSlot(const CGHeroInstance *h) const;
|
int firstBackpackSlot(const CArtifactSet *h) const;
|
||||||
int getGivenSpellID() const; //to be used with scrolls (and similar arts), -1 if none
|
int getGivenSpellID() const; //to be used with scrolls (and similar arts), -1 if none
|
||||||
|
|
||||||
virtual bool canBePutAt(const ArtifactLocation &al, bool assumeDestRemoved = false) const;
|
virtual bool canBePutAt(const CArtifactSet *artSet, int slot, bool assumeDestRemoved = false) const;
|
||||||
|
bool canBePutAt(const ArtifactLocation &al, bool assumeDestRemoved = false) const; //forwards to the above one
|
||||||
virtual bool canBeDisassembled() const;
|
virtual bool canBeDisassembled() const;
|
||||||
virtual void putAt(CGHeroInstance *h, ui16 slot);
|
virtual void putAt(ArtifactLocation &al);
|
||||||
virtual void removeFrom(CGHeroInstance *h, ui16 slot);
|
virtual void removeFrom(ArtifactLocation &al);
|
||||||
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
|
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;
|
std::vector<const CArtifact *> assemblyPossibilities(const CArtifactSet *h) const;
|
||||||
void move(ArtifactLocation &src, ArtifactLocation &dst);
|
void move(ArtifactLocation &src, ArtifactLocation &dst);
|
||||||
|
|
||||||
template <typename Handler> void serialize(Handler &h, const int version)
|
template <typename Handler> void serialize(Handler &h, const int version)
|
||||||
@ -127,15 +135,15 @@ public:
|
|||||||
|
|
||||||
std::vector<ConstituentInfo> constituentsInfo;
|
std::vector<ConstituentInfo> constituentsInfo;
|
||||||
|
|
||||||
bool canBePutAt(const ArtifactLocation &al, bool assumeDestRemoved = false) const OVERRIDE;
|
bool canBePutAt(const CArtifactSet *artSet, int slot, bool assumeDestRemoved = false) const OVERRIDE;
|
||||||
bool canBeDisassembled() const OVERRIDE;
|
bool canBeDisassembled() const OVERRIDE;
|
||||||
void putAt(CGHeroInstance *h, ui16 slot) OVERRIDE;
|
void putAt(ArtifactLocation &al) OVERRIDE;
|
||||||
void removeFrom(CGHeroInstance *h, ui16 slot) OVERRIDE;
|
void removeFrom(ArtifactLocation &al) OVERRIDE;
|
||||||
bool isPart(const CArtifactInstance *supposedPart) const OVERRIDE;
|
bool isPart(const CArtifactInstance *supposedPart) const OVERRIDE;
|
||||||
|
|
||||||
void createConstituents();
|
void createConstituents();
|
||||||
void addAsConstituent(CArtifactInstance *art, int slot);
|
void addAsConstituent(CArtifactInstance *art, int slot);
|
||||||
CArtifactInstance *figureMainConstituent(ui16 slot); //main constituent is replcaed with us (combined art), not lock
|
CArtifactInstance *figureMainConstituent(const ArtifactLocation &al); //main constituent is replcaed with us (combined art), not lock
|
||||||
|
|
||||||
CCombinedArtifactInstance();
|
CCombinedArtifactInstance();
|
||||||
|
|
||||||
@ -151,30 +159,6 @@ 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
|
// class DLL_LINKAGE IModableArt : public CArtifact //artifact which can have different properties, such as scroll or banner
|
||||||
// { //used only for dynamic cast :P
|
// { //used only for dynamic cast :P
|
||||||
// public:
|
// public:
|
||||||
@ -240,7 +224,7 @@ public:
|
|||||||
std::vector< ConstTransitivePtr<CArtifact> > artifacts;
|
std::vector< ConstTransitivePtr<CArtifact> > artifacts;
|
||||||
std::vector<CArtifact *> allowedArtifacts;
|
std::vector<CArtifact *> allowedArtifacts;
|
||||||
std::set<ui32> bigArtifacts; // Artifacts that cannot be moved to backpack, e.g. war machines.
|
std::set<ui32> bigArtifacts; // Artifacts that cannot be moved to backpack, e.g. war machines.
|
||||||
std::set<ui32> creatureArtifacts; // can be held by Stacks
|
//std::map<ui32, ui8> modableArtifacts; //1-scroll, 2-banner, 3-commander art with progressive bonus
|
||||||
|
|
||||||
void loadArtifacts(bool onlyTxt);
|
void loadArtifacts(bool onlyTxt);
|
||||||
void sortArts();
|
void sortArts();
|
||||||
@ -263,7 +247,6 @@ public:
|
|||||||
template <typename Handler> void serialize(Handler &h, const int version)
|
template <typename Handler> void serialize(Handler &h, const int version)
|
||||||
{
|
{
|
||||||
h & artifacts & allowedArtifacts & treasures & minors & majors & relics;
|
h & artifacts & allowedArtifacts & treasures & minors & majors & relics;
|
||||||
h & creatureArtifacts;
|
|
||||||
//if(!h.saving) sortArts();
|
//if(!h.saving) sortArts();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -283,67 +266,33 @@ struct DLL_LINKAGE ArtSlotInfo
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class DLL_LINKAGE IArtifactSetBase
|
class DLL_LINKAGE CArtifactSet
|
||||||
{ ///artifacts container
|
{
|
||||||
public:
|
|
||||||
virtual void setNewArtSlot(ui16 slot, CArtifactInstance *art, bool locked);
|
|
||||||
virtual const CArtifactInstance* getArt(ui16 pos, bool excludeLocked = true) const;
|
|
||||||
virtual CArtifactInstance* getArt(ui16 pos, bool excludeLocked = true); //NULL - no artifact
|
|
||||||
virtual bool hasArt(ui32 aid, bool onlyWorn = false) const;
|
|
||||||
virtual bool isPositionFree(ui16 pos, bool onlyLockCheck = false) const;
|
|
||||||
|
|
||||||
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_LINKAGE CArtifactSet : public IArtifactSetBase
|
|
||||||
{ ///hero artifacts
|
|
||||||
public:
|
public:
|
||||||
std::vector<ArtSlotInfo> artifactsInBackpack; //hero's artifacts from bag
|
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<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
|
||||||
|
|
||||||
ArtSlotInfo &retreiveNewArtSlot(ui16 slot);
|
ArtSlotInfo &retreiveNewArtSlot(ui16 slot);
|
||||||
|
void setNewArtSlot(ui16 slot, CArtifactInstance *art, bool locked);
|
||||||
void eraseArtSlot(ui16 slot);
|
void eraseArtSlot(ui16 slot);
|
||||||
|
|
||||||
const ArtSlotInfo *getSlot(ui16 pos) const;
|
const ArtSlotInfo *getSlot(ui16 pos) const;
|
||||||
si32 getArtPos(int aid, bool onlyWorn = true) 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;
|
si32 getArtPos(const CArtifactInstance *art) const;
|
||||||
const CArtifactInstance *getArtByInstanceId(int artInstId) 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;
|
si32 getArtTypeId(ui16 pos) const;
|
||||||
|
|
||||||
|
virtual ui8 bearerType() const = 0;
|
||||||
virtual ~CArtifactSet();
|
virtual ~CArtifactSet();
|
||||||
|
|
||||||
template <typename Handler> void serialize(Handler &h, const int version)
|
template <typename Handler> void serialize(Handler &h, const int version)
|
||||||
{
|
{
|
||||||
h & artifactsInBackpack & artifactsWorn;
|
h & artifactsInBackpack & artifactsWorn;
|
||||||
}
|
}
|
||||||
};
|
|
||||||
|
void artDeserializationFix(CBonusSystemNode *node);
|
||||||
class DLL_LINKAGE CCreatureArtifactSet : public IArtifactSetBase
|
|
||||||
{ ///creature artifacts
|
|
||||||
public:
|
|
||||||
std::vector<ArtSlotInfo> artifactsInBackpack; //artifacts carried by creature - 4 max (according to WoG)
|
|
||||||
ArtSlotInfo activeArtifact; //position 0 - GameConstants::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 <typename Handler> void serialize(Handler &h, const int version)
|
|
||||||
{
|
|
||||||
h & artifactsInBackpack & activeArtifact;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
@ -874,18 +874,6 @@ void CStackInstance::setArmyObj(const CArmedInstance *ArmyObj)
|
|||||||
attachTo(const_cast<CArmedInstance*>(_armyObj));
|
attachTo(const_cast<CArmedInstance*>(_armyObj));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// void CStackInstance::getParents(TCNodes &out, const CBonusSystemNode *source /*= NULL*/) const
|
|
||||||
// {
|
|
||||||
// out.insert(type);
|
|
||||||
//
|
|
||||||
// if(source && source != this) //we should be root, if not - do not inherit anything
|
|
||||||
// return;
|
|
||||||
//
|
|
||||||
// if(armyObj)
|
|
||||||
// out.insert(armyObj);
|
|
||||||
// else
|
|
||||||
// out.insert(&IObjectInterface::cb->gameState()->globalEffects);
|
|
||||||
// }
|
|
||||||
|
|
||||||
std::string CStackInstance::getQuantityTXT(bool capitalized /*= true*/) const
|
std::string CStackInstance::getQuantityTXT(bool capitalized /*= true*/) const
|
||||||
{
|
{
|
||||||
@ -930,9 +918,7 @@ void CStackInstance::deserializationFix()
|
|||||||
const CArmedInstance *armyBackup = _armyObj;
|
const CArmedInstance *armyBackup = _armyObj;
|
||||||
_armyObj = NULL;
|
_armyObj = NULL;
|
||||||
setArmyObj(armyBackup);
|
setArmyObj(armyBackup);
|
||||||
|
artDeserializationFix(this);
|
||||||
if(activeArtifact.artifact)
|
|
||||||
attachTo(activeArtifact.artifact);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int CStackInstance::getCreatureID() const
|
int CStackInstance::getCreatureID() const
|
||||||
@ -954,6 +940,11 @@ ui64 CStackInstance::getPower() const
|
|||||||
return type->AIValue * count;
|
return type->AIValue * count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ui8 CStackInstance::bearerType() const
|
||||||
|
{
|
||||||
|
return ArtBearer::CREATURE;
|
||||||
|
}
|
||||||
|
|
||||||
CStackBasicDescriptor::CStackBasicDescriptor()
|
CStackBasicDescriptor::CStackBasicDescriptor()
|
||||||
{
|
{
|
||||||
type = NULL;
|
type = NULL;
|
||||||
|
@ -26,7 +26,7 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class DLL_LINKAGE CStackInstance : public CBonusSystemNode, public CStackBasicDescriptor, public CCreatureArtifactSet
|
class DLL_LINKAGE CStackInstance : public CBonusSystemNode, public CStackBasicDescriptor, public CArtifactSet
|
||||||
{
|
{
|
||||||
const CArmedInstance *_armyObj; //stack must be part of some army, army must be part of some object
|
const CArmedInstance *_armyObj; //stack must be part of some army, army must be part of some object
|
||||||
public:
|
public:
|
||||||
@ -39,7 +39,7 @@ public:
|
|||||||
{
|
{
|
||||||
h & static_cast<CBonusSystemNode&>(*this);
|
h & static_cast<CBonusSystemNode&>(*this);
|
||||||
h & static_cast<CStackBasicDescriptor&>(*this);
|
h & static_cast<CStackBasicDescriptor&>(*this);
|
||||||
h & static_cast<CCreatureArtifactSet&>(*this);
|
h & static_cast<CArtifactSet&>(*this);
|
||||||
h & _armyObj & experience;
|
h & _armyObj & experience;
|
||||||
BONUS_TREE_DESERIALIZATION_FIX
|
BONUS_TREE_DESERIALIZATION_FIX
|
||||||
}
|
}
|
||||||
@ -67,7 +67,8 @@ public:
|
|||||||
void setArmyObj(const CArmedInstance *ArmyObj);
|
void setArmyObj(const CArmedInstance *ArmyObj);
|
||||||
void giveStackExp(expType exp);
|
void giveStackExp(expType exp);
|
||||||
bool valid(bool allowUnrandomized) const;
|
bool valid(bool allowUnrandomized) const;
|
||||||
virtual std::string nodeName() const OVERRIDE;
|
ui8 bearerType() const OVERRIDE; //from CArtifactSet
|
||||||
|
virtual std::string nodeName() const OVERRIDE; //from CBonusSystemnode
|
||||||
void deserializationFix();
|
void deserializationFix();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -818,7 +818,7 @@ BattleInfo * CGameState::setupBattle(int3 tile, const CArmedInstance *armies[2],
|
|||||||
return BattleInfo::setupBattle(tile, terrain, terType, armies, heroes, creatureBank, town);
|
return BattleInfo::setupBattle(tile, terrain, terType, armies, heroes, creatureBank, town);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CGameState::init(StartInfo * si, ui32 checksum, int Seed, int expectedPostInitSeed /*= -1*/)
|
void CGameState::init(StartInfo * si)
|
||||||
{
|
{
|
||||||
struct HLP
|
struct HLP
|
||||||
{
|
{
|
||||||
@ -852,7 +852,7 @@ void CGameState::init(StartInfo * si, ui32 checksum, int Seed, int expectedPostI
|
|||||||
case 4: //spell scroll
|
case 4: //spell scroll
|
||||||
{
|
{
|
||||||
CArtifactInstance * scroll = CArtifactInstance::createScroll(VLC->spellh->spells[curBonus.info2]);
|
CArtifactInstance * scroll = CArtifactInstance::createScroll(VLC->spellh->spells[curBonus.info2]);
|
||||||
scroll->putAt(hero, scroll->firstAvailableSlot(hero));
|
scroll->putAt(ArtifactLocation(hero, scroll->firstAvailableSlot(hero)));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 5: //prim skill
|
case 5: //prim skill
|
||||||
@ -904,8 +904,8 @@ void CGameState::init(StartInfo * si, ui32 checksum, int Seed, int expectedPostI
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
seed = Seed;
|
tlog0 << "\tUsing random seed: "<< si->seedToBeUsed << std::endl;
|
||||||
ran.seed((boost::int32_t)seed);
|
ran.seed((boost::int32_t)si->seedToBeUsed);
|
||||||
scenarioOps = new StartInfo(*si);
|
scenarioOps = new StartInfo(*si);
|
||||||
initialOpts = new StartInfo(*si);
|
initialOpts = new StartInfo(*si);
|
||||||
si = NULL;
|
si = NULL;
|
||||||
@ -986,16 +986,18 @@ void CGameState::init(StartInfo * si, ui32 checksum, int Seed, int expectedPostI
|
|||||||
|
|
||||||
|
|
||||||
//tlog0 <<"Reading and detecting map file (together): "<<tmh.getDif()<<std::endl;
|
//tlog0 <<"Reading and detecting map file (together): "<<tmh.getDif()<<std::endl;
|
||||||
if(checksum)
|
tlog0 << "\tOur checksum for the map: "<< map->checksum << std::endl;
|
||||||
|
if(scenarioOps->mapfileChecksum)
|
||||||
{
|
{
|
||||||
tlog0 << "\tServer checksum for " << scenarioOps->mapname <<": "<< checksum << std::endl;
|
tlog0 << "\tServer checksum for " << scenarioOps->mapname <<": "<< scenarioOps->mapfileChecksum << std::endl;
|
||||||
tlog0 << "\tOur checksum for the map: "<< map->checksum << std::endl;
|
if(map->checksum != scenarioOps->mapfileChecksum)
|
||||||
if(map->checksum != checksum)
|
|
||||||
{
|
{
|
||||||
tlog1 << "Wrong map checksum!!!" << std::endl;
|
tlog1 << "Wrong map checksum!!!" << std::endl;
|
||||||
throw std::string("Wrong checksum");
|
throw std::string("Wrong checksum");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
scenarioOps->mapfileChecksum = map->checksum;
|
||||||
|
|
||||||
day = 0;
|
day = 0;
|
||||||
loadTownDInfos();
|
loadTownDInfos();
|
||||||
@ -1576,10 +1578,14 @@ void CGameState::init(StartInfo * si, ui32 checksum, int Seed, int expectedPostI
|
|||||||
|
|
||||||
map->checkForObjectives(); //needs to be run when all objects are properly placed
|
map->checkForObjectives(); //needs to be run when all objects are properly placed
|
||||||
|
|
||||||
if(expectedPostInitSeed >= 0)
|
if(scenarioOps->seedPostInit > 0)
|
||||||
{
|
{
|
||||||
int actualSeed = ran();
|
int actualSeed = ran();
|
||||||
assert(expectedPostInitSeed == actualSeed); //RNG must be in the same state on all machines when initialization is done (otherwise we have desync)
|
assert(scenarioOps->seedPostInit == actualSeed); //RNG must be in the same state on all machines when initialization is done (otherwise we have desync)
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
scenarioOps->seedPostInit = ran(); //store the post init "seed"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2473,7 +2479,7 @@ void CGameState::giveHeroArtifact(CGHeroInstance *h, int aid)
|
|||||||
CArtifact * const artifact = VLC->arth->artifacts[aid]; //pointer to constant object
|
CArtifact * const artifact = VLC->arth->artifacts[aid]; //pointer to constant object
|
||||||
CArtifactInstance *ai = CArtifactInstance::createNewArtifactInstance(artifact);
|
CArtifactInstance *ai = CArtifactInstance::createNewArtifactInstance(artifact);
|
||||||
map->addNewArtifactInstance(ai);
|
map->addNewArtifactInstance(ai);
|
||||||
ai->putAt(h, ai->firstAvailableSlot(h));
|
ai->putAt(ArtifactLocation(h, ai->firstAvailableSlot(h)));
|
||||||
}
|
}
|
||||||
|
|
||||||
int3 CPath::startPos() const
|
int3 CPath::startPos() const
|
||||||
|
@ -348,7 +348,6 @@ class DLL_LINKAGE CGameState : public CNonConstInfoCallback
|
|||||||
public:
|
public:
|
||||||
ConstTransitivePtr<StartInfo> scenarioOps, initialOpts; //second one is a copy of settings received from pregame (not randomized)
|
ConstTransitivePtr<StartInfo> scenarioOps, initialOpts; //second one is a copy of settings received from pregame (not randomized)
|
||||||
ConstTransitivePtr<CCampaignState> campaign;
|
ConstTransitivePtr<CCampaignState> campaign;
|
||||||
ui32 seed;
|
|
||||||
ui8 currentPlayer; //ID of player currently having turn
|
ui8 currentPlayer; //ID of player currently having turn
|
||||||
ConstTransitivePtr<BattleInfo> curB; //current battle
|
ConstTransitivePtr<BattleInfo> curB; //current battle
|
||||||
ui32 day; //total number of days in game
|
ui32 day; //total number of days in game
|
||||||
@ -374,7 +373,7 @@ public:
|
|||||||
|
|
||||||
boost::shared_mutex *mx;
|
boost::shared_mutex *mx;
|
||||||
|
|
||||||
void init(StartInfo * si, ui32 checksum, int Seed, int expectedPostInitSeed = -1);
|
void init(StartInfo * si);
|
||||||
void loadTownDInfos();
|
void loadTownDInfos();
|
||||||
void randomizeObject(CGObjectInstance *cur);
|
void randomizeObject(CGObjectInstance *cur);
|
||||||
std::pair<int,int> pickObject(CGObjectInstance *obj); //chooses type of object to be randomized, returns <type, subtype>
|
std::pair<int,int> pickObject(CGObjectInstance *obj); //chooses type of object to be randomized, returns <type, subtype>
|
||||||
@ -413,7 +412,7 @@ public:
|
|||||||
int getDate(int mode=0) const; //mode=0 - total days in game, mode=1 - day of week, mode=2 - current week, mode=3 - current month
|
int getDate(int mode=0) const; //mode=0 - total days in game, mode=1 - day of week, mode=2 - current week, mode=3 - current month
|
||||||
template <typename Handler> void serialize(Handler &h, const int version)
|
template <typename Handler> void serialize(Handler &h, const int version)
|
||||||
{
|
{
|
||||||
h & scenarioOps & initialOpts & seed & currentPlayer & day & map & players & teams & hpool & globalEffects & campaign;
|
h & scenarioOps & initialOpts & currentPlayer & day & map & players & teams & hpool & globalEffects & campaign;
|
||||||
h & villages & forts & capitols;
|
h & villages & forts & capitols;
|
||||||
if(!h.saving)
|
if(!h.saving)
|
||||||
{
|
{
|
||||||
|
@ -1473,7 +1473,7 @@ std::string CGHeroInstance::nodeName() const
|
|||||||
void CGHeroInstance::putArtifact(ui16 pos, CArtifactInstance *art)
|
void CGHeroInstance::putArtifact(ui16 pos, CArtifactInstance *art)
|
||||||
{
|
{
|
||||||
assert(!getArt(pos));
|
assert(!getArt(pos));
|
||||||
art->putAt(this, pos);
|
art->putAt(ArtifactLocation(this, pos));
|
||||||
}
|
}
|
||||||
|
|
||||||
void CGHeroInstance::putInBackpack(CArtifactInstance *art)
|
void CGHeroInstance::putInBackpack(CArtifactInstance *art)
|
||||||
@ -1488,11 +1488,7 @@ bool CGHeroInstance::hasSpellbook() const
|
|||||||
|
|
||||||
void CGHeroInstance::deserializationFix()
|
void CGHeroInstance::deserializationFix()
|
||||||
{
|
{
|
||||||
for(bmap<ui16, ArtSlotInfo>::iterator i = artifactsWorn.begin(); i != artifactsWorn.end(); i++)
|
artDeserializationFix(this);
|
||||||
if(i->second.artifact && !i->second.locked)
|
|
||||||
attachTo(i->second.artifact);
|
|
||||||
|
|
||||||
//attachTo(&speciality);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CBonusSystemNode * CGHeroInstance::whereShouldBeAttached(CGameState *gs)
|
CBonusSystemNode * CGHeroInstance::whereShouldBeAttached(CGameState *gs)
|
||||||
@ -1535,6 +1531,11 @@ CGHeroInstance::ECanDig CGHeroInstance::diggingStatus() const
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ui8 CGHeroInstance::bearerType() const
|
||||||
|
{
|
||||||
|
return ArtBearer::HERO;
|
||||||
|
}
|
||||||
|
|
||||||
void CGDwelling::initObj()
|
void CGDwelling::initObj()
|
||||||
{
|
{
|
||||||
switch(ID)
|
switch(ID)
|
||||||
|
@ -395,7 +395,9 @@ public:
|
|||||||
|
|
||||||
CGHeroInstance();
|
CGHeroInstance();
|
||||||
virtual ~CGHeroInstance();
|
virtual ~CGHeroInstance();
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
ui8 bearerType() const OVERRIDE;
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
virtual CBonusSystemNode *whereShouldBeAttached(CGameState *gs) OVERRIDE;
|
virtual CBonusSystemNode *whereShouldBeAttached(CGameState *gs) OVERRIDE;
|
||||||
|
@ -56,6 +56,8 @@ void CConnection::init()
|
|||||||
{
|
{
|
||||||
CISer<CConnection>::smartPointerSerialization = false;
|
CISer<CConnection>::smartPointerSerialization = false;
|
||||||
COSer<CConnection>::smartPointerSerialization = false;
|
COSer<CConnection>::smartPointerSerialization = false;
|
||||||
|
CISer<CConnection>::sendStackInstanceByIds = true;
|
||||||
|
COSer<CConnection>::sendStackInstanceByIds = true;
|
||||||
registerTypes(static_cast<CISer<CConnection>&>(*this));
|
registerTypes(static_cast<CISer<CConnection>&>(*this));
|
||||||
registerTypes(static_cast<COSer<CConnection>&>(*this));
|
registerTypes(static_cast<COSer<CConnection>&>(*this));
|
||||||
#ifdef LIL_ENDIAN
|
#ifdef LIL_ENDIAN
|
||||||
@ -382,6 +384,7 @@ CSerializer::~CSerializer()
|
|||||||
CSerializer::CSerializer()
|
CSerializer::CSerializer()
|
||||||
{
|
{
|
||||||
smartVectorMembersSerialization = false;
|
smartVectorMembersSerialization = false;
|
||||||
|
sendStackInstanceByIds = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
127
lib/Connection.h
127
lib/Connection.h
@ -20,9 +20,10 @@
|
|||||||
|
|
||||||
#include "ConstTransitivePtr.h"
|
#include "ConstTransitivePtr.h"
|
||||||
|
|
||||||
const ui32 version = 731;
|
const ui32 version = 732;
|
||||||
class CConnection;
|
class CConnection;
|
||||||
class CGObjectInstance;
|
class CGObjectInstance;
|
||||||
|
class CStackInstance;
|
||||||
class CGameState;
|
class CGameState;
|
||||||
class CCreature;
|
class CCreature;
|
||||||
class LibClasses;
|
class LibClasses;
|
||||||
@ -246,6 +247,7 @@ public:
|
|||||||
TTypeVecMap vectors; //entry must be a pointer to vector containing pointers to the objects of key type
|
TTypeVecMap vectors; //entry must be a pointer to vector containing pointers to the objects of key type
|
||||||
|
|
||||||
bool smartVectorMembersSerialization;
|
bool smartVectorMembersSerialization;
|
||||||
|
bool sendStackInstanceByIds;
|
||||||
|
|
||||||
CSerializer();
|
CSerializer();
|
||||||
~CSerializer();
|
~CSerializer();
|
||||||
@ -344,6 +346,63 @@ struct VectorisedTypeFor
|
|||||||
>::type type;
|
>::type type;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template <typename Handler>
|
||||||
|
struct VariantVisitorSaver : boost::static_visitor<>
|
||||||
|
{
|
||||||
|
Handler &h;
|
||||||
|
VariantVisitorSaver(Handler &H):h(H)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
void operator()(const T &t)
|
||||||
|
{
|
||||||
|
h << t;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename Ser,typename T>
|
||||||
|
struct SaveIfStackInstance
|
||||||
|
{
|
||||||
|
static bool invoke(Ser &s, const T &data)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
template<typename Ser>
|
||||||
|
struct SaveIfStackInstance<Ser, CStackInstance *>
|
||||||
|
{
|
||||||
|
static bool invoke(Ser &s, const CStackInstance* const &data)
|
||||||
|
{
|
||||||
|
assert(data->armyObj);
|
||||||
|
TSlot slot = data->armyObj->findStack(data);
|
||||||
|
s << data->armyObj << slot;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
template<typename Ser,typename T>
|
||||||
|
struct LoadIfStackInstance
|
||||||
|
{
|
||||||
|
static bool invoke(Ser &s, T &data)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
template<typename Ser>
|
||||||
|
struct LoadIfStackInstance<Ser, CStackInstance *>
|
||||||
|
{
|
||||||
|
static bool invoke(Ser &s, CStackInstance* &data)
|
||||||
|
{
|
||||||
|
CArmedInstance *armedObj;
|
||||||
|
TSlot slot;
|
||||||
|
s >> armedObj >> slot;
|
||||||
|
assert(armedObj->hasStackAtSlot(slot));
|
||||||
|
data = armedObj->stacks[slot];
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/// The class which manages saving objects.
|
/// The class which manages saving objects.
|
||||||
template <typename Serializer> class DLL_LINKAGE COSer : public CSaverBase
|
template <typename Serializer> class DLL_LINKAGE COSer : public CSaverBase
|
||||||
{
|
{
|
||||||
@ -424,6 +483,12 @@ public:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(sendStackInstanceByIds)
|
||||||
|
{
|
||||||
|
const bool gotSaved = SaveIfStackInstance<Serializer,T>::invoke(*This(), data);
|
||||||
|
if(gotSaved)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if(smartPointerSerialization)
|
if(smartPointerSerialization)
|
||||||
{
|
{
|
||||||
@ -552,6 +617,15 @@ public:
|
|||||||
for(typename std::map<T1,T2>::const_iterator i=data.begin();i!=data.end();i++)
|
for(typename std::map<T1,T2>::const_iterator i=data.begin();i!=data.end();i++)
|
||||||
*this << i->first << i->second;
|
*this << i->first << i->second;
|
||||||
}
|
}
|
||||||
|
template <BOOST_VARIANT_ENUM_PARAMS(typename T)>
|
||||||
|
void saveSerializable(const boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> &data)
|
||||||
|
{
|
||||||
|
si32 which = data.which();
|
||||||
|
*this << which;
|
||||||
|
|
||||||
|
VariantVisitorSaver<Serializer> visitor(*this->This());
|
||||||
|
boost::apply_visitor(visitor, data);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -663,8 +737,9 @@ public:
|
|||||||
{
|
{
|
||||||
this->This()->read(&data,sizeof(data));
|
this->This()->read(&data,sizeof(data));
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void loadSerializable(T &data)
|
void loadSerializableBySerializeCall(T &data)
|
||||||
{
|
{
|
||||||
////that const cast is evil because it allows to implicitly overwrite const objects when deserializing
|
////that const cast is evil because it allows to implicitly overwrite const objects when deserializing
|
||||||
typedef typename boost::remove_const<T>::type nonConstT;
|
typedef typename boost::remove_const<T>::type nonConstT;
|
||||||
@ -672,6 +747,12 @@ public:
|
|||||||
hlp.serialize(*this,myVersion);
|
hlp.serialize(*this,myVersion);
|
||||||
//data.serialize(*this,myVersion);
|
//data.serialize(*this,myVersion);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
void loadSerializable(T &data)
|
||||||
|
{
|
||||||
|
loadSerializableBySerializeCall(data);
|
||||||
|
}
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void loadArray(T &data)
|
void loadArray(T &data)
|
||||||
{
|
{
|
||||||
@ -706,6 +787,13 @@ public:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(sendStackInstanceByIds)
|
||||||
|
{
|
||||||
|
bool gotLoaded = LoadIfStackInstance<Serializer,T>::invoke(*This(), data);
|
||||||
|
if(gotLoaded)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
ui32 pid = 0xffffffff; //pointer id (or maybe rather pointee id)
|
ui32 pid = 0xffffffff; //pointer id (or maybe rather pointee id)
|
||||||
if(smartPointerSerialization)
|
if(smartPointerSerialization)
|
||||||
{
|
{
|
||||||
@ -832,10 +920,43 @@ public:
|
|||||||
data.resize(length);
|
data.resize(length);
|
||||||
this->This()->read((void*)data.c_str(),length);
|
this->This()->read((void*)data.c_str(),length);
|
||||||
}
|
}
|
||||||
|
template <BOOST_VARIANT_ENUM_PARAMS(typename T)>
|
||||||
|
void loadSerializable(boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> &data)
|
||||||
|
{
|
||||||
|
si32 which;
|
||||||
|
*this >> which;
|
||||||
|
if(which == 0)
|
||||||
|
{
|
||||||
|
T0 obj;
|
||||||
|
*this >> obj;
|
||||||
|
data = obj;
|
||||||
|
}
|
||||||
|
else if(which == 1)
|
||||||
|
{
|
||||||
|
T1 obj;
|
||||||
|
*this >> obj;
|
||||||
|
data = obj;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
assert(0);
|
||||||
|
//TODO write more if needed, general solution would be much longer
|
||||||
|
}
|
||||||
|
void loadSerializable(CStackInstance *&s)
|
||||||
|
{
|
||||||
|
if(sendStackInstanceByIds)
|
||||||
|
{
|
||||||
|
CArmedInstance *armed;
|
||||||
|
TSlot slot;
|
||||||
|
*this >> armed >> slot;
|
||||||
|
assert(armed->hasStackAtSlot(slot));
|
||||||
|
s = armed->stacks[slot];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
loadSerializableBySerializeCall(s);
|
||||||
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
class DLL_LINKAGE CSaveFile
|
class DLL_LINKAGE CSaveFile
|
||||||
: public COSer<CSaveFile>
|
: public COSer<CSaveFile>
|
||||||
{
|
{
|
||||||
|
@ -88,7 +88,6 @@ namespace GameConstants
|
|||||||
|
|
||||||
const ui16 BACKPACK_START = 19;
|
const ui16 BACKPACK_START = 19;
|
||||||
const int ID_CATAPULT = 3, ID_LOCK = 145;
|
const int ID_CATAPULT = 3, ID_LOCK = 145;
|
||||||
const ui16 CREATURE_ART = 0; //position in CCreatureArtifactSet
|
|
||||||
|
|
||||||
//game modules
|
//game modules
|
||||||
const bool STACK_EXP = true;
|
const bool STACK_EXP = true;
|
||||||
@ -98,6 +97,11 @@ namespace GameConstants
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Enum declarations
|
// Enum declarations
|
||||||
|
namespace PrimarySkill
|
||||||
|
{
|
||||||
|
enum { ATTACK, DEFENSE, SPELL_POWER, KNOWLEDGE};
|
||||||
|
}
|
||||||
|
|
||||||
namespace EVictoryConditionType
|
namespace EVictoryConditionType
|
||||||
{
|
{
|
||||||
enum EVictoryConditionType { ARTIFACT, GATHERTROOP, GATHERRESOURCE, BUILDCITY, BUILDGRAIL, BEATHERO,
|
enum EVictoryConditionType { ARTIFACT, GATHERTROOP, GATHERRESOURCE, BUILDCITY, BUILDGRAIL, BEATHERO,
|
||||||
|
@ -1,7 +1,5 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
|
||||||
#include <boost/range.hpp>
|
|
||||||
#include "GameConstants.h"
|
#include "GameConstants.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -31,10 +29,7 @@ typedef std::set<const CBonusSystemNode*> TCNodes;
|
|||||||
typedef std::vector<CBonusSystemNode *> TNodesVector;
|
typedef std::vector<CBonusSystemNode *> TNodesVector;
|
||||||
typedef boost::function<bool(const Bonus*)> CSelector;
|
typedef boost::function<bool(const Bonus*)> CSelector;
|
||||||
|
|
||||||
namespace PrimarySkill
|
|
||||||
{
|
|
||||||
enum { ATTACK, DEFENSE, SPELL_POWER, KNOWLEDGE};
|
|
||||||
}
|
|
||||||
|
|
||||||
#define BONUS_TREE_DESERIALIZATION_FIX if(!h.saving && h.smartPointerSerialization) deserializationFix();
|
#define BONUS_TREE_DESERIALIZATION_FIX if(!h.saving && h.smartPointerSerialization) deserializationFix();
|
||||||
|
|
||||||
|
@ -307,7 +307,7 @@ public:
|
|||||||
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 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 putArtifact(const ArtifactLocation &al, const CArtifactInstance *a) = 0;
|
virtual void putArtifact(const ArtifactLocation &al, const CArtifactInstance *a) = 0;
|
||||||
virtual void removeArtifact(const ArtifactLocation &al) = 0;
|
virtual void removeArtifact(const ArtifactLocation &al) = 0;
|
||||||
virtual void moveArtifact(const ArtifactLocation &al1, const ArtifactLocation &al2) = 0;
|
virtual bool moveArtifact(const ArtifactLocation &al1, const ArtifactLocation &al2) = 0;
|
||||||
|
|
||||||
virtual void showCompInfo(ShowInInfobox * comp)=0;
|
virtual void showCompInfo(ShowInInfobox * comp)=0;
|
||||||
virtual void heroVisitCastle(int obj, int heroID)=0;
|
virtual void heroVisitCastle(int obj, int heroID)=0;
|
||||||
|
@ -845,34 +845,52 @@ typedef si32 TArtPos;
|
|||||||
|
|
||||||
struct ArtifactLocation
|
struct ArtifactLocation
|
||||||
{
|
{
|
||||||
ConstTransitivePtr<CGHeroInstance> hero;
|
typedef boost::variant<ConstTransitivePtr<CGHeroInstance>, ConstTransitivePtr<CStackInstance> > TArtHolder;
|
||||||
ConstTransitivePtr<CStackInstance> stack;
|
|
||||||
|
TArtHolder artHolder;
|
||||||
TArtPos slot;
|
TArtPos slot;
|
||||||
|
|
||||||
ArtifactLocation()
|
ArtifactLocation()
|
||||||
{
|
{
|
||||||
|
artHolder = ConstTransitivePtr<CGHeroInstance>();
|
||||||
slot = -1;
|
slot = -1;
|
||||||
stack = NULL;
|
|
||||||
hero = NULL;
|
|
||||||
}
|
}
|
||||||
ArtifactLocation(const CGHeroInstance *Hero, TArtPos Slot)
|
template <typename T>
|
||||||
|
ArtifactLocation(const T *ArtHolder, 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;
|
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;
|
slot = Slot;
|
||||||
}
|
}
|
||||||
ArtifactLocation(const CStackInstance *Stack, TArtPos Slot)
|
ArtifactLocation(TArtHolder ArtHolder, 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!
|
artHolder = ArtHolder;
|
||||||
hero = NULL;
|
|
||||||
slot = Slot;
|
slot = Slot;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
bool isHolder(const T *t) const
|
||||||
|
{
|
||||||
|
if(auto ptrToT = boost::get<ConstTransitivePtr<T> >(&artHolder))
|
||||||
|
{
|
||||||
|
return ptrToT->get() == t;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
DLL_LINKAGE const CArmedInstance *relatedObj() const; //hero or the stack owner
|
||||||
|
DLL_LINKAGE int owningPlayer() const;
|
||||||
|
DLL_LINKAGE CArtifactSet *getHolderArtSet();
|
||||||
|
DLL_LINKAGE CBonusSystemNode *getHolderNode();
|
||||||
|
DLL_LINKAGE const CArtifactSet *getHolderArtSet() const;
|
||||||
|
DLL_LINKAGE const CBonusSystemNode *getHolderNode() const;
|
||||||
|
|
||||||
DLL_LINKAGE const CArtifactInstance *getArt() const;
|
DLL_LINKAGE const CArtifactInstance *getArt() const;
|
||||||
DLL_LINKAGE CArtifactInstance *getArt();
|
DLL_LINKAGE CArtifactInstance *getArt();
|
||||||
DLL_LINKAGE const ArtSlotInfo *getSlot() const;
|
DLL_LINKAGE const ArtSlotInfo *getSlot() const;
|
||||||
template <typename Handler> void serialize(Handler &h, const int version)
|
template <typename Handler> void serialize(Handler &h, const int version)
|
||||||
{
|
{
|
||||||
h & hero & stack & slot;
|
h & artHolder & slot;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1764,20 +1782,13 @@ struct GarrisonHeroSwap : public CPackForServer
|
|||||||
struct ExchangeArtifacts : public CPackForServer
|
struct ExchangeArtifacts : public CPackForServer
|
||||||
//TODO: allow exchange between heroes, stacks and commanders
|
//TODO: allow exchange between heroes, stacks and commanders
|
||||||
{
|
{
|
||||||
|
ArtifactLocation src, dst;
|
||||||
ExchangeArtifacts(){};
|
ExchangeArtifacts(){};
|
||||||
ExchangeArtifacts(si32 H1, si32 H2, ui16 S1, ui16 S2)
|
|
||||||
:hid1(H1),hid2(H2),slot1(S1),slot2(S2)
|
|
||||||
{
|
|
||||||
s1 = s2 = StackLocation(NULL,0);
|
|
||||||
};
|
|
||||||
si32 hid1, hid2;
|
|
||||||
StackLocation s1, s2; //for creature stacks
|
|
||||||
ui16 slot1, slot2;
|
|
||||||
|
|
||||||
bool applyGh(CGameHandler *gh);
|
bool applyGh(CGameHandler *gh);
|
||||||
template <typename Handler> void serialize(Handler &h, const int version)
|
template <typename Handler> void serialize(Handler &h, const int version)
|
||||||
{
|
{
|
||||||
h & hid1 & hid2 & s1 & s2 & slot1 & slot2;
|
h & src & dst;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -536,6 +536,48 @@ DLL_LINKAGE const CStackInstance * StackLocation::getStack()
|
|||||||
return &army->getStack(slot);
|
return &army->getStack(slot);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct ObjectRetriever : boost::static_visitor<const CArmedInstance *>
|
||||||
|
{
|
||||||
|
const CArmedInstance * operator()(const ConstTransitivePtr<CGHeroInstance> &h) const
|
||||||
|
{
|
||||||
|
return h;
|
||||||
|
}
|
||||||
|
const CArmedInstance * operator()(const ConstTransitivePtr<CStackInstance> &s) const
|
||||||
|
{
|
||||||
|
return s->armyObj;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
template <typename T>
|
||||||
|
struct GetBase : boost::static_visitor<T*>
|
||||||
|
{
|
||||||
|
template <typename TArg>
|
||||||
|
T * operator()(TArg &arg) const
|
||||||
|
{
|
||||||
|
return arg;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
DLL_LINKAGE const CArmedInstance * ArtifactLocation::relatedObj() const
|
||||||
|
{
|
||||||
|
return boost::apply_visitor(ObjectRetriever(), artHolder);
|
||||||
|
}
|
||||||
|
|
||||||
|
DLL_LINKAGE int ArtifactLocation::owningPlayer() const
|
||||||
|
{
|
||||||
|
auto obj = relatedObj();
|
||||||
|
return obj ? obj->tempOwner : GameConstants::NEUTRAL_PLAYER;
|
||||||
|
}
|
||||||
|
|
||||||
|
DLL_LINKAGE CArtifactSet *ArtifactLocation::getHolderArtSet()
|
||||||
|
{
|
||||||
|
return boost::apply_visitor(GetBase<CArtifactSet>(), artHolder);
|
||||||
|
}
|
||||||
|
|
||||||
|
DLL_LINKAGE CBonusSystemNode *ArtifactLocation::getHolderNode()
|
||||||
|
{
|
||||||
|
return boost::apply_visitor(GetBase<CBonusSystemNode>(), artHolder);
|
||||||
|
}
|
||||||
|
|
||||||
DLL_LINKAGE const CArtifactInstance *ArtifactLocation::getArt() const
|
DLL_LINKAGE const CArtifactInstance *ArtifactLocation::getArt() const
|
||||||
{
|
{
|
||||||
const ArtSlotInfo *s = getSlot();
|
const ArtSlotInfo *s = getSlot();
|
||||||
@ -552,6 +594,18 @@ DLL_LINKAGE const CArtifactInstance *ArtifactLocation::getArt() const
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DLL_LINKAGE const CArtifactSet * ArtifactLocation::getHolderArtSet() const
|
||||||
|
{
|
||||||
|
ArtifactLocation *t = const_cast<ArtifactLocation*>(this);
|
||||||
|
return t->getHolderArtSet();
|
||||||
|
}
|
||||||
|
|
||||||
|
DLL_LINKAGE const CBonusSystemNode * ArtifactLocation::getHolderNode() const
|
||||||
|
{
|
||||||
|
ArtifactLocation *t = const_cast<ArtifactLocation*>(this);
|
||||||
|
return t->getHolderNode();
|
||||||
|
}
|
||||||
|
|
||||||
DLL_LINKAGE CArtifactInstance *ArtifactLocation::getArt()
|
DLL_LINKAGE CArtifactInstance *ArtifactLocation::getArt()
|
||||||
{
|
{
|
||||||
const ArtifactLocation *t = this;
|
const ArtifactLocation *t = this;
|
||||||
@ -560,11 +614,7 @@ DLL_LINKAGE CArtifactInstance *ArtifactLocation::getArt()
|
|||||||
|
|
||||||
DLL_LINKAGE const ArtSlotInfo *ArtifactLocation::getSlot() const
|
DLL_LINKAGE const ArtSlotInfo *ArtifactLocation::getSlot() const
|
||||||
{
|
{
|
||||||
if (hero)
|
return getHolderArtSet()->getSlot(slot);
|
||||||
return hero->getSlot(slot);
|
|
||||||
if (stack)
|
|
||||||
return stack->getSlot(slot);
|
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DLL_LINKAGE void ChangeStackCount::applyGs( CGameState *gs )
|
DLL_LINKAGE void ChangeStackCount::applyGs( CGameState *gs )
|
||||||
@ -662,14 +712,15 @@ DLL_LINKAGE void RebalanceStacks::applyGs( CGameState *gs )
|
|||||||
DLL_LINKAGE void PutArtifact::applyGs( CGameState *gs )
|
DLL_LINKAGE void PutArtifact::applyGs( CGameState *gs )
|
||||||
{
|
{
|
||||||
assert(art->canBePutAt(al));
|
assert(art->canBePutAt(al));
|
||||||
al.hero->putArtifact(al.slot, art);
|
art->putAt(al);
|
||||||
|
//al.hero->putArtifact(al.slot, art);
|
||||||
}
|
}
|
||||||
|
|
||||||
DLL_LINKAGE void EraseArtifact::applyGs( CGameState *gs )
|
DLL_LINKAGE void EraseArtifact::applyGs( CGameState *gs )
|
||||||
{
|
{
|
||||||
CArtifactInstance *a = al.getArt();
|
CArtifactInstance *a = al.getArt();
|
||||||
assert(a);
|
assert(a);
|
||||||
a->removeFrom(al.hero, al.slot);
|
a->removeFrom(al);
|
||||||
}
|
}
|
||||||
|
|
||||||
DLL_LINKAGE void MoveArtifact::applyGs( CGameState *gs )
|
DLL_LINKAGE void MoveArtifact::applyGs( CGameState *gs )
|
||||||
@ -681,49 +732,58 @@ DLL_LINKAGE void MoveArtifact::applyGs( CGameState *gs )
|
|||||||
a->move(src, dst);
|
a->move(src, dst);
|
||||||
|
|
||||||
//TODO what'll happen if Titan's thunder is equiped by pickin git up or the start of game?
|
//TODO what'll happen if Titan's thunder is equiped by pickin git up or the start of game?
|
||||||
if (a->artType->id == 135 && dst.hero && dst.slot == ArtifactPosition::RIGHT_HAND && !dst.hero->hasSpellbook()) //Titan's Thunder creates new spellbook on equip
|
if (a->artType->id == 135 && dst.slot == ArtifactPosition::RIGHT_HAND) //Titan's Thunder creates new spellbook on equip
|
||||||
gs->giveHeroArtifact(dst.hero, 0);
|
{
|
||||||
|
auto hPtr = boost::get<ConstTransitivePtr<CGHeroInstance> >(&dst.artHolder);
|
||||||
|
if(hPtr)
|
||||||
|
{
|
||||||
|
CGHeroInstance *h = *hPtr;
|
||||||
|
if(h && !h->hasSpellbook())
|
||||||
|
gs->giveHeroArtifact(h, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
DLL_LINKAGE void AssembledArtifact::applyGs( CGameState *gs )
|
DLL_LINKAGE void AssembledArtifact::applyGs( CGameState *gs )
|
||||||
{
|
{
|
||||||
CGHeroInstance *h = al.hero;
|
CArtifactSet *artSet = al.getHolderArtSet();
|
||||||
const CArtifactInstance *transformedArt = al.getArt();
|
const CArtifactInstance *transformedArt = al.getArt();
|
||||||
assert(transformedArt);
|
assert(transformedArt);
|
||||||
assert(vstd::contains(transformedArt->assemblyPossibilities(al.hero), builtArt));
|
assert(vstd::contains(transformedArt->assemblyPossibilities(artSet), builtArt));
|
||||||
|
|
||||||
CCombinedArtifactInstance *combinedArt = new CCombinedArtifactInstance(builtArt);
|
CCombinedArtifactInstance *combinedArt = new CCombinedArtifactInstance(builtArt);
|
||||||
gs->map->addNewArtifactInstance(combinedArt);
|
gs->map->addNewArtifactInstance(combinedArt);
|
||||||
//retrieve all constituents
|
//retrieve all constituents
|
||||||
BOOST_FOREACH(si32 constituentID, *builtArt->constituents)
|
BOOST_FOREACH(si32 constituentID, *builtArt->constituents)
|
||||||
{
|
{
|
||||||
int pos = h->getArtPos(constituentID);
|
int pos = artSet->getArtPos(constituentID);
|
||||||
assert(pos >= 0);
|
assert(pos >= 0);
|
||||||
CArtifactInstance *constituentInstance = h->getArt(pos);
|
CArtifactInstance *constituentInstance = artSet->getArt(pos);
|
||||||
|
|
||||||
//move constituent from hero to be part of new, combined artifact
|
//move constituent from hero to be part of new, combined artifact
|
||||||
constituentInstance->removeFrom(h, pos);
|
constituentInstance->removeFrom(al);
|
||||||
combinedArt->addAsConstituent(constituentInstance, pos);
|
combinedArt->addAsConstituent(constituentInstance, pos);
|
||||||
if(!vstd::contains(combinedArt->artType->possibleSlots, al.slot) && vstd::contains(combinedArt->artType->possibleSlots, pos))
|
if(!vstd::contains(combinedArt->artType->possibleSlots[artSet->bearerType()], al.slot) && vstd::contains(combinedArt->artType->possibleSlots[artSet->bearerType()], pos))
|
||||||
al.slot = pos;
|
al.slot = pos;
|
||||||
}
|
}
|
||||||
|
|
||||||
//put new combined artifacts
|
//put new combined artifacts
|
||||||
combinedArt->putAt(h, al.slot);
|
combinedArt->putAt(al);
|
||||||
}
|
}
|
||||||
|
|
||||||
DLL_LINKAGE void DisassembledArtifact::applyGs( CGameState *gs )
|
DLL_LINKAGE void DisassembledArtifact::applyGs( CGameState *gs )
|
||||||
{
|
{
|
||||||
CGHeroInstance *h = al.hero;
|
|
||||||
CCombinedArtifactInstance *disassembled = dynamic_cast<CCombinedArtifactInstance*>(al.getArt());
|
CCombinedArtifactInstance *disassembled = dynamic_cast<CCombinedArtifactInstance*>(al.getArt());
|
||||||
assert(disassembled);
|
assert(disassembled);
|
||||||
|
|
||||||
std::vector<CCombinedArtifactInstance::ConstituentInfo> constituents = disassembled->constituentsInfo;
|
std::vector<CCombinedArtifactInstance::ConstituentInfo> constituents = disassembled->constituentsInfo;
|
||||||
disassembled->removeFrom(h, al.slot);
|
disassembled->removeFrom(al);
|
||||||
BOOST_FOREACH(CCombinedArtifactInstance::ConstituentInfo &ci, constituents)
|
BOOST_FOREACH(CCombinedArtifactInstance::ConstituentInfo &ci, constituents)
|
||||||
{
|
{
|
||||||
|
ArtifactLocation constituentLoc = al;
|
||||||
|
constituentLoc.slot = (ci.slot >= 0 ? ci.slot : al.slot); //-1 is slot of main constituent -> it'll replace combined artifact in its pos
|
||||||
disassembled->detachFrom(ci.art);
|
disassembled->detachFrom(ci.art);
|
||||||
ci.art->putAt(h, ci.slot >= 0 ? ci.slot : al.slot); //-1 is slot of main constituent -> it'll replace combined artifact in its pos
|
ci.art->putAt(constituentLoc);
|
||||||
}
|
}
|
||||||
|
|
||||||
gs->map->eraseArtifactInstance(disassembled);
|
gs->map->eraseArtifactInstance(disassembled);
|
||||||
|
@ -94,7 +94,7 @@ void registerTypes1(Serializer &s)
|
|||||||
s.template registerType<BattleInfo>();
|
s.template registerType<BattleInfo>();
|
||||||
s.template registerType<CArtifactInstance>();
|
s.template registerType<CArtifactInstance>();
|
||||||
s.template registerType<CCombinedArtifactInstance>();
|
s.template registerType<CCombinedArtifactInstance>();
|
||||||
s.template registerType<CCreatureArtifactInstance>();
|
//s.template registerType<CCreatureArtifactInstance>();
|
||||||
//s.template registerType<ArtSlotInfo>();
|
//s.template registerType<ArtSlotInfo>();
|
||||||
//s.template registerType<ArtifactLocation>();
|
//s.template registerType<ArtifactLocation>();
|
||||||
//s.template registerType<StackLocation>();
|
//s.template registerType<StackLocation>();
|
||||||
|
@ -58,6 +58,9 @@ struct StartInfo
|
|||||||
typedef bmap<int, PlayerSettings> TPlayerInfos;
|
typedef bmap<int, PlayerSettings> TPlayerInfos;
|
||||||
TPlayerInfos playerInfos; //color indexed
|
TPlayerInfos playerInfos; //color indexed
|
||||||
|
|
||||||
|
ui32 seedToBeUsed; //0 if not sure (client requests server to decide, will be send in reply pack)
|
||||||
|
ui32 seedPostInit; //so we know that game is correctly synced at the start; 0 if not known yet
|
||||||
|
ui32 mapfileChecksum; //0 if not relevant
|
||||||
ui8 turnTime; //in minutes, 0=unlimited
|
ui8 turnTime; //in minutes, 0=unlimited
|
||||||
std::string mapname;
|
std::string mapname;
|
||||||
ui8 whichMapInCampaign; //used only for mode CAMPAIGN
|
ui8 whichMapInCampaign; //used only for mode CAMPAIGN
|
||||||
@ -84,6 +87,8 @@ struct StartInfo
|
|||||||
h & mode;
|
h & mode;
|
||||||
h & difficulty;
|
h & difficulty;
|
||||||
h & playerInfos;
|
h & playerInfos;
|
||||||
|
h & seedToBeUsed & seedPostInit;
|
||||||
|
h & mapfileChecksum;
|
||||||
h & turnTime;
|
h & turnTime;
|
||||||
h & mapname;
|
h & mapname;
|
||||||
h & whichMapInCampaign;
|
h & whichMapInCampaign;
|
||||||
@ -92,6 +97,7 @@ struct StartInfo
|
|||||||
|
|
||||||
StartInfo()
|
StartInfo()
|
||||||
{
|
{
|
||||||
|
mapfileChecksum = seedPostInit = seedToBeUsed = 0;
|
||||||
mode = INVALID;
|
mode = INVALID;
|
||||||
choosenCampaignBonus = -1;
|
choosenCampaignBonus = -1;
|
||||||
}
|
}
|
||||||
|
@ -794,7 +794,6 @@ int CGameHandler::moveStack(int stack, BattleHex dest)
|
|||||||
|
|
||||||
CGameHandler::CGameHandler(void)
|
CGameHandler::CGameHandler(void)
|
||||||
{
|
{
|
||||||
seedInitial = seedPostInit = -1;
|
|
||||||
QID = 1;
|
QID = 1;
|
||||||
//gs = NULL;
|
//gs = NULL;
|
||||||
IObjectInterface::cb = this;
|
IObjectInterface::cb = this;
|
||||||
@ -814,13 +813,12 @@ CGameHandler::~CGameHandler(void)
|
|||||||
void CGameHandler::init(StartInfo *si)
|
void CGameHandler::init(StartInfo *si)
|
||||||
{
|
{
|
||||||
extern DLL_LINKAGE boost::rand48 ran;
|
extern DLL_LINKAGE boost::rand48 ran;
|
||||||
if(seedInitial < 0)
|
if(!si->seedToBeUsed)
|
||||||
seedInitial = std::time(NULL);
|
si->seedToBeUsed = std::time(NULL);
|
||||||
|
|
||||||
gs = new CGameState();
|
gs = new CGameState();
|
||||||
tlog0 << "Gamestate created!" << std::endl;
|
tlog0 << "Gamestate created!" << std::endl;
|
||||||
gs->init(si, 0, seedInitial);
|
gs->init(si);
|
||||||
seedPostInit = ran();
|
|
||||||
tlog0 << "Gamestate initialized!" << std::endl;
|
tlog0 << "Gamestate initialized!" << std::endl;
|
||||||
|
|
||||||
for(std::map<ui8,PlayerState>::iterator i = gs->players.begin(); i != gs->players.end(); i++)
|
for(std::map<ui8,PlayerState>::iterator i = gs->players.begin(); i != gs->players.end(); i++)
|
||||||
@ -1207,8 +1205,7 @@ void CGameHandler::run(bool resume)
|
|||||||
//ui32 seed;
|
//ui32 seed;
|
||||||
if(!resume)
|
if(!resume)
|
||||||
{
|
{
|
||||||
ui32 sum = gs->map ? gs->map->checksum : 612;
|
(*cc) << gs->initialOpts; // gs->scenarioOps
|
||||||
(*cc) << gs->initialOpts << sum << gs->seed << seedPostInit; // gs->scenarioOps
|
|
||||||
}
|
}
|
||||||
|
|
||||||
(*cc) >> quantity; //how many players will be handled at that client
|
(*cc) >> quantity; //how many players will be handled at that client
|
||||||
@ -2503,14 +2500,14 @@ bool CGameHandler::garrisonSwap( si32 tid )
|
|||||||
|
|
||||||
// With the amount of changes done to the function, it's more like transferArtifacts.
|
// With the amount of changes done to the function, it's more like transferArtifacts.
|
||||||
// Function moves artifact from src to dst. If dst is not a backpack and is already occupied, old dst art goes to backpack and is replaced.
|
// Function moves artifact from src to dst. If dst is not a backpack and is already occupied, old dst art goes to backpack and is replaced.
|
||||||
bool CGameHandler::moveArtifact(si32 srcHeroID, si32 destHeroID, ui16 srcSlot, ui16 destSlot)
|
bool CGameHandler::moveArtifact(const ArtifactLocation &al1, const ArtifactLocation &al2)
|
||||||
{
|
{
|
||||||
const CGHeroInstance *srcHero = getHero(srcHeroID);
|
ArtifactLocation src = al1, dst = al2;
|
||||||
const CGHeroInstance *destHero = getHero(destHeroID);
|
const int srcPlayer = src.owningPlayer(), dstPlayer = dst.owningPlayer();
|
||||||
ArtifactLocation src(srcHero, srcSlot), dst(destHero, destSlot);
|
const CArmedInstance *srcObj = src.relatedObj(), *dstObj = dst.relatedObj();
|
||||||
|
|
||||||
// Make sure exchange is even possible between the two heroes.
|
// Make sure exchange is even possible between the two heroes.
|
||||||
if(!isAllowedExchange(srcHeroID, destHeroID))
|
if(!isAllowedExchange(srcObj->id, dstObj->id))
|
||||||
COMPLAIN_RET("That heroes cannot make any exchange!");
|
COMPLAIN_RET("That heroes cannot make any exchange!");
|
||||||
|
|
||||||
const CArtifactInstance *srcArtifact = src.getArt();
|
const CArtifactInstance *srcArtifact = src.getArt();
|
||||||
@ -2518,72 +2515,38 @@ bool CGameHandler::moveArtifact(si32 srcHeroID, si32 destHeroID, ui16 srcSlot, u
|
|||||||
|
|
||||||
if (srcArtifact == NULL)
|
if (srcArtifact == NULL)
|
||||||
COMPLAIN_RET("No artifact to move!");
|
COMPLAIN_RET("No artifact to move!");
|
||||||
if (destArtifact && srcHero->tempOwner != destHero->tempOwner)
|
if (destArtifact && srcPlayer != dstPlayer)
|
||||||
COMPLAIN_RET("Can't touch artifact on hero of another player!");
|
COMPLAIN_RET("Can't touch artifact on hero of another player!");
|
||||||
|
|
||||||
// Check if src/dest slots are appropriate for the artifacts exchanged.
|
// Check if src/dest slots are appropriate for the artifacts exchanged.
|
||||||
// Moving to the backpack is always allowed.
|
// Moving to the backpack is always allowed.
|
||||||
if ((!srcArtifact || destSlot < GameConstants::BACKPACK_START)
|
if ((!srcArtifact || dst.slot < GameConstants::BACKPACK_START)
|
||||||
&& srcArtifact && !srcArtifact->canBePutAt(dst, true))
|
&& srcArtifact && !srcArtifact->canBePutAt(dst, true))
|
||||||
COMPLAIN_RET("Cannot move artifact!");
|
COMPLAIN_RET("Cannot move artifact!");
|
||||||
|
|
||||||
if ((srcArtifact && srcArtifact->artType->id == GameConstants::ID_LOCK) || (destArtifact && destArtifact->artType->id == GameConstants::ID_LOCK))
|
if ((srcArtifact && srcArtifact->artType->id == GameConstants::ID_LOCK) || (destArtifact && destArtifact->artType->id == GameConstants::ID_LOCK))
|
||||||
COMPLAIN_RET("Cannot move artifact locks.");
|
COMPLAIN_RET("Cannot move artifact locks.");
|
||||||
|
|
||||||
if (destSlot >= GameConstants::BACKPACK_START && srcArtifact->artType->isBig())
|
if (dst.slot >= GameConstants::BACKPACK_START && srcArtifact->artType->isBig())
|
||||||
COMPLAIN_RET("Cannot put big artifacts in backpack!");
|
COMPLAIN_RET("Cannot put big artifacts in backpack!");
|
||||||
if (srcSlot == ArtifactPosition::MACH4 || destSlot == ArtifactPosition::MACH4)
|
if (src.slot == ArtifactPosition::MACH4 || dst.slot == ArtifactPosition::MACH4)
|
||||||
COMPLAIN_RET("Cannot move catapult!");
|
COMPLAIN_RET("Cannot move catapult!");
|
||||||
|
|
||||||
if(dst.slot >= GameConstants::BACKPACK_START)
|
if(dst.slot >= GameConstants::BACKPACK_START)
|
||||||
vstd::amin(dst.slot, GameConstants::BACKPACK_START + dst.hero->artifactsInBackpack.size());
|
vstd::amin(dst.slot, GameConstants::BACKPACK_START + dst.getHolderArtSet()->artifactsInBackpack.size());
|
||||||
|
|
||||||
if (src.slot == dst.slot && src.hero == dst.hero)
|
if (src.slot == dst.slot && src.artHolder == dst.artHolder)
|
||||||
COMPLAIN_RET("Won't move artifact: Dest same as source!");
|
COMPLAIN_RET("Won't move artifact: Dest same as source!");
|
||||||
|
|
||||||
//moving art to backpack is always allowed (we've ruled out exceptions)
|
if(dst.slot < GameConstants::BACKPACK_START && destArtifact) //moving art to another slot
|
||||||
if(destSlot >= GameConstants::BACKPACK_START)
|
|
||||||
{
|
{
|
||||||
moveArtifact(src, dst);
|
//old artifact must be removed first
|
||||||
}
|
moveArtifact(dst, ArtifactLocation(dst.artHolder, dst.getHolderArtSet()->artifactsInBackpack.size() + GameConstants::BACKPACK_START));
|
||||||
else //moving art to another slot
|
|
||||||
{
|
|
||||||
if(destArtifact) //old artifact must be removed first
|
|
||||||
{
|
|
||||||
moveArtifact(dst, ArtifactLocation(destHero, destHero->artifactsInBackpack.size() + GameConstants::BACKPACK_START));
|
|
||||||
}
|
|
||||||
moveArtifact(src, dst);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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;
|
MoveArtifact ma;
|
||||||
ma.src = al1;
|
ma.src = src;
|
||||||
ma.dst = al2;
|
ma.dst = dst;
|
||||||
sendAndApply(&ma);
|
sendAndApply(&ma);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -5550,7 +5513,7 @@ void CGameHandler::giveHeroArtifact(const CGHeroInstance *h, const CArtifactInst
|
|||||||
{
|
{
|
||||||
assert(a->artType);
|
assert(a->artType);
|
||||||
ArtifactLocation al;
|
ArtifactLocation al;
|
||||||
al.hero = h;
|
al.artHolder = const_cast<CGHeroInstance*>(h);
|
||||||
|
|
||||||
int slot = -1;
|
int slot = -1;
|
||||||
if(pos < 0)
|
if(pos < 0)
|
||||||
@ -5588,10 +5551,7 @@ void CGameHandler::giveHeroNewArtifact(const CGHeroInstance *h, const CArtifact
|
|||||||
CArtifactInstance *a = NULL;
|
CArtifactInstance *a = NULL;
|
||||||
if(!artType->constituents)
|
if(!artType->constituents)
|
||||||
{
|
{
|
||||||
if (vstd::contains(VLC->arth->creatureArtifacts, artType->id))
|
a = new CArtifactInstance();
|
||||||
a = new CCreatureArtifactInstance();
|
|
||||||
else
|
|
||||||
a = new CArtifactInstance();
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -91,8 +91,6 @@ public:
|
|||||||
PlayerStatuses states; //player color -> player state
|
PlayerStatuses states; //player color -> player state
|
||||||
std::set<CConnection*> conns;
|
std::set<CConnection*> conns;
|
||||||
|
|
||||||
si32 seedInitial, seedPostInit;
|
|
||||||
|
|
||||||
//queries stuff
|
//queries stuff
|
||||||
boost::recursive_mutex gsm;
|
boost::recursive_mutex gsm;
|
||||||
ui32 QID;
|
ui32 QID;
|
||||||
@ -158,7 +156,7 @@ public:
|
|||||||
void giveHeroArtifact(const CGHeroInstance *h, const CArtifactInstance *a, int pos) OVERRIDE;
|
void giveHeroArtifact(const CGHeroInstance *h, const CArtifactInstance *a, int pos) OVERRIDE;
|
||||||
void putArtifact(const ArtifactLocation &al, const CArtifactInstance *a) OVERRIDE;
|
void putArtifact(const ArtifactLocation &al, const CArtifactInstance *a) OVERRIDE;
|
||||||
void removeArtifact(const ArtifactLocation &al) OVERRIDE;
|
void removeArtifact(const ArtifactLocation &al) OVERRIDE;
|
||||||
void moveArtifact(const ArtifactLocation &al1, const ArtifactLocation &al2) OVERRIDE;
|
bool moveArtifact(const ArtifactLocation &al1, const ArtifactLocation &al2) OVERRIDE;
|
||||||
|
|
||||||
void showCompInfo(ShowInInfobox * comp) OVERRIDE;
|
void showCompInfo(ShowInInfobox * comp) OVERRIDE;
|
||||||
void heroVisitCastle(int obj, int heroID) OVERRIDE;
|
void heroVisitCastle(int obj, int heroID) OVERRIDE;
|
||||||
@ -212,10 +210,6 @@ public:
|
|||||||
bool buyArtifact( const IMarket *m, const CGHeroInstance *h, int rid, int aid); //for artifact merchant and black market -> buying for any resource in special building / advobject
|
bool buyArtifact( const IMarket *m, const CGHeroInstance *h, int rid, int aid); //for artifact merchant and black market -> buying for any resource in special building / advobject
|
||||||
bool sellArtifact( const IMarket *m, const CGHeroInstance *h, int aid, int rid); //for artifact merchant selling
|
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 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 garrisonSwap(si32 tid);
|
||||||
bool upgradeCreature( ui32 objid, ui8 pos, ui32 upgID );
|
bool upgradeCreature( ui32 objid, ui8 pos, ui32 upgID );
|
||||||
bool recruitCreatures(si32 objid, ui32 crid, ui32 cram, si32 level);
|
bool recruitCreatures(si32 objid, ui32 crid, ui32 cram, si32 level);
|
||||||
|
@ -133,21 +133,8 @@ bool GarrisonHeroSwap::applyGh( CGameHandler *gh )
|
|||||||
|
|
||||||
bool ExchangeArtifacts::applyGh( CGameHandler *gh )
|
bool ExchangeArtifacts::applyGh( CGameHandler *gh )
|
||||||
{
|
{
|
||||||
ERROR_IF_NOT_OWNS(hid1);//second hero can be ally
|
ERROR_IF_NOT(src.owningPlayer());//second hero can be ally
|
||||||
if (hid1)
|
return gh->moveArtifact(src, dst);
|
||||||
{ //TODO: polymorph
|
|
||||||
if (hid2)
|
|
||||||
return gh->moveArtifact(hid1,hid2,slot1,slot2);
|
|
||||||
else
|
|
||||||
return gh->moveArtifact(hid1,s2,slot1,slot2);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (hid2)
|
|
||||||
return gh->moveArtifact(s1,hid2,slot1,slot2);
|
|
||||||
else
|
|
||||||
return gh->moveArtifact(s1,s2,slot1,slot2);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AssembleArtifacts::applyGh( CGameHandler *gh )
|
bool AssembleArtifacts::applyGh( CGameHandler *gh )
|
||||||
|
Loading…
Reference in New Issue
Block a user