mirror of
https://github.com/vcmi/vcmi.git
synced 2024-11-24 08:32:34 +02:00
Compile fixes, more work on new artifact system.
This commit is contained in:
parent
b3fd14b524
commit
471c23ba71
@ -27,4 +27,4 @@ extern "C" DLL_F_EXPORT CBattleGameInterface* GetNewBattleAI()
|
||||
extern "C" DLL_F_EXPORT void ReleaseBattleAI(CBattleGameInterface* i)
|
||||
{
|
||||
delete (CStupidAI*)i;
|
||||
}
|
||||
}
|
||||
|
@ -18,7 +18,6 @@ CClientState * CCS;
|
||||
CGameInfo::CGameInfo()
|
||||
{
|
||||
mh = NULL;
|
||||
state = NULL;
|
||||
}
|
||||
|
||||
void CGameInfo::setFromLib()
|
||||
|
@ -212,8 +212,7 @@ void CClient::endGame( bool closeConnection /*= true*/ )
|
||||
delete CGI->mh;
|
||||
const_cast<CGameInfo*>(CGI)->mh = NULL;
|
||||
|
||||
delete CGI->state;
|
||||
const_cast<CGameInfo*>(CGI)->state = NULL;
|
||||
const_cast<CGameInfo*>(CGI)->state.dellNull();
|
||||
tlog0 << "Deleted mapHandler and gameState." << std::endl;
|
||||
|
||||
LOCPLINT = NULL;
|
||||
|
@ -112,6 +112,7 @@ public:
|
||||
void showGarrisonDialog(int upobj, int hid, bool removableUnits, const boost::function<void()> &cb){};
|
||||
void showThievesGuildWindow(int requestingObjId){};
|
||||
void giveResource(int player, int which, int val){};
|
||||
|
||||
void giveCreatures (const CArmedInstance * objid, const CGHeroInstance * h, const CCreatureSet &creatures, bool remove) {};
|
||||
void takeCreatures (int objid, TSlots creatures){};
|
||||
void takeCreatures (int objid, std::vector<CStackBasicDescriptor> creatures){};
|
||||
@ -123,11 +124,18 @@ public:
|
||||
bool addToSlot(const StackLocation &sl, const CCreature *c, TQuantity count){return false;}
|
||||
void tryJoiningArmy(const CArmedInstance *src, const CArmedInstance *dst, bool removeObjWhenFinished, bool allowMerging){}
|
||||
bool moveStack(const StackLocation &src, const StackLocation &dst, TQuantity count = -1){return false;}
|
||||
|
||||
void giveHeroNewArtifact(const CGHeroInstance *h, const CArtifact *artType, int pos) OVERRIDE {};
|
||||
void giveHeroArtifact(const CGHeroInstance *h, const CArtifactInstance *a, int pos) OVERRIDE {};
|
||||
void putArtifact(const ArtifactLocation &al, const CArtifactInstance *a) OVERRIDE {};
|
||||
void removeArtifact(const ArtifactLocation &al) OVERRIDE {};
|
||||
void moveArtifact(const ArtifactLocation &al1, const ArtifactLocation &al2) OVERRIDE {};
|
||||
|
||||
void showCompInfo(ShowInInfobox * comp){};
|
||||
void heroVisitCastle(int obj, int heroID){};
|
||||
void stopHeroVisitCastle(int obj, int heroID){};
|
||||
void giveHeroArtifact(int artid, int hid, int position){}; //pos==-1 - first free slot in backpack=0; pos==-2 - default if available or backpack
|
||||
void giveNewArtifact(int hid, int position){};
|
||||
//void giveHeroArtifact(int artid, int hid, int position){};
|
||||
//void giveNewArtifact(int hid, int position){};
|
||||
bool removeArtifact(const CArtifact* art, int hid){return false;};
|
||||
void startBattleI(const CArmedInstance *army1, const CArmedInstance *army2, int3 tile, const CGHeroInstance *hero1, const CGHeroInstance *hero2, bool creatureBank = false, boost::function<void(BattleResult*)> cb = 0, const CGTownInstance *town = NULL){}; //use hero=NULL for no hero
|
||||
void startBattleI(const CArmedInstance *army1, const CArmedInstance *army2, int3 tile, boost::function<void(BattleResult*)> cb = 0, bool creatureBank = false){}; //if any of armies is hero, hero will be used
|
||||
|
@ -49,6 +49,7 @@
|
||||
#include "../lib/HeroBonus.h"
|
||||
#include "../lib/CCreatureHandler.h"
|
||||
#include "CMusicHandler.h"
|
||||
#include "../lib/BattleState.h"
|
||||
|
||||
/*
|
||||
* GUIClasses.cpp, part of VCMI engine
|
||||
|
@ -899,17 +899,6 @@ public:
|
||||
void show(SDL_Surface * to);
|
||||
};
|
||||
|
||||
namespace Arts
|
||||
{
|
||||
enum EPos
|
||||
{
|
||||
PRE_FIRST = -1,
|
||||
HEAD, SHOULDERS, NECK, RIGHT_HAND, LEFT_HAND, TORSO, RIGHT_RING, LEFT_RING, FEET, MISC1, MISC2, MISC3, MISC4,
|
||||
MACH1, MACH2, MACH3, MACH4, SPELLBOOK, MISC5,
|
||||
AFTER_LAST
|
||||
};
|
||||
}
|
||||
|
||||
class CArtPlace: public LRClickableAreaWTextComp
|
||||
{
|
||||
public:
|
||||
|
@ -167,6 +167,19 @@ void RebalanceStacks::applyCl( CClient *cl )
|
||||
INTERFACE_CALL_IF_PRESENT(dst.army->tempOwner,stacksRebalanced, src, dst, count);
|
||||
}
|
||||
|
||||
void PutArtifact::applyCl( CClient *cl )
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void EraseArtifact::applyCl( CClient *cl )
|
||||
{
|
||||
}
|
||||
|
||||
void MoveArtifact::applyCl( CClient *cl )
|
||||
{
|
||||
}
|
||||
|
||||
void GiveBonus::applyCl( CClient *cl )
|
||||
{
|
||||
switch(who)
|
||||
|
23
global.h
23
global.h
@ -1,3 +1,4 @@
|
||||
#pragma once
|
||||
#ifndef __GLOBAL_H__
|
||||
#define __GLOBAL_H__
|
||||
#include <iostream>
|
||||
@ -123,6 +124,8 @@ const int BFIELD_WIDTH = 17;
|
||||
const int BFIELD_HEIGHT = 11;
|
||||
const int BFIELD_SIZE = BFIELD_WIDTH * BFIELD_HEIGHT;
|
||||
|
||||
const int SPELLBOOK_GOLD_COST = 500;
|
||||
|
||||
enum EMarketMode
|
||||
{
|
||||
RESOURCE_RESOURCE, RESOURCE_PLAYER, CREATURE_RESOURCE, RESOURCE_ARTIFACT,
|
||||
@ -130,6 +133,26 @@ enum EMarketMode
|
||||
MARTKET_AFTER_LAST_PLACEHOLDER
|
||||
};
|
||||
|
||||
namespace Res
|
||||
{
|
||||
enum ERes
|
||||
{
|
||||
WOOD = 0, MERCURY, ORE, SULFUR, CRYSTAL, GEMS, GOLD, MITHRIL
|
||||
};
|
||||
}
|
||||
|
||||
namespace Arts
|
||||
{
|
||||
enum EPos
|
||||
{
|
||||
PRE_FIRST = -1,
|
||||
HEAD, SHOULDERS, NECK, RIGHT_HAND, LEFT_HAND, TORSO, RIGHT_RING, LEFT_RING, FEET, MISC1, MISC2, MISC3, MISC4,
|
||||
MACH1, MACH2, MACH3, MACH4, SPELLBOOK, MISC5,
|
||||
AFTER_LAST
|
||||
};
|
||||
const ui16 BACKPACK_START = 19;
|
||||
}
|
||||
|
||||
enum EAlignment
|
||||
{
|
||||
GOOD, EVIL, NEUTRAL
|
||||
|
@ -13,6 +13,9 @@
|
||||
#include <boost/algorithm/string/replace.hpp>
|
||||
#include "../lib/VCMI_Lib.h"
|
||||
#include "CSpellHandler.h"
|
||||
#include "CObjectHandler.h"
|
||||
#include "NetPacks.h"
|
||||
|
||||
extern CLodHandler *bitmaph;
|
||||
using namespace boost::assign;
|
||||
|
||||
@ -874,13 +877,13 @@ CArtifactInstance::CArtifactInstance( CArtifact *Art)
|
||||
|
||||
void CArtifactInstance::setType( CArtifact *Art )
|
||||
{
|
||||
art = Art;
|
||||
artType = Art;
|
||||
attachTo(Art);
|
||||
}
|
||||
|
||||
std::string CArtifactInstance::nodeName() const
|
||||
{
|
||||
return "Artifact instance of " + (art ? art->Name() : std::string("uninitialized")) + " type";
|
||||
return "Artifact instance of " + (artType ? artType->Name() : std::string("uninitialized")) + " type";
|
||||
}
|
||||
|
||||
CArtifactInstance * CArtifactInstance::createScroll( const CSpell *s)
|
||||
@ -893,5 +896,68 @@ CArtifactInstance * CArtifactInstance::createScroll( const CSpell *s)
|
||||
|
||||
void CArtifactInstance::init()
|
||||
{
|
||||
art = NULL;
|
||||
id = -1;
|
||||
}
|
||||
|
||||
int CArtifactInstance::firstAvailableSlot(const CGHeroInstance *h) const
|
||||
{
|
||||
BOOST_FOREACH(ui16 slot, artType->possibleSlots)
|
||||
{
|
||||
if(artType->fitsAt(h->artifWorn, slot))
|
||||
{
|
||||
//we've found a free suitable slot.
|
||||
return slot;
|
||||
}
|
||||
}
|
||||
|
||||
//if haven't find proper slot, use backpack
|
||||
return firstBackpackSlot(h);
|
||||
}
|
||||
|
||||
int CArtifactInstance::firstBackpackSlot(const CGHeroInstance *h) const
|
||||
{
|
||||
if(!artType->isBig()) //discard big artifact
|
||||
return Arts::BACKPACK_START + h->artifactsInBackpack.size();
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
bool CArtifactInstance::canBePutAt(const ArtifactLocation &al) const
|
||||
{
|
||||
if(!vstd::contains(artType->possibleSlots, al.slot))
|
||||
return false;
|
||||
|
||||
//simple artifact -> test if slot is free [combined artifacts have this function overridden]
|
||||
return al.hero->isPositionFree(al.slot);
|
||||
}
|
||||
|
||||
void CArtifactInstance::putAt(CGHeroInstance *h, ui16 slot)
|
||||
{
|
||||
assert(canBePutAt(ArtifactLocation(h, slot)));
|
||||
|
||||
ArtSlotInfo &asi = slot < Arts::BACKPACK_START
|
||||
? h->artifactsWorn[slot]
|
||||
: *h->artifactsInBackpack.insert(h->artifactsInBackpack.begin() + slot - Arts::BACKPACK_START, ArtSlotInfo());
|
||||
|
||||
asi.artifact = this;
|
||||
asi.locked = false;
|
||||
|
||||
h->attachTo(this);
|
||||
}
|
||||
|
||||
void CArtifactInstance::removeFrom(CGHeroInstance *h, ui16 slot)
|
||||
{
|
||||
assert(h->CArtifactSet::getArt(slot) == this);
|
||||
if(slot < Arts::BACKPACK_START)
|
||||
{
|
||||
h->artifactsWorn.erase(slot);
|
||||
h->detachFrom(this);
|
||||
}
|
||||
else
|
||||
{
|
||||
slot -= Arts::BACKPACK_START;
|
||||
h->artifactsInBackpack.erase(h->artifactsInBackpack.begin() + slot);
|
||||
}
|
||||
|
||||
//TODO delete me?
|
||||
}
|
@ -18,6 +18,8 @@
|
||||
*/
|
||||
class CDefHandler;
|
||||
class CArtifact;
|
||||
class CGHeroInstance;
|
||||
struct ArtifactLocation;
|
||||
|
||||
class DLL_EXPORT CArtifact : public CBonusSystemNode //container for artifacts
|
||||
{
|
||||
@ -62,7 +64,7 @@ class DLL_EXPORT CArtifactInstance : public CBonusSystemNode
|
||||
{
|
||||
void init();
|
||||
public:
|
||||
ConstTransitivePtr<CArtifact> art;
|
||||
ConstTransitivePtr<CArtifact> artType;
|
||||
si32 id; //id of the instance
|
||||
|
||||
CArtifactInstance();
|
||||
@ -71,10 +73,17 @@ public:
|
||||
std::string nodeName() const OVERRIDE;
|
||||
void setType(CArtifact *Art);
|
||||
|
||||
int firstAvailableSlot(const CGHeroInstance *h) const;
|
||||
int firstBackpackSlot(const CGHeroInstance *h) const;
|
||||
bool canBePutAt(const ArtifactLocation &al) const;
|
||||
|
||||
void putAt(CGHeroInstance *h, ui16 slot);
|
||||
void removeFrom(CGHeroInstance *h, ui16 slot);
|
||||
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{
|
||||
h & static_cast<CBonusSystemNode&>(*this);
|
||||
h & art & id;
|
||||
h & artType & id;
|
||||
}
|
||||
|
||||
static CArtifactInstance *createScroll(const CSpell *s);
|
||||
|
@ -759,13 +759,9 @@ int CGameState::getDate(int mode) const
|
||||
CGameState::CGameState()
|
||||
{
|
||||
mx = new boost::shared_mutex();
|
||||
map = NULL;
|
||||
curB = NULL;
|
||||
scenarioOps = NULL;
|
||||
applierGs = new CApplier<CBaseForGSApply>;
|
||||
registerTypes2(*applierGs);
|
||||
objCaller = new CObjectCallersHandler;
|
||||
campaign = NULL;
|
||||
}
|
||||
CGameState::~CGameState()
|
||||
{
|
||||
|
@ -3593,9 +3593,16 @@ void CGArtifact::initObj()
|
||||
{
|
||||
blockVisit = true;
|
||||
if(ID == 5)
|
||||
{
|
||||
hoverName = VLC->arth->artifacts[subID]->Name();
|
||||
if(!storedArtifact->artType)
|
||||
storedArtifact->setType(VLC->arth->artifacts[subID]);
|
||||
}
|
||||
if(ID == 93)
|
||||
subID = 1;
|
||||
|
||||
assert(storedArtifact->artType);
|
||||
assert(storedArtifact->parents.size());
|
||||
}
|
||||
|
||||
void CGArtifact::onHeroVisit( const CGHeroInstance * h ) const
|
||||
@ -3618,7 +3625,7 @@ void CGArtifact::onHeroVisit( const CGHeroInstance * h ) const
|
||||
break;
|
||||
case 93:
|
||||
{
|
||||
int spellID = art->getBonus(Selector::type(Bonus::SPELL))->subtype;
|
||||
int spellID = storedArtifact->getBonus(Selector::type(Bonus::SPELL))->subtype;
|
||||
iw.components.push_back (Component(Component::SPELL, spellID,0,0));
|
||||
iw.text.addTxt (MetaString::ADVOB_TXT,135);
|
||||
iw.text.addReplacement(MetaString::SPELL_NAME, spellID);
|
||||
@ -3647,23 +3654,7 @@ void CGArtifact::onHeroVisit( const CGHeroInstance * h ) const
|
||||
|
||||
void CGArtifact::pick(const CGHeroInstance * h) const
|
||||
{
|
||||
if (VLC->arth->artifacts[subID]->isModable())
|
||||
{//TODO: create new instance, initialize it
|
||||
if (ID == 93) //scroll
|
||||
{
|
||||
NewArtifact na;
|
||||
//na.value = spell;
|
||||
na.artid = subID;
|
||||
cb->sendAndApply(&na);
|
||||
cb->giveNewArtifact(h->id, -2);
|
||||
}
|
||||
else
|
||||
cb->giveNewArtifact(h->id, -2);; //nothing / zero / empty by default
|
||||
}
|
||||
else
|
||||
{
|
||||
cb->giveHeroArtifact(subID,h->id,-2);
|
||||
}
|
||||
cb->giveHeroArtifact(h, storedArtifact, -2);
|
||||
cb->removeObject(id);
|
||||
}
|
||||
|
||||
@ -3822,7 +3813,7 @@ void CGPickable::onHeroVisit( const CGHeroInstance * h ) const
|
||||
//TODO: what if no space in backpack?
|
||||
iw.components.push_back(Component(4, val2, 1, 0));
|
||||
iw.text.addReplacement(MetaString::ART_NAMES, val2);
|
||||
cb->giveHeroArtifact(val2,h->id,-2);
|
||||
cb->giveHeroNewArtifact(h, VLC->arth->artifacts[val2],-2);
|
||||
}
|
||||
cb->showInfoDialog(&iw);
|
||||
break;
|
||||
@ -3836,7 +3827,7 @@ void CGPickable::onHeroVisit( const CGHeroInstance * h ) const
|
||||
iw.components.push_back(Component(4,val1,1,0));
|
||||
iw.text.addTxt(MetaString::ADVOB_TXT, 125);
|
||||
iw.text.addReplacement(MetaString::ART_NAMES, val1);
|
||||
cb->giveHeroArtifact(val1,h->id,-2);
|
||||
cb->giveHeroNewArtifact(h, VLC->arth->artifacts[val1],-2);
|
||||
cb->showInfoDialog(&iw);
|
||||
break;
|
||||
}
|
||||
@ -3850,7 +3841,7 @@ void CGPickable::onHeroVisit( const CGHeroInstance * h ) const
|
||||
|
||||
if(type) //there is an artifact
|
||||
{
|
||||
cb->giveHeroArtifact(val1,h->id,-2);
|
||||
cb->giveHeroNewArtifact(h, VLC->arth->artifacts[val1],-2);
|
||||
InfoWindow iw;
|
||||
iw.soundID = soundBase::treasure;
|
||||
iw.player = h->tempOwner;
|
||||
@ -4452,7 +4443,7 @@ void CGSeerHut::completeQuest (const CGHeroInstance * h) const //reward
|
||||
cb->changeSecSkill(h->id, rID, rVal, false);
|
||||
break;
|
||||
case 8: // artifact
|
||||
cb->giveHeroArtifact(rID, h->id, -2);
|
||||
cb->giveHeroNewArtifact(h, VLC->arth->artifacts[rID],-2);
|
||||
break;
|
||||
case 9:// spell
|
||||
{
|
||||
@ -5009,7 +5000,7 @@ void CGPandoraBox::giveContents( const CGHeroInstance *h, bool afterBattle ) con
|
||||
cb->giveResource(h->getOwner(),i,resources[i]);
|
||||
|
||||
for(int i=0; i<artifacts.size(); i++)
|
||||
cb->giveHeroArtifact(artifacts[i],h->id,-2);
|
||||
cb->giveHeroNewArtifact(h, VLC->arth->artifacts[artifacts[i]],-2);
|
||||
|
||||
iw.components.clear();
|
||||
iw.text.clear();
|
||||
@ -5410,7 +5401,7 @@ void CGOnceVisitable::onHeroVisit( const CGHeroInstance * h ) const
|
||||
break;
|
||||
case 1: //art
|
||||
iw.components.push_back(Component(Component::ARTIFACT,bonusType,0,0));
|
||||
cb->giveHeroArtifact(bonusType,h->id,-2);
|
||||
cb->giveHeroNewArtifact(h, VLC->arth->artifacts[bonusType],-2);
|
||||
iw.text.addTxt(MetaString::ADVOB_TXT, txtid);
|
||||
if (ID == 22) //Corpse
|
||||
{
|
||||
@ -5532,7 +5523,7 @@ void CGOnceVisitable::searchTomb(const CGHeroInstance *h, ui32 accept) const
|
||||
iw.components.push_back(Component(Component::ARTIFACT,bonusType,0,0));
|
||||
iw.text.addReplacement(MetaString::ART_NAMES, bonusType);
|
||||
|
||||
cb->giveHeroArtifact(bonusType,h->id,-2);
|
||||
cb->giveHeroNewArtifact(h, VLC->arth->artifacts[bonusType],-2);
|
||||
}
|
||||
|
||||
if(!h->hasBonusFrom(Bonus::OBJECT,ID)) //we don't have modifier from this object yet
|
||||
@ -5871,7 +5862,7 @@ void CBank::endBattle (const CGHeroInstance *h, const BattleResult *result) cons
|
||||
iw.components.push_back (Component (Component::ARTIFACT, *it, 0, 0));
|
||||
loot << "%s";
|
||||
loot.addReplacement(MetaString::ART_NAMES, *it);
|
||||
cb->giveHeroArtifact (*it, h->id ,-2);
|
||||
cb->giveHeroNewArtifact (h, VLC->arth->artifacts[*it], -2);
|
||||
}
|
||||
//display loot
|
||||
if (!iw.components.empty())
|
||||
@ -6935,3 +6926,59 @@ void CGUniversity::onHeroVisit(const CGHeroInstance * h) const
|
||||
ow.window = OpenWindow::UNIVERSITY_WINDOW;
|
||||
cb->sendAndApply(&ow);
|
||||
}
|
||||
|
||||
const CArtifactInstance* CArtifactSet::getArt(ui16 pos) const
|
||||
{
|
||||
if(const ArtSlotInfo *si = getSlot(pos))
|
||||
{
|
||||
if(si->artifact && !si->locked)
|
||||
return si->artifact;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
si32 CArtifactSet::getArtPos(int aid, bool onlyWorn /*= true*/) const
|
||||
{
|
||||
for(std::map<ui16, ArtSlotInfo>::const_iterator i = artifactsWorn.begin(); i != artifactsWorn.end(); i++)
|
||||
if(i->second.artifact->artType->id == aid)
|
||||
return i->first;
|
||||
|
||||
if(onlyWorn)
|
||||
return -1;
|
||||
|
||||
for(int i = 0; i < artifactsInBackpack.size(); i++)
|
||||
if(artifactsInBackpack[i].artifact->artType->id == aid)
|
||||
return Arts::BACKPACK_START + i;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
bool CArtifactSet::hasArt(ui32 aid, bool onlyWorn /*= true*/) const
|
||||
{
|
||||
return getArtPos(aid, onlyWorn) != -1;
|
||||
}
|
||||
|
||||
const ArtSlotInfo * CArtifactSet::getSlot(ui16 pos) const
|
||||
{
|
||||
if(vstd::contains(artifactsWorn, pos))
|
||||
return &artifactsWorn[pos];
|
||||
if(pos >= Arts::AFTER_LAST )
|
||||
{
|
||||
int backpackPos = (int)pos - Arts::BACKPACK_START;
|
||||
if(backpackPos < 0 || backpackPos >= artifactsInBackpack.size())
|
||||
return NULL;
|
||||
else
|
||||
return &artifactsInBackpack[backpackPos];
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bool CArtifactSet::isPositionFree(ui16 pos) const
|
||||
{
|
||||
if(const ArtSlotInfo *s = getSlot(pos))
|
||||
return !s->artifact && !s->locked;
|
||||
|
||||
return true; //no slot means not used
|
||||
}
|
@ -243,7 +243,40 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
class DLL_EXPORT CGHeroInstance : public CArmedInstance, public IBoatGenerator
|
||||
struct DLL_EXPORT ArtSlotInfo
|
||||
{
|
||||
ConstTransitivePtr<CArtifactInstance> artifact;
|
||||
ui8 locked; //if locked, then artifact points to the combined artifact
|
||||
|
||||
ArtSlotInfo()
|
||||
{
|
||||
locked = false;
|
||||
}
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{
|
||||
h & artifact & locked;
|
||||
}
|
||||
};
|
||||
|
||||
class DLL_EXPORT CArtifactSet
|
||||
{
|
||||
public:
|
||||
std::vector<ArtSlotInfo> artifactsInBackpack; //hero's artifacts from bag
|
||||
bmap<ui16, ArtSlotInfo> artifactsWorn; //map<position,artifact_id>; positions: 0 - head; 1 - shoulders; 2 - neck; 3 - right hand; 4 - left hand; 5 - torso; 6 - right ring; 7 - left ring; 8 - feet; 9 - misc1; 10 - misc2; 11 - misc3; 12 - misc4; 13 - mach1; 14 - mach2; 15 - mach3; 16 - mach4; 17 - spellbook; 18 - misc5
|
||||
|
||||
const ArtSlotInfo *getSlot(ui16 pos) const;
|
||||
const CArtifactInstance* getArt(ui16 pos) const; //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)
|
||||
bool hasArt(ui32 aid, bool onlyWorn = true) const; //checks if hero possess artifact of given id (either in backack or worn)
|
||||
bool isPositionFree(ui16 pos) const;
|
||||
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{
|
||||
h & artifactsInBackpack & artifactsWorn;
|
||||
}
|
||||
};
|
||||
|
||||
class DLL_EXPORT CGHeroInstance : public CArmedInstance, public IBoatGenerator, public CArtifactSet
|
||||
{
|
||||
public:
|
||||
enum SecondarySkill
|
||||
@ -276,13 +309,12 @@ public:
|
||||
const CGTownInstance * visitedTown; //set if hero is visiting town or in the town garrison
|
||||
const CGBoat *boat; //set to CGBoat when sailing
|
||||
|
||||
std::vector<const CArtifactInstance*> gartifacts; //hero's artifacts from bag
|
||||
std::map<ui16, const CArtifactInstance*> gartifWorn; //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
|
||||
|
||||
std::vector<const CArtifact*> artifacts; //hero's artifacts from bag
|
||||
std::map<ui16, const CArtifact*> artifWorn; //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
|
||||
std::set<ui32> spells; //known spells (spell IDs)
|
||||
|
||||
|
||||
struct DLL_EXPORT Patrol
|
||||
{
|
||||
Patrol(){patrolling=false;patrolRadious=-1;};
|
||||
@ -293,6 +325,7 @@ public:
|
||||
h & patrolling & patrolRadious;
|
||||
}
|
||||
} patrol;
|
||||
|
||||
struct DLL_EXPORT HeroSpecial : CBonusSystemNode
|
||||
{
|
||||
bool growthsWithLevel;
|
||||
@ -310,6 +343,7 @@ public:
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{
|
||||
h & static_cast<CArmedInstance&>(*this);
|
||||
h & static_cast<CArtifactSet&>(*this);
|
||||
h & exp & level & name & biography & portrait & mana & secSkills & movement
|
||||
& sex & inTownGarrison & artifacts & artifWorn & spells & patrol & moveDir;
|
||||
|
||||
@ -777,9 +811,9 @@ public:
|
||||
class DLL_EXPORT CGArtifact : public CArmedInstance
|
||||
{
|
||||
public:
|
||||
CArtifactInstance *art;
|
||||
|
||||
CArtifactInstance *storedArtifact;
|
||||
std::string message;
|
||||
|
||||
void onHeroVisit(const CGHeroInstance * h) const;
|
||||
void fightForArt(ui32 agreed, const CGHeroInstance *h) const;
|
||||
void endBattle(BattleResult *result, const CGHeroInstance *h) const;
|
||||
@ -789,7 +823,7 @@ public:
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{
|
||||
h & static_cast<CArmedInstance&>(*this);
|
||||
h & message & art;
|
||||
h & message & storedArtifact;
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -420,11 +420,14 @@ public:
|
||||
typedef typename VectorisedTypeFor<TObjectType>::type VType;
|
||||
if(const VectorisedObjectInfo<VType> *info = getVectorisedTypeInfo<VType>())
|
||||
{
|
||||
*this << getIdFromVectorItem<VType>(*info, data);
|
||||
return;
|
||||
si32 id = getIdFromVectorItem<VType>(*info, data);
|
||||
*this << id;
|
||||
if(id != -1) //vector id is enough
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if(smartPointerSerialization)
|
||||
{
|
||||
std::map<const void*,ui32>::iterator i = savedPointers.find(data);
|
||||
@ -686,10 +689,13 @@ public:
|
||||
typedef typename VectorisedTypeFor<TObjectType>::type VType; //eg: CGHeroInstance -> CGobjectInstance
|
||||
if(const VectorisedObjectInfo<VType> *info = getVectorisedTypeInfo<VType>())
|
||||
{
|
||||
ui32 id;
|
||||
si32 id;
|
||||
*this >> id;
|
||||
data = static_cast<T>(getVectorItemFromId(*info, id));
|
||||
return;
|
||||
if(id != -1)
|
||||
{
|
||||
data = static_cast<T>(getVectorItemFromId(*info, id));
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,9 +1,14 @@
|
||||
#pragma once
|
||||
|
||||
class CGameHandler;
|
||||
|
||||
template <typename T>
|
||||
class ConstTransitivePtr
|
||||
{
|
||||
T *ptr;
|
||||
ConstTransitivePtr(const T *Ptr)
|
||||
: ptr(const_cast<T*>(Ptr))
|
||||
{}
|
||||
public:
|
||||
ConstTransitivePtr(T *Ptr = NULL)
|
||||
: ptr(Ptr)
|
||||
@ -42,8 +47,16 @@ public:
|
||||
return ptr;
|
||||
}
|
||||
|
||||
void dellNull()
|
||||
{
|
||||
delete ptr;
|
||||
ptr = NULL;
|
||||
}
|
||||
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{
|
||||
h & ptr;
|
||||
}
|
||||
|
||||
friend CGameHandler;
|
||||
};
|
||||
|
@ -38,6 +38,8 @@ struct TerrainTile;
|
||||
struct PlayerState;
|
||||
class CTown;
|
||||
struct StackLocation;
|
||||
struct ArtifactLocation;
|
||||
class CArtifactInstance;
|
||||
|
||||
class DLL_EXPORT IGameCallback
|
||||
{
|
||||
@ -87,8 +89,8 @@ public:
|
||||
virtual void showGarrisonDialog(int upobj, int hid, bool removableUnits, const boost::function<void()> &cb) =0; //cb will be called when player closes garrison window
|
||||
virtual void showThievesGuildWindow(int requestingObjId) =0;
|
||||
virtual void giveResource(int player, int which, int val)=0;
|
||||
|
||||
virtual void giveCreatures (const CArmedInstance *objid, const CGHeroInstance * h, const CCreatureSet &creatures, bool remove) =0;
|
||||
//virtual void takeCreatures (int objid, TSlots creatures) =0;
|
||||
virtual void takeCreatures (int objid, std::vector<CStackBasicDescriptor> creatures) =0;
|
||||
virtual bool changeStackCount(const StackLocation &sl, TQuantity count, bool absoluteValue = false) =0;
|
||||
virtual bool changeStackType(const StackLocation &sl, CCreature *c) =0;
|
||||
@ -98,11 +100,18 @@ public:
|
||||
virtual bool addToSlot(const StackLocation &sl, const CCreature *c, TQuantity count) =0; //makes new stack or increases count of already existing
|
||||
virtual void tryJoiningArmy(const CArmedInstance *src, const CArmedInstance *dst, bool removeObjWhenFinished, bool allowMerging) =0; //merges army from src do dst or opens a garrison window
|
||||
virtual bool moveStack(const StackLocation &src, const StackLocation &dst, TQuantity count) = 0;
|
||||
|
||||
virtual void giveHeroNewArtifact(const CGHeroInstance *h, const CArtifact *artType, int pos) = 0;
|
||||
virtual void giveHeroArtifact(const CGHeroInstance *h, const CArtifactInstance *a, int pos) = 0; //pos==-1 - first free slot in backpack=0; pos==-2 - default if available or backpack
|
||||
virtual void putArtifact(const ArtifactLocation &al, const CArtifactInstance *a) = 0;
|
||||
virtual void removeArtifact(const ArtifactLocation &al) = 0;
|
||||
virtual void moveArtifact(const ArtifactLocation &al1, const ArtifactLocation &al2) = 0;
|
||||
|
||||
virtual void showCompInfo(ShowInInfobox * comp)=0;
|
||||
virtual void heroVisitCastle(int obj, int heroID)=0;
|
||||
virtual void stopHeroVisitCastle(int obj, int heroID)=0;
|
||||
virtual void giveHeroArtifact(int artid, int hid, int position)=0; //pos==-1 - first free slot in backpack=0; pos==-2 - default if available or backpack
|
||||
virtual void giveNewArtifact(int hid, int position)=0;
|
||||
//virtual void giveHeroArtifact(int artid, int hid, int position)=0; //pos==-1 - first free slot in backpack=0; pos==-2 - default if available or backpack
|
||||
//virtual void giveNewArtifact(int hid, int position)=0;
|
||||
virtual bool removeArtifact(const CArtifact* art, int hid) = 0;
|
||||
virtual void startBattleI(const CArmedInstance *army1, const CArmedInstance *army2, int3 tile, const CGHeroInstance *hero1, const CGHeroInstance *hero2, bool creatureBank = false, boost::function<void(BattleResult*)> cb = 0, const CGTownInstance *town = NULL)=0; //use hero=NULL for no hero
|
||||
virtual void startBattleI(const CArmedInstance *army1, const CArmedInstance *army2, int3 tile, boost::function<void(BattleResult*)> cb = 0, bool creatureBank = false)=0; //if any of armies is hero, hero will be used
|
||||
|
@ -27,7 +27,9 @@ class CCampaignState;
|
||||
class CArtifact;
|
||||
class CSelectionScreen;
|
||||
class CGObjectInstance;
|
||||
class CArtifactInstance;
|
||||
//class CMapInfo;
|
||||
struct ArtSlotInfo;
|
||||
|
||||
struct CPack
|
||||
{
|
||||
@ -708,12 +710,11 @@ struct NewArtifact : public CPackForClient //520
|
||||
//void applyCl(CClient *cl);
|
||||
DLL_EXPORT void applyGs(CGameState *gs);
|
||||
|
||||
si32 artid;
|
||||
si32 value; //initializing parameter
|
||||
ConstTransitivePtr<CArtifactInstance> art;
|
||||
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{
|
||||
h & artid & value;
|
||||
h & art;
|
||||
}
|
||||
};
|
||||
|
||||
@ -724,7 +725,6 @@ struct StackLocation
|
||||
|
||||
StackLocation()
|
||||
{
|
||||
army = NULL;
|
||||
slot = -1;
|
||||
}
|
||||
StackLocation(const CArmedInstance *Army, TSlot Slot)
|
||||
@ -827,7 +827,6 @@ struct RebalanceStacks : CGarrisonOperationPack //526
|
||||
}
|
||||
};
|
||||
|
||||
typedef CArtifact TTempArtInstance;
|
||||
typedef si32 TArtPos;
|
||||
|
||||
struct ArtifactLocation
|
||||
@ -837,7 +836,6 @@ struct ArtifactLocation
|
||||
|
||||
ArtifactLocation()
|
||||
{
|
||||
hero = NULL;
|
||||
slot = -1;
|
||||
}
|
||||
ArtifactLocation(const CGHeroInstance *Hero, TArtPos Slot)
|
||||
@ -845,7 +843,9 @@ struct ArtifactLocation
|
||||
hero = const_cast<CGHeroInstance*>(Hero); //we are allowed here to const cast -> change will go through one of our packages... do not abuse!
|
||||
slot = Slot;
|
||||
}
|
||||
DLL_EXPORT const TTempArtInstance *getArt();
|
||||
DLL_EXPORT const CArtifactInstance *getArt() const;
|
||||
DLL_EXPORT CArtifactInstance *getArt();
|
||||
DLL_EXPORT const ArtSlotInfo *getSlot() const;
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{
|
||||
h & hero & slot;
|
||||
@ -855,14 +855,14 @@ struct ArtifactLocation
|
||||
struct PutArtifact : CGarrisonOperationPack //526
|
||||
{
|
||||
ArtifactLocation al;
|
||||
TTempArtInstance *art;
|
||||
ConstTransitivePtr<CArtifactInstance> art;
|
||||
|
||||
void applyCl(CClient *cl);
|
||||
DLL_EXPORT void applyGs(CGameState *gs);
|
||||
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{
|
||||
h & src & dst & count;
|
||||
h & al & art;
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -178,7 +178,7 @@ DLL_EXPORT void SetAvailableHeroes::applyGs( CGameState *gs )
|
||||
|
||||
for (int i = 0; i < AVAILABLE_HEROES_PER_PLAYER; i++)
|
||||
{
|
||||
CGHeroInstance *h = (hid[i]>=0 ? gs->hpool.heroesPool[hid[i]] : NULL);
|
||||
CGHeroInstance *h = (hid[i]>=0 ? (CGHeroInstance*)gs->hpool.heroesPool[hid[i]] : NULL);
|
||||
if(h && army[i])
|
||||
h->setToArmy(*army[i]);
|
||||
p->availableHeroes.push_back(h);
|
||||
@ -294,7 +294,7 @@ DLL_EXPORT void RemoveObject::applyGs( CGameState *gs )
|
||||
CGCreature *cre = static_cast<CGCreature*>(obj);
|
||||
gs->map->monsters[cre->identifier]->pos = int3 (-1,-1,-1); //use nonexistent monster for quest :>
|
||||
}
|
||||
gs->map->objects[id] = NULL;
|
||||
gs->map->objects[id].dellNull();
|
||||
}
|
||||
|
||||
static int getDir(int3 src, int3 dst)
|
||||
@ -583,28 +583,12 @@ DLL_EXPORT void NewObject::applyGs( CGameState *gs )
|
||||
}
|
||||
DLL_EXPORT void NewArtifact::applyGs( CGameState *gs )
|
||||
{
|
||||
// IModableArt * art;
|
||||
//
|
||||
// std::map<ui32,ui8>::iterator itr = VLC->arth->modableArtifacts.find(artid);
|
||||
// switch (itr->second)
|
||||
// {
|
||||
// case 1:
|
||||
// art = new CScroll;
|
||||
// break;
|
||||
// case 2:
|
||||
// art = new CCustomizableArt;
|
||||
// break;
|
||||
// case 3:
|
||||
// art = new CCommanderArt;
|
||||
// break;
|
||||
// default:
|
||||
// tlog1<<"unhandled customizable artifact!\n";
|
||||
// };
|
||||
// *art = *static_cast<IModableArt*>(+VLC->arth->artifacts[artid]); //copy properties
|
||||
// art->ID = gs->map->artInstances.size();
|
||||
// art->SetProperty (value); //init scroll, banner, commander art
|
||||
// art->Init(); //set bonuses for new instance
|
||||
// gs->map->artInstances.push_back(art);
|
||||
assert(!vstd::contains(gs->map->artInstances, art));
|
||||
art->id = gs->map->artInstances.size();
|
||||
gs->map->artInstances.push_back(art);
|
||||
|
||||
assert(!art->parents.size());
|
||||
art->attachTo(art->artType);
|
||||
}
|
||||
|
||||
DLL_EXPORT const CStackInstance * StackLocation::getStack()
|
||||
@ -617,6 +601,24 @@ DLL_EXPORT const CStackInstance * StackLocation::getStack()
|
||||
return &army->getStack(slot);
|
||||
}
|
||||
|
||||
DLL_EXPORT const CArtifactInstance *ArtifactLocation::getArt() const
|
||||
{
|
||||
const ArtSlotInfo *s = getSlot();
|
||||
if(s && !s->locked && s->artifact)
|
||||
return s->artifact;
|
||||
}
|
||||
|
||||
DLL_EXPORT CArtifactInstance *ArtifactLocation::getArt()
|
||||
{
|
||||
const ArtifactLocation *t = this;
|
||||
return const_cast<CArtifactInstance*>(t->getArt());
|
||||
}
|
||||
|
||||
DLL_EXPORT const ArtSlotInfo *ArtifactLocation::getSlot() const
|
||||
{
|
||||
return hero->getSlot(slot);
|
||||
}
|
||||
|
||||
DLL_EXPORT void ChangeStackCount::applyGs( CGameState *gs )
|
||||
{
|
||||
if(absoluteValue)
|
||||
@ -685,6 +687,24 @@ DLL_EXPORT void RebalanceStacks::applyGs( CGameState *gs )
|
||||
}
|
||||
}
|
||||
|
||||
DLL_EXPORT void PutArtifact::applyGs( CGameState *gs )
|
||||
{
|
||||
assert(art->canBePutAt(al));
|
||||
art->putAt(al.hero, al.slot);
|
||||
}
|
||||
|
||||
DLL_EXPORT void EraseArtifact::applyGs( CGameState *gs )
|
||||
{
|
||||
CArtifactInstance *a = al.getArt();
|
||||
assert(a);
|
||||
a->removeFrom(al.hero, al.slot);
|
||||
}
|
||||
|
||||
DLL_EXPORT void MoveArtifact::applyGs( CGameState *gs )
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
DLL_EXPORT void SetAvailableArtifacts::applyGs( CGameState *gs )
|
||||
{
|
||||
if(id >= 0)
|
||||
@ -904,8 +924,7 @@ void BattleResult::applyGs( CGameState *gs )
|
||||
h->bonuses.remove_if(Bonus::OneBattle);
|
||||
|
||||
gs->curB->belligerents[0]->battle = gs->curB->belligerents[1]->battle = NULL;
|
||||
delete gs->curB;
|
||||
gs->curB = NULL;
|
||||
gs->curB.dellNull();
|
||||
}
|
||||
|
||||
void BattleStackMoved::applyGs( CGameState *gs )
|
||||
|
@ -149,6 +149,9 @@ void registerTypes2(Serializer &s)
|
||||
s.template registerType<InsertNewStack>();
|
||||
s.template registerType<RebalanceStacks>();
|
||||
s.template registerType<SetAvailableArtifacts>();
|
||||
s.template registerType<PutArtifact>();
|
||||
s.template registerType<EraseArtifact>();
|
||||
s.template registerType<MoveArtifact>();
|
||||
|
||||
s.template registerType<SaveGame>();
|
||||
s.template registerType<SetSelection>();
|
||||
|
@ -1584,7 +1584,7 @@ void Mapa::readObjects( const unsigned char * bufor, int &i)
|
||||
{
|
||||
innerArt = new CArtifactInstance();
|
||||
}
|
||||
art->art = innerArt;
|
||||
art->storedArtifact = innerArt;
|
||||
addNewArtifactInstance(innerArt);
|
||||
break;
|
||||
}
|
||||
|
@ -1609,98 +1609,7 @@ void CGameHandler::stopHeroVisitCastle(int obj, int heroID)
|
||||
vc.tid = obj;
|
||||
sendAndApply(&vc);
|
||||
}
|
||||
void CGameHandler::giveHeroArtifact(int artid, int hid, int position) //pos==-1 - first free slot in backpack
|
||||
{
|
||||
const CGHeroInstance* h = getHero(hid);
|
||||
CArtifact * const art = VLC->arth->artifacts[artid];
|
||||
|
||||
SetHeroArtifacts sha;
|
||||
sha.hid = hid;
|
||||
sha.artifacts = h->artifacts;
|
||||
sha.artifWorn = h->artifWorn;
|
||||
|
||||
if(position<0)
|
||||
{
|
||||
if(position == -2)
|
||||
{
|
||||
int i;
|
||||
for(i=0; i<art->possibleSlots.size(); i++) //try to put artifact into first available slot
|
||||
{
|
||||
if(art->fitsAt(sha.artifWorn, art->possibleSlots[i]))
|
||||
{
|
||||
//we've found a free suitable slot.
|
||||
VLC->arth->equipArtifact(sha.artifWorn, art->possibleSlots[i], VLC->arth->artifacts[artid]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(i == art->possibleSlots.size() && !art->isBig()) //if haven't find proper slot, use backpack or discard big artifact
|
||||
sha.artifacts.push_back(art);
|
||||
}
|
||||
else if (!art->isBig()) //should be -1 => put artifact into backpack
|
||||
{
|
||||
sha.artifacts.push_back(art);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(art->fitsAt(sha.artifWorn, ui16(position)))
|
||||
{
|
||||
VLC->arth->equipArtifact(sha.artifWorn, position, art);
|
||||
}
|
||||
else if (!art->isBig())
|
||||
{
|
||||
sha.artifacts.push_back(art);
|
||||
}
|
||||
}
|
||||
|
||||
sendAndApply(&sha);
|
||||
}
|
||||
void CGameHandler::giveNewArtifact(int hid, int position)
|
||||
{
|
||||
// const CGHeroInstance* h = getHero(hid);
|
||||
// CArtifact * art = gs->map->artInstances.back(); //we use it only to immediatelly equip new artifact
|
||||
//
|
||||
// SetHeroArtifacts sha;
|
||||
// sha.hid = hid;
|
||||
// sha.artifacts = h->artifacts;
|
||||
// sha.artifWorn = h->artifWorn;
|
||||
//
|
||||
// if(position<0)
|
||||
// {
|
||||
// if(position == -2)
|
||||
// {
|
||||
// int i;
|
||||
// for(i=0; i<art->possibleSlots.size(); i++) //try to put artifact into first available slot
|
||||
// {
|
||||
// if( !vstd::contains(sha.artifWorn, art->possibleSlots[i]) )
|
||||
// {
|
||||
// //we've found a free suitable slot
|
||||
// VLC->arth->equipArtifact(sha.artifWorn, art->possibleSlots[i], art);
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
// if(i == art->possibleSlots.size() && !art->isBig()) //if haven't find proper slot, use backpack or discard big artifact
|
||||
// sha.artifacts.push_back(art);
|
||||
// }
|
||||
// else if (!art->isBig()) //should be -1 => put artifact into backpack
|
||||
// {
|
||||
// sha.artifacts.push_back(art);
|
||||
// }
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// if(!vstd::contains(sha.artifWorn,ui16(position)))
|
||||
// {
|
||||
// VLC->arth->equipArtifact(sha.artifWorn, position, art);
|
||||
// }
|
||||
// else if (!art->isBig())
|
||||
// {
|
||||
// sha.artifacts.push_back(art);
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// sendAndApply(&sha);
|
||||
}
|
||||
bool CGameHandler::removeArtifact(const CArtifact* art, int hid)
|
||||
{
|
||||
const CGHeroInstance* h = getHero(hid);
|
||||
@ -1735,6 +1644,10 @@ bool CGameHandler::removeArtifact(const CArtifact* art, int hid)
|
||||
return true;
|
||||
}
|
||||
|
||||
void CGameHandler::removeArtifact(const ArtifactLocation &al)
|
||||
{
|
||||
|
||||
}
|
||||
void CGameHandler::startBattleI(const CArmedInstance *army1, const CArmedInstance *army2, int3 tile, const CGHeroInstance *hero1, const CGHeroInstance *hero2, bool creatureBank, boost::function<void(BattleResult*)> cb, const CGTownInstance *town) //use hero=NULL for no hero
|
||||
{
|
||||
engageIntoBattle(army1->tempOwner);
|
||||
@ -1976,6 +1889,7 @@ void CGameHandler::sendToAllClients( CPackForClient * info )
|
||||
|
||||
void CGameHandler::sendAndApply( CPackForClient * info )
|
||||
{
|
||||
//TODO? mutex
|
||||
sendToAllClients(info);
|
||||
gs->apply(info);
|
||||
}
|
||||
@ -2370,16 +2284,20 @@ bool CGameHandler::recruitCreatures( si32 objid, ui32 crid, ui32 cram, si32 from
|
||||
|
||||
if(warMachine)
|
||||
{
|
||||
const CGHeroInstance *h = dynamic_cast<const CGHeroInstance*>(dst);
|
||||
if(!h)
|
||||
COMPLAIN_RET("Only hero can buy war machines");
|
||||
|
||||
switch(crid)
|
||||
{
|
||||
case 146:
|
||||
giveHeroArtifact(4, dst->id, 13);
|
||||
giveHeroNewArtifact(h, VLC->arth->artifacts[4], Arts::MACH1);
|
||||
break;
|
||||
case 147:
|
||||
giveHeroArtifact(6, dst->id, 15);
|
||||
giveHeroNewArtifact(h, VLC->arth->artifacts[6], Arts::MACH3);
|
||||
break;
|
||||
case 148:
|
||||
giveHeroArtifact(5, dst->id, 14);
|
||||
giveHeroNewArtifact(h, VLC->arth->artifacts[5], Arts::MACH2);
|
||||
break;
|
||||
default:
|
||||
complain("This war machine cannot be recruited!");
|
||||
@ -2770,13 +2688,14 @@ bool CGameHandler::buyArtifact( ui32 hid, si32 aid )
|
||||
if(aid==0) //spellbook
|
||||
{
|
||||
if(!vstd::contains(town->builtBuildings,si32(0)) && complain("Cannot buy a spellbook, no mage guild in the town!")
|
||||
|| getResource(hero->getOwner(),6)<500 && complain("Cannot buy a spellbook, not enough gold!")
|
||||
|| hero->getArt(17) && complain("Cannot buy a spellbook, hero already has a one!")
|
||||
|| getResource(hero->getOwner(), Res::GOLD) < SPELLBOOK_GOLD_COST && complain("Cannot buy a spellbook, not enough gold!")
|
||||
|| hero->getArt(Arts::SPELLBOOK) && complain("Cannot buy a spellbook, hero already has a one!")
|
||||
)
|
||||
return false;
|
||||
|
||||
giveResource(hero->getOwner(),6,-500);
|
||||
giveHeroArtifact(0,hid,17);
|
||||
giveResource(hero->getOwner(),Res::GOLD,-SPELLBOOK_GOLD_COST);
|
||||
giveHeroNewArtifact(hero, VLC->arth->artifacts[0], Arts::SPELLBOOK);
|
||||
assert(hero->getArt(Arts::SPELLBOOK));
|
||||
giveSpells(town,hero);
|
||||
return true;
|
||||
}
|
||||
@ -2785,7 +2704,7 @@ bool CGameHandler::buyArtifact( ui32 hid, si32 aid )
|
||||
int price = VLC->arth->artifacts[aid]->price;
|
||||
if(vstd::contains(hero->artifWorn,ui16(9+aid)) && complain("Hero already has this machine!")
|
||||
|| !vstd::contains(town->builtBuildings,si32(16)) && complain("No blackismith!")
|
||||
|| gs->getPlayer(hero->getOwner())->resources[6] < price && complain("Not enough gold!") //no gold
|
||||
|| gs->getPlayer(hero->getOwner())->resources[Res::GOLD] < price && complain("Not enough gold!") //no gold
|
||||
|| (!(town->subID == 6 && vstd::contains(town->builtBuildings,si32(22) ) )
|
||||
&& town->town->warMachine!= aid ) && complain("This machine is unavailable here!") )
|
||||
{
|
||||
@ -2793,7 +2712,7 @@ bool CGameHandler::buyArtifact( ui32 hid, si32 aid )
|
||||
}
|
||||
|
||||
giveResource(hero->getOwner(),6,-price);
|
||||
giveHeroArtifact(aid,hid,9+aid);
|
||||
giveHeroNewArtifact(hero, VLC->arth->artifacts[aid], 9+aid);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@ -2847,7 +2766,7 @@ bool CGameHandler::buyArtifact(const IMarket *m, const CGHeroInstance *h, int ri
|
||||
|
||||
sendAndApply(&saa);
|
||||
|
||||
giveHeroArtifact(aid, h->id, -2);
|
||||
giveHeroNewArtifact(h, VLC->arth->artifacts[aid], -2);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -4347,7 +4266,7 @@ bool CGameHandler::dig( const CGHeroInstance *h )
|
||||
iw.text.addTxt(MetaString::GENERAL_TXT, 58); //"Congratulations! After spending many hours digging here, your hero has uncovered the "
|
||||
iw.text.addTxt(MetaString::ART_NAMES, 2);
|
||||
iw.soundID = soundBase::ULTIMATEARTIFACT;
|
||||
giveHeroArtifact(2, h->id, -1); //give grail
|
||||
giveHeroNewArtifact(h, VLC->arth->artifacts[2], -1); //give grail
|
||||
sendAndApply(&iw);
|
||||
|
||||
iw.text.clear();
|
||||
@ -5018,6 +4937,61 @@ void CGameHandler::runBattle()
|
||||
|
||||
endBattle(gs->curB->tile, gs->curB->heroes[0], gs->curB->heroes[1]);
|
||||
}
|
||||
|
||||
void CGameHandler::giveHeroArtifact(const CGHeroInstance *h, const CArtifactInstance *a, int pos)
|
||||
{
|
||||
assert(a->artType);
|
||||
ArtifactLocation al;
|
||||
al.hero = h;
|
||||
|
||||
int slot = -1;
|
||||
if(pos < 0)
|
||||
{
|
||||
if(pos == -2)
|
||||
slot = a->firstAvailableSlot(h);
|
||||
else
|
||||
slot = a->firstBackpackSlot(h);
|
||||
}
|
||||
else
|
||||
{
|
||||
slot = pos;
|
||||
}
|
||||
|
||||
al.slot = slot;
|
||||
|
||||
if(slot < 0 || !a->canBePutAt(al))
|
||||
{
|
||||
complain("Cannot put artifact in that slot!");
|
||||
return;
|
||||
}
|
||||
|
||||
putArtifact(al, a);
|
||||
}
|
||||
void CGameHandler::putArtifact(const ArtifactLocation &al, const CArtifactInstance *a)
|
||||
{
|
||||
PutArtifact pa;
|
||||
pa.art = a;
|
||||
pa.al = al;
|
||||
sendAndApply(&pa);
|
||||
}
|
||||
|
||||
void CGameHandler::moveArtifact(const ArtifactLocation &al1, const ArtifactLocation &al2)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void CGameHandler::giveHeroNewArtifact(const CGHeroInstance *h, const CArtifact *artType, int pos)
|
||||
{
|
||||
CArtifactInstance *a = NULL;
|
||||
a->artType = artType; //NOT via settype -> all bonus-related stuff must be done by NewArtifact apply
|
||||
|
||||
NewArtifact na;
|
||||
na.art = a;
|
||||
sendAndApply(&na);
|
||||
|
||||
giveHeroArtifact(h, a, pos);
|
||||
}
|
||||
|
||||
CasualtiesAfterBattle::CasualtiesAfterBattle(const CArmedInstance *army, BattleInfo *bat)
|
||||
{
|
||||
int color = army->tempOwner;
|
||||
@ -5026,7 +5000,7 @@ CasualtiesAfterBattle::CasualtiesAfterBattle(const CArmedInstance *army, BattleI
|
||||
|
||||
BOOST_FOREACH(CStack *st, bat->stacks)
|
||||
{
|
||||
if(vstd::contains(st->state, SUMMONED)) //don't take into account sumoned stacks
|
||||
if(vstd::contains(st->state, SUMMONED)) //don't take into account summoned stacks
|
||||
continue;
|
||||
|
||||
if(st->owner==color && !army->slotEmpty(st->slot) && st->count < army->getStackCount(st->slot))
|
||||
|
@ -128,60 +128,67 @@ public:
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
//from IGameCallback
|
||||
//get info
|
||||
int getCurrentPlayer();
|
||||
int getSelectedHero();
|
||||
int getCurrentPlayer() OVERRIDE;
|
||||
int getSelectedHero() OVERRIDE;
|
||||
|
||||
|
||||
//do sth
|
||||
void changeSpells(int hid, bool give, const std::set<ui32> &spells);
|
||||
bool removeObject(int objid);
|
||||
void setBlockVis(int objid, bool bv);
|
||||
void setOwner(int objid, ui8 owner);
|
||||
void setHoverName(int objid, MetaString * name);
|
||||
void setObjProperty(int objid, int prop, si64 val);
|
||||
void levelUpHero(int ID, int skill);//handle client respond and send one more request if needed
|
||||
void levelUpHero(int ID);//initial call - check if hero have remaining levelups & handle them
|
||||
void changePrimSkill(int ID, int which, si64 val, bool abs=false);
|
||||
void changeSecSkill(int ID, int which, int val, bool abs=false);
|
||||
void showInfoDialog(InfoWindow *iw);
|
||||
void showBlockingDialog(BlockingDialog *iw, const CFunctionList<void(ui32)> &callback);
|
||||
ui32 showBlockingDialog(BlockingDialog *iw); //synchronous version of above
|
||||
void showGarrisonDialog(int upobj, int hid, bool removableUnits, const boost::function<void()> &cb);
|
||||
void showThievesGuildWindow(int requestingObjId); //TODO: make something more general?
|
||||
void giveResource(int player, int which, int val);
|
||||
void giveCreatures (const CArmedInstance *objid, const CGHeroInstance * h, const CCreatureSet &creatures, bool remove);
|
||||
void takeCreatures (int objid, std::vector<CStackBasicDescriptor> creatures);
|
||||
bool changeStackType(const StackLocation &sl, CCreature *c);
|
||||
bool changeStackCount(const StackLocation &sl, TQuantity count, bool absoluteValue = false);
|
||||
bool insertNewStack(const StackLocation &sl, const CCreature *c, TQuantity count);
|
||||
bool eraseStack(const StackLocation &sl, bool forceRemoval = false);
|
||||
bool swapStacks(const StackLocation &sl1, const StackLocation &sl2);
|
||||
bool addToSlot(const StackLocation &sl, const CCreature *c, TQuantity count);
|
||||
void tryJoiningArmy(const CArmedInstance *src, const CArmedInstance *dst, bool removeObjWhenFinished, bool allowMerging);
|
||||
bool moveStack(const StackLocation &src, const StackLocation &dst, TQuantity count = -1);
|
||||
void showCompInfo(ShowInInfobox * comp);
|
||||
void heroVisitCastle(int obj, int heroID);
|
||||
void vistiCastleObjects (const CGTownInstance *t, const CGHeroInstance *h);
|
||||
void stopHeroVisitCastle(int obj, int heroID);
|
||||
void giveHeroArtifact(int artid, int hid, int position); //pos==-1 - first free slot in backpack; pos==-2 - default if available or backpack
|
||||
void giveNewArtifact(int hid, int position);
|
||||
bool removeArtifact(const CArtifact* art, int hid);
|
||||
void startBattleI(const CArmedInstance *army1, const CArmedInstance *army2, int3 tile, const CGHeroInstance *hero1, const CGHeroInstance *hero2, bool creatureBank = false, boost::function<void(BattleResult*)> cb = 0, const CGTownInstance *town = NULL); //use hero=NULL for no hero
|
||||
void startBattleI(const CArmedInstance *army1, const CArmedInstance *army2, int3 tile, boost::function<void(BattleResult*)> cb = 0, bool creatureBank = false); //if any of armies is hero, hero will be used
|
||||
void startBattleI(const CArmedInstance *army1, const CArmedInstance *army2, boost::function<void(BattleResult*)> cb = 0, bool creatureBank = false); //if any of armies is hero, hero will be used, visitable tile of second obj is place of battle//void startBattleI(int heroID, CCreatureSet army, int3 tile, boost::function<void(BattleResult*)> cb); //for hero<=>neutral army
|
||||
void setAmount(int objid, ui32 val);
|
||||
bool teleportHero(si32 hid, si32 dstid, ui8 source, ui8 asker = 255);
|
||||
bool moveHero(si32 hid, int3 dst, ui8 instant, ui8 asker = 255);
|
||||
void changeSpells(int hid, bool give, const std::set<ui32> &spells) OVERRIDE;
|
||||
bool removeObject(int objid) OVERRIDE;
|
||||
void setBlockVis(int objid, bool bv) OVERRIDE;
|
||||
void setOwner(int objid, ui8 owner) OVERRIDE;
|
||||
void setHoverName(int objid, MetaString * name) OVERRIDE;
|
||||
void setObjProperty(int objid, int prop, si64 val) OVERRIDE;
|
||||
void changePrimSkill(int ID, int which, si64 val, bool abs=false) OVERRIDE;
|
||||
void changeSecSkill(int ID, int which, int val, bool abs=false) OVERRIDE;
|
||||
void showInfoDialog(InfoWindow *iw) OVERRIDE;
|
||||
void showBlockingDialog(BlockingDialog *iw, const CFunctionList<void(ui32)> &callback) OVERRIDE;
|
||||
ui32 showBlockingDialog(BlockingDialog *iw) OVERRIDE; //synchronous version of above
|
||||
void showGarrisonDialog(int upobj, int hid, bool removableUnits, const boost::function<void()> &cb) OVERRIDE;
|
||||
void showThievesGuildWindow(int requestingObjId) OVERRIDE; //TODO: make something more general?
|
||||
void giveResource(int player, int which, int val) OVERRIDE;
|
||||
|
||||
void giveCreatures (const CArmedInstance *objid, const CGHeroInstance * h, const CCreatureSet &creatures, bool remove) OVERRIDE;
|
||||
void takeCreatures (int objid, std::vector<CStackBasicDescriptor> creatures) OVERRIDE;
|
||||
bool changeStackType(const StackLocation &sl, CCreature *c) OVERRIDE;
|
||||
bool changeStackCount(const StackLocation &sl, TQuantity count, bool absoluteValue = false) OVERRIDE;
|
||||
bool insertNewStack(const StackLocation &sl, const CCreature *c, TQuantity count) OVERRIDE;
|
||||
bool eraseStack(const StackLocation &sl, bool forceRemoval = false) OVERRIDE;
|
||||
bool swapStacks(const StackLocation &sl1, const StackLocation &sl2) OVERRIDE;
|
||||
bool addToSlot(const StackLocation &sl, const CCreature *c, TQuantity count) OVERRIDE;
|
||||
void tryJoiningArmy(const CArmedInstance *src, const CArmedInstance *dst, bool removeObjWhenFinished, bool allowMerging) OVERRIDE;
|
||||
bool moveStack(const StackLocation &src, const StackLocation &dst, TQuantity count = -1) OVERRIDE;
|
||||
|
||||
void giveHeroNewArtifact(const CGHeroInstance *h, const CArtifact *artType, int pos) OVERRIDE;
|
||||
void giveHeroArtifact(const CGHeroInstance *h, const CArtifactInstance *a, int pos) OVERRIDE;
|
||||
void putArtifact(const ArtifactLocation &al, const CArtifactInstance *a) OVERRIDE;
|
||||
void removeArtifact(const ArtifactLocation &al) OVERRIDE;
|
||||
void moveArtifact(const ArtifactLocation &al1, const ArtifactLocation &al2) OVERRIDE;
|
||||
|
||||
void showCompInfo(ShowInInfobox * comp) OVERRIDE;
|
||||
void heroVisitCastle(int obj, int heroID) OVERRIDE;
|
||||
void stopHeroVisitCastle(int obj, int heroID) OVERRIDE;
|
||||
bool removeArtifact(const CArtifact* art, int hid) OVERRIDE;
|
||||
void startBattleI(const CArmedInstance *army1, const CArmedInstance *army2, int3 tile, const CGHeroInstance *hero1, const CGHeroInstance *hero2, bool creatureBank = false, boost::function<void(BattleResult*)> cb = 0, const CGTownInstance *town = NULL) OVERRIDE; //use hero=NULL for no hero
|
||||
void startBattleI(const CArmedInstance *army1, const CArmedInstance *army2, int3 tile, boost::function<void(BattleResult*)> cb = 0, bool creatureBank = false) OVERRIDE; //if any of armies is hero, hero will be used
|
||||
void startBattleI(const CArmedInstance *army1, const CArmedInstance *army2, boost::function<void(BattleResult*)> cb = 0, bool creatureBank = false) OVERRIDE; //if any of armies is hero, hero will be used, visitable tile of second obj is place of battle//void startBattleI(int heroID, CCreatureSet army, int3 tile, boost::function<void(BattleResult*)> cb) OVERRIDE; //for hero<=>neutral army
|
||||
void setAmount(int objid, ui32 val) OVERRIDE;
|
||||
bool moveHero(si32 hid, int3 dst, ui8 instant, ui8 asker = 255) OVERRIDE;
|
||||
void giveHeroBonus(GiveBonus * bonus) OVERRIDE;
|
||||
void setMovePoints(SetMovePoints * smp) OVERRIDE;
|
||||
void setManaPoints(int hid, int val) OVERRIDE;
|
||||
void giveHero(int id, int player) OVERRIDE;
|
||||
void changeObjPos(int objid, int3 newPos, ui8 flags) OVERRIDE;
|
||||
void heroExchange(si32 hero1, si32 hero2) OVERRIDE;
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void useScholarSkill(si32 hero1, si32 hero2);
|
||||
void setPortalDwelling(const CGTownInstance * town, bool forced, bool clear);
|
||||
bool tryAttackingGuard(const int3 &guardPos, const CGHeroInstance * h);
|
||||
void visitObjectOnTile(const TerrainTile &t, const CGHeroInstance * h);
|
||||
void giveHeroBonus(GiveBonus * bonus);
|
||||
void setMovePoints(SetMovePoints * smp);
|
||||
void setManaPoints(int hid, int val);
|
||||
void giveHero(int id, int player);
|
||||
void changeObjPos(int objid, int3 newPos, ui8 flags);
|
||||
void useScholarSkill(si32 hero1, si32 hero2);
|
||||
void heroExchange(si32 hero1, si32 hero2);
|
||||
void setPortalDwelling(const CGTownInstance * town, bool forced, bool clear);
|
||||
bool teleportHero(si32 hid, si32 dstid, ui8 source, ui8 asker = 255);
|
||||
void vistiCastleObjects (const CGTownInstance *t, const CGHeroInstance *h);
|
||||
void levelUpHero(int ID, int skill);//handle client respond and send one more request if needed
|
||||
void levelUpHero(int ID);//initial call - check if hero have remaining levelups & handle them
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void init(StartInfo *si, int Seed);
|
||||
|
@ -22,3 +22,4 @@
|
||||
#include <boost/asio.hpp>
|
||||
#include <boost/thread.hpp>
|
||||
#include <boost/foreach.hpp>
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user