1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-07-17 01:32:21 +02:00

* restored objects functionalities (hopefully working)

* new file in vcmi lib: IGameCallback.cpp
This commit is contained in:
Michał W. Urbańczyk
2008-12-27 01:01:59 +00:00
parent d0d60175d7
commit 4a8ae4ed9a
19 changed files with 2316 additions and 2103 deletions

View File

@ -1,177 +1,176 @@
#ifndef __CADVMAPINTERFACE_H__ #ifndef __CADVMAPINTERFACE_H__
#define __CADVMAPINTERFACE_H__ #define __CADVMAPINTERFACE_H__
#include <typeinfo> #include <typeinfo>
#include "global.h" #include "global.h"
#include "SDL.h" #include "SDL.h"
#include "CPlayerInterface.h" #include "CPlayerInterface.h"
#include <map> #include <map>
#include "AdventureMapButton.h" #include "AdventureMapButton.h"
class CDefHandler; class CDefHandler;
class CCallback; class CCallback;
struct CPath; struct CPath;
class CAdvMapInt; class CAdvMapInt;
class CGHeroInstance; class CGHeroInstance;
class CGTownInstance; class CGTownInstance;
class CHeroWindow; class CHeroWindow;
/*****************************/ /*****************************/
class CMinimap class CMinimap
: public ClickableL, public ClickableR, public Hoverable, public MotionInterested, public virtual CIntObject : public ClickableL, public ClickableR, public Hoverable, public MotionInterested, public virtual CIntObject
{ {
public: public:
SDL_Surface * radar; SDL_Surface * radar;
SDL_Surface * temps; SDL_Surface * temps;
std::map<int,SDL_Color> colors; std::map<int,SDL_Color> colors;
std::map<int,SDL_Color> colorsBlocked; std::map<int,SDL_Color> colorsBlocked;
std::vector<SDL_Surface *> map, FoW; //one bitmap for each level (terrain, Fog of War) std::vector<SDL_Surface *> map, FoW; //one bitmap for each level (terrain, Fog of War)
//TODO flagged buildings std::string statusbarTxt, rcText;
std::string statusbarTxt, rcText;
CMinimap(bool draw=true);
CMinimap(bool draw=true); void draw();
void draw(); void redraw(int level=-1);// (level==-1) => redraw all levels
void redraw(int level=-1);// (level==-1) => redraw all levels void updateRadar();
void updateRadar();
void clickRight (tribool down);
void clickRight (tribool down); void clickLeft (tribool down);
void clickLeft (tribool down); void hover (bool on);
void hover (bool on); void mouseMoved (const SDL_MouseMotionEvent & sEvent);
void mouseMoved (const SDL_MouseMotionEvent & sEvent); void activate(); // makes button active
void activate(); // makes button active void deactivate(); // makes button inactive (but don't deletes)
void deactivate(); // makes button inactive (but don't deletes) void hideTile(const int3 &pos); //puts FoW
void hideTile(const int3 &pos); //puts FoW void showTile(const int3 &pos); //removes FoW
void showTile(const int3 &pos); //removes FoW };
}; class CTerrainRect
class CTerrainRect : public ClickableL, public ClickableR, public Hoverable, public MotionInterested
: public ClickableL, public ClickableR, public Hoverable, public MotionInterested {
{ public:
public: int tilesw, tilesh; //width and height of terrain to blit in tiles
int tilesw, tilesh; //width and height of terrain to blit in tiles int3 curHoveredTile;
int3 curHoveredTile; int moveX, moveY; //shift between actual position of screen and the one we wil blit; ranges from -31 to 31 (in pixels)
int moveX, moveY; //shift between actual position of screen and the one we wil blit; ranges from -31 to 31 (in pixels)
CDefHandler * arrows;
CDefHandler * arrows; CTerrainRect();
CTerrainRect(); CPath * currentPath;
CPath * currentPath; void activate();
void activate(); void deactivate();
void deactivate(); void clickLeft(tribool down);
void clickLeft(tribool down); void clickRight(tribool down);
void clickRight(tribool down); void hover(bool on);
void hover(bool on); void mouseMoved (const SDL_MouseMotionEvent & sEvent);
void mouseMoved (const SDL_MouseMotionEvent & sEvent); void show();
void show(); void showPath();
void showPath(); int3 whichTileIsIt(const int & x, const int & y); //x,y are cursor position
int3 whichTileIsIt(const int & x, const int & y); //x,y are cursor position int3 whichTileIsIt(); //uses current cursor pos
int3 whichTileIsIt(); //uses current cursor pos };
}; class CResDataBar
class CResDataBar :public ClickableR, public virtual CIntObject
:public ClickableR, public virtual CIntObject {
{ public:
public: SDL_Surface * bg;
SDL_Surface * bg; std::vector<std::pair<int,int> > txtpos;
std::vector<std::pair<int,int> > txtpos; std::string datetext;
std::string datetext;
void clickRight (tribool down);
void clickRight (tribool down); void activate();
void activate(); void deactivate();
void deactivate(); CResDataBar();
CResDataBar(); CResDataBar(const std::string &defname, int x, int y, int offx, int offy, int resdist, int datedist);
CResDataBar(const std::string &defname, int x, int y, int offx, int offy, int resdist, int datedist); ~CResDataBar();
~CResDataBar();
void draw();
void draw(); };
}; class CInfoBar
class CInfoBar :public virtual CIntObject, public TimeInterested
:public virtual CIntObject, public TimeInterested {
{ public:
public: CDefHandler *day, *week1, *week2, *week3, *week4;
CDefHandler *day, *week1, *week2, *week3, *week4; SComponent * current;
SComponent * current; int mode;
int mode; int pom;
int pom;
CInfoBar();
CInfoBar(); ~CInfoBar();
~CInfoBar(); void newDay(int Day);
void newDay(int Day); void showComp(SComponent * comp, int time=5000);
void showComp(SComponent * comp, int time=5000); void tick();
void tick(); void draw(const CGObjectInstance * specific=NULL); // if specific==0 function draws info about selected hero/town
void draw(const CGObjectInstance * specific=NULL); // if specific==0 function draws info about selected hero/town void blitAnim(int mode);//0 - day, 1 - week
void blitAnim(int mode);//0 - day, 1 - week CDefHandler * getAnim(int mode);
CDefHandler * getAnim(int mode); };
}; /*****************************/
/*****************************/ class CAdvMapInt : public CMainInterface, public KeyInterested //adventure map interface
class CAdvMapInt : public CMainInterface, public KeyInterested //adventure map interface {
{ public:
public: CAdvMapInt(int Player);
CAdvMapInt(int Player); ~CAdvMapInt();
~CAdvMapInt();
int3 position; //top left corner of visible map part
int3 position; //top left corner of visible map part int player;
int player;
std::vector<CDefHandler *> gems;
std::vector<CDefHandler *> gems;
bool scrollingLeft ;
bool scrollingLeft ; bool scrollingRight ;
bool scrollingRight ; bool scrollingUp ;
bool scrollingUp ; bool scrollingDown ;
bool scrollingDown ; bool updateScreen, updateMinimap ;
bool updateScreen, updateMinimap ; unsigned char anim, animValHitCount; //animation frame
unsigned char anim, animValHitCount; //animation frame unsigned char heroAnim, heroAnimValHitCount; //animation frame
unsigned char heroAnim, heroAnimValHitCount; //animation frame
CMinimap minimap;
CMinimap minimap;
SDL_Surface * bg;
SDL_Surface * bg; AdventureMapButton kingOverview,//- kingdom overview
AdventureMapButton kingOverview,//- kingdom overview underground,//- underground switch
underground,//- underground switch questlog,//- questlog
questlog,//- questlog sleepWake, //- sleep/wake hero
sleepWake, //- sleep/wake hero moveHero, //- move hero
moveHero, //- move hero spellbook,//- spellbook
spellbook,//- spellbook advOptions, //- adventure options
advOptions, //- adventure options sysOptions,//- system options
sysOptions,//- system options nextHero, //- next hero
nextHero, //- next hero endTurn;//- end turn
endTurn;//- end turn //CHeroList herolist;
//CHeroList herolist;
CTerrainRect terrain; //visible terrain
CTerrainRect terrain; //visible terrain
CStatusBar statusbar;
CStatusBar statusbar; CResDataBar resdatabar;
CResDataBar resdatabar;
CHeroList heroList;
CHeroList heroList; CTownList townList;
CTownList townList; CInfoBar infoBar;
CInfoBar infoBar;
CHeroWindow * heroWindow;
CHeroWindow * heroWindow;
const CArmedInstance *selection;
const CArmedInstance *selection;
//fuctions binded to buttons
//fuctions binded to buttons void fshowOverview();
void fshowOverview(); void fswitchLevel();
void fswitchLevel(); void fshowQuestlog();
void fshowQuestlog(); void fsleepWake();
void fsleepWake(); void fmoveHero();
void fmoveHero(); void fshowSpellbok();
void fshowSpellbok(); void fadventureOPtions();
void fadventureOPtions(); void fsystemOptions();
void fsystemOptions(); void fnextHero();
void fnextHero(); void fendTurn();
void fendTurn();
void activate();
void activate(); void deactivate();
void deactivate();
void show(SDL_Surface * to=NULL); //shows and activates adv. map interface
void show(SDL_Surface * to=NULL); //shows and activates adv. map interface void hide(); //deactivates advmap interface
void hide(); //deactivates advmap interface void update(); //redraws terrain
void update(); //redraws terrain
void select(const CArmedInstance *sel);
void select(const CArmedInstance *sel); void selectionChanged();
void selectionChanged(); void centerOn(int3 on);
void centerOn(int3 on); int3 verifyPos(int3 ver);
int3 verifyPos(int3 ver); void handleRightClick(std::string text, tribool down, CIntObject * client);
void handleRightClick(std::string text, tribool down, CIntObject * client); void keyPressed(const SDL_KeyboardEvent & key);
void keyPressed(const SDL_KeyboardEvent & key);
};
}; #endif // __CADVMAPINTERFACE_H__
#endif // __CADVMAPINTERFACE_H__

View File

@ -648,7 +648,10 @@ void CCallback::setFormation(const CGHeroInstance * hero, bool tight)
void CCallback::setSelection(const CArmedInstance * obj) void CCallback::setSelection(const CArmedInstance * obj)
{ {
*cl->serv << ui16(514) << obj->id; SetSelection ss;
ss.player = player;
ss.id = obj->id;
*cl->serv << ui16(514) << ss;
} }
void CCallback::recruitHero(const CGTownInstance *town, const CGHeroInstance *hero) void CCallback::recruitHero(const CGTownInstance *town, const CGHeroInstance *hero)

View File

@ -6,6 +6,7 @@
#include <boost/random/linear_congruential.hpp> #include <boost/random/linear_congruential.hpp>
#include "hch/CDefObjInfoHandler.h" #include "hch/CDefObjInfoHandler.h"
#include "hch/CArtHandler.h" #include "hch/CArtHandler.h"
#include "hch/CGeneralTextHandler.h"
#include "hch/CTownHandler.h" #include "hch/CTownHandler.h"
#include "hch/CSpellHandler.h" #include "hch/CSpellHandler.h"
#include "hch/CHeroHandler.h" #include "hch/CHeroHandler.h"
@ -28,6 +29,79 @@ boost::rand48 ran;
#undef max #undef max
#endif #endif
std::string DLL_EXPORT toString(MetaString &ms)
{
std::string ret;
for(size_t i=0;i<ms.message.size();++i)
{
if(ms.message[i]>0)
{
ret += ms.strings[ms.message[i]-1];
}
else
{
std::vector<std::string> *vec;
int type = ms.texts[-ms.message[i]-1].first,
ser = ms.texts[-ms.message[i]-1].second;
if(type == 5)
{
ret += VLC->arth->artifacts[ser].Name();
continue;
}
else if(type == 7)
{
ret += VLC->creh->creatures[ser].namePl;
continue;
}
else if(type == 9)
{
ret += VLC->objh->mines[ser].first;
continue;
}
else if(type == 10)
{
ret += VLC->objh->mines[ser].second;
continue;
}
else
{
switch(type)
{
case 1:
vec = &VLC->generaltexth->allTexts;
break;
case 2:
vec = &VLC->objh->xtrainfo;
break;
case 3:
vec = &VLC->objh->names;
break;
case 4:
vec = &VLC->objh->restypes;
break;
case 6:
vec = &VLC->generaltexth->arraytxt;
break;
case 8:
vec = &VLC->objh->creGens;
break;
case 11:
vec = &VLC->objh->advobtxt;
break;
case 12:
vec = &VLC->generaltexth->artifEvents;
break;
}
ret += (*vec)[ser];
}
}
}
for(size_t i=0; i < ms.replacements.size(); ++i)
{
ret.replace(ret.find("%s"),2,ms.replacements[i]);
}
return ret;
}
CGObjectInstance * createObject(int id, int subid, int3 pos, int owner) CGObjectInstance * createObject(int id, int subid, int3 pos, int owner)
{ {
@ -624,6 +698,12 @@ void CGameState::applyNL(IPack * pack)
h->artifWorn = sha->artifWorn; h->artifWorn = sha->artifWorn;
break; break;
} }
case 514:
{
SetSelection *ss = static_cast<SetSelection*>(pack);
players[ss->player].currentSelection = ss->id;
break;
}
case 515: case 515:
{ {
HeroRecruited *sha = static_cast<HeroRecruited*>(pack); HeroRecruited *sha = static_cast<HeroRecruited*>(pack);
@ -652,23 +732,13 @@ void CGameState::applyNL(IPack * pack)
case 1001://set object property case 1001://set object property
{ {
SetObjectProperty *p = static_cast<SetObjectProperty*>(pack); SetObjectProperty *p = static_cast<SetObjectProperty*>(pack);
if(p->what == 3) //set creatures amount setObjProperty(p);
{ break;
tlog5 << "Setting creatures amount in " << p->id << std::endl; }
static_cast<CGCreature*>(map->objects[p->id])->army.slots[0].second = p->val; case 1002:
break; {
} SetHoverName *shn = static_cast<SetHoverName*>(pack);
ui8 CGObjectInstance::*point; map->objects[shn->id]->hoverName = toString(shn->name);
switch(p->what)
{
case 1:
point = &CGObjectInstance::tempOwner;
break;
case 2:
point = &CGObjectInstance::blockVisit;
break;
}
map->objects[p->id]->*point = p->val;
break; break;
} }
case 2000: case 2000:
@ -1381,6 +1451,9 @@ void CGameState::init(StartInfo * si, Mapa * map, int Seed)
} }
} }
} }
for(int i=0; i<map->objects.size(); i++)
map->objects[i]->initObj();
} }
bool CGameState::battleShootCreatureStack(int ID, int dest) bool CGameState::battleShootCreatureStack(int ID, int dest)
@ -1498,6 +1571,31 @@ void CGameState::loadTownDInfos()
capitols[i] = new CGDefInfo(*VLC->dobjinfo->castles[i]); capitols[i] = new CGDefInfo(*VLC->dobjinfo->castles[i]);
} }
} }
void CGameState::setObjProperty( SetObjectProperty * p )
{
CGObjectInstance *obj = map->objects[p->id];
switch(p->what)
{
case 1:
obj->tempOwner = p->val;
break;
case 2:
obj->blockVisit = p->val;
break;
case 3:
static_cast<CArmedInstance*>(obj)->army.slots[0].second = p->val;
break;
case 4:
static_cast<CGVisitableOPH*>(obj)->visitors.insert(p->val);
break;
case 5:
static_cast<CGVisitableOPW*>(obj)->visited = p->val;
break;
}
}
int BattleInfo::calculateDmg(const CStack* attacker, const CStack* defender, const CGHeroInstance * attackerHero, const CGHeroInstance * defendingHero, bool shooting) int BattleInfo::calculateDmg(const CStack* attacker, const CStack* defender, const CGHeroInstance * attackerHero, const CGHeroInstance * defendingHero, bool shooting)
{ {
int attackerAttackBonus = attacker->creature->attack + (attackerHero ? attackerHero->getPrimSkillLevel(0) : 0); int attackerAttackBonus = attacker->creature->attack + (attackerHero ? attackerHero->getPrimSkillLevel(0) : 0);

View File

@ -1,222 +1,230 @@
#ifndef __CGAMESTATE_H__ #ifndef __CGAMESTATE_H__
#define __CGAMESTATE_H__ #define __CGAMESTATE_H__
#include "global.h" #include "global.h"
#ifndef _MSC_VER #ifndef _MSC_VER
#include "hch/CCreatureHandler.h" #include "hch/CCreatureHandler.h"
#include "lib/VCMI_Lib.h" #include "lib/VCMI_Lib.h"
#endif #endif
#include <set> #include <set>
#include <vector> #include <vector>
#ifdef _WIN32 #ifdef _WIN32
#include <tchar.h> #include <tchar.h>
#else #else
#include "tchar_amigaos4.h" #include "tchar_amigaos4.h"
#endif #endif
class CTown; class CTown;
class CScriptCallback; class CScriptCallback;
class CCallback; class CCallback;
class CLuaCallback; class CLuaCallback;
class CCPPObjectScript; class CCPPObjectScript;
class CCreatureSet; class CCreatureSet;
class CStack; class CStack;
class CGHeroInstance; class CGHeroInstance;
class CGTownInstance; class CGTownInstance;
class CArmedInstance; class CArmedInstance;
class CGDefInfo; class CGDefInfo;
class CObjectScript; class CObjectScript;
class CGObjectInstance; class CGObjectInstance;
class CCreature; class CCreature;
struct Mapa; struct Mapa;
struct StartInfo; struct StartInfo;
struct SDL_Surface; struct SDL_Surface;
class CMapHandler; class CMapHandler;
class CPathfinder; class CPathfinder;
struct IPack; struct IPack;
struct SetObjectProperty;
namespace boost struct MetaString;
{
class shared_mutex;
} std::string DLL_EXPORT toString(MetaString &ms);
struct DLL_EXPORT PlayerState
{ namespace boost
public: {
ui8 color, serial; class shared_mutex;
ui32 currentSelection; //id of hero/town, 0xffffffff if none }
std::vector<std::vector<std::vector<ui8> > > fogOfWarMap; //true - visible, false - hidden
std::vector<si32> resources; struct DLL_EXPORT PlayerState
std::vector<CGHeroInstance *> heroes; {
std::vector<CGTownInstance *> towns; public:
std::vector<CGHeroInstance *> availableHeroes; //heroes available in taverns ui8 color, serial;
PlayerState():color(-1),currentSelection(0xffffffff){}; ui32 currentSelection; //id of hero/town, 0xffffffff if none
template <typename Handler> void serialize(Handler &h, const int version) std::vector<std::vector<std::vector<ui8> > > fogOfWarMap; //true - visible, false - hidden
{ std::vector<si32> resources;
h & color & serial & currentSelection & fogOfWarMap & resources; std::vector<CGHeroInstance *> heroes;
//TODO: vectors of heroes/towns std::vector<CGTownInstance *> towns;
} std::vector<CGHeroInstance *> availableHeroes; //heroes available in taverns
}; PlayerState():color(-1),currentSelection(0xffffffff){};
template <typename Handler> void serialize(Handler &h, const int version)
struct DLL_EXPORT BattleInfo {
{ h & color & serial & currentSelection & fogOfWarMap & resources;
ui8 side1, side2; //TODO: vectors of heroes/towns
si32 round, activeStack; }
ui8 siege; // = 0 ordinary battle = 1 a siege with a Fort = 2 a siege with a Citadel = 3 a siege with a Castle };
int3 tile; //for background and bonuses
si32 hero1, hero2; struct DLL_EXPORT BattleInfo
CCreatureSet army1, army2; {
std::vector<CStack*> stacks; ui8 side1, side2;
si32 round, activeStack;
template <typename Handler> void serialize(Handler &h, const int version) ui8 siege; // = 0 ordinary battle = 1 a siege with a Fort = 2 a siege with a Citadel = 3 a siege with a Castle
{ int3 tile; //for background and bonuses
h & side1 & side2 & round & activeStack & siege & tile & stacks & army1 & army2 & hero1 & hero2; si32 hero1, hero2;
} CCreatureSet army1, army2;
CStack * getNextStack(); //which stack will have turn after current one std::vector<CStack*> stacks;
std::vector<CStack> getStackQueue(); //returns stack in order of their movement action
CStack * getStack(int stackID); template <typename Handler> void serialize(Handler &h, const int version)
CStack * getStackT(int tileID); {
void getAccessibilityMap(bool *accessibility, int stackToOmmit=-1); //send pointer to at least 187 allocated bytes h & side1 & side2 & round & activeStack & siege & tile & stacks & army1 & army2 & hero1 & hero2;
void getAccessibilityMapForTwoHex(bool *accessibility, bool atackerSide, int stackToOmmit=-1); //send pointer to at least 187 allocated bytes }
void makeBFS(int start, bool*accessibility, int *predecessor, int *dists); //*accessibility must be prepared bool[187] array; last two pointers must point to the at least 187-elements int arrays - there is written result CStack * getNextStack(); //which stack will have turn after current one
std::vector<int> getPath(int start, int dest, bool*accessibility); std::vector<CStack> getStackQueue(); //returns stack in order of their movement action
std::vector<int> getAccessibility(int stackID); //returns vector of accessible tiles (taking into account the creature range) CStack * getStack(int stackID);
CStack * getStackT(int tileID);
bool isStackBlocked(int ID); //returns true if there is neighbouring enemy stack void getAccessibilityMap(bool *accessibility, int stackToOmmit=-1); //send pointer to at least 187 allocated bytes
static signed char mutualPosition(int hex1, int hex2); //returns info about mutual position of given hexes (-1 - they're distant, 0 - left top, 1 - right top, 2 - right, 3 - right bottom, 4 - left bottom, 5 - left) void getAccessibilityMapForTwoHex(bool *accessibility, bool atackerSide, int stackToOmmit=-1); //send pointer to at least 187 allocated bytes
static std::vector<int> neighbouringTiles(int hex); void makeBFS(int start, bool*accessibility, int *predecessor, int *dists); //*accessibility must be prepared bool[187] array; last two pointers must point to the at least 187-elements int arrays - there is written result
static int calculateDmg(const CStack* attacker, const CStack* defender, const CGHeroInstance * attackerHero, const CGHeroInstance * defendingHero, bool shooting); //TODO: add additional conditions and require necessary data std::vector<int> getPath(int start, int dest, bool*accessibility);
void calculateCasualties(std::set<std::pair<ui32,si32> > *casualties); std::vector<int> getAccessibility(int stackID); //returns vector of accessible tiles (taking into account the creature range)
};
bool isStackBlocked(int ID); //returns true if there is neighbouring enemy stack
class DLL_EXPORT CStack static signed char mutualPosition(int hex1, int hex2); //returns info about mutual position of given hexes (-1 - they're distant, 0 - left top, 1 - right top, 2 - right, 3 - right bottom, 4 - left bottom, 5 - left)
{ static std::vector<int> neighbouringTiles(int hex);
public: static int calculateDmg(const CStack* attacker, const CStack* defender, const CGHeroInstance * attackerHero, const CGHeroInstance * defendingHero, bool shooting); //TODO: add additional conditions and require necessary data
ui32 ID; //unique ID of stack void calculateCasualties(std::set<std::pair<ui32,si32> > *casualties);
CCreature * creature; };
ui32 amount, baseAmount;
ui32 firstHPleft; //HP of first creature in stack class DLL_EXPORT CStack
ui8 owner, slot; //owner - player colour (255 for neutrals), slot - position in garrison (may be 255 for neutrals/called creatures) {
ui8 attackerOwned; //if true, this stack is owned by attakcer (this one from left hand side of battle) public:
ui16 position; //position on battlefield ui32 ID; //unique ID of stack
ui8 counterAttacks; //how many counter attacks can be performed more in this turn (by default set at the beginning of the round to 1) CCreature * creature;
si16 shots; //how many shots left ui32 amount, baseAmount;
ui32 firstHPleft; //HP of first creature in stack
std::set<EAbilities> abilities; ui8 owner, slot; //owner - player colour (255 for neutrals), slot - position in garrison (may be 255 for neutrals/called creatures)
std::set<ECombatInfo> state; ui8 attackerOwned; //if true, this stack is owned by attakcer (this one from left hand side of battle)
struct StackEffect ui16 position; //position on battlefield
{ ui8 counterAttacks; //how many counter attacks can be performed more in this turn (by default set at the beginning of the round to 1)
ui16 id; //spell id si16 shots; //how many shots left
ui8 level; //skill level
ui16 turnsRemain; std::set<EAbilities> abilities;
template <typename Handler> void serialize(Handler &h, const int version) std::set<ECombatInfo> state;
{ struct StackEffect
h & id & level & turnsRemain; {
} ui16 id; //spell id
}; ui8 level; //skill level
std::vector<StackEffect> effects; ui16 turnsRemain;
template <typename Handler> void serialize(Handler &h, const int version)
CStack(CCreature * C, int A, int O, int I, bool AO, int S); {
CStack() : creature(NULL),amount(-1),owner(255), position(-1), ID(-1), attackerOwned(true), firstHPleft(-1), slot(255), baseAmount(-1), counterAttacks(1), effects(), state(), abilities(){} h & id & level & turnsRemain;
const StackEffect * getEffect(ui16 id) const; //effect id (SP) }
ui32 speed() const; };
template <typename Handler> void save(Handler &h, const int version) std::vector<StackEffect> effects;
{
h & creature->idNumber; CStack(CCreature * C, int A, int O, int I, bool AO, int S);
} CStack() : creature(NULL),amount(-1),owner(255), position(-1), ID(-1), attackerOwned(true), firstHPleft(-1), slot(255), baseAmount(-1), counterAttacks(1), effects(), state(), abilities(){}
template <typename Handler> void load(Handler &h, const int version) const StackEffect * getEffect(ui16 id) const; //effect id (SP)
{ ui32 speed() const;
ui32 id; template <typename Handler> void save(Handler &h, const int version)
h & id; {
creature = &VLC->creh->creatures[id]; h & creature->idNumber;
abilities = creature->abilities; }
} template <typename Handler> void load(Handler &h, const int version)
template <typename Handler> void serialize(Handler &h, const int version) {
{ ui32 id;
h & ID & amount & baseAmount & firstHPleft & owner & slot & attackerOwned & position & state & counterAttacks h & id;
& shots; creature = &VLC->creh->creatures[id];
if(h.saving) abilities = creature->abilities;
save(h,version); }
else template <typename Handler> void serialize(Handler &h, const int version)
load(h,version); {
} h & ID & amount & baseAmount & firstHPleft & owner & slot & attackerOwned & position & state & counterAttacks
bool alive() const & shots;
{ if(h.saving)
return vstd::contains(state,ALIVE); save(h,version);
} else
}; load(h,version);
}
struct UpgradeInfo bool alive() const
{ {
int oldID; //creature to be upgraded return vstd::contains(state,ALIVE);
std::vector<int> newID; //possible upgrades }
std::vector<std::set<std::pair<int,int> > > cost; // cost[upgrade_serial] -> set of pairs<resource_ID,resource_amount> };
UpgradeInfo(){oldID = -1;};
}; struct UpgradeInfo
{
class DLL_EXPORT CGameState int oldID; //creature to be upgraded
{ std::vector<int> newID; //possible upgrades
private: std::vector<std::set<std::pair<int,int> > > cost; // cost[upgrade_serial] -> set of pairs<resource_ID,resource_amount>
StartInfo* scenarioOps; UpgradeInfo(){oldID = -1;};
ui32 seed; };
ui8 currentPlayer; //ID of player currently having turn
BattleInfo *curB; //current battle class DLL_EXPORT CGameState
ui32 day; //total number of days in game {
Mapa * map; private:
std::map<ui8,PlayerState> players; //ID <-> player state StartInfo* scenarioOps;
std::map<int, CGDefInfo*> villages, forts, capitols; //def-info for town graphics ui32 seed;
std::vector<ui32> resVals; ui8 currentPlayer; //ID of player currently having turn
BattleInfo *curB; //current battle
struct DLL_EXPORT HeroesPool ui32 day; //total number of days in game
{ Mapa * map;
std::map<ui32,CGHeroInstance *> heroesPool; //[subID] - heroes available to buy; NULL if not available std::map<ui8,PlayerState> players; //ID <-> player state
std::map<ui32,ui8> pavailable; // [subid] -> which players can recruit hero std::map<int, CGDefInfo*> villages, forts, capitols; //def-info for town graphics
std::vector<ui32> resVals;
CGHeroInstance * pickHeroFor(bool native, int player, const CTown *town, int notThatOne=-1);
} hpool; //we have here all heroes available on this map that are not hired struct DLL_EXPORT HeroesPool
{
boost::shared_mutex *mx; std::map<ui32,CGHeroInstance *> heroesPool; //[subID] - heroes available to buy; NULL if not available
std::map<ui32,ui8> pavailable; // [subid] -> which players can recruit hero
CGameState();
~CGameState(); CGHeroInstance * pickHeroFor(bool native, int player, const CTown *town, int notThatOne=-1);
void init(StartInfo * si, Mapa * map, int Seed); } hpool; //we have here all heroes available on this map that are not hired
void loadTownDInfos();
void applyNL(IPack * pack); boost::shared_mutex *mx;
void apply(IPack * pack);
void randomizeObject(CGObjectInstance *cur); CGameState();
std::pair<int,int> pickObject(CGObjectInstance *obj); ~CGameState();
int pickHero(int owner); void init(StartInfo * si, Mapa * map, int Seed);
void loadTownDInfos();
CGHeroInstance *getHero(int objid); void applyNL(IPack * pack);
CGTownInstance *getTown(int objid);
void setObjProperty( SetObjectProperty * p );
bool battleMoveCreatureStack(int ID, int dest); void apply(IPack * pack);
bool battleAttackCreatureStack(int ID, int dest); void randomizeObject(CGObjectInstance *cur);
bool battleShootCreatureStack(int ID, int dest); std::pair<int,int> pickObject(CGObjectInstance *obj);
int battleGetStack(int pos); //returns ID of stack at given tile int pickHero(int owner);
UpgradeInfo getUpgradeInfo(CArmedInstance *obj, int stackPos);
float getMarketEfficiency(int player, int mode=0); CGHeroInstance *getHero(int objid);
std::set<int3> tilesToReveal(int3 pos, int radious, int player) const; //if player==-1 => adds all tiles in radious CGTownInstance *getTown(int objid);
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 bool battleMoveCreatureStack(int ID, int dest);
template <typename Handler> void serialize(Handler &h, const int version) bool battleAttackCreatureStack(int ID, int dest);
{ bool battleShootCreatureStack(int ID, int dest);
h & scenarioOps & seed & currentPlayer & day & map & players & resVals; int battleGetStack(int pos); //returns ID of stack at given tile
if(!h.saving) UpgradeInfo getUpgradeInfo(CArmedInstance *obj, int stackPos);
{ float getMarketEfficiency(int player, int mode=0);
loadTownDInfos(); std::set<int3> tilesToReveal(int3 pos, int radious, int player) const; //if player==-1 => adds all tiles in radious
} public:
//TODO: hero pool 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)
{
friend class CCallback; h & scenarioOps & seed & currentPlayer & day & map & players & resVals;
friend class CPathfinder;; if(!h.saving)
friend class CLuaCallback; {
friend class CClient; loadTownDInfos();
friend void initGameState(Mapa * map, CGameInfo * cgi); }
friend class CScriptCallback; //TODO: hero pool
friend class CMapHandler; }
friend class CGameHandler;
}; friend class CCallback;
friend class CPathfinder;;
friend class CLuaCallback;
#endif // __CGAMESTATE_H__ friend class CClient;
friend void initGameState(Mapa * map, CGameInfo * cgi);
friend class IGameCallback;
friend class CMapHandler;
friend class CGameHandler;
};
#endif // __CGAMESTATE_H__

View File

@ -1076,6 +1076,8 @@ void CPlayerInterface::yourTurn()
adventureInt->infoBar.newDay(cb->getDate(1)); adventureInt->infoBar.newDay(cb->getDate(1));
//select first hero if available.
//TODO: check if hero is slept
if(adventureInt->heroList.items.size()) if(adventureInt->heroList.items.size())
adventureInt->select(adventureInt->heroList.items[0].first); adventureInt->select(adventureInt->heroList.items[0].first);
else else
@ -1193,7 +1195,7 @@ void CPlayerInterface::heroMoved(const HeroMoveDetails & details)
if(adventureInt == curint) if(adventureInt == curint)
adventureInt->minimap.draw(); adventureInt->minimap.draw();
if(details.style) if(details.style>0)
return; return;
//initializing objects and performing first step of move //initializing objects and performing first step of move

View File

@ -1,12 +1,14 @@
0.64 -> 0.next (???) [as for r651] 0.64 -> 0.next (???) [as for r672]
GENERAL: GENERAL:
* move some settings to the config/settings.txt file * move some settings to the config/settings.txt file
* partial support for new screen resolutions * partial support for new screen resolutions
* /Data and /Sprites subfolders can be used for adding files not present in .lod archives * /Data and /Sprites subfolders can be used for adding files not present in .lod archives
* fixed crashbug occuring when hero levelled above 15 level * fixed crashbug occuring when hero levelled above 15 level
* support for non-standard screen resolutions
ADVENTURE INTERFACE: ADVENTURE INTERFACE:
* added water animation * added water animation
* speed of scrolling map and hero movement can be adjusted in the System Options Window
TOWN INTERFACE: TOWN INTERFACE:
* the scroll tab won't remain hanged to our mouse position if we move the mouse away from the scroll bar * the scroll tab won't remain hanged to our mouse position if we move the mouse away from the scroll bar
@ -18,6 +20,9 @@ BATTLES
* war machines support partially added * war machines support partially added
* queue of stacks narrowed * queue of stacks narrowed
* spell effect animation displaying improvements * spell effect animation displaying improvements
* positive/negative spells cannot be cast on hostile/our stacks
* showing spell effects affecting stack in creature info window
* more appropriate coloring of stack amount box when stack is affected by a spell
* several reported bugs fixed * several reported bugs fixed
* new spells supported: * new spells supported:
a) Haste a) Haste
@ -26,12 +31,19 @@ BATTLES
d) slow d) slow
e) implosion e) implosion
f) forgetfulness f) forgetfulness
g) shield
h) air shield
i) bless
j) curse
k) bloodlust
l) weakness
m) stone skin
n) prayer
o) frenzy
AI: AI PLAYER:
* Genius AI (first VCMI AI) will control computer creatures during the combat. * Genius AI (first VCMI AI) will control computer creatures during the combat.
GENERAL:
* started making external settings file (will be used for support for non 800x600 screen resolutions)
And a lot of minor fixes And a lot of minor fixes
0.63 -> 0.64 (Nov 01 2008) 0.63 -> 0.64 (Nov 01 2008)

View File

@ -18,82 +18,9 @@
#include <boost/foreach.hpp> #include <boost/foreach.hpp>
#include <boost/thread.hpp> #include <boost/thread.hpp>
#include <boost/thread/shared_mutex.hpp> #include <boost/thread/shared_mutex.hpp>
#include <sstream>
CSharedCond<std::set<IPack*> > mess(new std::set<IPack*>); CSharedCond<std::set<IPack*> > mess(new std::set<IPack*>);
std::string toString(MetaString &ms)
{
std::string ret;
for(size_t i=0;i<ms.message.size();++i)
{
if(ms.message[i]>0)
{
ret += ms.strings[ms.message[i]-1];
}
else
{
std::vector<std::string> *vec;
int type = ms.texts[-ms.message[i]-1].first,
ser = ms.texts[-ms.message[i]-1].second;
if(type == 5)
{
ret += CGI->arth->artifacts[ser].Name();
continue;
}
else if(type == 7)
{
ret += CGI->creh->creatures[ser].namePl;
continue;
}
else if(type == 9)
{
ret += CGI->objh->mines[ser].first;
continue;
}
else if(type == 10)
{
ret += CGI->objh->mines[ser].second;
continue;
}
else
{
switch(type)
{
case 1:
vec = &CGI->generaltexth->allTexts;
break;
case 2:
vec = &CGI->objh->xtrainfo;
break;
case 3:
vec = &CGI->objh->names;
break;
case 4:
vec = &CGI->objh->restypes;
break;
case 6:
vec = &CGI->generaltexth->arraytxt;
break;
case 8:
vec = &CGI->objh->creGens;
break;
case 11:
vec = &CGI->objh->advobtxt;
break;
case 12:
vec = &CGI->generaltexth->artifEvents;
break;
}
ret += (*vec)[ser];
}
}
}
for(size_t i=0; i < ms.replacements.size(); ++i)
{
ret.replace(ret.find("%s"),2,ms.replacements[i]);
}
return ret;
}
CClient::CClient(void) CClient::CClient(void)
{ {
} }
@ -101,6 +28,7 @@ CClient::CClient(CConnection *con, StartInfo *si)
:serv(con) :serv(con)
{ {
timeHandler tmh; timeHandler tmh;
IObjectInterface::cb = this;
CGI->state = new CGameState(); CGI->state = new CGameState();
tlog0 <<"\tGamestate: "<<tmh.getDif()<<std::endl; tlog0 <<"\tGamestate: "<<tmh.getDif()<<std::endl;
CConnection &c(*con); CConnection &c(*con);
@ -449,6 +377,14 @@ void CClient::process(int what)
tlog4 << "Player "<<(int)color<<" sends a message: " << message << std::endl; tlog4 << "Player "<<(int)color<<" sends a message: " << message << std::endl;
break; break;
} }
case 514:
{
SetSelection ss;
*serv >> ss;
tlog5 << "Selection of player " << (int)ss.player << " set to " << ss.id << std::endl;
gs->apply(&ss);
break;
}
case 515: case 515:
{ {
HeroRecruited hr; HeroRecruited hr;
@ -475,9 +411,7 @@ void CClient::process(int what)
SetHoverName shn; SetHoverName shn;
*serv >> shn; *serv >> shn;
tlog5 << "Setting a name of " << shn.id <<" object to "<< toString(shn.name) <<std::endl; tlog5 << "Setting a name of " << shn.id <<" object to "<< toString(shn.name) <<std::endl;
gs->mx->lock(); gs->apply(&shn);
//gs->map->objects[shn.id]->hoverName = toString(shn.name);
gs->mx->unlock();
break; break;
} }
case 2000: case 2000:
@ -668,8 +602,11 @@ void CClient::process(int what)
case 9999: case 9999:
break; break;
default: default:
throw std::string("Not supported server message!"); {
break; std::ostringstream ex;
ex << "Not supported server message (type=" << what <<")";
throw ex.str();
}
} }
} }
void CClient::waitForMoveAndSend(int color) void CClient::waitForMoveAndSend(int color)
@ -709,3 +646,13 @@ void CClient::save(const std::string & fname)
{ {
*serv << ui16(98) << fname; *serv << ui16(98) << fname;
} }
int CClient::getCurrentPlayer()
{
return gs->currentPlayer;
}
int CClient::getSelectedHero()
{
return IGameCallback::getSelectedHero(getCurrentPlayer())->id;
}

View File

@ -1,63 +1,87 @@
#ifndef __CLIENT_H__ #ifndef __CLIENT_H__
#define __CLIENT_H__ #define __CLIENT_H__
#include "../global.h" #include "../global.h"
#include <boost/thread.hpp> #include <boost/thread.hpp>
struct StartInfo; #include "../lib/IGameCallback.h"
class CGameState; struct StartInfo;
class CGameInterface; class CGameState;
class CConnection; class CGameInterface;
class CCallback; class CConnection;
class CClient; class CCallback;
void processCommand(const std::string &message, CClient *&client); class CClient;
namespace boost void processCommand(const std::string &message, CClient *&client);
{ namespace boost
class mutex; {
class condition_variable; class mutex;
} class condition_variable;
}
template <typename T>
struct CSharedCond template <typename T>
{ struct CSharedCond
boost::mutex *mx; {
boost::condition_variable *cv; boost::mutex *mx;
T *res; boost::condition_variable *cv;
CSharedCond(T*R) T *res;
{ CSharedCond(T*R)
res = R; {
mx = new boost::mutex; res = R;
cv = new boost::condition_variable; mx = new boost::mutex;
} cv = new boost::condition_variable;
~CSharedCond() }
{ ~CSharedCond()
delete res; {
delete mx; delete res;
delete cv; delete mx;
} delete cv;
}; }
};
class CClient
{ class CClient : public IGameCallback
CCallback *cb; {
CGameState *gs; CCallback *cb;
std::map<ui8,CGameInterface *> playerint; std::map<ui8,CGameInterface *> playerint;
CConnection *serv; CConnection *serv;
void waitForMoveAndSend(int color); void waitForMoveAndSend(int color);
public: public:
CClient(void); CClient(void);
CClient(CConnection *con, StartInfo *si); CClient(CConnection *con, StartInfo *si);
~CClient(void); ~CClient(void);
void close(); void close();
void save(const std::string & fname); void save(const std::string & fname);
void process(int what); void process(int what);
void run(); void run();
//////////////////////////////////////////////////////////////////////////
friend class CCallback; //handling players actions //from IGameCallback
friend class CScriptCallback; //for objects scripts int getCurrentPlayer();
friend void processCommand(const std::string &message, CClient *&client); //handling console int getSelectedHero();
};
//not working yet, will be implement somewhen later with support for local-sim-based gameplay
#endif // __CLIENT_H__ void changeSpells(int hid, bool give, const std::set<ui32> &spells){};
void 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, int val){};
void changePrimSkill(int ID, int which, int val, bool abs=false){};
void showInfoDialog(InfoWindow *iw){};
void showYesNoDialog(YesNoDialog *iw, const CFunctionList<void(ui32)> &callback){};
void showSelectionDialog(SelectionDialog *iw, const CFunctionList<void(ui32)> &callback){}; //returns question id
void giveResource(int player, int which, int val){};
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 startBattleI(const CCreatureSet * army1, const CCreatureSet * army2, int3 tile, const CGHeroInstance *hero1, const CGHeroInstance *hero2, boost::function<void(BattleResult*)> cb){}; //use hero=NULL for no hero
void startBattleI(int heroID, CCreatureSet army, int3 tile, boost::function<void(BattleResult*)> cb){}; //for hero<=>neutral army
void setAmount(int objid, ui32 val){};
void moveHero(int hid, int3 pos, bool instant){};
//////////////////////////////////////////////////////////////////////////
friend class CCallback; //handling players actions
friend void processCommand(const std::string &message, CClient *&client); //handling console
};
#endif // __CLIENT_H__

View File

@ -3,7 +3,7 @@
clientSettings clientSettings
{ {
port=3030; port=3030;
resolution=800x600; // format: WxH resolution=1024x768; // format: WxH
bpp=24; // bpp!=24 => problems bpp=24; // bpp!=24 => problems
fullscreen=0; //0 - windowed mode, 1 - fullscreen fullscreen=0; //0 - windowed mode, 1 - fullscreen
server=127.0.0.1; //use 127.0.0.1 for localhost server=127.0.0.1; //use 127.0.0.1 for localhost

View File

@ -17,19 +17,20 @@
#include "../CGameState.h" #include "../CGameState.h"
#include "../lib/NetPacks.h" #include "../lib/NetPacks.h"
std::map<int,std::map<int, std::vector<int> > > CGTeleport::objs;
IGameCallback * IObjectInterface::cb = NULL; IGameCallback * IObjectInterface::cb = NULL;
DLL_EXPORT void loadToIt(std::string &dest, std::string &src, int &iter, int mode); DLL_EXPORT void loadToIt(std::string &dest, std::string &src, int &iter, int mode);
extern CLodHandler * bitmaph; extern CLodHandler * bitmaph;
extern boost::rand48 ran; extern boost::rand48 ran;
void IObjectInterface::onHeroVisit(const CGHeroInstance * h) void IObjectInterface::onHeroVisit(const CGHeroInstance * h) const
{}; {};
void IObjectInterface::onHeroLeave(const CGHeroInstance * h) void IObjectInterface::onHeroLeave(const CGHeroInstance * h) const
{}; {};
void IObjectInterface::newTurn () void IObjectInterface::newTurn () const
{}; {};
IObjectInterface::~IObjectInterface() IObjectInterface::~IObjectInterface()
@ -645,7 +646,7 @@ bool CGHeroInstance::needsLastStack() const
{ {
return true; return true;
} }
void CGHeroInstance::onHeroVisit(const CGHeroInstance * h) void CGHeroInstance::onHeroVisit(const CGHeroInstance * h) const
{ {
//TODO: check for allies //TODO: check for allies
if(tempOwner == h->tempOwner) //our hero if(tempOwner == h->tempOwner) //our hero
@ -673,7 +674,7 @@ const std::string & CGHeroInstance::getBiography() const
} }
void CGHeroInstance::initObj() void CGHeroInstance::initObj()
{ {
cb->setBlockVis(id,true); blockVisit = true;
} }
int CGTownInstance::getSightDistance() const //returns sight distance int CGTownInstance::getSightDistance() const //returns sight distance
{ {
@ -795,7 +796,7 @@ bool CGTownInstance::needsLastStack() const
else return false; else return false;
} }
void CGTownInstance::onHeroVisit(const CGHeroInstance * h) void CGTownInstance::onHeroVisit(const CGHeroInstance * h) const
{ {
if(getOwner() != h->getOwner()) if(getOwner() != h->getOwner())
{ {
@ -804,7 +805,7 @@ void CGTownInstance::onHeroVisit(const CGHeroInstance * h)
cb->heroVisitCastle(id,h->id); cb->heroVisitCastle(id,h->id);
} }
void CGTownInstance::onHeroLeave(const CGHeroInstance * h) void CGTownInstance::onHeroLeave(const CGHeroInstance * h) const
{ {
cb->stopHeroVisitCastle(id,h->id); cb->stopHeroVisitCastle(id,h->id);
} }
@ -813,28 +814,16 @@ void CGTownInstance::initObj()
{ {
MetaString ms; MetaString ms;
ms << name << ", " << town->Name(); ms << name << ", " << town->Name();
cb->setHoverName(id,&ms); hoverName = toString(ms);
} }
//std::vector<int> CVisitableOPH::yourObjects() void CGVisitableOPH::onHeroVisit( const CGHeroInstance * h ) const
//{
// std::vector<int> ret;
// ret.push_back(51);//camp
// ret.push_back(23);//tower
// ret.push_back(61);//axis
// ret.push_back(32);//garden
// ret.push_back(100);//stone
// ret.push_back(102);//tree
// return ret;
//}
void CGVisitableOPH::onHeroVisit( const CGHeroInstance * h )
{ {
if(visitors.find(h->id)==visitors.end()) if(visitors.find(h->id)==visitors.end())
{ {
onNAHeroVisit(h->id, false); onNAHeroVisit(h->id, false);
if(ID != 102) //not tree if(ID != 102) //not tree
visitors.insert(h->id); cb->setObjProperty(id,4,h->id); //add to the visitors
} }
else else
{ {
@ -850,16 +839,16 @@ void CGVisitableOPH::initObj()
ttype = -1; ttype = -1;
} }
void CGVisitableOPH::treeSelected( int heroID, int resType, int resVal, int expVal, ui32 result ) void CGVisitableOPH::treeSelected( int heroID, int resType, int resVal, int expVal, ui32 result ) const
{ {
if(result==0) //player agreed to give res for exp if(result==0) //player agreed to give res for exp
{ {
cb->giveResource(cb->getOwner(heroID),resType,-resVal); //take resource cb->giveResource(cb->getOwner(heroID),resType,-resVal); //take resource
cb->changePrimSkill(heroID,4,expVal); //give exp cb->changePrimSkill(heroID,4,expVal); //give exp
visitors.insert(heroID); //set state to visited cb->setObjProperty(id,4,heroID); //add to the visitors
} }
} }
void CGVisitableOPH::onNAHeroVisit(int heroID, bool alreadyVisited) void CGVisitableOPH::onNAHeroVisit(int heroID, bool alreadyVisited) const
{ {
int id=0, subid=0, ot=0, val=1; int id=0, subid=0, ot=0, val=1;
switch(ID) switch(ID)
@ -925,7 +914,7 @@ void CGVisitableOPH::onNAHeroVisit(int heroID, bool alreadyVisited)
val = VLC->heroh->reqExp(h->level+val) - VLC->heroh->reqExp(h->level); val = VLC->heroh->reqExp(h->level+val) - VLC->heroh->reqExp(h->level);
if(!ttype) if(!ttype)
{ {
visitors.insert(heroID); cb->setObjProperty(id,4,heroID); //add to the visitors
InfoWindow iw; InfoWindow iw;
iw.components.push_back(Component(id,subid,1,0)); iw.components.push_back(Component(id,subid,1,0));
iw.player = cb->getOwner(heroID); iw.player = cb->getOwner(heroID);
@ -1010,9 +999,10 @@ const std::string & CGVisitableOPH::getHoverText() const
const CGHeroInstance *h = cb->getSelectedHero(cb->getCurrentPlayer()); const CGHeroInstance *h = cb->getSelectedHero(cb->getCurrentPlayer());
if(h) if(h)
{ {
hoverName += ' ';
hoverName += (vstd::contains(visitors,h->id)) hoverName += (vstd::contains(visitors,h->id))
? (VLC->generaltexth->allTexts[353]) //not visited ? (VLC->generaltexth->allTexts[352]) //visited
: ( VLC->generaltexth->allTexts[352]); //visited : ( VLC->generaltexth->allTexts[353]); //not visited
} }
return hoverName; return hoverName;
} }
@ -1022,13 +1012,12 @@ bool CArmedInstance::needsLastStack() const
return false; return false;
} }
void CGCreature::onHeroVisit( const CGHeroInstance * h ) void CGCreature::onHeroVisit( const CGHeroInstance * h ) const
{ {
army.slots[0].first = subID;
cb->startBattleI(h->id,army,pos,boost::bind(&CGCreature::endBattle,this,_1)); cb->startBattleI(h->id,army,pos,boost::bind(&CGCreature::endBattle,this,_1));
} }
void CGCreature::endBattle( BattleResult *result ) void CGCreature::endBattle( BattleResult *result ) const
{ {
if(result->winner==0) if(result->winner==0)
{ {
@ -1040,12 +1029,19 @@ void CGCreature::endBattle( BattleResult *result )
for(std::set<std::pair<ui32,si32> >::iterator i=result->casualties[1].begin(); i!=result->casualties[1].end(); i++) for(std::set<std::pair<ui32,si32> >::iterator i=result->casualties[1].begin(); i!=result->casualties[1].end(); i++)
if(i->first == subID) if(i->first == subID)
killedAmount += i->second; killedAmount += i->second;
cb->setAmount(id, army.slots[0].second - killedAmount); cb->setAmount(id, army.slots.find(0)->second.second - killedAmount);
MetaString ms;
int pom = CCreature::getQuantityID(army.slots.find(0)->second.second);
pom = 174 + 3*pom + 1;
ms << std::pair<ui8,ui32>(6,pom) << " " << std::pair<ui8,ui32>(7,subID);
cb->setHoverName(id,&ms);
} }
} }
void CGCreature::initObj() void CGCreature::initObj()
{ {
army.slots[0].first = subID;
si32 &amount = army.slots[0].second; si32 &amount = army.slots[0].second;
CCreature &c = VLC->creh->creatures[subID]; CCreature &c = VLC->creh->creatures[subID];
if(!amount) if(!amount)
@ -1053,4 +1049,364 @@ void CGCreature::initObj()
amount = c.ammMax; amount = c.ammMax;
else else
amount = c.ammMin + (ran() % (c.ammMax - c.ammMin)); amount = c.ammMin + (ran() % (c.ammMax - c.ammMin));
MetaString ms;
int pom = CCreature::getQuantityID(army.slots.find(0)->second.second);
pom = 174 + 3*pom + 1;
ms << std::pair<ui8,ui32>(6,pom) << " " << std::pair<ui8,ui32>(7,subID);
hoverName = toString(ms);
}
void CGMine::onHeroVisit( const CGHeroInstance * h ) const
{
if(subID == 7) //TODO: support for abandoned mine
return;
if(h->tempOwner == tempOwner) //we're visiting our mine
return; //TODO: leaving garrison
//TODO: check if mine is guarded
cb->setOwner(id,h->tempOwner); //not ours? flag it!
MetaString ms;
ms << std::pair<ui8,ui32>(9,subID) << " (" << std::pair<ui8,ui32>(6,23+h->tempOwner) << ")";
cb->setHoverName(id,&ms);
int vv=1; //amount of resource per turn
if (subID==0 || subID==2)
vv++;
else if (subID==6)
vv = 1000;
InfoWindow iw;
iw.text << std::pair<ui8,ui32>(10,subID);
iw.player = h->tempOwner;
iw.components.push_back(Component(2,subID,vv,-1));
cb->showInfoDialog(&iw);
}
void CGMine::newTurn() const
{
if (tempOwner == NEUTRAL_PLAYER)
return;
int vv = 1;
if (subID==0 || subID==2)
vv++;
else if (subID==6)
vv = 1000;
cb->giveResource(tempOwner,subID,vv);
}
void CGMine::initObj()
{
MetaString ms;
ms << std::pair<ui8,ui32>(9,subID);
if(tempOwner >= PLAYER_LIMIT)
tempOwner = NEUTRAL_PLAYER;
else
ms << " (" << std::pair<ui8,ui32>(6,23+tempOwner) << ")";
hoverName = toString(ms);
}
void CGResource::initObj()
{
blockVisit = true;
hoverName = VLC->objh->restypes[subID];
if(!amount)
{
switch(subID)
{
case 6:
amount = 500 + (rand()%6)*100;
break;
case 0: case 2:
amount = 6 + (rand()%5);
break;
default:
amount = 3 + (rand()%3);
break;
}
}
}
void CGResource::onHeroVisit( const CGHeroInstance * h ) const
{
//TODO: handle guards (when battles are finished)
if(message.length())
{
InfoWindow iw;
iw.player = h->tempOwner;
iw.text << message;
cb->showInfoDialog(&iw);
}
cb->giveResource(h->tempOwner,subID,amount);
ShowInInfobox sii;
sii.player = h->tempOwner;
sii.c = Component(2,subID,amount,0);
sii.text << std::pair<ui8,ui32>(11,113);
sii.text.replacements.push_back(VLC->objh->restypes[subID]);
cb->showCompInfo(&sii);
cb->removeObject(id);
}
void CGVisitableOPW::newTurn() const
{
if (cb->getDate(1)==1) //first day of week
{
cb->setObjProperty(id,5,false);
MetaString ms; //set text to "not visited"
ms << std::pair<ui8,ui32>(3,ID) << " " << std::pair<ui8,ui32>(1,353);
cb->setHoverName(id,&ms);
}
}
void CGVisitableOPW::onHeroVisit( const CGHeroInstance * h ) const
{
int mid;
switch (ID)
{
case 55:
mid = 92;
break;
case 112:
mid = 170;
break;
case 109:
mid = 164;
break;
}
if (visited)
{
if (ID!=112)
mid++;
else
mid--;
InfoWindow iw;
iw.player = h->tempOwner;
iw.text << std::pair<ui8,ui32>(11,mid);
cb->showInfoDialog(&iw);
}
else
{
int type, sub, val;
type = 2;
switch (ID)
{
case 55:
if (rand()%2)
{
sub = 5;
val = 5;
}
else
{
sub = 6;
val = 500;
}
break;
case 112:
mid = 170;
sub = (rand() % 5) + 1;
val = (rand() % 4) + 3;
break;
case 109:
mid = 164;
sub = 6;
if(cb->getDate(2)<2)
val = 500;
else
val = 1000;
}
cb->giveResource(h->tempOwner,sub,val);
InfoWindow iw;
iw.player = h->tempOwner;
iw.components.push_back(Component(type,sub,val,0));
iw.text << std::pair<ui8,ui32>(11,mid);
cb->showInfoDialog(&iw);
cb->setObjProperty(id,5,true);
MetaString ms; //set text to "visited"
ms << std::pair<ui8,ui32>(3,ID) << " " << std::pair<ui8,ui32>(1,352);
cb->setHoverName(id,&ms);
}
}
void CGTeleport::onHeroVisit( const CGHeroInstance * h ) const
{
int destinationid=-1;
switch(ID)
{
case 43: //one way - find correspong exit monolith
if(vstd::contains(objs,44) && vstd::contains(objs[44],subID) && objs[44][subID].size())
destinationid = objs[44][subID][rand()%objs[44][subID].size()];
else
tlog2 << "Cannot find corresponding exit monolith for "<< id << std::endl;
break;
case 45: //two way monolith - pick any other one
if(vstd::contains(objs,45) && vstd::contains(objs[45],subID) && objs[45][subID].size()>1)
while ((destinationid = objs[45][subID][rand()%objs[45][subID].size()])==id);
else
tlog2 << "Cannot find corresponding exit monolith for "<< id << std::endl;
break;
case 103: //find nearest subterranean gate on the other level
{
std::pair<int,double> best(-1,150000); //pair<id,dist>
for(int i=0; i<objs[103][0].size(); i++)
{
if(cb->getObj(objs[103][0][i])->pos.z == pos.z) continue; //gates on our level are not interesting
double hlp = cb->getObj(objs[103][0][i])->pos.dist2d(pos);
if(hlp<best.second)
{
best.first = objs[103][0][i];
best.second = hlp;
}
}
if(best.first<0)
return;
else
destinationid = best.first;
break;
}
}
if(destinationid < 0)
{
tlog2 << "Cannot find exit... :( \n";
return;
}
cb->moveHero(h->id,
(ID!=103)
? (CGHeroInstance::convertPosition(cb->getObj(destinationid)->pos,true))
: (cb->getObj(destinationid)->pos),
true);
}
void CGTeleport::initObj()
{
objs[ID][subID].push_back(id);
}
void CGArtifact::initObj()
{
blockVisit = true;
if(ID == 5)
hoverName = VLC->arth->artifacts[subID].Name();
}
void CGArtifact::onHeroVisit( const CGHeroInstance * h ) const
{
cb->giveHeroArtifact(subID,h->id,-2);
InfoWindow iw;
iw.player = h->tempOwner;
iw.components.push_back(Component(4,subID,0,0));
iw.text << std::pair<ui8,ui32>(12,subID);
cb->showInfoDialog(&iw);
}
void CGPickable::initObj()
{
blockVisit = true;
switch(ID)
{
case 12: //campfire
val2 = (ran()%3) + 4; //4 - 6
val1 = val2 * 100;
type = ran()%6; //given resource
break;
case 101: //treasure chest
{
int hlp = ran()%100;
if(hlp >= 95)
{
type = 1;
val1 = VLC->arth->treasures[ran()%VLC->arth->treasures.size()]->id;
return;
}
else if (hlp >= 65)
{
val1 = 2000;
}
else if(hlp >= 33)
{
val1 = 1500;
}
else
{
val1 = 1000;
}
val2 = val1 - 500;
type = 0;
break;
}
}
}
void CGPickable::onHeroVisit( const CGHeroInstance * h ) const
{
switch(ID)
{
case 12: //campfire
{
cb->giveResource(h->tempOwner,type,val2); //non-gold resource
cb->giveResource(h->tempOwner,6,val1);//gold
InfoWindow iw;
iw.player = h->tempOwner;
iw.components.push_back(Component(2,6,val1,0));
iw.components.push_back(Component(2,type,val2,0));
iw.text << std::pair<ui8,ui32>(11,23);
cb->showInfoDialog(&iw);
break;
}
case 101: //treasure chest
{
if (subID) //not OH3 treasure chest
{
tlog2 << "Not supported WoG treasure chest!\n";
return;
}
if(type) //there is an artifact
{
cb->giveHeroArtifact(val1,h->id,-2);
InfoWindow iw;
iw.player = h->tempOwner;
iw.components.push_back(Component(4,val1,1,0));
iw.text << std::pair<ui8,ui32>(11,145);
iw.text.replacements.push_back(VLC->arth->artifacts[val1].Name());
cb->showInfoDialog(&iw);
break;
}
else
{
SelectionDialog sd;
sd.player = h->tempOwner;
sd.text << std::pair<ui8,ui32>(11,146);
sd.components.push_back(Component(2,6,val1,0));
sd.components.push_back(Component(5,0,val2,0));
boost::function<void(ui32)> fun = boost::bind(&CGPickable::chosen,this,_1,h->id);
cb->showSelectionDialog(&sd,fun);
return;
}
}
}
cb->removeObject(id);
}
void CGPickable::chosen( int which, int heroID ) const
{
switch(which)
{
case 0: //player pick gold
cb->giveResource(cb->getOwner(heroID),6,val1);
break;
case 1: //player pick exp
cb->changePrimSkill(heroID, 4, val2);
break;
default:
throw std::string("Unhandled treasure choice");
}
} }

View File

@ -1,439 +1,453 @@
#ifndef __COBJECTHANDLER_H__ #ifndef __COBJECTHANDLER_H__
#define __COBJECTHANDLER_H__ #define __COBJECTHANDLER_H__
#include "../global.h" #include "../global.h"
#include <string> #include <string>
#include <vector> #include <vector>
#include <set> #include <set>
#include <map> #include <map>
#include "CCreatureHandler.h" #include "CCreatureHandler.h"
using boost::logic::tribool; using boost::logic::tribool;
class IGameCallback; class IGameCallback;
struct BattleResult; struct BattleResult;
class CCPPObjectScript; class CCPPObjectScript;
class CGObjectInstance; class CGObjectInstance;
class CScript; class CScript;
class CObjectScript; class CObjectScript;
class CGHeroInstance; class CGHeroInstance;
class CTown; class CTown;
class CHero; class CHero;
class CBuilding; class CBuilding;
class CSpell; class CSpell;
class CGTownInstance; class CGTownInstance;
class CArtifact; class CArtifact;
class CGDefInfo; class CGDefInfo;
class CSpecObjInfo; class CSpecObjInfo;
class DLL_EXPORT CCastleEvent class DLL_EXPORT CCastleEvent
{ {
public: public:
std::string name, message; std::string name, message;
int wood, mercury, ore, sulfur, crystal, gems, gold; //gain / loss of resources int wood, mercury, ore, sulfur, crystal, gems, gold; //gain / loss of resources
unsigned char players; //players for whom this event can be applied unsigned char players; //players for whom this event can be applied
bool forHuman, forComputer; bool forHuman, forComputer;
int firstShow; //postpone of first encounter time in days int firstShow; //postpone of first encounter time in days
int forEvery; //every n days this event will occure int forEvery; //every n days this event will occure
unsigned char bytes[6]; //build specific buildings (raw format, similar to town's) unsigned char bytes[6]; //build specific buildings (raw format, similar to town's)
int gen[7]; //additional creatures in i-th level dwelling int gen[7]; //additional creatures in i-th level dwelling
bool operator<(const CCastleEvent &drugie) const bool operator<(const CCastleEvent &drugie) const
{ {
return firstShow<drugie.firstShow; return firstShow<drugie.firstShow;
} }
}; };
class DLL_EXPORT IObjectInterface class CQuest
{ {
public: public:
static IGameCallback *cb; ui8 missionType; //type of mission: 0 - no mission; 1 - reach level; 2 - reach main statistics values; 3 - win with a certain hero; 4 - win with a certain creature; 5 - collect some atifacts; 6 - have certain troops in army; 7 - collect resources; 8 - be a certain hero; 9 - be a certain playe
si32 lastDay; //after this day (first day is 0) mission cannot be completed; if -1 - no limit
IObjectInterface();
virtual ~IObjectInterface(); ui32 m13489val;
std::vector<ui32> m2stats;
virtual void onHeroVisit(const CGHeroInstance * h); std::vector<ui16> m5arts; //artifacts id
virtual void onHeroLeave(const CGHeroInstance * h); std::vector<std::pair<ui32, ui32> > m6creatures; //pair[cre id, cre count]
virtual void newTurn(); std::vector<ui32> m7resources;
virtual void initObj();
}; std::string firstVisitText, nextVisitText, completedText;
};
class DLL_EXPORT CGObjectInstance : protected IObjectInterface
{ class DLL_EXPORT IObjectInterface
protected: {
public: public:
mutable std::string hoverName; static IGameCallback *cb;
int3 pos; //h3m pos
int ID, subID; //normal ID (this one from OH3 maps ;]) - eg. town=98; hero=34 IObjectInterface();
si32 id;//number of object in CObjectHandler's vector virtual ~IObjectInterface();
CGDefInfo * defInfo;
CCPPObjectScript * state; virtual void onHeroVisit(const CGHeroInstance * h) const;
CSpecObjInfo * info; virtual void onHeroLeave(const CGHeroInstance * h) const;
unsigned char animPhaseShift; virtual void newTurn() const;
virtual void initObj();
ui8 tempOwner; //uzywane dla szybkosci, skrypt ma obowiazek aktualizowac te zmienna };
ui8 blockVisit; //if non-zero then blocks the tile but is visitable from neighbouring tile
class DLL_EXPORT CGObjectInstance : protected IObjectInterface
int getOwner() const; {
void setOwner(int ow); protected:
int getWidth() const; //returns width of object graphic in tiles public:
int getHeight() const; //returns height of object graphic in tiles mutable std::string hoverName;
bool visitableAt(int x, int y) const; //returns true if object is visitable at location (x, y) form left top tile of image (x, y in tiles) int3 pos; //h3m pos
bool blockingAt(int x, int y) const; //returns true if object is blocking location (x, y) form left top tile of image (x, y in tiles) int ID, subID; //normal ID (this one from OH3 maps ;]) - eg. town=98; hero=34
bool operator<(const CGObjectInstance & cmp) const; //screen printing priority comparing si32 id;//number of object in CObjectHandler's vector
CGObjectInstance(); CGDefInfo * defInfo;
virtual ~CGObjectInstance(); CCPPObjectScript * state;
CGObjectInstance(const CGObjectInstance & right); CSpecObjInfo * info;
CGObjectInstance& operator=(const CGObjectInstance & right); unsigned char animPhaseShift;
virtual const std::string & getHoverText() const;
////////////////////////////////////////////////////////////////////////// ui8 tempOwner; //uzywane dla szybkosci, skrypt ma obowiazek aktualizowac te zmienna
void initObj(); ui8 blockVisit; //if non-zero then blocks the tile but is visitable from neighbouring tile
friend class CGameHandler; int getOwner() const;
}; void setOwner(int ow);
int getWidth() const; //returns width of object graphic in tiles
class DLL_EXPORT CArmedInstance: public CGObjectInstance int getHeight() const; //returns height of object graphic in tiles
{ bool visitableAt(int x, int y) const; //returns true if object is visitable at location (x, y) form left top tile of image (x, y in tiles)
public: bool blockingAt(int x, int y) const; //returns true if object is blocking location (x, y) form left top tile of image (x, y in tiles)
CCreatureSet army; //army bool operator<(const CGObjectInstance & cmp) const; //screen printing priority comparing
virtual bool needsLastStack() const; //true if last stack cannot be taken CGObjectInstance();
}; virtual ~CGObjectInstance();
CGObjectInstance(const CGObjectInstance & right);
class DLL_EXPORT CGHeroInstance : public CArmedInstance CGObjectInstance& operator=(const CGObjectInstance & right);
{ virtual const std::string & getHoverText() const;
public: //////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////// void initObj();
mutable int moveDir; //format: 123 friend class CGameHandler;
// 8 4 };
// 765
mutable ui8 isStanding, tacticFormationEnabled; class DLL_EXPORT CArmedInstance: public CGObjectInstance
{
////////////////////////////////////////////////////////////////////////// public:
CCreatureSet army; //army
CHero * type; virtual bool needsLastStack() const; //true if last stack cannot be taken
ui32 exp; //experience point };
int level; //current level of hero
std::string name; //may be custom class DLL_EXPORT CGHeroInstance : public CArmedInstance
std::string biography; //if custom {
int portrait; //may be custom public:
int mana; // remaining spell points //////////////////////////////////////////////////////////////////////////
std::vector<int> primSkills; //0-attack, 1-defence, 2-spell power, 3-knowledge
std::vector<std::pair<ui8,ui8> > secSkills; //first - ID of skill, second - level of skill (1 - basic, 2 - adv., 3 - expert); if hero has ability (-1, -1) it meansthat it should have default secondary abilities mutable int moveDir; //format: 123
int movement; //remaining movement points // 8 4
int identifier; //from the map file // 765
bool sex; mutable ui8 isStanding, tacticFormationEnabled;
struct DLL_EXPORT Patrol
{ //////////////////////////////////////////////////////////////////////////
Patrol(){patrolling=false;patrolRadious=-1;};
bool patrolling; CHero * type;
int patrolRadious; ui32 exp; //experience point
} patrol; int level; //current level of hero
bool inTownGarrison; // if hero is in town garrison std::string name; //may be custom
CGTownInstance * visitedTown; //set if hero is visiting town or in the town garrison std::string biography; //if custom
std::vector<ui32> artifacts; //hero's artifacts from bag int portrait; //may be custom
std::map<ui16,ui32> 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 int mana; // remaining spell points
std::set<ui32> spells; //known spells (spell IDs) std::vector<int> primSkills; //0-attack, 1-defence, 2-spell power, 3-knowledge
std::vector<std::pair<ui8,ui8> > secSkills; //first - ID of skill, second - level of skill (1 - basic, 2 - adv., 3 - expert); if hero has ability (-1, -1) it meansthat it should have default secondary abilities
////////////////////////////////////////////////////////////////////////// int movement; //remaining movement points
int identifier; //from the map file
const std::string &getBiography() const; bool sex;
bool needsLastStack()const; struct DLL_EXPORT Patrol
unsigned int getTileCost(const EterrainType & ttype, const Eroad & rdtype, const Eriver & rvtype) const; {
unsigned int getLowestCreatureSpeed() const; Patrol(){patrolling=false;patrolRadious=-1;};
unsigned int getAdditiveMoveBonus() const; bool patrolling;
float getMultiplicativeMoveBonus() const; int patrolRadious;
int3 getPosition(bool h3m) const; //h3m=true - returns position of hero object; h3m=false - returns position of hero 'manifestation' } patrol;
int getSightDistance() const; //returns sight distance of this hero bool inTownGarrison; // if hero is in town garrison
int manaLimit() const; //maximum mana value for this hero (basically 10*knowledge) CGTownInstance * visitedTown; //set if hero is visiting town or in the town garrison
bool canWalkOnSea() const; std::vector<ui32> artifacts; //hero's artifacts from bag
int getCurrentLuck() const; std::map<ui16,ui32> 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
int getCurrentMorale() const; std::set<ui32> spells; //known spells (spell IDs)
int getPrimSkillLevel(int id) const;
int getSecSkillLevel(const int & ID) const; //0 - no skill //////////////////////////////////////////////////////////////////////////
int maxMovePoints(bool onLand) const;
ui32 getArtAtPos(ui16 pos) const; //-1 - no artifact const std::string &getBiography() const;
void setArtAtPos(ui16 pos, int art); bool needsLastStack()const;
const CArtifact * getArt(int pos) const; unsigned int getTileCost(const EterrainType & ttype, const Eroad & rdtype, const Eriver & rvtype) const;
int getSpellSecLevel(int spell) const; //returns level of secondary ability (fire, water, earth, air magic) known to this hero and applicable to given spell; -1 if error unsigned int getLowestCreatureSpeed() const;
static int3 convertPosition(int3 src, bool toh3m); //toh3m=true: manifest->h3m; toh3m=false: h3m->manifest unsigned int getAdditiveMoveBonus() const;
float getMultiplicativeMoveBonus() const;
////////////////////////////////////////////////////////////////////////// int3 getPosition(bool h3m) const; //h3m=true - returns position of hero object; h3m=false - returns position of hero 'manifestation'
int getSightDistance() const; //returns sight distance of this hero
void initHero(); int manaLimit() const; //maximum mana value for this hero (basically 10*knowledge)
void initHero(int SUBID); bool canWalkOnSea() const;
CGHeroInstance(); int getCurrentLuck() const;
virtual ~CGHeroInstance(); int getCurrentMorale() const;
int getPrimSkillLevel(int id) const;
////////////////////////////////////////////////////////////////////////// int getSecSkillLevel(const int & ID) const; //0 - no skill
void initObj(); int maxMovePoints(bool onLand) const;
void onHeroVisit(const CGHeroInstance * h); ui32 getArtAtPos(ui16 pos) const; //-1 - no artifact
}; void setArtAtPos(ui16 pos, int art);
const CArtifact * getArt(int pos) const;
class DLL_EXPORT CGTownInstance : public CArmedInstance int getSpellSecLevel(int spell) const; //returns level of secondary ability (fire, water, earth, air magic) known to this hero and applicable to given spell; -1 if error
{ static int3 convertPosition(int3 src, bool toh3m); //toh3m=true: manifest->h3m; toh3m=false: h3m->manifest
public:
CTown * town; //////////////////////////////////////////////////////////////////////////
std::string name; // name of town
int builded; //how many buildings has been built this turn void initHero();
int destroyed; //how many buildings has been destroyed this turn void initHero(int SUBID);
const CGHeroInstance * garrisonHero, *visitingHero; CGHeroInstance();
int identifier; //special identifier from h3m (only > RoE maps) virtual ~CGHeroInstance();
int alignment;
std::set<si32> forbiddenBuildings, builtBuildings; //////////////////////////////////////////////////////////////////////////
std::vector<int> possibleSpells, obligatorySpells; void initObj();
std::vector<std::vector<ui32> > spells; //spells[level] -> vector of spells, first will be available in guild void onHeroVisit(const CGHeroInstance * h) const;
};
struct StrInfo
{ class DLL_EXPORT CGTownInstance : public CArmedInstance
std::map<si32,ui32> creatures; //level - available amount {
public:
template <typename Handler> void serialize(Handler &h, const int version) CTown * town;
{ std::string name; // name of town
h & creatures; int builded; //how many buildings has been built this turn
} int destroyed; //how many buildings has been destroyed this turn
} strInfo; const CGHeroInstance * garrisonHero, *visitingHero;
std::set<CCastleEvent> events; int identifier; //special identifier from h3m (only > RoE maps)
int alignment;
std::set<si32> forbiddenBuildings, builtBuildings;
bool needsLastStack() const; std::vector<int> possibleSpells, obligatorySpells;
int getSightDistance() const; //returns sight distance std::vector<std::vector<ui32> > spells; //spells[level] -> vector of spells, first will be available in guild
int fortLevel() const; //0 - none, 1 - fort, 2 - citadel, 3 - castle
int hallLevel() const; // -1 - none, 0 - village, 1 - town, 2 - city, 3 - capitol struct StrInfo
int mageGuildLevel() const; // -1 - none, 0 - village, 1 - town, 2 - city, 3 - capitol {
bool creatureDwelling(const int & level, bool upgraded=false) const; std::map<si32,ui32> creatures; //level - available amount
int getHordeLevel(const int & HID) const; //HID - 0 or 1; returns creature level or -1 if that horde structure is not present
int creatureGrowth(const int & level) const; template <typename Handler> void serialize(Handler &h, const int version)
bool hasFort() const; {
bool hasCapitol() const; h & creatures;
int dailyIncome() const; }
int spellsAtLevel(int level, bool checkGuild) const; //levels are counted from 1 (1 - 5) } strInfo;
std::set<CCastleEvent> events;
CGTownInstance();
virtual ~CGTownInstance();
bool needsLastStack() const;
////////////////////////////////////////////////////////////////////////// int getSightDistance() const; //returns sight distance
int fortLevel() const; //0 - none, 1 - fort, 2 - citadel, 3 - castle
int hallLevel() const; // -1 - none, 0 - village, 1 - town, 2 - city, 3 - capitol
void onHeroVisit(const CGHeroInstance * h); int mageGuildLevel() const; // -1 - none, 0 - village, 1 - town, 2 - city, 3 - capitol
void onHeroLeave(const CGHeroInstance * h); bool creatureDwelling(const int & level, bool upgraded=false) const;
void initObj(); int getHordeLevel(const int & HID) const; //HID - 0 or 1; returns creature level or -1 if that horde structure is not present
}; int creatureGrowth(const int & level) const;
bool hasFort() const;
class DLL_EXPORT CGVisitableOPH : public CGObjectInstance //objects visitable only once per hero bool hasCapitol() const;
{ int dailyIncome() const;
public: int spellsAtLevel(int level, bool checkGuild) const; //levels are counted from 1 (1 - 5)
std::set<si32> visitors; //ids of heroes who have visited this obj
si8 ttype; //tree type - used only by trees of knowledge: 0 - give level for free; 1 - take 2000 gold; 2 - take 10 gems CGTownInstance();
const std::string & getHoverText() const; virtual ~CGTownInstance();
void onHeroVisit(const CGHeroInstance * h); //////////////////////////////////////////////////////////////////////////
void onNAHeroVisit(int heroID, bool alreadyVisited);
void initObj();
void treeSelected(int heroID, int resType, int resVal, int expVal, ui32 result); //handle player's anwer to the Tree of Knowledge dialog void onHeroVisit(const CGHeroInstance * h) const;
}; void onHeroLeave(const CGHeroInstance * h) const;
void initObj();
class DLL_EXPORT CGEvent : public CGObjectInstance //event objects };
{
public: class DLL_EXPORT CGVisitableOPH : public CGObjectInstance //objects visitable only once per hero
bool areGuarders; //true if there are {
CCreatureSet guarders; public:
bool isMessage; //true if there is a message std::set<si32> visitors; //ids of heroes who have visited this obj
std::string message; si8 ttype; //tree type - used only by trees of knowledge: 0 - give level for free; 1 - take 2000 gold; 2 - take 10 gems
unsigned int gainedExp; const std::string & getHoverText() const;
int manaDiff; //amount of gained / lost mana
int moraleDiff; //morale modifier void onHeroVisit(const CGHeroInstance * h) const;
int luckDiff; //luck modifier void onNAHeroVisit(int heroID, bool alreadyVisited) const;
int wood, mercury, ore, sulfur, crystal, gems, gold; //gained / lost resources void initObj();
unsigned int attack; //added attack points void treeSelected(int heroID, int resType, int resVal, int expVal, ui32 result) const; //handle player's anwer to the Tree of Knowledge dialog
unsigned int defence; //added defence points };
unsigned int power; //added power points
unsigned int knowledge; //added knowledge points class DLL_EXPORT CGEvent : public CGObjectInstance //event objects
std::vector<int> abilities; //gained abilities {
std::vector<int> abilityLevels; //levels of gained abilities public:
std::vector<int> artifacts; //gained artifacts bool areGuarders; //true if there are
std::vector<int> spells; //gained spells CCreatureSet guarders;
CCreatureSet creatures; //gained creatures bool isMessage; //true if there is a message
unsigned char availableFor; //players whom this event is available for std::string message;
bool computerActivate; //true if computre player can activate this event unsigned int gainedExp;
bool humanActivate; //true if human player can activate this event int manaDiff; //amount of gained / lost mana
}; int moraleDiff; //morale modifier
int luckDiff; //luck modifier
class DLL_EXPORT CGCreature : public CArmedInstance //creatures on map int wood, mercury, ore, sulfur, crystal, gems, gold; //gained / lost resources
{ unsigned int attack; //added attack points
public: unsigned int defence; //added defence points
ui32 identifier; //unique code for this monster (used in missions) unsigned int power; //added power points
ui8 character; //chracter of this set of creatures (0 - the most friendly, 4 - the most hostile) unsigned int knowledge; //added knowledge points
std::string message; //message printed for attacking hero std::vector<int> abilities; //gained abilities
std::vector<ui32> resources; //[res_id], resources given to hero that has won with monsters std::vector<int> abilityLevels; //levels of gained abilities
si32 gainedArtifact; //ID of artifact gained to hero, -1 if none std::vector<int> artifacts; //gained artifacts
ui8 neverFlees; //if true, the troops will never flee std::vector<int> spells; //gained spells
ui8 notGrowingTeam; //if true, number of units won't grow CCreatureSet creatures; //gained creatures
unsigned char availableFor; //players whom this event is available for
void onHeroVisit(const CGHeroInstance * h); bool computerActivate; //true if computre player can activate this event
void endBattle(BattleResult *result); bool humanActivate; //true if human player can activate this event
void initObj(); };
};
class DLL_EXPORT CGCreature : public CArmedInstance //creatures on map
{
class DLL_EXPORT CGSignBottle : public CGObjectInstance //signs and ocean bottles public:
{ ui32 identifier; //unique code for this monster (used in missions)
//TODO: generate default message if sign is 'empty' ui8 character; //chracter of this set of creatures (0 - the most friendly, 4 - the most hostile)
public: std::string message; //message printed for attacking hero
std::string message; std::vector<ui32> resources; //[res_id], resources given to hero that has won with monsters
}; si32 gainedArtifact; //ID of artifact gained to hero, -1 if none
ui8 neverFlees; //if true, the troops will never flee
class DLL_EXPORT CGSeerHut : public CGObjectInstance ui8 notGrowingTeam; //if true, number of units won't grow
{
public: void onHeroVisit(const CGHeroInstance * h) const;
unsigned char missionType; //type of mission: 0 - no mission; 1 - reach level; 2 - reach main statistics values; 3 - win with a certain hero; 4 - win with a certain creature; 5 - collect some atifacts; 6 - have certain troops in army; 7 - collect resources; 8 - be a certain hero; 9 - be a certain player void endBattle(BattleResult *result) const;
bool isDayLimit; //if true, there is a day limit void initObj();
int lastDay; //after this day (first day is 0) mission cannot be completed };
int m1level; //for mission 1
int m2attack, m2defence, m2power, m2knowledge;//for mission 2
unsigned char m3bytes[4];//for mission 3 class DLL_EXPORT CGSignBottle : public CGObjectInstance //signs and ocean bottles
unsigned char m4bytes[4];//for mission 4 {
std::vector<int> m5arts;//for mission 5 - artifact ID //TODO: generate default message if sign is 'empty'
std::vector<CCreature *> m6cre;//for mission 6 public:
std::vector<int> m6number; std::string message;
int m7wood, m7mercury, m7ore, m7sulfur, m7crystal, m7gems, m7gold; //for mission 7 };
int m8hero;//for mission 8 - hero ID
int m9player; //for mission 9 - number; from 0 to 7 class DLL_EXPORT CGSeerHut : public CGObjectInstance, public CQuest
{
std::string firstVisitText, nextVisitText, completedText; public:
char rewardType; //type of reward: 0 - no reward; 1 - experience; 2 - mana points; 3 - morale bonus; 4 - luck bonus; 5 - resources; 6 - main ability bonus (attak, defence etd.); 7 - secondary ability gain; 8 - artifact; 9 - spell; 10 - creature
char rewardType; //type of reward: 0 - no reward; 1 - experience; 2 - mana points; 3 - morale bonus; 4 - luck bonus; 5 - resources; 6 - main ability bonus (attak, defence etd.); 7 - secondary ability gain; 8 - artifact; 9 - spell; 10 - creature //for reward 1
//for reward 1 int r1exp;
int r1exp; //for reward 2
//for reward 2 int r2mana;
int r2mana; //for reward 3
//for reward 3 int r3morale;
int r3morale; //for reward 4
//for reward 4 int r4luck;
int r4luck; //for reward 5
//for reward 5 unsigned char r5type; //0 - wood, 1 - mercury, 2 - ore, 3 - sulfur, 4 - crystal, 5 - gems, 6 - gold
unsigned char r5type; //0 - wood, 1 - mercury, 2 - ore, 3 - sulfur, 4 - crystal, 5 - gems, 6 - gold int r5amount;
int r5amount; //for reward 6
//for reward 6 unsigned char r6type; //0 - attack, 1 - defence, 2 - power, 3 - knowledge
unsigned char r6type; //0 - attack, 1 - defence, 2 - power, 3 - knowledge int r6amount;
int r6amount; //for reward 7
//for reward 7 int r7ability; //ability id
int r7ability; //ability id unsigned char r7level; //1 - basic, 2 - advanced, 3 - expert
unsigned char r7level; //1 - basic, 2 - advanced, 3 - expert //for reward 8
//for reward 8 int r8art;//artifact id
int r8art;//artifact id //for reward 9
//for reward 9 int r9spell;//spell id
int r9spell;//spell id //for reward 10
//for reward 10 int r10creature; //creature id
int r10creature; //creature id int r10amount;
int r10amount; };
};
class DLL_EXPORT CGWitchHut : public CGObjectInstance
class DLL_EXPORT CGWitchHut : public CGObjectInstance {
{ public:
public: std::vector<int> allowedAbilities;
std::vector<int> allowedAbilities; };
};
class DLL_EXPORT CGScholar : public CGObjectInstance
class DLL_EXPORT CGScholar : public CGObjectInstance {
{ public:
public: ui8 bonusType; //255 - random, 0 - primary skill, 1 - secondary skill, 2 - spell
ui8 bonusType; //255 - random, 0 - primary skill, 1 - secondary skill, 2 - spell
ui8 r0type;
ui8 r0type; ui32 r1; //Ability ID
ui32 r1; //Ability ID ui32 r2; //Spell ID
ui32 r2; //Spell ID };
};
class DLL_EXPORT CGGarrison : public CArmedInstance
class DLL_EXPORT CGGarrison : public CArmedInstance {
{ public:
public: bool removableUnits;
bool removableUnits; };
};
class DLL_EXPORT CGArtifact : public CArmedInstance
class DLL_EXPORT CGArtifact : public CArmedInstance {
{ public:
public: std::string message;
std::string message; ui32 spell; //if it's spell scroll
ui32 spell; //if it's spell scroll void onHeroVisit(const CGHeroInstance * h) const;
}; void initObj();
};
class DLL_EXPORT CGResource : public CArmedInstance
{ class DLL_EXPORT CGResource : public CArmedInstance
public: {
int amount; //0 if random public:
std::string message; int amount; //0 if random
}; std::string message;
class DLL_EXPORT CGShrine : public CGObjectInstance void onHeroVisit(const CGHeroInstance * h) const;
{ void initObj();
public: };
unsigned char spell; //number of spell or 255 if random
}; class DLL_EXPORT CGPickable : public CGObjectInstance //campfire, treasure chest
{
class DLL_EXPORT CGPandoraBox : public CArmedInstance ui32 type, val1, val2;
{
public: void onHeroVisit(const CGHeroInstance * h) const;
std::string message; void initObj();
void chosen(int which, int heroID) const;
//gained things: };
unsigned int gainedExp;
int manaDiff; class DLL_EXPORT CGShrine : public CGObjectInstance
int moraleDiff; {
int luckDiff; public:
int wood, mercury, ore, sulfur, crystal, gems, gold; unsigned char spell; //number of spell or 255 if random
int attack, defence, power, knowledge; };
std::vector<int> abilities;
std::vector<int> abilityLevels; class DLL_EXPORT CGPandoraBox : public CArmedInstance
std::vector<int> artifacts; {
std::vector<int> spells; public:
CCreatureSet creatures; std::string message;
};
//gained things:
class DLL_EXPORT CGQuestGuard : public CArmedInstance unsigned int gainedExp;
{ int manaDiff;
public: int moraleDiff;
char missionType; //type of mission: 0 - no mission; 1 - reach level; 2 - reach main statistics values; 3 - win with a certain hero; 4 - win with a certain creature; 5 - collect some atifacts; 6 - have certain troops in army; 7 - collect resources; 8 - be a certain hero; 9 - be a certain player int luckDiff;
bool isDayLimit; //if true, there is a day limit int wood, mercury, ore, sulfur, crystal, gems, gold;
int lastDay; //after this day (first day is 0) mission cannot be completed int attack, defence, power, knowledge;
//for mission 1 std::vector<int> abilities;
int m1level; std::vector<int> abilityLevels;
//for mission 2 std::vector<int> artifacts;
int m2attack, m2defence, m2power, m2knowledge; std::vector<int> spells;
//for mission 3 CCreatureSet creatures;
unsigned char m3bytes[4]; };
//for mission 4
unsigned char m4bytes[4]; class DLL_EXPORT CGQuestGuard : public CGObjectInstance, public CQuest
//for mission 5 {
std::vector<int> m5arts; //artifacts id public:
//for mission 6 };
std::vector<CCreature *> m6cre;
std::vector<int> m6number; class DLL_EXPORT CGMine : public CArmedInstance
//for mission 7 {
int m7wood, m7mercury, m7ore, m7sulfur, m7crystal, m7gems, m7gold; public:
//for mission 8 void onHeroVisit(const CGHeroInstance * h) const;
int m8hero; //hero id void newTurn() const;
//for mission 9 void initObj();
int m9player; //number; from 0 to 7 };
std::string firstVisitText, nextVisitText, completedText; class DLL_EXPORT CGVisitableOPW : public CGObjectInstance //objects visitable OPW
}; {
public:
class DLL_EXPORT CObjectHandler ui8 visited; //true if object has been visited this week
{
public: void onHeroVisit(const CGHeroInstance * h) const;
std::vector<std::string> names; //vector of objects; i-th object in vector has subnumber i void newTurn() const;
std::vector<int> cregens; //type 17. dwelling subid -> creature ID };
void loadObjects();
class DLL_EXPORT CGTeleport : public CGObjectInstance //teleports and subterranean gates
std::vector<std::string> creGens; //names of creatures' generators {
std::vector<std::string> advobtxt; public:
std::vector<std::string> xtrainfo; static std::map<int,std::map<int, std::vector<int> > > objs; //map[ID][subID] => vector of ids
std::vector<std::string> restypes; void onHeroVisit(const CGHeroInstance * h) const;
std::vector<std::pair<std::string,std::string> > mines; //first - name; second - event description void initObj();
}; };
class DLL_EXPORT CObjectHandler
{
#endif // __COBJECTHANDLER_H__ public:
std::vector<std::string> names; //vector of objects; i-th object in vector has subnumber i
std::vector<int> cregens; //type 17. dwelling subid -> creature ID
void loadObjects();
std::vector<std::string> creGens; //names of creatures' generators
std::vector<std::string> advobtxt;
std::vector<std::string> xtrainfo;
std::vector<std::string> restypes;
std::vector<std::pair<std::string,std::string> > mines; //first - name; second - event description
};
#endif // __COBJECTHANDLER_H__

36
lib/IGameCallback.cpp Normal file
View File

@ -0,0 +1,36 @@
#define VCMI_DLL
#include "IGameCallback.h"
#include "../CGameState.h"
#include "../map.h"
#include "../hch/CObjectHandler.h"
const CGObjectInstance* IGameCallback::getObj(int objid)
{
return gs->map->objects[objid];
}
const CGHeroInstance* IGameCallback::getHero(int objid)
{
return dynamic_cast<const CGHeroInstance*>(gs->map->objects[objid]);
}
const CGTownInstance* IGameCallback::getTown(int objid)
{
return dynamic_cast<const CGTownInstance*>(gs->map->objects[objid]);
}
int IGameCallback::getOwner(int heroID)
{
return gs->map->objects[heroID]->tempOwner;
}
int IGameCallback::getResource(int player, int which)
{
return gs->players.find(player)->second.resources[which];
}
int IGameCallback::getDate(int mode)
{
return gs->getDate(mode);
}
const CGHeroInstance* IGameCallback::getSelectedHero( int player )
{
return getHero(gs->players.find(player)->second.currentSelection);
}

View File

@ -1,54 +1,58 @@
#ifndef __IGAMECALLBACK_H__ #ifndef __IGAMECALLBACK_H__
#define __IGAMECALLBACK_H__ #define __IGAMECALLBACK_H__
#include "../global.h" #include "../global.h"
#include <vector> #include <vector>
#include <set> #include <set>
#include "../client/FunctionList.h" #include "../client/FunctionList.h"
class CGObjectInstance; class CGObjectInstance;
class CGTownInstance; class CGTownInstance;
class CGHeroInstance; class CGHeroInstance;
struct SelectionDialog; struct SelectionDialog;
struct YesNoDialog; struct YesNoDialog;
struct InfoWindow; struct InfoWindow;
struct MetaString; struct MetaString;
struct ShowInInfobox; struct ShowInInfobox;
struct BattleResult; struct BattleResult;
class CGameState;
class IGameCallback
{ class DLL_EXPORT IGameCallback
public: {
virtual ~IGameCallback(){}; protected:
CGameState *gs;
virtual int getOwner(int heroID)=0; public:
virtual int getResource(int player, int which)=0; virtual ~IGameCallback(){};
virtual int getSelectedHero()=0;
virtual int getDate(int mode=0)=0; virtual int getOwner(int heroID);
virtual const CGObjectInstance* getObj(int objid)=0; virtual int getResource(int player, int which);
virtual const CGHeroInstance* getHero(int objid)=0; virtual int getDate(int mode=0);
virtual const CGTownInstance* getTown(int objid)=0; virtual const CGObjectInstance* getObj(int objid);
virtual const CGHeroInstance* getSelectedHero(int player)=0; //NULL if no hero is selected virtual const CGHeroInstance* getHero(int objid);
virtual int getCurrentPlayer()=0; virtual const CGTownInstance* getTown(int objid);
virtual const CGHeroInstance* getSelectedHero(int player); //NULL if no hero is selected
//do sth virtual int getCurrentPlayer()=0;
virtual void changeSpells(int hid, bool give, const std::set<ui32> &spells)=0; virtual int getSelectedHero()=0;
virtual void removeObject(int objid)=0;
virtual void setBlockVis(int objid, bool bv)=0; //do sth
virtual void setOwner(int objid, ui8 owner)=0; virtual void changeSpells(int hid, bool give, const std::set<ui32> &spells)=0;
virtual void setHoverName(int objid, MetaString * name)=0; virtual void removeObject(int objid)=0;
virtual void changePrimSkill(int ID, int which, int val, bool abs=false)=0; virtual void setBlockVis(int objid, bool bv)=0;
virtual void showInfoDialog(InfoWindow *iw)=0; virtual void setOwner(int objid, ui8 owner)=0;
virtual void showYesNoDialog(YesNoDialog *iw, const CFunctionList<void(ui32)> &callback)=0; virtual void setHoverName(int objid, MetaString * name)=0;
virtual void showSelectionDialog(SelectionDialog *iw, const CFunctionList<void(ui32)> &callback)=0; //returns question id virtual void setObjProperty(int objid, int prop, int val)=0;
virtual void giveResource(int player, int which, int val)=0; virtual void changePrimSkill(int ID, int which, int val, bool abs=false)=0;
virtual void showCompInfo(ShowInInfobox * comp)=0; virtual void showInfoDialog(InfoWindow *iw)=0;
virtual void heroVisitCastle(int obj, int heroID)=0; virtual void showYesNoDialog(YesNoDialog *iw, const CFunctionList<void(ui32)> &callback)=0;
virtual void stopHeroVisitCastle(int obj, int heroID)=0; virtual void showSelectionDialog(SelectionDialog *iw, const CFunctionList<void(ui32)> &callback)=0; //returns question id
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 giveResource(int player, int which, int val)=0;
virtual void startBattleI(const CCreatureSet * army1, const CCreatureSet * army2, int3 tile, const CGHeroInstance *hero1, const CGHeroInstance *hero2, boost::function<void(BattleResult*)> cb)=0; //use hero=NULL for no hero virtual void showCompInfo(ShowInInfobox * comp)=0;
virtual void startBattleI(int heroID, CCreatureSet army, int3 tile, boost::function<void(BattleResult*)> cb)=0; //for hero<=>neutral army virtual void heroVisitCastle(int obj, int heroID)=0;
virtual void setAmount(int objid, ui32 val)=0; virtual void stopHeroVisitCastle(int obj, int heroID)=0;
virtual void moveHero(int hid, int3 pos, bool instant)=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 startBattleI(const CCreatureSet * army1, const CCreatureSet * army2, int3 tile, const CGHeroInstance *hero1, const CGHeroInstance *hero2, boost::function<void(BattleResult*)> cb)=0; //use hero=NULL for no hero
#endif // __IGAMECALLBACK_H__ virtual void startBattleI(int heroID, CCreatureSet army, int3 tile, boost::function<void(BattleResult*)> cb)=0; //for hero<=>neutral army
virtual void setAmount(int objid, ui32 val)=0;
virtual void moveHero(int hid, int3 pos, bool instant)=0;
};
#endif // __IGAMECALLBACK_H__

View File

@ -236,6 +236,18 @@ struct SetHeroArtifacts : public CPack<SetHeroArtifacts> //509
} }
}; };
struct SetSelection : public CPack<SetSelection> //514
{
SetSelection(){type = 514;};
ui8 player;
ui32 id;
template <typename Handler> void serialize(Handler &h, const int version)
{
h & id & player;
}
};
struct HeroRecruited : public CPack<HeroRecruited> //515 struct HeroRecruited : public CPack<HeroRecruited> //515
{ {
HeroRecruited(){type = 515;}; HeroRecruited(){type = 515;};
@ -346,7 +358,7 @@ struct InfoWindow : public CPack<InfoWindow> //103 - displays simple info windo
struct SetObjectProperty : public CPack<SetObjectProperty>//1001 struct SetObjectProperty : public CPack<SetObjectProperty>//1001
{ {
ui32 id; ui32 id;
ui8 what; //1 - owner; 2 - blockvis; 3 - amount (works with creatures stacks) ui8 what; //1 - owner; 2 - blockvis
ui32 val; ui32 val;
SetObjectProperty(){type = 1001;}; SetObjectProperty(){type = 1001;};
SetObjectProperty(ui32 ID, ui8 What, ui32 Val):id(ID),what(What),val(Val){type = 1001;}; SetObjectProperty(ui32 ID, ui8 What, ui32 Val):id(ID),what(What),val(Val){type = 1001;};

View File

@ -310,6 +310,10 @@
RelativePath="..\hch\CTownHandler.cpp" RelativePath="..\hch\CTownHandler.cpp"
> >
</File> </File>
<File
RelativePath=".\IGameCallback.cpp"
>
</File>
<File <File
RelativePath="..\map.cpp" RelativePath="..\map.cpp"
> >

531
map.cpp
View File

@ -577,203 +577,7 @@ int Mapa::loadSeerHut( unsigned char * bufor, int i, CGObjectInstance *& nobj )
if(version>RoE) if(version>RoE)
{ {
hut->missionType = bufor[i]; ++i; loadQuest(hut,bufor,i);
switch(hut->missionType)
{
case 0:
i+=3;
return i;
case 1:
{
hut->m1level = readNormalNr(bufor,i); i+=4;
int limit = readNormalNr(bufor,i); i+=4;
if(limit == ((int)0xffffffff))
{
hut->isDayLimit = false;
hut->lastDay = -1;
}
else
{
hut->isDayLimit = true;
hut->lastDay = limit;
}
break;
}
case 2:
{
hut->m2attack = bufor[i]; ++i;
hut->m2defence = bufor[i]; ++i;
hut->m2power = bufor[i]; ++i;
hut->m2knowledge = bufor[i]; ++i;
int limit = readNormalNr(bufor,i); i+=4;
if(limit == ((int)0xffffffff))
{
hut->isDayLimit = false;
hut->lastDay = -1;
}
else
{
hut->isDayLimit = true;
hut->lastDay = limit;
}
break;
}
case 3:
{
hut->m3bytes[0] = bufor[i]; ++i;
hut->m3bytes[1] = bufor[i]; ++i;
hut->m3bytes[2] = bufor[i]; ++i;
hut->m3bytes[3] = bufor[i]; ++i;
int limit = readNormalNr(bufor,i); i+=4;
if(limit == ((int)0xffffffff))
{
hut->isDayLimit = false;
hut->lastDay = -1;
}
else
{
hut->isDayLimit = true;
hut->lastDay = limit;
}
break;
}
case 4:
{
hut->m4bytes[0] = bufor[i]; ++i;
hut->m4bytes[1] = bufor[i]; ++i;
hut->m4bytes[2] = bufor[i]; ++i;
hut->m4bytes[3] = bufor[i]; ++i;
int limit = readNormalNr(bufor,i); i+=4;
if(limit == ((int)0xffffffff))
{
hut->isDayLimit = false;
hut->lastDay = -1;
}
else
{
hut->isDayLimit = true;
hut->lastDay = limit;
}
break;
}
case 5:
{
int artNumber = bufor[i]; ++i;
for(int yy=0; yy<artNumber; ++yy)
{
int artid = readNormalNr(bufor,i, 2); i+=2;
hut->m5arts.push_back(artid);
}
int limit = readNormalNr(bufor,i); i+=4;
if(limit == ((int)0xffffffff))
{
hut->isDayLimit = false;
hut->lastDay = -1;
}
else
{
hut->isDayLimit = true;
hut->lastDay = limit;
}
break;
}
case 6:
{
int typeNumber = bufor[i]; ++i;
for(int hh=0; hh<typeNumber; ++hh)
{
int creType = readNormalNr(bufor,i, 2); i+=2;
int creNumb = readNormalNr(bufor,i, 2); i+=2;
hut->m6cre.push_back(&(VLC->creh->creatures[creType]));
hut->m6number.push_back(creNumb);
}
int limit = readNormalNr(bufor,i); i+=4;
if(limit == ((int)0xffffffff))
{
hut->isDayLimit = false;
hut->lastDay = -1;
}
else
{
hut->isDayLimit = true;
hut->lastDay = limit;
}
break;
}
case 7:
{
hut->m7wood = readNormalNr(bufor,i); i+=4;
hut->m7mercury = readNormalNr(bufor,i); i+=4;
hut->m7ore = readNormalNr(bufor,i); i+=4;
hut->m7sulfur = readNormalNr(bufor,i); i+=4;
hut->m7crystal = readNormalNr(bufor,i); i+=4;
hut->m7gems = readNormalNr(bufor,i); i+=4;
hut->m7gold = readNormalNr(bufor,i); i+=4;
int limit = readNormalNr(bufor,i); i+=4;
if(limit == ((int)0xffffffff))
{
hut->isDayLimit = false;
hut->lastDay = -1;
}
else
{
hut->isDayLimit = true;
hut->lastDay = limit;
}
break;
}
case 8:
{
int heroType = bufor[i]; ++i;
hut->m8hero = heroType;
int limit = readNormalNr(bufor,i); i+=4;
if(limit == ((int)0xffffffff))
{
hut->isDayLimit = false;
hut->lastDay = -1;
}
else
{
hut->isDayLimit = true;
hut->lastDay = limit;
}
break;
}
case 9:
{
hut->m9player = bufor[i]; ++i;
int limit = readNormalNr(bufor,i); i+=4;
if(limit == ((int)0xffffffff))
{
hut->isDayLimit = false;
hut->lastDay = -1;
}
else
{
hut->isDayLimit = true;
hut->lastDay = limit;
}
break;
}
}//internal switch end (seer huts)
int len1 = readNormalNr(bufor,i); i+=4;
for(int ee=0; ee<len1; ++ee)
{
hut->firstVisitText += bufor[i]; ++i;
}
int len2 = readNormalNr(bufor,i); i+=4;
for(int ee=0; ee<len2; ++ee)
{
hut->nextVisitText += bufor[i]; ++i;
}
int len3 = readNormalNr(bufor,i); i+=4;
for(int ee=0; ee<len3; ++ee)
{
hut->completedText += bufor[i]; ++i;
}
} }
else //RoE else //RoE
{ {
@ -1848,7 +1652,40 @@ void Mapa::readObjects( unsigned char * bufor, int &i)
loadHero(nobj, bufor, i); loadHero(nobj, bufor, i);
break; break;
} }
case 54: case 71: case 72: case 73: case 74: case 75: case 162: case 163: case 164: case 51: //Mercenary Camp
case 23: //Marletto Tower
case 61: // Star Axis
case 32: // Garden of Revelation
case 100: //Learning Stone
case 102: //Tree of Knowledge
{
nobj = new CGVisitableOPH();
break;
}
case 55: //mystical garden
case 112://windmill
case 109://water wheel
{
nobj = new CGVisitableOPW();
break;
}
case 43: //teleport
case 44: //teleport
case 45: //teleport
case 103://subterranean gate
{
nobj = new CGTeleport();
break;
}
case 12: //campfire
case 101: //treasure chest
{
nobj = new CGPickable();
break;
}
case 54: //Monster
case 71: case 72: case 73: case 74: case 75: // Random Monster 1 - 4
case 162: case 163: case 164: // Random Monster 5 - 7
{ {
CGCreature *cre = new CGCreature(); CGCreature *cre = new CGCreature();
nobj = cre; nobj = cre;
@ -1971,7 +1808,8 @@ void Mapa::readObjects( unsigned char * bufor, int &i)
i+=8; i+=8;
break; break;
} }
case 5: case 65: case 66: case 67: case 68: case 69: //artifact case 5: //artifact
case 65: case 66: case 67: case 68: case 69: //random artifact
case 93: //spell scroll case 93: //spell scroll
{ {
CGArtifact *art = new CGArtifact(); CGArtifact *art = new CGArtifact();
@ -1991,7 +1829,7 @@ void Mapa::readObjects( unsigned char * bufor, int &i)
} }
break; break;
} }
case 76: case 79: //resource case 76: case 79: //random resource; resource
{ {
CGResource *res = new CGResource(); CGResource *res = new CGResource();
nobj = res; nobj = res;
@ -2011,12 +1849,22 @@ void Mapa::readObjects( unsigned char * bufor, int &i)
break; break;
} }
case 77: case 98: //town case 77: case 98: //random town; town
{ {
loadTown(nobj, bufor, i); loadTown(nobj, bufor, i);
break; break;
} }
case 53: case 17: case 18: case 19: case 20: case 42: case 87: case 220://cases 17 - 20 and 42 - tests case 53:
{
nobj = new CGMine();
nobj->setOwner(bufor[i++]);
i+=3;
break;
}
case 17: case 18: case 19: case 20: //dwellings
case 42: //lighthouse
case 87: //shipyard
case 220://mine (?)
{ {
nobj = new CGObjectInstance(); nobj = new CGObjectInstance();
nobj->setOwner(bufor[i++]); nobj->setOwner(bufor[i++]);
@ -2157,206 +2005,7 @@ void Mapa::readObjects( unsigned char * bufor, int &i)
{ {
CGQuestGuard *guard = new CGQuestGuard(); CGQuestGuard *guard = new CGQuestGuard();
nobj = guard; nobj = guard;
guard->missionType = bufor[i]; ++i; loadQuest(guard, bufor, i);
int len1, len2, len3;
switch(guard->missionType)
{
case 0:
{
goto borderguardend;
break;
}
case 1:
{
guard->m1level = readNormalNr(bufor,i); i+=4;
int limit = readNormalNr(bufor,i); i+=4;
if(limit == ((int)0xffffffff))
{
guard->isDayLimit = false;
guard->lastDay = -1;
}
else
{
guard->isDayLimit = true;
guard->lastDay = limit;
}
break;
}
case 2:
{
guard->m2attack = bufor[i]; ++i;
guard->m2defence = bufor[i]; ++i;
guard->m2power = bufor[i]; ++i;
guard->m2knowledge = bufor[i]; ++i;
int limit = readNormalNr(bufor,i); i+=4;
if(limit == ((int)0xffffffff))
{
guard->isDayLimit = false;
guard->lastDay = -1;
}
else
{
guard->isDayLimit = true;
guard->lastDay = limit;
}
break;
}
case 3:
{
guard->m3bytes[0] = bufor[i]; ++i;
guard->m3bytes[1] = bufor[i]; ++i;
guard->m3bytes[2] = bufor[i]; ++i;
guard->m3bytes[3] = bufor[i]; ++i;
int limit = readNormalNr(bufor,i); i+=4;
if(limit == ((int)0xffffffff))
{
guard->isDayLimit = false;
guard->lastDay = -1;
}
else
{
guard->isDayLimit = true;
guard->lastDay = limit;
}
break;
}
case 4:
{
guard->m4bytes[0] = bufor[i]; ++i;
guard->m4bytes[1] = bufor[i]; ++i;
guard->m4bytes[2] = bufor[i]; ++i;
guard->m4bytes[3] = bufor[i]; ++i;
int limit = readNormalNr(bufor,i); i+=4;
if(limit == ((int)0xffffffff))
{
guard->isDayLimit = false;
guard->lastDay = -1;
}
else
{
guard->isDayLimit = true;
guard->lastDay = limit;
}
break;
}
case 5:
{
int artNumber = bufor[i]; ++i;
for(int yy=0; yy<artNumber; ++yy)
{
guard->m5arts.push_back(readNormalNr(bufor,i, 2)); i+=2;
}
int limit = readNormalNr(bufor,i); i+=4;
if(limit == ((int)0xffffffff))
{
guard->isDayLimit = false;
guard->lastDay = -1;
}
else
{
guard->isDayLimit = true;
guard->lastDay = limit;
}
break;
}
case 6:
{
int typeNumber = bufor[i]; ++i;
for(int hh=0; hh<typeNumber; ++hh)
{
int creType = readNormalNr(bufor,i, 2); i+=2;
int creNumb = readNormalNr(bufor,i, 2); i+=2;
guard->m6cre.push_back(&(VLC->creh->creatures[creType]));
guard->m6number.push_back(creNumb);
}
int limit = readNormalNr(bufor,i); i+=4;
if(limit == ((int)0xffffffff))
{
guard->isDayLimit = false;
guard->lastDay = -1;
}
else
{
guard->isDayLimit = true;
guard->lastDay = limit;
}
break;
}
case 7:
{
guard->m7wood = readNormalNr(bufor,i); i+=4;
guard->m7mercury = readNormalNr(bufor,i); i+=4;
guard->m7ore = readNormalNr(bufor,i); i+=4;
guard->m7sulfur = readNormalNr(bufor,i); i+=4;
guard->m7crystal = readNormalNr(bufor,i); i+=4;
guard->m7gems = readNormalNr(bufor,i); i+=4;
guard->m7gold = readNormalNr(bufor,i); i+=4;
int limit = readNormalNr(bufor,i); i+=4;
if(limit == ((int)0xffffffff))
{
guard->isDayLimit = false;
guard->lastDay = -1;
}
else
{
guard->isDayLimit = true;
guard->lastDay = limit;
}
break;
}
case 8:
{
int heroType = bufor[i]; ++i;
guard->m8hero = heroType;
int limit = readNormalNr(bufor,i); i+=4;
if(limit == ((int)0xffffffff))
{
guard->isDayLimit = false;
guard->lastDay = -1;
}
else
{
guard->isDayLimit = true;
guard->lastDay = limit;
}
break;
}
case 9:
{
guard->m9player = bufor[i]; ++i;
int limit = readNormalNr(bufor,i); i+=4;
if(limit == ((int)0xffffffff))
{
guard->isDayLimit = false;
guard->lastDay = -1;
}
else
{
guard->isDayLimit = true;
guard->lastDay = limit;
}
break;
}
}//internal switch end (seer huts)
len1 = readNormalNr(bufor,i); i+=4;
for(int ee=0; ee<len1; ++ee)
{
guard->firstVisitText += bufor[i]; ++i;
}
len2 = readNormalNr(bufor,i); i+=4;
for(int ee=0; ee<len2; ++ee)
{
guard->nextVisitText += bufor[i]; ++i;
}
len3 = readNormalNr(bufor,i); i+=4;
for(int ee=0; ee<len3; ++ee)
{
guard->completedText += bufor[i]; ++i;
}
borderguardend:
break; break;
} }
case 214: //hero placeholder case 214: //hero placeholder
@ -2428,3 +2077,81 @@ bool Mapa::isInTheMap( int3 pos )
return false; return false;
else return true; else return true;
} }
void Mapa::loadQuest(CQuest * guard, unsigned char * bufor, int & i)
{
guard->missionType = bufor[i]; ++i;
int len1, len2, len3;
switch(guard->missionType)
{
case 0:
return;
case 2:
{
guard->m2stats.resize(4);
for(int x=0; x<4; x++)
{
guard->m2stats[x] = bufor[i++];
}
}
break;
case 1:
case 3:
case 4:
{
guard->m13489val = readNormalNr(bufor,i); i+=4;
break;
}
case 5:
{
int artNumber = bufor[i]; ++i;
for(int yy=0; yy<artNumber; ++yy)
{
guard->m5arts.push_back(readNormalNr(bufor,i, 2)); i+=2;
}
break;
}
case 6:
{
int typeNumber = bufor[i]; ++i;
for(int hh=0; hh<typeNumber; ++hh)
{
ui32 creType = readNormalNr(bufor,i, 2); i+=2;
ui32 creNumb = readNormalNr(bufor,i, 2); i+=2;
guard->m6creatures.push_back(std::make_pair(creType,creNumb));
}
break;
}
case 7:
{
guard->m7resources.resize(7);
for(int x=0; x<7; x++)
{
guard->m7resources[x] = readNormalNr(bufor,i);
i+=4;
}
break;
}
case 8:
case 9:
{
guard->m13489val = bufor[i]; ++i;
break;
}
}
int limit = readNormalNr(bufor,i); i+=4;
if(limit == ((int)0xffffffff))
{
guard->lastDay = -1;
}
else
{
guard->lastDay = limit;
}
guard->firstVisitText = readString(bufor,i);
guard->nextVisitText = readString(bufor,i);
guard->completedText = readString(bufor,i);
}

782
map.h
View File

@ -1,390 +1,392 @@
#ifndef __MAP_H__ #ifndef __MAP_H__
#define __MAP_H__ #define __MAP_H__
#ifdef _MSC_VER #ifdef _MSC_VER
#pragma warning (disable : 4482) #pragma warning (disable : 4482)
#endif #endif
#include <cstring> #include <cstring>
#include <vector> #include <vector>
#include <map> #include <map>
#include <set> #include <set>
#include "global.h" #include "global.h"
class CGDefInfo; class CGDefInfo;
class CGObjectInstance; class CGObjectInstance;
class CGHeroInstance; class CGHeroInstance;
class CGTownInstance; class CQuest;
enum ESortBy{_name, _playerAm, _size, _format, _viccon, _loscon}; class CGTownInstance;
enum EDefType {TOWN_DEF, HERO_DEF, CREATURES_DEF, SEERHUT_DEF, RESOURCE_DEF, TERRAINOBJ_DEF, enum ESortBy{_name, _playerAm, _size, _format, _viccon, _loscon};
EVENTOBJ_DEF, SIGN_DEF, GARRISON_DEF, ARTIFACT_DEF, WITCHHUT_DEF, SCHOLAR_DEF, PLAYERONLY_DEF, enum EDefType {TOWN_DEF, HERO_DEF, CREATURES_DEF, SEERHUT_DEF, RESOURCE_DEF, TERRAINOBJ_DEF,
SHRINE_DEF, SPELLSCROLL_DEF, PANDORA_DEF, GRAIL_DEF, CREGEN_DEF, CREGEN2_DEF, CREGEN3_DEF, EVENTOBJ_DEF, SIGN_DEF, GARRISON_DEF, ARTIFACT_DEF, WITCHHUT_DEF, SCHOLAR_DEF, PLAYERONLY_DEF,
BORDERGUARD_DEF, HEROPLACEHOLDER_DEF}; SHRINE_DEF, SPELLSCROLL_DEF, PANDORA_DEF, GRAIL_DEF, CREGEN_DEF, CREGEN2_DEF, CREGEN3_DEF,
BORDERGUARD_DEF, HEROPLACEHOLDER_DEF};
class DLL_EXPORT CSpecObjInfo
{ class DLL_EXPORT CSpecObjInfo
public: {
virtual ~CSpecObjInfo(){}; public:
}; virtual ~CSpecObjInfo(){};
};
class DLL_EXPORT CCreGenObjInfo : public CSpecObjInfo
{ class DLL_EXPORT CCreGenObjInfo : public CSpecObjInfo
public: {
unsigned char player; //owner public:
bool asCastle; unsigned char player; //owner
int identifier; bool asCastle;
unsigned char castles[2]; //allowed castles int identifier;
}; unsigned char castles[2]; //allowed castles
class DLL_EXPORT CCreGen2ObjInfo : public CSpecObjInfo };
{ class DLL_EXPORT CCreGen2ObjInfo : public CSpecObjInfo
public: {
unsigned char player; //owner public:
bool asCastle; unsigned char player; //owner
int identifier; bool asCastle;
unsigned char castles[2]; //allowed castles int identifier;
unsigned char minLevel, maxLevel; //minimal and maximal level of creature in dwelling: <0, 6> unsigned char castles[2]; //allowed castles
}; unsigned char minLevel, maxLevel; //minimal and maximal level of creature in dwelling: <0, 6>
class DLL_EXPORT CCreGen3ObjInfo : public CSpecObjInfo };
{ class DLL_EXPORT CCreGen3ObjInfo : public CSpecObjInfo
public: {
unsigned char player; //owner public:
unsigned char minLevel, maxLevel; //minimal and maximal level of creature in dwelling: <0, 6> unsigned char player; //owner
}; unsigned char minLevel, maxLevel; //minimal and maximal level of creature in dwelling: <0, 6>
};
struct DLL_EXPORT Sresource
{ struct DLL_EXPORT Sresource
std::string resName; //name of this resource {
int amount; //it can be greater and lesser than 0 std::string resName; //name of this resource
}; int amount; //it can be greater and lesser than 0
struct DLL_EXPORT TimeEvent };
{ struct DLL_EXPORT TimeEvent
std::string eventName; {
std::string message; std::string eventName;
std::vector<Sresource> decIncRes; //decreases / increases of resources std::string message;
unsigned int whichPlayers; //which players are affected by this event (+1 - first, +2 - second, +4 - third, +8 - fourth etc.) std::vector<Sresource> decIncRes; //decreases / increases of resources
bool areHumansAffected; unsigned int whichPlayers; //which players are affected by this event (+1 - first, +2 - second, +4 - third, +8 - fourth etc.)
bool areCompsAffected; bool areHumansAffected;
int firstAfterNDays; //how many days after appears this event bool areCompsAffected;
int nextAfterNDays; //how many days after the epperance before appaers this event int firstAfterNDays; //how many days after appears this event
}; int nextAfterNDays; //how many days after the epperance before appaers this event
struct DLL_EXPORT TerrainTile };
{ struct DLL_EXPORT TerrainTile
EterrainType tertype; // type of terrain {
unsigned char terview; // look of terrain EterrainType tertype; // type of terrain
Eriver nuine; // type of Eriver (0 if there is no Eriver) unsigned char terview; // look of terrain
unsigned char rivDir; // direction of Eriver Eriver nuine; // type of Eriver (0 if there is no Eriver)
Eroad malle; // type of Eroad (0 if there is no Eriver) unsigned char rivDir; // direction of Eriver
unsigned char roadDir; // direction of Eroad Eroad malle; // type of Eroad (0 if there is no Eriver)
unsigned char siodmyTajemniczyBajt; //bitfield, info whether this tile is coastal and how to rotate tile graphics unsigned char roadDir; // direction of Eroad
unsigned char siodmyTajemniczyBajt; //bitfield, info whether this tile is coastal and how to rotate tile graphics
bool visitable; //false = not visitable; true = visitable
bool blocked; //false = free; true = blocked; bool visitable; //false = not visitable; true = visitable
bool blocked; //false = free; true = blocked;
std::vector <CGObjectInstance*> visitableObjects; //pointers to objects hero can visit while being on this tile
std::vector <CGObjectInstance*> blockingObjects; //pointers to objects that are blocking this tile std::vector <CGObjectInstance*> visitableObjects; //pointers to objects hero can visit while being on this tile
std::vector <CGObjectInstance*> blockingObjects; //pointers to objects that are blocking this tile
template <typename Handler> void serialize(Handler &h, const int version)
{ template <typename Handler> void serialize(Handler &h, const int version)
h & tertype & terview & nuine & rivDir & malle &roadDir & siodmyTajemniczyBajt; {
} h & tertype & terview & nuine & rivDir & malle &roadDir & siodmyTajemniczyBajt;
}; }
struct DLL_EXPORT SheroName //name of starting hero };
{ struct DLL_EXPORT SheroName //name of starting hero
int heroID; {
std::string heroName; int heroID;
std::string heroName;
template <typename Handler> void serialize(Handler &h, const int version)
{ template <typename Handler> void serialize(Handler &h, const int version)
h & heroID & heroName; {
} h & heroID & heroName;
}; }
struct DLL_EXPORT PlayerInfo };
{ struct DLL_EXPORT PlayerInfo
si32 p7, p8, p9; {
ui8 canHumanPlay; si32 p7, p8, p9;
ui8 canComputerPlay; ui8 canHumanPlay;
ui32 AITactic; //(00 - random, 01 - warrior, 02 - builder, 03 - explorer) ui8 canComputerPlay;
ui32 allowedFactions; //(01 - castle; 02 - rampart; 04 - tower; 08 - inferno; 16 - necropolis; 32 - dungeon; 64 - stronghold; 128 - fortress; 256 - conflux); ui32 AITactic; //(00 - random, 01 - warrior, 02 - builder, 03 - explorer)
ui8 isFactionRandom; ui32 allowedFactions; //(01 - castle; 02 - rampart; 04 - tower; 08 - inferno; 16 - necropolis; 32 - dungeon; 64 - stronghold; 128 - fortress; 256 - conflux);
ui32 mainHeroPortrait; //it's ID of hero with choosen portrait; 255 if standard ui8 isFactionRandom;
std::string mainHeroName; ui32 mainHeroPortrait; //it's ID of hero with choosen portrait; 255 if standard
std::vector<SheroName> heroesNames; std::string mainHeroName;
ui8 hasMainTown; std::vector<SheroName> heroesNames;
ui8 generateHeroAtMainTown; ui8 hasMainTown;
int3 posOfMainTown; ui8 generateHeroAtMainTown;
ui8 team; int3 posOfMainTown;
ui8 generateHero; ui8 team;
ui8 generateHero;
template <typename Handler> void serialize(Handler &h, const int version)
{ template <typename Handler> void serialize(Handler &h, const int version)
h & p7 & p8 & p9 & canHumanPlay & canComputerPlay & AITactic & allowedFactions & isFactionRandom & {
mainHeroPortrait & mainHeroName & heroesNames & hasMainTown & generateHeroAtMainTown & h & p7 & p8 & p9 & canHumanPlay & canComputerPlay & AITactic & allowedFactions & isFactionRandom &
posOfMainTown & team & generateHero; mainHeroPortrait & mainHeroName & heroesNames & hasMainTown & generateHeroAtMainTown &
} posOfMainTown & team & generateHero;
}; }
struct DLL_EXPORT LossCondition };
{ struct DLL_EXPORT LossCondition
ElossCon typeOfLossCon; {
int3 castlePos; ElossCon typeOfLossCon;
int3 heroPos; int3 castlePos;
int timeLimit; // in days int3 heroPos;
int timeLimit; // in days
template <typename Handler> void serialize(Handler &h, const int version)
{ template <typename Handler> void serialize(Handler &h, const int version)
h & typeOfLossCon & castlePos & heroPos & timeLimit; {
} h & typeOfLossCon & castlePos & heroPos & timeLimit;
}; }
struct DLL_EXPORT CspecificVictoryConidtions };
{ struct DLL_EXPORT CspecificVictoryConidtions
bool allowNormalVictory; {
bool appliesToAI; bool allowNormalVictory;
}; bool appliesToAI;
struct DLL_EXPORT VicCon0 : public CspecificVictoryConidtions //acquire artifact };
{ struct DLL_EXPORT VicCon0 : public CspecificVictoryConidtions //acquire artifact
int ArtifactID; {
}; int ArtifactID;
struct DLL_EXPORT VicCon1 : public CspecificVictoryConidtions //accumulate creatures };
{ struct DLL_EXPORT VicCon1 : public CspecificVictoryConidtions //accumulate creatures
int monsterID; {
int neededQuantity; int monsterID;
}; int neededQuantity;
struct DLL_EXPORT VicCon2 : public CspecificVictoryConidtions // accumulate resources };
{ struct DLL_EXPORT VicCon2 : public CspecificVictoryConidtions // accumulate resources
int resourceID; {
int neededQuantity; int resourceID;
}; int neededQuantity;
struct DLL_EXPORT VicCon3 : public CspecificVictoryConidtions // upgrade specific town };
{ struct DLL_EXPORT VicCon3 : public CspecificVictoryConidtions // upgrade specific town
int3 posOfCity; {
int councilNeededLevel; //0 - town; 1 - city; 2 - capitol int3 posOfCity;
int fortNeededLevel;// 0 - fort; 1 - citadel; 2 - castle int councilNeededLevel; //0 - town; 1 - city; 2 - capitol
}; int fortNeededLevel;// 0 - fort; 1 - citadel; 2 - castle
struct DLL_EXPORT VicCon4 : public CspecificVictoryConidtions // build grail structure };
{ struct DLL_EXPORT VicCon4 : public CspecificVictoryConidtions // build grail structure
bool anyLocation; {
int3 whereBuildGrail; bool anyLocation;
}; int3 whereBuildGrail;
struct DLL_EXPORT VicCon5 : public CspecificVictoryConidtions // defeat a specific hero };
{ struct DLL_EXPORT VicCon5 : public CspecificVictoryConidtions // defeat a specific hero
int3 locationOfHero; {
}; int3 locationOfHero;
struct DLL_EXPORT VicCon6 : public CspecificVictoryConidtions // capture a specific town };
{ struct DLL_EXPORT VicCon6 : public CspecificVictoryConidtions // capture a specific town
int3 locationOfTown; {
}; int3 locationOfTown;
struct DLL_EXPORT VicCon7 : public CspecificVictoryConidtions // defeat a specific monster };
{ struct DLL_EXPORT VicCon7 : public CspecificVictoryConidtions // defeat a specific monster
int3 locationOfMonster; {
}; int3 locationOfMonster;
struct DLL_EXPORT VicCona : public CspecificVictoryConidtions //transport specific artifact };
{ struct DLL_EXPORT VicCona : public CspecificVictoryConidtions //transport specific artifact
int artifactID; {
int3 destinationPlace; int artifactID;
}; int3 destinationPlace;
struct DLL_EXPORT Rumor };
{ struct DLL_EXPORT Rumor
std::string name, text; {
std::string name, text;
template <typename Handler> void serialize(Handler &h, const int version)
{ template <typename Handler> void serialize(Handler &h, const int version)
h & name & text; {
} h & name & text;
}; }
};
struct DLL_EXPORT DisposedHero
{ struct DLL_EXPORT DisposedHero
ui32 ID; {
ui16 portrait; //0xFF - default ui32 ID;
std::string name; ui16 portrait; //0xFF - default
ui8 players; //who can hire this hero (bitfield) std::string name;
ui8 players; //who can hire this hero (bitfield)
template <typename Handler> void serialize(Handler &h, const int version)
{ template <typename Handler> void serialize(Handler &h, const int version)
h & ID & portrait & name & players; {
} h & ID & portrait & name & players;
}; }
};
class DLL_EXPORT CMapEvent
{ class DLL_EXPORT CMapEvent
public: {
std::string name, message; public:
si32 wood, mercury, ore, sulfur, crystal, gems, gold; //gained / taken resources std::string name, message;
ui8 players; //affected players si32 wood, mercury, ore, sulfur, crystal, gems, gold; //gained / taken resources
ui8 humanAffected; ui8 players; //affected players
ui8 computerAffected; ui8 humanAffected;
ui32 firstOccurence; ui8 computerAffected;
ui32 nextOccurence; //after nextOccurance day event will occure; if it it 0, event occures only one time; ui32 firstOccurence;
template <typename Handler> void serialize(Handler &h, const int version) ui32 nextOccurence; //after nextOccurance day event will occure; if it it 0, event occures only one time;
{ template <typename Handler> void serialize(Handler &h, const int version)
h & name & message & wood & mercury & ore & sulfur & crystal & gems & gold {
& players & humanAffected & computerAffected & firstOccurence & nextOccurence; h & name & message & wood & mercury & ore & sulfur & crystal & gems & gold
} & players & humanAffected & computerAffected & firstOccurence & nextOccurence;
}; }
class DLL_EXPORT CMapHeader };
{ class DLL_EXPORT CMapHeader
public: {
Eformat version; // version of map Eformat public:
bool areAnyPLayers; // if there are any playable players on map Eformat version; // version of map Eformat
int height, width; bool areAnyPLayers; // if there are any playable players on map
bool twoLevel; // if map has underground level int height, width;
std::string name; //name of map bool twoLevel; // if map has underground level
std::string description; //and description std::string name; //name of map
int difficulty; // 0 easy - 4 impossible std::string description; //and description
int levelLimit; int difficulty; // 0 easy - 4 impossible
LossCondition lossCondition; int levelLimit;
EvictoryConditions victoryCondition; //victory conditions LossCondition lossCondition;
CspecificVictoryConidtions * vicConDetails; // used only if vistory conditions aren't standard EvictoryConditions victoryCondition; //victory conditions
PlayerInfo players[8]; // info about players CspecificVictoryConidtions * vicConDetails; // used only if vistory conditions aren't standard
std::vector<int> teams; // teams[i] = team of player no i PlayerInfo players[8]; // info about players
int howManyTeams; std::vector<int> teams; // teams[i] = team of player no i
CMapHeader(unsigned char *map); //an argument is a reference to string described a map (unpacked) int howManyTeams;
}; CMapHeader(unsigned char *map); //an argument is a reference to string described a map (unpacked)
class DLL_EXPORT CMapInfo : public CMapHeader };
{ class DLL_EXPORT CMapInfo : public CMapHeader
public: {
std::string filename; public:
int playerAmnt, humenPlayers; std::string filename;
CMapInfo(std::string fname, unsigned char *map):CMapHeader(map),filename(fname) int playerAmnt, humenPlayers;
{ CMapInfo(std::string fname, unsigned char *map):CMapHeader(map),filename(fname)
playerAmnt=humenPlayers=0; {
for (int i=0;i<PLAYER_LIMIT;i++) playerAmnt=humenPlayers=0;
{ for (int i=0;i<PLAYER_LIMIT;i++)
if (players[i].canHumanPlay) {playerAmnt++;humenPlayers++;} {
else if (players[i].canComputerPlay) {playerAmnt++;} if (players[i].canHumanPlay) {playerAmnt++;humenPlayers++;}
} else if (players[i].canComputerPlay) {playerAmnt++;}
}; }
}; };
};
class DLL_EXPORT mapSorter
{ class DLL_EXPORT mapSorter
public: {
ESortBy sortBy; public:
bool operator()(const CMapHeader & a, const CMapHeader& b) ESortBy sortBy;
{ bool operator()(const CMapHeader & a, const CMapHeader& b)
switch (sortBy) {
{ switch (sortBy)
case _format: {
return (a.version<b.version); case _format:
break; return (a.version<b.version);
case _loscon: break;
return (a.lossCondition.typeOfLossCon<b.lossCondition.typeOfLossCon); case _loscon:
break; return (a.lossCondition.typeOfLossCon<b.lossCondition.typeOfLossCon);
case _playerAm: break;
int playerAmntB,humenPlayersB,playerAmntA,humenPlayersA; case _playerAm:
playerAmntB=humenPlayersB=playerAmntA=humenPlayersA=0; int playerAmntB,humenPlayersB,playerAmntA,humenPlayersA;
for (int i=0;i<8;i++) playerAmntB=humenPlayersB=playerAmntA=humenPlayersA=0;
{ for (int i=0;i<8;i++)
if (a.players[i].canHumanPlay) {playerAmntA++;humenPlayersA++;} {
else if (a.players[i].canComputerPlay) {playerAmntA++;} if (a.players[i].canHumanPlay) {playerAmntA++;humenPlayersA++;}
if (b.players[i].canHumanPlay) {playerAmntB++;humenPlayersB++;} else if (a.players[i].canComputerPlay) {playerAmntA++;}
else if (b.players[i].canComputerPlay) {playerAmntB++;} if (b.players[i].canHumanPlay) {playerAmntB++;humenPlayersB++;}
} else if (b.players[i].canComputerPlay) {playerAmntB++;}
if (playerAmntB!=playerAmntA) }
return (playerAmntA<playerAmntB); if (playerAmntB!=playerAmntA)
else return (playerAmntA<playerAmntB);
return (humenPlayersA<humenPlayersB); else
break; return (humenPlayersA<humenPlayersB);
case _size: break;
return (a.width<b.width); case _size:
break; return (a.width<b.width);
case _viccon: break;
return (a.victoryCondition<b.victoryCondition); case _viccon:
break; return (a.victoryCondition<b.victoryCondition);
case _name: break;
return (a.name<b.name); case _name:
break; return (a.name<b.name);
default: break;
return (a.name<b.name); default:
break; return (a.name<b.name);
} break;
}; }
mapSorter(ESortBy es):sortBy(es){}; };
}; mapSorter(ESortBy es):sortBy(es){};
struct DLL_EXPORT Mapa };
{ struct DLL_EXPORT Mapa
Eformat version; // version of map Eformat {
ui32 checksum; Eformat version; // version of map Eformat
int twoLevel; // if map has underground level ui32 checksum;
int difficulty; // 0 easy - 4 impossible int twoLevel; // if map has underground level
int levelLimit; int difficulty; // 0 easy - 4 impossible
bool areAnyPLayers; // if there are any playable players on map int levelLimit;
std::string name; //name of map bool areAnyPLayers; // if there are any playable players on map
std::string description; //and description std::string name; //name of map
int height, width; std::string description; //and description
TerrainTile*** terrain; int height, width;
std::vector<Rumor> rumors; TerrainTile*** terrain;
std::vector<DisposedHero> disposedHeroes; std::vector<Rumor> rumors;
std::vector<CGHeroInstance*> predefinedHeroes; std::vector<DisposedHero> disposedHeroes;
std::vector<CGDefInfo *> defy; // list of .def files with definitions from .h3m (may be custom) std::vector<CGHeroInstance*> predefinedHeroes;
std::set<CGDefInfo *> defs; // other defInfos - for randomized objects, objects added or modified by scripts std::vector<CGDefInfo *> defy; // list of .def files with definitions from .h3m (may be custom)
PlayerInfo players[8]; // info about players std::set<CGDefInfo *> defs; // other defInfos - for randomized objects, objects added or modified by scripts
std::vector<int> teams; // teams[i] = team of player no i PlayerInfo players[8]; // info about players
LossCondition lossCondition; std::vector<int> teams; // teams[i] = team of player no i
EvictoryConditions victoryCondition; //victory conditions LossCondition lossCondition;
CspecificVictoryConidtions * vicConDetails; // used only if vistory conditions aren't standard EvictoryConditions victoryCondition; //victory conditions
int howManyTeams; CspecificVictoryConidtions * vicConDetails; // used only if vistory conditions aren't standard
std::vector<bool> allowedSpell; //allowedSpell[spell_ID] - if the spell is allowed int howManyTeams;
std::vector<bool> allowedArtifact; //allowedArtifact[artifact_ID] - if the artifact is allowed std::vector<bool> allowedSpell; //allowedSpell[spell_ID] - if the spell is allowed
std::vector<bool> allowedAbilities; //allowedAbilities[ability_ID] - if the ability is allowed std::vector<bool> allowedArtifact; //allowedArtifact[artifact_ID] - if the artifact is allowed
std::vector<bool> allowedHeroes; //allowedHeroes[hero_ID] - if the hero is allowed std::vector<bool> allowedAbilities; //allowedAbilities[ability_ID] - if the ability is allowed
std::vector<CMapEvent> events; std::vector<bool> allowedHeroes; //allowedHeroes[hero_ID] - if the hero is allowed
std::vector<CMapEvent> events;
int3 grailPos;
int grailRadious; int3 grailPos;
int grailRadious;
std::vector<CGObjectInstance*> objects;
std::vector<CGHeroInstance*> heroes; std::vector<CGObjectInstance*> objects;
std::vector<CGTownInstance*> towns; std::vector<CGHeroInstance*> heroes;
std::vector<CGTownInstance*> towns;
void initFromBytes(unsigned char * bufor); //creates map from decompressed .h3m data
void initFromBytes(unsigned char * bufor); //creates map from decompressed .h3m data
void readEvents( unsigned char * bufor, int &i);
void readObjects( unsigned char * bufor, int &i); void readEvents( unsigned char * bufor, int &i);
void readDefInfo( unsigned char * bufor, int &i); void readObjects( unsigned char * bufor, int &i);
void readTerrain( unsigned char * bufor, int &i); void loadQuest( CQuest * guard, unsigned char * bufor, int & i);
void readPredefinedHeroes( unsigned char * bufor, int &i); void readDefInfo( unsigned char * bufor, int &i);
void readHeader( unsigned char * bufor, int &i); void readTerrain( unsigned char * bufor, int &i);
void readRumors( unsigned char * bufor, int &i); void readPredefinedHeroes( unsigned char * bufor, int &i);
void loadViCLossConditions( unsigned char * bufor, int &i); void readHeader( unsigned char * bufor, int &i);
void loadPlayerInfo( int &pom, unsigned char * bufor, int &i); void readRumors( unsigned char * bufor, int &i);
void loadHero( CGObjectInstance * &nobj, unsigned char * bufor, int &i); void loadViCLossConditions( unsigned char * bufor, int &i);
void loadTown( CGObjectInstance * &nobj, unsigned char * bufor, int &i); void loadPlayerInfo( int &pom, unsigned char * bufor, int &i);
int loadSeerHut( unsigned char * bufor, int i, CGObjectInstance *& nobj); void loadHero( CGObjectInstance * &nobj, unsigned char * bufor, int &i);
void loadTown( CGObjectInstance * &nobj, unsigned char * bufor, int &i);
int loadSeerHut( unsigned char * bufor, int i, CGObjectInstance *& nobj);
void addBlockVisTiles(CGObjectInstance * obj);
void removeBlockVisTiles(CGObjectInstance * obj);
Mapa(std::string filename); //creates map structure from .h3m file void addBlockVisTiles(CGObjectInstance * obj);
CGHeroInstance * getHero(int ID, int mode=0); void removeBlockVisTiles(CGObjectInstance * obj);
bool isInTheMap(int3 pos); Mapa(std::string filename); //creates map structure from .h3m file
template <typename Handler> void serialize(Handler &h, const int version) CGHeroInstance * getHero(int ID, int mode=0);
{ bool isInTheMap(int3 pos);
h & version & name & description & width & height & twoLevel & difficulty & levelLimit & rumors & defy & defs template <typename Handler> void serialize(Handler &h, const int version)
& players & teams & lossCondition & victoryCondition & howManyTeams & allowedSpell & allowedAbilities {
& allowedArtifact &allowedHeroes & events; h & version & name & description & width & height & twoLevel & difficulty & levelLimit & rumors & defy & defs
//TODO: viccondetails & players & teams & lossCondition & victoryCondition & howManyTeams & allowedSpell & allowedAbilities
if(h.saving) & allowedArtifact &allowedHeroes & events;
{ //TODO: viccondetails
//saving terrain if(h.saving)
for (int i = 0; i < width ; i++) {
for (int j = 0; j < height ; j++) //saving terrain
for (int k = 0; k <= twoLevel ; k++) for (int i = 0; i < width ; i++)
h & terrain[i][j][k]; for (int j = 0; j < height ; j++)
} for (int k = 0; k <= twoLevel ; k++)
else h & terrain[i][j][k];
{ }
//loading terrain else
terrain = new TerrainTile**[width]; // allocate memory {
for (int ii=0;ii<width;ii++) //loading terrain
{ terrain = new TerrainTile**[width]; // allocate memory
terrain[ii] = new TerrainTile*[height]; // allocate memory for (int ii=0;ii<width;ii++)
for(int jj=0;jj<height;jj++) {
terrain[ii][jj] = new TerrainTile[twoLevel+1]; terrain[ii] = new TerrainTile*[height]; // allocate memory
} for(int jj=0;jj<height;jj++)
for (int i = 0; i < width ; i++) terrain[ii][jj] = new TerrainTile[twoLevel+1];
for (int j = 0; j < height ; j++) }
for (int k = 0; k <= twoLevel ; k++) for (int i = 0; i < width ; i++)
h & terrain[i][j][k]; for (int j = 0; j < height ; j++)
} for (int k = 0; k <= twoLevel ; k++)
//TODO: recreate blockvis maps h & terrain[i][j][k];
} }
}; //TODO: recreate blockvis maps
#endif // __MAP_H__ }
};
#endif // __MAP_H__

View File

@ -1027,9 +1027,9 @@ upgend:
} }
case 514: case 514:
{ {
ui32 id; SetSelection ss;
c >> id; c >> ss;
gs->players[*players.begin()].currentSelection = id; sendAndApply(&ss);
break; break;
} }
case 515: case 515:
@ -1517,9 +1517,6 @@ void CGameHandler::init(StartInfo *si, int Seed)
gs->init(si,map,Seed); gs->init(si,map,Seed);
tlog0 << "Gamestate initialized!" << std::endl; tlog0 << "Gamestate initialized!" << std::endl;
for(int i=0; i<gs->map->objects.size(); i++)
gs->map->objects[i]->initObj();
/****************************LUA OBJECT SCRIPTS************************************************/ /****************************LUA OBJECT SCRIPTS************************************************/
//std::vector<std::string> * lf = CLuaHandler::searchForScripts("scripts/lua/objects"); //files //std::vector<std::string> * lf = CLuaHandler::searchForScripts("scripts/lua/objects"); //files
//for (int i=0; i<lf->size(); i++) //for (int i=0; i<lf->size(); i++)
@ -1627,7 +1624,8 @@ void CGameHandler::newTurn()
sendAndApply(&n); sendAndApply(&n);
tlog5 << "Info about turn " << n.day << "has been sent!" << std::endl; tlog5 << "Info about turn " << n.day << "has been sent!" << std::endl;
for(size_t i = 0; i<gs->map->objects.size(); i++) for(size_t i = 0; i<gs->map->objects.size(); i++)
gs->map->objects[i]->newTurn(); if(gs->map->objects[i])
gs->map->objects[i]->newTurn();
} }
void CGameHandler::run() void CGameHandler::run()
{ {
@ -1962,32 +1960,11 @@ void CGameHandler::setOwner(int objid, ui8 owner)
SetObjectProperty sop(objid,1,owner); SetObjectProperty sop(objid,1,owner);
sendAndApply(&sop); sendAndApply(&sop);
} }
const CGObjectInstance* CGameHandler::getObj(int objid)
{
return gs->map->objects[objid];
}
const CGHeroInstance* CGameHandler::getHero(int objid)
{
return dynamic_cast<const CGHeroInstance*>(gs->map->objects[objid]);
}
const CGTownInstance* CGameHandler::getTown(int objid)
{
return dynamic_cast<const CGTownInstance*>(gs->map->objects[objid]);
}
void CGameHandler::setHoverName(int objid, MetaString* name) void CGameHandler::setHoverName(int objid, MetaString* name)
{ {
SetHoverName shn(objid, *name); SetHoverName shn(objid, *name);
sendAndApply(&shn); sendAndApply(&shn);
} }
int CGameHandler::getOwner(int heroID)
{
return gs->map->objects[heroID]->tempOwner;
}
int CGameHandler::getResource(int player, int which)
{
return gs->players.find(player)->second.resources[which];
}
void CGameHandler::showInfoDialog(InfoWindow *iw) void CGameHandler::showInfoDialog(InfoWindow *iw)
{ {
sendToAllClients(iw); sendToAllClients(iw);
@ -2000,26 +1977,11 @@ void CGameHandler::showSelectionDialog(SelectionDialog *iw, const CFunctionList<
{ {
ask(iw,iw->player,callback); ask(iw,iw->player,callback);
} }
int CGameHandler::getCurrentPlayer()
int CGameHandler::getSelectedHero()
{
//int ret;
//if (LOCPLINT->adventureInt->selection->ID == HEROI_TYPE)
// ret = ((CGHeroInstance*)(LOCPLINT->adventureInt->selection))->subID;
//else
// ret = -1;;
return -1;
}
const CGHeroInstance* CGameHandler::getSelectedHero( int player )
{ {
return getHero(gs->players.find(player)->second.currentSelection); return gs->currentPlayer;
} }
int CGameHandler::getDate(int mode)
{
return getDate(mode);
}
void CGameHandler::giveResource(int player, int which, int val) void CGameHandler::giveResource(int player, int which, int val)
{ {
SetResource sr; SetResource sr;
@ -2108,7 +2070,16 @@ void CGameHandler::changeSpells( int hid, bool give, const std::set<ui32> &spell
sendAndApply(&cs); sendAndApply(&cs);
} }
int CGameHandler::getCurrentPlayer() int CGameHandler::getSelectedHero()
{ {
return gs->currentPlayer; return IGameCallback::getSelectedHero(getCurrentPlayer())->id;
}
void CGameHandler::setObjProperty( int objid, int prop, int val )
{
SetObjectProperty sob;
sob.id = objid;
sob.what = prop;
sob.val = val;
sendAndApply(&sob);
} }

View File

@ -1,173 +1,167 @@
#ifndef __CGAMEHANDLER_H__ #ifndef __CGAMEHANDLER_H__
#define __CGAMEHANDLER_H__ #define __CGAMEHANDLER_H__
#include "../global.h" #include "../global.h"
#include <set> #include <set>
#include "../client/FunctionList.h" #include "../client/FunctionList.h"
#include "../CGameState.h" #include "../CGameState.h"
#include "../lib/Connection.h" #include "../lib/Connection.h"
#include "../lib/IGameCallback.h" #include "../lib/IGameCallback.h"
#include <boost/function.hpp> #include <boost/function.hpp>
#include <boost/thread.hpp> #include <boost/thread.hpp>
class CVCMIServer; class CVCMIServer;
class CGameState; class CGameState;
struct StartInfo; struct StartInfo;
class CCPPObjectScript; class CCPPObjectScript;
class CScriptCallback; class CScriptCallback;
struct BattleResult; struct BattleResult;
struct BattleAttack; struct BattleAttack;
struct BattleStackAttacked; struct BattleStackAttacked;
template <typename T> struct CPack; template <typename T> struct CPack;
template <typename T> struct Query; template <typename T> struct Query;
class CGHeroInstance; class CGHeroInstance;
extern std::map<ui32, CFunctionList<void(ui32)> > callbacks; //question id => callback functions - for selection dialogs extern std::map<ui32, CFunctionList<void(ui32)> > callbacks; //question id => callback functions - for selection dialogs
extern boost::mutex gsm; extern boost::mutex gsm;
struct PlayerStatus struct PlayerStatus
{ {
bool makingTurn, engagedIntoBattle; bool makingTurn, engagedIntoBattle;
std::set<ui32> queries; std::set<ui32> queries;
PlayerStatus():makingTurn(false),engagedIntoBattle(false){}; PlayerStatus():makingTurn(false),engagedIntoBattle(false){};
template <typename Handler> void serialize(Handler &h, const int version) template <typename Handler> void serialize(Handler &h, const int version)
{ {
h & makingTurn & engagedIntoBattle & queries; h & makingTurn & engagedIntoBattle & queries;
} }
}; };
class PlayerStatuses class PlayerStatuses
{ {
public: public:
std::map<ui8,PlayerStatus> players; std::map<ui8,PlayerStatus> players;
boost::mutex mx; boost::mutex mx;
boost::condition_variable cv; //notifies when any changes are made boost::condition_variable cv; //notifies when any changes are made
void addPlayer(ui8 player); void addPlayer(ui8 player);
PlayerStatus operator[](ui8 player); PlayerStatus operator[](ui8 player);
bool hasQueries(ui8 player); bool hasQueries(ui8 player);
bool checkFlag(ui8 player, bool PlayerStatus::*flag); bool checkFlag(ui8 player, bool PlayerStatus::*flag);
void setFlag(ui8 player, bool PlayerStatus::*flag, bool val); void setFlag(ui8 player, bool PlayerStatus::*flag, bool val);
void addQuery(ui8 player, ui32 id); void addQuery(ui8 player, ui32 id);
void removeQuery(ui8 player, ui32 id); void removeQuery(ui8 player, ui32 id);
template <typename Handler> void serialize(Handler &h, const int version) template <typename Handler> void serialize(Handler &h, const int version)
{ {
h & players; h & players;
} }
}; };
class CGameHandler : public IGameCallback class CGameHandler : public IGameCallback
{ {
static ui32 QID; static ui32 QID;
CGameState *gs; //std::set<CCPPObjectScript *> cppscripts; //C++ scripts
//std::set<CCPPObjectScript *> cppscripts; //C++ scripts //std::map<int, std::map<std::string, CObjectScript*> > objscr; //non-C++ scripts
//std::map<int, std::map<std::string, CObjectScript*> > objscr; //non-C++ scripts
CVCMIServer *s;
CVCMIServer *s; std::map<int,CConnection*> connections; //player color -> connection to clinet with interface of that player
std::map<int,CConnection*> connections; //player color -> connection to clinet with interface of that player PlayerStatuses states; //player color -> player state
PlayerStatuses states; //player color -> player state std::set<CConnection*> conns;
std::set<CConnection*> conns;
void changeSecSkill(int ID, ui16 which, int val, bool abs=false);
void changeSecSkill(int ID, ui16 which, int val, bool abs=false); void giveSpells(const CGTownInstance *t, const CGHeroInstance *h);
void giveSpells(const CGTownInstance *t, const CGHeroInstance *h); void moveStack(int stack, int dest);
void moveStack(int stack, int dest); void startBattle(CCreatureSet army1, CCreatureSet army2, int3 tile, CGHeroInstance *hero1, CGHeroInstance *hero2, boost::function<void(BattleResult*)> cb); //use hero=NULL for no hero
void startBattle(CCreatureSet army1, CCreatureSet army2, int3 tile, CGHeroInstance *hero1, CGHeroInstance *hero2, boost::function<void(BattleResult*)> cb); //use hero=NULL for no hero void prepareAttack(BattleAttack &bat, CStack *att, CStack *def); //if last parameter is true, attack is by shooting, if false it's a melee attack
void prepareAttack(BattleAttack &bat, CStack *att, CStack *def); //if last parameter is true, attack is by shooting, if false it's a melee attack void prepareAttacked(BattleStackAttacked &bsa, CStack *def);
void prepareAttacked(BattleStackAttacked &bsa, CStack *def); void checkForBattleEnd( std::vector<CStack*> &stacks );
void checkForBattleEnd( std::vector<CStack*> &stacks ); void setupBattle( BattleInfo * curB, int3 tile, CCreatureSet &army1, CCreatureSet &army2, CGHeroInstance * hero1, CGHeroInstance * hero2 );
void setupBattle( BattleInfo * curB, int3 tile, CCreatureSet &army1, CCreatureSet &army2, CGHeroInstance * hero1, CGHeroInstance * hero2 );
public:
public: CGameHandler(void);
CGameHandler(void); ~CGameHandler(void);
~CGameHandler(void);
//////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////// //from IGameCallback
//from IGameCallback //get info
//get info int getCurrentPlayer();
int getOwner(int heroID); int getSelectedHero();
int getResource(int player, int which);
int getSelectedHero();
int getDate(int mode=0); //do sth
const CGObjectInstance* getObj(int objid); void changeSpells(int hid, bool give, const std::set<ui32> &spells);
const CGHeroInstance* getHero(int objid); void removeObject(int objid);
const CGTownInstance* getTown(int objid); void setBlockVis(int objid, bool bv);
const CGHeroInstance* getSelectedHero(int player); //NULL if no hero is selected void setOwner(int objid, ui8 owner);
int getCurrentPlayer(); void setHoverName(int objid, MetaString * name);
void setObjProperty(int objid, int prop, int val);
//do sth void changePrimSkill(int ID, int which, int val, bool abs=false);
void changeSpells(int hid, bool give, const std::set<ui32> &spells); void showInfoDialog(InfoWindow *iw);
void removeObject(int objid); void showYesNoDialog(YesNoDialog *iw, const CFunctionList<void(ui32)> &callback);
void setBlockVis(int objid, bool bv); void showSelectionDialog(SelectionDialog *iw, const CFunctionList<void(ui32)> &callback); //returns question id
void setOwner(int objid, ui8 owner); void giveResource(int player, int which, int val);
void setHoverName(int objid, MetaString * name); void showCompInfo(ShowInInfobox * comp);
void changePrimSkill(int ID, int which, int val, bool abs=false); void heroVisitCastle(int obj, int heroID);
void showInfoDialog(InfoWindow *iw); void stopHeroVisitCastle(int obj, int heroID);
void showYesNoDialog(YesNoDialog *iw, const CFunctionList<void(ui32)> &callback); void giveHeroArtifact(int artid, int hid, int position); //pos==-1 - first free slot in backpack; pos==-2 - default if available or backpack
void showSelectionDialog(SelectionDialog *iw, const CFunctionList<void(ui32)> &callback); //returns question id void startBattleI(const CCreatureSet * army1, const CCreatureSet * army2, int3 tile, const CGHeroInstance *hero1, const CGHeroInstance *hero2, boost::function<void(BattleResult*)> cb); //use hero=NULL for no hero
void giveResource(int player, int which, int val); void startBattleI(int heroID, CCreatureSet army, int3 tile, boost::function<void(BattleResult*)> cb); //for hero<=>neutral army
void showCompInfo(ShowInInfobox * comp); void setAmount(int objid, ui32 val);
void heroVisitCastle(int obj, int heroID); void moveHero(int hid, int3 pos, bool instant);
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 startBattleI(const CCreatureSet * army1, const CCreatureSet * army2, int3 tile, const CGHeroInstance *hero1, const CGHeroInstance *hero2, boost::function<void(BattleResult*)> cb); //use hero=NULL for no hero void init(StartInfo *si, int Seed);
void startBattleI(int heroID, CCreatureSet army, int3 tile, boost::function<void(BattleResult*)> cb); //for hero<=>neutral army void handleConnection(std::set<int> players, CConnection &c);
void setAmount(int objid, ui32 val); template <typename Handler> void serialize(Handler &h, const int version)
void moveHero(int hid, int3 pos, bool instant); {
////////////////////////////////////////////////////////////////////////// h & QID & gs & states;
}
void init(StartInfo *si, int Seed); template <typename T> void applyAndAsk(Query<T> * sel, ui8 player, boost::function<void(ui32)> &callback)
void handleConnection(std::set<int> players, CConnection &c); {
template <typename Handler> void serialize(Handler &h, const int version) gsm.lock();
{ sel->id = QID;
h & QID & gs & states; callbacks[QID] = callback;
} states.addQuery(player,QID);
template <typename T> void applyAndAsk(Query<T> * sel, ui8 player, boost::function<void(ui32)> &callback) QID++;
{ sendAndApply(sel);
gsm.lock(); gsm.unlock();
sel->id = QID; }
callbacks[QID] = callback; template <typename T> void ask(Query<T> * sel, ui8 player, const CFunctionList<void(ui32)> &callback)
states.addQuery(player,QID); {
QID++; gsm.lock();
sendAndApply(sel); sel->id = QID;
gsm.unlock(); callbacks[QID] = callback;
} states.addQuery(player,QID);
template <typename T> void ask(Query<T> * sel, ui8 player, const CFunctionList<void(ui32)> &callback) sendToAllClients(sel);
{ QID++;
gsm.lock(); gsm.unlock();
sel->id = QID; }
callbacks[QID] = callback;
states.addQuery(player,QID); template <typename T>void sendDataToClients(const T & data)
sendToAllClients(sel); {
QID++; for(std::set<CConnection*>::iterator i=conns.begin(); i!=conns.end();i++)
gsm.unlock(); {
} (*i)->wmx->lock();
**i << data;
template <typename T>void sendDataToClients(const T & data) (*i)->wmx->unlock();
{ }
for(std::set<CConnection*>::iterator i=conns.begin(); i!=conns.end();i++) }
{ template <typename T>void sendToAllClients(CPack<T> * info)
(*i)->wmx->lock(); {
**i << data; for(std::set<CConnection*>::iterator i=conns.begin(); i!=conns.end();i++)
(*i)->wmx->unlock(); {
} (*i)->wmx->lock();
} **i << info->getType() << *info->This();
template <typename T>void sendToAllClients(CPack<T> * info) (*i)->wmx->unlock();
{ }
for(std::set<CConnection*>::iterator i=conns.begin(); i!=conns.end();i++) }
{ template <typename T>void sendAndApply(CPack<T> * info)
(*i)->wmx->lock(); {
**i << info->getType() << *info->This(); gs->apply(info);
(*i)->wmx->unlock(); sendToAllClients(info);
} }
} void run();
template <typename T>void sendAndApply(CPack<T> * info) void newTurn();
{
gs->apply(info); friend class CVCMIServer;
sendToAllClients(info); friend class CScriptCallback;
} };
void run();
void newTurn(); #endif // __CGAMEHANDLER_H__
friend class CVCMIServer;
friend class CScriptCallback;
};
#endif // __CGAMEHANDLER_H__