mirror of
https://github.com/vcmi/vcmi.git
synced 2025-01-12 02:28:11 +02:00
Partial support for customizable artifacts and Spell Scroll. Still doesn't work, though.
This commit is contained in:
parent
0f314e106c
commit
b75cf89f86
@ -319,7 +319,7 @@ void CClient::newGame( CConnection *con, StartInfo *si )
|
||||
CGI->state = new CGameState();
|
||||
tlog0 <<"\tGamestate: "<<tmh.getDif()<<std::endl;
|
||||
serv = con;
|
||||
CConnection &c(*con);
|
||||
CConnection &c(*con);
|
||||
////////////////////////////////////////////////////
|
||||
ui8 pom8;
|
||||
c << ui8(2) << ui8(1); //new game; one client
|
||||
|
@ -113,6 +113,7 @@ public:
|
||||
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 giveCustomArtifact(int artid, int hid, int position, int value){};
|
||||
bool removeArtifact(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
|
||||
|
@ -10,6 +10,7 @@
|
||||
#include <boost/lexical_cast.hpp>
|
||||
#include <boost/foreach.hpp>
|
||||
#include <boost/random/linear_congruential.hpp>
|
||||
#include <boost/algorithm/string/replace.hpp>
|
||||
#include "../lib/VCMI_Lib.h"
|
||||
extern CLodHandler *bitmaph;
|
||||
using namespace boost::assign;
|
||||
@ -182,7 +183,8 @@ void CArtifact::getParents(TCNodes &out, const CBonusSystemNode *root /*= NULL*/
|
||||
|
||||
void CScroll::Init()
|
||||
{
|
||||
bonuses.push_back (Bonus (Bonus::PERMANENT, Bonus::SPELL,0, id, spellid, Bonus::INDEPENDENT_MAX));
|
||||
bonuses.push_back (Bonus (Bonus::PERMANENT, Bonus::SPELL, Bonus::ARTIFACT, 0, id, spellid, Bonus::INDEPENDENT_MAX));
|
||||
//boost::algorithm::replace_first(description, "[spell name]", VLC->spellh->spells[spellid].name);
|
||||
}
|
||||
|
||||
CArtHandler::CArtHandler()
|
||||
@ -192,6 +194,7 @@ CArtHandler::CArtHandler()
|
||||
// War machines are the default big artifacts.
|
||||
for (ui32 i = 3; i <= 6; i++)
|
||||
bigArtifacts.insert(i);
|
||||
modableArtifacts = boost::assign::map_list_of(1, 1)(146,3)(147,3)(148,3)(150,3)(151,3)(152,3)(154,3)(156,2);
|
||||
}
|
||||
|
||||
CArtHandler::~CArtHandler()
|
||||
@ -217,9 +220,28 @@ void CArtHandler::loadArtifacts(bool onlyTxt)
|
||||
}
|
||||
VLC->generaltexth->artifNames.resize(ARTIFACTS_QUANTITY);
|
||||
VLC->generaltexth->artifDescriptions.resize(ARTIFACTS_QUANTITY);
|
||||
std::map<ui32,ui8>::iterator itr;
|
||||
for (int i=0; i<ARTIFACTS_QUANTITY; i++)
|
||||
{
|
||||
CArtifact *art = new CArtifact;
|
||||
CArtifact *art;
|
||||
if ((itr = modableArtifacts.find(i)) != modableArtifacts.end())
|
||||
{
|
||||
switch (itr->second)
|
||||
{
|
||||
case 1:
|
||||
art = new CScroll;
|
||||
break;
|
||||
case 2:
|
||||
art = new CCustomizableArt;
|
||||
break;
|
||||
case 3:
|
||||
art = new CCommanderArt;
|
||||
break;
|
||||
};
|
||||
}
|
||||
else
|
||||
art = new CArtifact;
|
||||
|
||||
CArtifact &nart = *art;
|
||||
nart.id=i;
|
||||
loadToIt(VLC->generaltexth->artifNames[i],buf,it,4);
|
||||
|
@ -21,6 +21,7 @@ class CArtifact;
|
||||
|
||||
class DLL_EXPORT CArtifact : public CBonusSystemNode //container for artifacts
|
||||
{
|
||||
protected:
|
||||
std::string name, description; //set if custom
|
||||
public:
|
||||
enum EartClass {ART_SPECIAL=1, ART_TREASURE=2, ART_MINOR=4, ART_MAJOR=8, ART_RELIC=16}; //artifact classes
|
||||
@ -32,6 +33,8 @@ public:
|
||||
bool canBeAssembledTo (const std::map<ui16, CArtifact*> &artifWorn, ui32 artifactID) const;
|
||||
void addBonusesTo (BonusList *otherBonuses) const;
|
||||
void removeBonusesFrom (BonusList *otherBonuses) const;
|
||||
virtual void SetProperty (int mod){};
|
||||
virtual void Init(){};
|
||||
int getArtClassSerial() const; //0 - treasure, 1 - minor, 2 - major, 3 - relic, 4 - spell scroll, 5 - other
|
||||
|
||||
ui32 price;
|
||||
@ -54,47 +57,58 @@ public:
|
||||
void getParents(TCNodes &out, const CBonusSystemNode *root = NULL) const;
|
||||
};
|
||||
|
||||
class DLL_EXPORT IModableArt //artifact which can have different properties, such as scroll or banner
|
||||
{
|
||||
class DLL_EXPORT IModableArt : public CArtifact //artifact which can have different properties, such as scroll or banner
|
||||
{ //used only for dynamic cast :P
|
||||
public:
|
||||
virtual void Init() = 0;
|
||||
};
|
||||
si32 ID; //used for smart serialization
|
||||
|
||||
class DLL_EXPORT CScroll : public CArtifact, public IModableArt // Spell Scroll
|
||||
{
|
||||
public:
|
||||
CScroll(spelltype sid){spellid = sid;};
|
||||
spelltype spellid;
|
||||
void Init();
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{
|
||||
h & static_cast<CArtifact&>(*this);
|
||||
h & ID;
|
||||
}
|
||||
};
|
||||
|
||||
class DLL_EXPORT CScroll : public IModableArt // Spell Scroll
|
||||
{
|
||||
public:
|
||||
CScroll(){spellid=0;};
|
||||
CScroll(spelltype sid){spellid = sid;};
|
||||
spelltype spellid;
|
||||
void Init();
|
||||
void SetProperty (int mod){spellid = mod;};
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{
|
||||
h & static_cast<IModableArt&>(*this);
|
||||
h & spellid;
|
||||
}
|
||||
};
|
||||
|
||||
class DLL_EXPORT CCustomizableArt : public CArtifact, public IModableArt // Warlord's Banner with multiple options
|
||||
class DLL_EXPORT CCustomizableArt : public IModableArt // Warlord's Banner with multiple options
|
||||
{
|
||||
public:
|
||||
ui8 mode;
|
||||
CCustomizableArt(){mode=0;};
|
||||
void Init(){};
|
||||
void SelectMode (int mod){};
|
||||
void SetProperty (int mod){};
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{
|
||||
h & static_cast<CArtifact&>(*this);
|
||||
h & static_cast<IModableArt&>(*this);
|
||||
h & mode;
|
||||
}
|
||||
};
|
||||
|
||||
class DLL_EXPORT CCommanderArt : public CArtifact, public IModableArt // Growing with time
|
||||
class DLL_EXPORT CCommanderArt : public IModableArt // Growing with time
|
||||
{
|
||||
public:
|
||||
ui32 level;
|
||||
CCommanderArt(){level = 0;};
|
||||
void Init(){};
|
||||
void SetProperty (int mod){level = mod;};
|
||||
void Upgrade(){level++;};
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{
|
||||
h & static_cast<CArtifact&>(*this);
|
||||
h & static_cast<IModableArt&>(*this);
|
||||
h & level;
|
||||
}
|
||||
};
|
||||
@ -107,6 +121,7 @@ public:
|
||||
std::vector<CArtifact *> artifacts;
|
||||
std::vector<CArtifact *> allowedArtifacts;
|
||||
std::set<ui32> bigArtifacts; // Artifacts that cannot be moved to backpack, e.g. war machines.
|
||||
std::map<ui32, ui8> modableArtifacts; //1-scroll, 2-banner, 3-commander art with progressive bonus
|
||||
|
||||
void loadArtifacts(bool onlyTxt);
|
||||
void sortArts();
|
||||
|
@ -3591,24 +3591,36 @@ void CGArtifact::initObj()
|
||||
blockVisit = true;
|
||||
if(ID == 5)
|
||||
hoverName = VLC->arth->artifacts[subID]->Name();
|
||||
if(ID == 93)
|
||||
subID = 1;
|
||||
}
|
||||
|
||||
void CGArtifact::onHeroVisit( const CGHeroInstance * h ) const
|
||||
{
|
||||
if(!stacksCount())
|
||||
{
|
||||
if(ID == 5)
|
||||
InfoWindow iw;
|
||||
iw.soundID = soundBase::treasure;
|
||||
iw.player = h->tempOwner;
|
||||
switch(ID)
|
||||
{
|
||||
InfoWindow iw;
|
||||
iw.soundID = soundBase::treasure;
|
||||
iw.player = h->tempOwner;
|
||||
iw.components.push_back(Component(4,subID,0,0));
|
||||
if(message.length())
|
||||
iw.text << message;
|
||||
else
|
||||
iw.text << std::pair<ui8,ui32>(12,subID);
|
||||
cb->showInfoDialog(&iw);
|
||||
case 5:
|
||||
{
|
||||
iw.components.push_back(Component(4,subID,0,0));
|
||||
if(message.length())
|
||||
iw.text << message;
|
||||
else
|
||||
iw.text << std::pair<ui8,ui32>(12,subID);
|
||||
}
|
||||
break;
|
||||
case 93:
|
||||
iw.components.push_back (Component(Component::SPELL, spell,0,0));
|
||||
iw.text.addTxt (MetaString::ADVOB_TXT,135);
|
||||
iw.text.addReplacement(MetaString::SPELL_NAME, spell);
|
||||
break;
|
||||
|
||||
}
|
||||
cb->showInfoDialog(&iw);
|
||||
pick(h);
|
||||
}
|
||||
else
|
||||
@ -3629,15 +3641,22 @@ void CGArtifact::onHeroVisit( const CGHeroInstance * h ) const
|
||||
|
||||
void CGArtifact::pick(const CGHeroInstance * h) const
|
||||
{
|
||||
if(ID == 5) //Artifact
|
||||
{
|
||||
if (VLC->arth->artifacts[subID]->isModable()) //TODO: create new instance, initialize it
|
||||
{}
|
||||
cb->giveHeroArtifact(subID,h->id,-2);
|
||||
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 if(ID == 93) // Spell scroll
|
||||
else
|
||||
{
|
||||
//TODO: support for the spell scroll
|
||||
cb->giveHeroArtifact(subID,h->id,-2);
|
||||
}
|
||||
cb->removeObject(id);
|
||||
}
|
||||
|
@ -47,6 +47,7 @@ struct InfoWindow;
|
||||
struct Component;
|
||||
struct BankConfig;
|
||||
struct UpdateHeroSpeciality;
|
||||
struct NewArtifact;
|
||||
class CGBoat;
|
||||
|
||||
class DLL_EXPORT CQuest
|
||||
|
@ -61,6 +61,7 @@ struct TerrainTile;
|
||||
class CHeroClass;
|
||||
class CCampaign;
|
||||
class CCampaignState;
|
||||
class IModableArt;
|
||||
|
||||
namespace boost
|
||||
{
|
||||
@ -142,7 +143,8 @@ public:
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{
|
||||
h & color & human & currentSelection & team & resources & status;
|
||||
h & heroes & towns & availableHeroes & dwellings & bonuses & status & daysWithoutCastle;
|
||||
h & heroes & towns & availableHeroes & dwellings & bonuses;
|
||||
h & status & daysWithoutCastle;
|
||||
h & enteredLosingCheatCode & enteredWinningCheatCode;
|
||||
h & static_cast<CBonusSystemNode&>(*this);
|
||||
}
|
||||
|
@ -385,8 +385,9 @@ CSerializer::CSerializer()
|
||||
void CSerializer::addStdVecItems(CGameState *gs, LibClasses *lib)
|
||||
{
|
||||
registerVectoredType(&gs->map->objects, &CGObjectInstance::id);
|
||||
registerVectoredType(&lib->heroh->heroes, &CHero::ID);
|
||||
registerVectoredType(&lib->creh->creatures, &CCreature::idNumber);
|
||||
registerVectoredType(&lib->arth->artifacts, &CArtifact::id);
|
||||
registerVectoredType(&lib->heroh->heroes, &CHero::ID);
|
||||
registerVectoredType(&gs->map->artInstances, &IModableArt::ID);
|
||||
smartVectorMembersSerialization = true;
|
||||
}
|
||||
|
@ -93,6 +93,7 @@ public:
|
||||
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 bool removeArtifact(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
|
||||
|
@ -694,6 +694,21 @@ struct SetAvailableArtifacts : public CPackForClient //519
|
||||
}
|
||||
};
|
||||
|
||||
struct NewArtifact : public CPackForClient
|
||||
{
|
||||
NewArtifact(){type = 520;};
|
||||
//void applyCl(CClient *cl);
|
||||
DLL_EXPORT void applyGs(CGameState *gs);
|
||||
|
||||
si32 artid;
|
||||
si32 value; //initializing parameter
|
||||
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{
|
||||
h & artid & value;
|
||||
}
|
||||
};
|
||||
|
||||
struct NewTurn : public CPackForClient //101
|
||||
{
|
||||
enum weekType {NORMAL, DOUBLE_GROWTH, BONUS_GROWTH, DEITYOFFIRE, PLAGUE, CUSTOM, NO_ACTION, NONE};
|
||||
|
@ -455,9 +455,11 @@ DLL_EXPORT void SetHeroArtifacts::applyGs( CGameState *gs )
|
||||
if(!vstd::contains(artifWorn,i->first) || artifWorn[i->first] != i->second)
|
||||
unequiped.push_back(i->second);
|
||||
|
||||
for(std::map<ui16,CArtifact*>::const_iterator i = artifWorn.begin(); i != artifWorn.end(); i++)
|
||||
for(std::map<ui16,CArtifact*>::iterator i = artifWorn.begin(); i != artifWorn.end(); i++)
|
||||
if(!vstd::contains(h->artifWorn,i->first) || h->artifWorn[i->first] != i->second)
|
||||
{
|
||||
equiped.push_back(i->second);
|
||||
}
|
||||
|
||||
//update hero data
|
||||
h->artifacts = artifacts;
|
||||
@ -584,6 +586,31 @@ DLL_EXPORT void NewObject::applyGs( CGameState *gs )
|
||||
o->initObj();
|
||||
assert(o->defInfo);
|
||||
}
|
||||
DLL_EXPORT void NewArtifact::applyGs( CGameState *gs )
|
||||
{
|
||||
CArtifact * 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 = *(VLC->arth->artifacts[artid]); //copy properties
|
||||
static_cast<IModableArt*>(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(static_cast<IModableArt*>(art));
|
||||
}
|
||||
|
||||
DLL_EXPORT void SetAvailableArtifacts::applyGs( CGameState *gs )
|
||||
{
|
||||
@ -630,11 +657,6 @@ DLL_EXPORT void NewTurn::applyGs( CGameState *gs )
|
||||
BOOST_FOREACH(CGHeroInstance *h, gs->map->heroes)
|
||||
h->bonuses.remove_if(Bonus::OneDay);
|
||||
|
||||
if(resetBuilded) //reset amount of structures set in this turn in towns
|
||||
{
|
||||
BOOST_FOREACH(CGTownInstance* t, gs->map->towns)
|
||||
t->builded = 0;
|
||||
}
|
||||
if(gs->getDate(1)) //new week, Monday that is
|
||||
{
|
||||
for( std::map<ui8, PlayerState>::iterator i=gs->players.begin() ; i!=gs->players.end();i++)
|
||||
@ -690,6 +712,11 @@ DLL_EXPORT void NewTurn::applyGs( CGameState *gs )
|
||||
|
||||
i->second.bonuses.remove_if(Bonus::OneDay);
|
||||
}
|
||||
if(resetBuilded) //reset amount of structures set in this turn in towns
|
||||
{
|
||||
BOOST_FOREACH(CGTownInstance* t, gs->map->towns)
|
||||
t->builded = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -137,6 +137,7 @@ void registerTypes2(Serializer &s)
|
||||
s.template registerType<AdvmapSpellCast>();
|
||||
s.template registerType<OpenWindow>();
|
||||
s.template registerType<NewObject>();
|
||||
s.template registerType<NewArtifact>();
|
||||
s.template registerType<SetAvailableArtifacts>();
|
||||
|
||||
s.template registerType<SaveGame>();
|
||||
|
@ -30,7 +30,7 @@ class CGHeroInstance;
|
||||
class CGCreature;
|
||||
class CQuest;
|
||||
class CGTownInstance;
|
||||
|
||||
class IModableArt;
|
||||
|
||||
|
||||
struct DLL_EXPORT TerrainTile
|
||||
@ -254,6 +254,7 @@ struct DLL_EXPORT Mapa : public CMapHeader
|
||||
std::vector<CGObjectInstance*> objects;
|
||||
std::vector<CGHeroInstance*> heroes;
|
||||
std::vector<CGTownInstance*> towns;
|
||||
std::vector<IModableArt *> artInstances; //stores single scrolls
|
||||
std::map<ui16, CGCreature*> monsters;
|
||||
std::map<ui16, CGHeroInstance*> heroesToBeat;
|
||||
|
||||
@ -288,7 +289,7 @@ struct DLL_EXPORT Mapa : public CMapHeader
|
||||
{
|
||||
h & static_cast<CMapHeader&>(*this);
|
||||
h & rumors & allowedSpell & allowedAbilities & allowedArtifact & allowedHeroes & events & grailPos;
|
||||
h & monsters & heroesToBeat; //hoprfully serialization is now automagical?
|
||||
h & monsters & heroesToBeat & artInstances; //hoprfully serialization is now automagical?
|
||||
|
||||
//TODO: viccondetails
|
||||
if(h.saving)
|
||||
|
@ -1211,6 +1211,7 @@ void CGameHandler::newTurn()
|
||||
NewTurn n2; //just to handle creature growths after bonuses are applied
|
||||
n2.specialWeek = NewTurn::NO_ACTION;
|
||||
n2.day = gs->day;
|
||||
n2.resetBuilded = true;
|
||||
|
||||
for(std::vector<CGTownInstance *>::iterator j = gs->map->towns.begin(); j!=gs->map->towns.end(); j++)//handle towns
|
||||
{
|
||||
@ -2264,6 +2265,52 @@ void CGameHandler::giveHeroArtifact(int artid, int hid, int position) //pos==-1
|
||||
|
||||
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(CArtifact* art, int hid)
|
||||
{
|
||||
const CGHeroInstance* h = getHero(hid);
|
||||
|
@ -143,6 +143,7 @@ public:
|
||||
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);
|
||||
void moveArtifact(int hid, int oldPosition, int destPos);
|
||||
bool removeArtifact(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
|
||||
|
Loading…
Reference in New Issue
Block a user