mirror of
https://github.com/vcmi/vcmi.git
synced 2024-11-24 08:32:34 +02:00
New files
For VCMI_LIB: lib/RegisterTypes.cpp lib/NetPacksLib.cpp For VCMI_CLIENT: client/NetPacksClient.cpp (+ headers) Removed files FOR VCMI_CLIENT: hch/CAbilityHandler.cpp and header Redone sending and applying messages server => client May be still buggy.
This commit is contained in:
commit
320e04a121
@ -49,6 +49,7 @@
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="4"
|
||||
DebugInformationFormat="4"
|
||||
DisableSpecificWarnings="4512"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
@ -127,6 +128,7 @@
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="3"
|
||||
DebugInformationFormat="3"
|
||||
DisableSpecificWarnings="4512"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
@ -210,6 +212,7 @@
|
||||
ProgramDataBaseFileName="$(SolutionDir)$(ConfigurationName)\GeniusAI.pdb"
|
||||
WarningLevel="3"
|
||||
DebugInformationFormat="3"
|
||||
DisableSpecificWarnings="4512"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
|
@ -26,7 +26,7 @@
|
||||
#ifdef max
|
||||
#undef max
|
||||
#endif
|
||||
extern CSharedCond<std::set<IPack*> > mess;
|
||||
extern CSharedCond<std::set<CPack*> > mess;
|
||||
|
||||
int gcd(int x, int y)
|
||||
{
|
||||
@ -48,6 +48,12 @@ HeroMoveDetails::HeroMoveDetails(int3 Src, int3 Dst, CGHeroInstance*Ho)
|
||||
{
|
||||
owner = ho->getOwner();
|
||||
};
|
||||
|
||||
template <ui16 N> bool isType(CPack *pack)
|
||||
{
|
||||
return pack->getType() == N;
|
||||
}
|
||||
|
||||
bool CCallback::moveHero(int ID, CPath * path, int idtype, int pathType)
|
||||
{
|
||||
CGHeroInstance * hero = NULL;
|
||||
@ -108,13 +114,17 @@ bool CCallback::moveHero(int ID, CPath * path, int idtype, int pathType)
|
||||
*cl->serv << ui16(501) << hero->id << stpos << endpos;
|
||||
{//wait till there is server answer
|
||||
boost::unique_lock<boost::mutex> lock(*mess.mx);
|
||||
while(std::find_if(mess.res->begin(),mess.res->end(),IPack::isType<501>) == mess.res->end())
|
||||
while(std::find_if(mess.res->begin(),mess.res->end(),&isType<501>) == mess.res->end())
|
||||
mess.cv->wait(lock);
|
||||
std::set<IPack*>::iterator itr = std::find_if(mess.res->begin(),mess.res->end(),IPack::isType<501>);
|
||||
TryMoveHero tmh = *static_cast<TryMoveHero*>(*itr);
|
||||
std::set<CPack*>::iterator itr = std::find_if(mess.res->begin(),mess.res->end(),&isType<501>);
|
||||
TryMoveHero *tmh = static_cast<TryMoveHero*>(*itr);
|
||||
mess.res->erase(itr);
|
||||
if(!tmh.result)
|
||||
if(!tmh->result)
|
||||
{
|
||||
delete tmh;
|
||||
return false;
|
||||
}
|
||||
delete tmh;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
|
@ -45,7 +45,6 @@ public:
|
||||
CArtHandler * arth;
|
||||
CHeroHandler * heroh;
|
||||
CCreatureHandler * creh;
|
||||
CAbilityHandler * abilh;
|
||||
CSpellHandler * spellh;
|
||||
CMapHandler * mh;
|
||||
CBuildingHandler * buildh;
|
||||
|
@ -1,34 +1,19 @@
|
||||
#include "stdafx.h"
|
||||
#include "CGameInterface.h"
|
||||
#include "CAdvmapInterface.h"
|
||||
#include "CMessage.h"
|
||||
#include "mapHandler.h"
|
||||
#include "SDL_Extensions.h"
|
||||
#include "SDL_framerate.h"
|
||||
#include "CCursorHandler.h"
|
||||
#include "CCallback.h"
|
||||
#include "SDL_Extensions.h"
|
||||
#include "hch/CLodHandler.h"
|
||||
#include "CPathfinder.h"
|
||||
#include <sstream>
|
||||
#include "hch/CHeroHandler.h"
|
||||
#include "SDL_framerate.h"
|
||||
#include "AI/EmptyAI/CEmptyAI.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <windows.h> //for .dll libs
|
||||
#else
|
||||
#include <dlfcn.h>
|
||||
#endif
|
||||
using namespace CSDL_Ext;
|
||||
|
||||
CGlobalAI * CAIHandler::getNewAI(CCallback * cb, std::string dllname)
|
||||
{
|
||||
char temp[50];
|
||||
dllname = "AI/"+dllname;
|
||||
CGlobalAI * ret=NULL;
|
||||
CGlobalAI*(*getAI)(); //TODO use me
|
||||
void(*getName)(char*); //TODO use me
|
||||
CGlobalAI*(*getAI)();
|
||||
void(*getName)(char*);
|
||||
|
||||
#ifdef _WIN32
|
||||
HINSTANCE dll = LoadLibraryA(dllname.c_str());
|
||||
@ -52,6 +37,3 @@ CGlobalAI * CAIHandler::getNewAI(CCallback * cb, std::string dllname)
|
||||
|
||||
return ret;
|
||||
}
|
||||
//CGlobalAI::CGlobalAI()
|
||||
//{
|
||||
//}
|
||||
|
555
CGameState.cpp
555
CGameState.cpp
@ -14,12 +14,15 @@
|
||||
#include "hch/CObjectHandler.h"
|
||||
#include "hch/CCreatureHandler.h"
|
||||
#include "lib/VCMI_Lib.h"
|
||||
#include "lib/Connection.h"
|
||||
#include "map.h"
|
||||
#include "StartInfo.h"
|
||||
#include "lib/NetPacks.h"
|
||||
#include <boost/foreach.hpp>
|
||||
#include <boost/thread.hpp>
|
||||
#include <boost/thread/shared_mutex.hpp>
|
||||
|
||||
#include "lib/RegisterTypes.h"
|
||||
boost::rand48 ran;
|
||||
|
||||
|
||||
@ -30,6 +33,38 @@ boost::rand48 ran;
|
||||
#undef max
|
||||
#endif
|
||||
|
||||
class CBaseForGSApply
|
||||
{
|
||||
public:
|
||||
virtual void applyOnGS(CGameState *gs, void *pack) const =0;
|
||||
};
|
||||
template <typename T> class CApplyOnGS : public CBaseForGSApply
|
||||
{
|
||||
public:
|
||||
void applyOnGS(CGameState *gs, void *pack) const
|
||||
{
|
||||
T *ptr = static_cast<T*>(pack);
|
||||
ptr->applyGs(gs);
|
||||
}
|
||||
};
|
||||
|
||||
class CGSApplier
|
||||
{
|
||||
public:
|
||||
std::map<ui16,CBaseForGSApply*> apps;
|
||||
|
||||
CGSApplier()
|
||||
{
|
||||
registerTypes2(*this);
|
||||
}
|
||||
template<typename T> void registerType(const T * t=NULL)
|
||||
{
|
||||
ui16 ID = typeList.registerType(t);
|
||||
apps[ID] = new CApplyOnGS<T>;
|
||||
}
|
||||
|
||||
} *applier = NULL;
|
||||
|
||||
std::string DLL_EXPORT toString(MetaString &ms)
|
||||
{
|
||||
std::string ret;
|
||||
@ -506,512 +541,13 @@ CGHeroInstance* CGameState::HeroesPool::pickHeroFor(bool native, int player, con
|
||||
}
|
||||
}
|
||||
|
||||
void CGameState::applyNL(IPack * pack)
|
||||
{
|
||||
switch(pack->getType())
|
||||
{
|
||||
case 101://NewTurn
|
||||
{
|
||||
NewTurn * n = static_cast<NewTurn*>(pack);
|
||||
day = n->day;
|
||||
BOOST_FOREACH(NewTurn::Hero h, n->heroes) //give mana/movement point
|
||||
{
|
||||
static_cast<CGHeroInstance*>(map->objects[h.id])->movement = h.move;
|
||||
static_cast<CGHeroInstance*>(map->objects[h.id])->mana = h.mana;
|
||||
}
|
||||
BOOST_FOREACH(SetResources h, n->res) //give resources
|
||||
applyNL(&h);
|
||||
BOOST_FOREACH(SetAvailableCreatures h, n->cres) //set available creatures in towns
|
||||
applyNL(&h);
|
||||
if(n->resetBuilded) //reset amount of structures set in this turn in towns
|
||||
BOOST_FOREACH(CGTownInstance* t, map->towns)
|
||||
t->builded = 0;
|
||||
BOOST_FOREACH(CGHeroInstance *h, map->heroes)
|
||||
h->bonuses.remove_if(HeroBonus::OneDay);
|
||||
if(getDate(1) == 7) //new week
|
||||
BOOST_FOREACH(CGHeroInstance *h, map->heroes)
|
||||
h->bonuses.remove_if(HeroBonus::OneWeek);
|
||||
break;
|
||||
}
|
||||
case 102: //set resource amount
|
||||
{
|
||||
SetResource *sr = static_cast<SetResource*>(pack);
|
||||
players[sr->player].resources[sr->resid] = sr->val;
|
||||
break;
|
||||
}
|
||||
case 104:
|
||||
{
|
||||
SetResources *sr = static_cast<SetResources*>(pack);
|
||||
for(int i=0;i<sr->res.size();i++)
|
||||
players[sr->player].resources[i] = sr->res[i];
|
||||
break;
|
||||
}
|
||||
case 105:
|
||||
{
|
||||
SetPrimSkill *sr = static_cast<SetPrimSkill*>(pack);
|
||||
CGHeroInstance *hero = getHero(sr->id);
|
||||
if(sr->which <4)
|
||||
{
|
||||
if(sr->abs)
|
||||
hero->primSkills[sr->which] = sr->val;
|
||||
else
|
||||
hero->primSkills[sr->which] += sr->val;
|
||||
}
|
||||
else if(sr->which == 4) //XP
|
||||
{
|
||||
if(sr->abs)
|
||||
hero->exp = sr->val;
|
||||
else
|
||||
hero->exp += sr->val;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 106:
|
||||
{
|
||||
SetSecSkill *sr = static_cast<SetSecSkill*>(pack);
|
||||
CGHeroInstance *hero = getHero(sr->id);
|
||||
if(hero->getSecSkillLevel(sr->which) == 0)
|
||||
{
|
||||
hero->secSkills.push_back(std::pair<int,int>(sr->which, sr->val));
|
||||
}
|
||||
else
|
||||
{
|
||||
for(unsigned i=0;i<hero->secSkills.size();i++)
|
||||
{
|
||||
if(hero->secSkills[i].first == sr->which)
|
||||
{
|
||||
if(sr->abs)
|
||||
hero->secSkills[i].second = sr->val;
|
||||
else
|
||||
hero->secSkills[i].second += sr->val;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 108:
|
||||
{
|
||||
HeroVisitCastle *vc = static_cast<HeroVisitCastle*>(pack);
|
||||
CGHeroInstance *h = getHero(vc->hid);
|
||||
CGTownInstance *t = getTown(vc->tid);
|
||||
if(vc->start())
|
||||
{
|
||||
if(vc->garrison())
|
||||
{
|
||||
t->garrisonHero = h;
|
||||
h->visitedTown = t;
|
||||
h->inTownGarrison = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
t->visitingHero = h;
|
||||
h->visitedTown = t;
|
||||
h->inTownGarrison = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(vc->garrison())
|
||||
{
|
||||
t->garrisonHero = NULL;
|
||||
h->visitedTown = NULL;
|
||||
h->inTownGarrison = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
t->visitingHero = NULL;
|
||||
h->visitedTown = NULL;
|
||||
h->inTownGarrison = false;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 109:
|
||||
{
|
||||
ChangeSpells *rh = static_cast<ChangeSpells*>(pack);
|
||||
CGHeroInstance *hero = getHero(rh->hid);
|
||||
if(rh->learn)
|
||||
BOOST_FOREACH(ui32 sid, rh->spells)
|
||||
hero->spells.insert(sid);
|
||||
else
|
||||
BOOST_FOREACH(ui32 sid, rh->spells)
|
||||
hero->spells.erase(sid);
|
||||
break;
|
||||
}
|
||||
case 110:
|
||||
{
|
||||
SetMana *rh = static_cast<SetMana*>(pack);
|
||||
CGHeroInstance *hero = getHero(rh->hid);
|
||||
hero->mana = rh->val;
|
||||
break;
|
||||
}
|
||||
case 111:
|
||||
{
|
||||
SetMovePoints *rh = static_cast<SetMovePoints*>(pack);
|
||||
CGHeroInstance *hero = getHero(rh->hid);
|
||||
hero->movement = rh->val;
|
||||
break;
|
||||
}
|
||||
case 112:
|
||||
{
|
||||
FoWChange *rh = static_cast<FoWChange*>(pack);
|
||||
BOOST_FOREACH(int3 t, rh->tiles)
|
||||
players[rh->player].fogOfWarMap[t.x][t.y][t.z] = rh->mode;
|
||||
break;
|
||||
}
|
||||
case 113:
|
||||
{
|
||||
SetAvailableHeroes *rh = static_cast<SetAvailableHeroes*>(pack);
|
||||
players[rh->player].availableHeroes.clear();
|
||||
|
||||
CGHeroInstance *h = (rh->hid1>=0 ? hpool.heroesPool[rh->hid1] : NULL);
|
||||
players[rh->player].availableHeroes.push_back(h);
|
||||
if(h && rh->flags & 1)
|
||||
{
|
||||
h->army.slots.clear();
|
||||
h->army.slots[0] = std::pair<ui32,si32>(VLC->creh->nameToID[h->type->refTypeStack[0]],1);
|
||||
}
|
||||
|
||||
h = (rh->hid2>=0 ? hpool.heroesPool[rh->hid2] : NULL);
|
||||
players[rh->player].availableHeroes.push_back(h);
|
||||
if(rh->flags & 2)
|
||||
{
|
||||
h->army.slots.clear();
|
||||
h->army.slots[0] = std::pair<ui32,si32>(VLC->creh->nameToID[h->type->refTypeStack[0]],1);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 115:
|
||||
{
|
||||
GiveBonus *rh = static_cast<GiveBonus*>(pack);
|
||||
CGHeroInstance *h = getHero(rh->hid);
|
||||
h->bonuses.push_back(rh->bonus);
|
||||
h->bonuses.back().description = toString(rh->bdescr);
|
||||
break;
|
||||
}
|
||||
case 116:
|
||||
{
|
||||
ChangeObjPos *rh = static_cast<ChangeObjPos*>(pack);
|
||||
CGObjectInstance *obj = map->objects[rh->objid];
|
||||
if(!obj)
|
||||
{
|
||||
tlog1 << "Wrong ChangeObjPos: object " << rh->objid << " doesn't exist!\n";
|
||||
return;
|
||||
}
|
||||
map->removeBlockVisTiles(obj);
|
||||
obj->pos = rh->nPos;
|
||||
map->addBlockVisTiles(obj);
|
||||
break;
|
||||
}
|
||||
case 500:
|
||||
{
|
||||
RemoveObject *rh = static_cast<RemoveObject*>(pack);
|
||||
CGObjectInstance *obj = map->objects[rh->id];
|
||||
if(obj->ID==HEROI_TYPE)
|
||||
{
|
||||
CGHeroInstance *h = static_cast<CGHeroInstance*>(obj);
|
||||
std::vector<CGHeroInstance*>::iterator nitr = std::find(map->heroes.begin(), map->heroes.end(),h);
|
||||
map->heroes.erase(nitr);
|
||||
int player = h->tempOwner;
|
||||
nitr = std::find(players[player].heroes.begin(), players[player].heroes.end(), h);
|
||||
players[player].heroes.erase(nitr);
|
||||
if(h->visitedTown)
|
||||
{
|
||||
if(h->inTownGarrison)
|
||||
h->visitedTown->garrisonHero = NULL;
|
||||
else
|
||||
h->visitedTown->visitingHero = NULL;
|
||||
h->visitedTown = NULL;
|
||||
}
|
||||
}
|
||||
map->objects[rh->id] = NULL;
|
||||
|
||||
//unblock tiles
|
||||
if(obj->defInfo)
|
||||
{
|
||||
map->removeBlockVisTiles(obj);
|
||||
}
|
||||
|
||||
|
||||
break;
|
||||
}
|
||||
case 501://hero try-move
|
||||
{
|
||||
TryMoveHero * n = static_cast<TryMoveHero*>(pack);
|
||||
CGHeroInstance *h = static_cast<CGHeroInstance*>(map->objects[n->id]);
|
||||
h->movement = n->movePoints;
|
||||
if(n->start!=n->end && n->result)
|
||||
{
|
||||
map->removeBlockVisTiles(h);
|
||||
h->pos = n->end;
|
||||
map->addBlockVisTiles(h);
|
||||
}
|
||||
BOOST_FOREACH(int3 t, n->fowRevealed)
|
||||
players[h->getOwner()].fogOfWarMap[t.x][t.y][t.z] = 1;
|
||||
break;
|
||||
}
|
||||
case 502:
|
||||
{
|
||||
SetGarrisons * n = static_cast<SetGarrisons*>(pack);
|
||||
for(std::map<ui32,CCreatureSet>::iterator i = n->garrs.begin(); i!=n->garrs.end(); i++)
|
||||
{
|
||||
CArmedInstance *ai = static_cast<CArmedInstance*>(map->objects[i->first]);
|
||||
ai->army = i->second;
|
||||
if(ai->ID==TOWNI_TYPE && (static_cast<CGTownInstance*>(ai))->garrisonHero) //if there is a hero in garrison then we must update also his army
|
||||
const_cast<CGHeroInstance*>((static_cast<CGTownInstance*>(ai))->garrisonHero)->army = i->second;
|
||||
else if(ai->ID==HEROI_TYPE)
|
||||
{
|
||||
CGHeroInstance *h = static_cast<CGHeroInstance*>(ai);
|
||||
if(h->visitedTown && h->inTownGarrison)
|
||||
h->visitedTown->army = i->second;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 503:
|
||||
{
|
||||
//SetStrInfo *ssi = static_cast<SetStrInfo*>(pack);
|
||||
//static_cast<CGTownInstance*>(map->objects[ssi->tid])->strInfo.creatures = ssi->cres;
|
||||
break;
|
||||
}
|
||||
case 504:
|
||||
{
|
||||
NewStructures *ns = static_cast<NewStructures*>(pack);
|
||||
CGTownInstance*t = static_cast<CGTownInstance*>(map->objects[ns->tid]);
|
||||
BOOST_FOREACH(si32 bid,ns->bid)
|
||||
t->builtBuildings.insert(bid);
|
||||
t->builded = ns->builded;
|
||||
break;
|
||||
}
|
||||
case 506:
|
||||
{
|
||||
SetAvailableCreatures *sac = static_cast<SetAvailableCreatures*>(pack);
|
||||
static_cast<CGTownInstance*>(map->objects[sac->tid])->strInfo.creatures = sac->creatures;
|
||||
break;
|
||||
}
|
||||
case 508:
|
||||
{
|
||||
SetHeroesInTown *sac = static_cast<SetHeroesInTown*>(pack);
|
||||
CGTownInstance *t = getTown(sac->tid);
|
||||
CGHeroInstance *v = getHero(sac->visiting), *g = getHero(sac->garrison);
|
||||
t->visitingHero = v;
|
||||
t->garrisonHero = g;
|
||||
if(v)
|
||||
{
|
||||
v->visitedTown = t;
|
||||
v->inTownGarrison = false;
|
||||
map->addBlockVisTiles(v);
|
||||
}
|
||||
if(g)
|
||||
{
|
||||
g->visitedTown = t;
|
||||
g->inTownGarrison = true;
|
||||
map->removeBlockVisTiles(g);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 509:
|
||||
{
|
||||
SetHeroArtifacts *sha = static_cast<SetHeroArtifacts*>(pack);
|
||||
CGHeroInstance *h = getHero(sha->hid);
|
||||
h->artifacts = sha->artifacts;
|
||||
h->artifWorn = sha->artifWorn;
|
||||
break;
|
||||
}
|
||||
case 514:
|
||||
{
|
||||
SetSelection *ss = static_cast<SetSelection*>(pack);
|
||||
players[ss->player].currentSelection = ss->id;
|
||||
break;
|
||||
}
|
||||
case 515:
|
||||
{
|
||||
HeroRecruited *sha = static_cast<HeroRecruited*>(pack);
|
||||
CGHeroInstance *h = hpool.heroesPool[sha->hid];
|
||||
CGTownInstance *t = getTown(sha->tid);
|
||||
h->setOwner(sha->player);
|
||||
h->pos = sha->tile;
|
||||
h->movement = h->maxMovePoints(true);
|
||||
|
||||
hpool.heroesPool.erase(sha->hid);
|
||||
if(h->id < 0)
|
||||
{
|
||||
h->id = map->objects.size();
|
||||
map->objects.push_back(h);
|
||||
}
|
||||
else
|
||||
map->objects[h->id] = h;
|
||||
|
||||
h->initHeroDefInfo();
|
||||
map->heroes.push_back(h);
|
||||
players[h->tempOwner].heroes.push_back(h);
|
||||
map->addBlockVisTiles(h);
|
||||
t->visitingHero = h;
|
||||
h->visitedTown = t;
|
||||
h->inTownGarrison = false;
|
||||
break;
|
||||
}
|
||||
case 516:
|
||||
{
|
||||
GiveHero *sha = static_cast<GiveHero*>(pack);
|
||||
CGHeroInstance *h = getHero(sha->id);
|
||||
map->removeBlockVisTiles(h,true);
|
||||
h->setOwner(sha->player);
|
||||
h->movement = h->maxMovePoints(true);
|
||||
h->initHeroDefInfo();
|
||||
map->heroes.push_back(h);
|
||||
players[h->tempOwner].heroes.push_back(h);
|
||||
map->addBlockVisTiles(h);
|
||||
h->inTownGarrison = false;
|
||||
break;
|
||||
}
|
||||
case 1001://set object property
|
||||
{
|
||||
SetObjectProperty *p = static_cast<SetObjectProperty*>(pack);
|
||||
CGObjectInstance *obj = map->objects[p->id];
|
||||
if(!obj)
|
||||
tlog1 << "Wrong object ID - property cannot be set!\n";
|
||||
else
|
||||
obj->setProperty(p->what,p->val);
|
||||
break;
|
||||
}
|
||||
case 1002:
|
||||
{
|
||||
SetHoverName *shn = static_cast<SetHoverName*>(pack);
|
||||
map->objects[shn->id]->hoverName = toString(shn->name);
|
||||
break;
|
||||
}
|
||||
case 2000:
|
||||
{
|
||||
HeroLevelUp * bs = static_cast<HeroLevelUp*>(pack);
|
||||
getHero(bs->heroid)->level = bs->level;
|
||||
break;
|
||||
}
|
||||
case 3000:
|
||||
{
|
||||
BattleStart * bs = static_cast<BattleStart*>(pack);
|
||||
curB = bs->info;
|
||||
break;
|
||||
}
|
||||
case 3001:
|
||||
{
|
||||
BattleNextRound *ns = static_cast<BattleNextRound*>(pack);
|
||||
curB->castedSpells[0] = curB->castedSpells[1] = 0;
|
||||
curB->round = ns->round;
|
||||
for(int i=0; i<curB->stacks.size();i++)
|
||||
{
|
||||
curB->stacks[i]->state -= DEFENDING;
|
||||
curB->stacks[i]->state -= WAITING;
|
||||
curB->stacks[i]->state -= MOVED;
|
||||
curB->stacks[i]->state -= HAD_MORALE;
|
||||
curB->stacks[i]->counterAttacks = 1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 3002:
|
||||
{
|
||||
BattleSetActiveStack *ns = static_cast<BattleSetActiveStack*>(pack);
|
||||
curB->activeStack = ns->stack;
|
||||
CStack *st = curB->getStack(ns->stack);
|
||||
if(vstd::contains(st->state,MOVED))
|
||||
st->state.insert(HAD_MORALE);
|
||||
break;
|
||||
}
|
||||
case 3003:
|
||||
{
|
||||
BattleResult *br = static_cast<BattleResult*>(pack);
|
||||
for(unsigned i=0;i<curB->stacks.size();i++)
|
||||
delete curB->stacks[i];
|
||||
|
||||
//remove any "until next battle" bonuses
|
||||
CGHeroInstance *h;
|
||||
h = getHero(curB->hero1);
|
||||
if(h)
|
||||
h->bonuses.remove_if(HeroBonus::OneBattle);
|
||||
h = getHero(curB->hero2);
|
||||
if(h)
|
||||
h->bonuses.remove_if(HeroBonus::OneBattle);
|
||||
|
||||
delete curB;
|
||||
curB = NULL;
|
||||
break;
|
||||
}
|
||||
case 3004:
|
||||
{
|
||||
BattleStackMoved *br = static_cast<BattleStackMoved*>(pack);
|
||||
curB->getStack(br->stack)->position = br->tile;
|
||||
break;
|
||||
}
|
||||
case 3005:
|
||||
{
|
||||
BattleStackAttacked *br = static_cast<BattleStackAttacked*>(pack);
|
||||
CStack * at = curB->getStack(br->stackAttacked);
|
||||
at->amount = br->newAmount;
|
||||
at->firstHPleft = br->newHP;
|
||||
if(br->killed())
|
||||
at->state -= ALIVE;
|
||||
break;
|
||||
}
|
||||
case 3006:
|
||||
{
|
||||
BattleAttack *br = static_cast<BattleAttack*>(pack);
|
||||
CStack *attacker = curB->getStack(br->stackAttacking);
|
||||
if(br->counter())
|
||||
attacker->counterAttacks--;
|
||||
if(br->shot())
|
||||
attacker->shots--;
|
||||
applyNL(&br->bsa);
|
||||
break;
|
||||
}
|
||||
case 3007:
|
||||
{
|
||||
StartAction *br = static_cast<StartAction*>(pack);
|
||||
CStack *st = curB->getStack(br->ba.stackNumber);
|
||||
switch(br->ba.actionType)
|
||||
{
|
||||
case 3:
|
||||
st->state.insert(DEFENDING);
|
||||
break;
|
||||
case 8:
|
||||
st->state.insert(WAITING);
|
||||
break;
|
||||
case 2: case 6: case 7: case 9: case 10: case 11:
|
||||
st->state.insert(MOVED);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 3009:
|
||||
{
|
||||
SpellCasted *sc = static_cast<SpellCasted*>(pack);
|
||||
CGHeroInstance *h = (sc->side) ? getHero(curB->hero2) : getHero(curB->hero1);
|
||||
if(h)
|
||||
{
|
||||
h->mana -= VLC->spellh->spells[sc->id].costs[sc->skill];
|
||||
if(h->mana < 0) h->mana = 0;
|
||||
}
|
||||
if(sc->side >= 0 && sc->side < 2)
|
||||
{
|
||||
curB->castedSpells[sc->side]++;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 3010:
|
||||
{
|
||||
SetStackEffect *sc = static_cast<SetStackEffect*>(pack);
|
||||
CStack *stack = curB->getStack(sc->stack);
|
||||
stack->effects.push_back(sc->effect);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
void CGameState::apply(IPack * pack)
|
||||
{
|
||||
while(!mx->try_lock())
|
||||
boost::this_thread::sleep(boost::posix_time::milliseconds(50)); //give other threads time to finish
|
||||
applyNL(pack);
|
||||
mx->unlock();
|
||||
}
|
||||
//void CGameState::apply(CPack * pack)
|
||||
//{
|
||||
// while(!mx->try_lock())
|
||||
// boost::this_thread::sleep(boost::posix_time::milliseconds(50)); //give other threads time to finish
|
||||
// //applyNL(pack);
|
||||
// mx->unlock();
|
||||
//}
|
||||
int CGameState::pickHero(int owner)
|
||||
{
|
||||
int h=-1;
|
||||
@ -1285,6 +821,7 @@ CGameState::CGameState()
|
||||
map = NULL;
|
||||
curB = NULL;
|
||||
scenarioOps = NULL;
|
||||
applier = new CGSApplier;
|
||||
}
|
||||
CGameState::~CGameState()
|
||||
{
|
||||
@ -1292,6 +829,7 @@ CGameState::~CGameState()
|
||||
delete map;
|
||||
delete curB;
|
||||
delete scenarioOps;
|
||||
delete applier;
|
||||
}
|
||||
void CGameState::init(StartInfo * si, Mapa * map, int Seed)
|
||||
{
|
||||
@ -1948,6 +1486,11 @@ int CGameState::canBuildStructure( const CGTownInstance *t, int ID )
|
||||
return ret;
|
||||
}
|
||||
|
||||
void CGameState::apply(CPack *pack)
|
||||
{
|
||||
applier->apps[typeList.getTypeID(pack)]->applyOnGS(this,pack);
|
||||
}
|
||||
|
||||
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);
|
||||
|
10
CGameState.h
10
CGameState.h
@ -33,9 +33,9 @@ struct StartInfo;
|
||||
struct SDL_Surface;
|
||||
class CMapHandler;
|
||||
class CPathfinder;
|
||||
struct IPack;
|
||||
struct SetObjectProperty;
|
||||
struct MetaString;
|
||||
struct CPack;
|
||||
|
||||
|
||||
std::string DLL_EXPORT toString(MetaString &ms);
|
||||
@ -198,7 +198,7 @@ struct UpgradeInfo
|
||||
|
||||
class DLL_EXPORT CGameState
|
||||
{
|
||||
private:
|
||||
public:
|
||||
StartInfo* scenarioOps;
|
||||
ui32 seed;
|
||||
ui8 currentPlayer; //ID of player currently having turn
|
||||
@ -226,12 +226,10 @@ private:
|
||||
|
||||
void init(StartInfo * si, Mapa * map, int Seed);
|
||||
void loadTownDInfos();
|
||||
void applyNL(IPack * pack);
|
||||
|
||||
void apply(IPack * pack);
|
||||
void randomizeObject(CGObjectInstance *cur);
|
||||
std::pair<int,int> pickObject(CGObjectInstance *obj);
|
||||
int pickHero(int owner);
|
||||
void apply(CPack *pack);
|
||||
CGHeroInstance *getHero(int objid);
|
||||
CGTownInstance *getTown(int objid);
|
||||
bool battleMoveCreatureStack(int ID, int dest);
|
||||
@ -243,7 +241,7 @@ private:
|
||||
float getMarketEfficiency(int player, int mode=0);
|
||||
std::set<int3> tilesToReveal(int3 pos, int radious, int player) const; //if player==-1 => adds all tiles in radious
|
||||
int canBuildStructure(const CGTownInstance *t, int ID);// 0 - no more than one capitol, 1 - lack of water, 2 - forbidden, 3 - Add another level to Mage Guild, 4 - already built, 5 - cannot build, 6 - cannot afford, 7 - build, 8 - lack of requirements
|
||||
public:
|
||||
|
||||
CGameState();
|
||||
~CGameState();
|
||||
void getNeighbours(int3 tile, std::vector<int3> &vec, bool onLand);
|
||||
|
7
CMT.cpp
7
CMT.cpp
@ -27,7 +27,6 @@
|
||||
#include "CAdvmapInterface.h"
|
||||
#include "hch/CBuildingHandler.h"
|
||||
#include "hch/CVideoHandler.h"
|
||||
#include "hch/CAbilityHandler.h"
|
||||
#include "hch/CHeroHandler.h"
|
||||
#include "hch/CCreatureHandler.h"
|
||||
#include "hch/CSpellHandler.h"
|
||||
@ -47,9 +46,7 @@
|
||||
#undef main
|
||||
#endif
|
||||
std::string NAME = NAME_VER + std::string(" (client)");
|
||||
DLL_EXPORT void initDLL(CLodHandler *b);
|
||||
SDL_Surface * screen, * screen2;
|
||||
extern SDL_Surface * CSDL_Ext::std32bppSurface;
|
||||
std::queue<SDL_Event> events;
|
||||
boost::mutex eventsM;
|
||||
TTF_Font * TNRB16, *TNR, *GEOR13, *GEORXX, *GEORM, *GEOR16;
|
||||
@ -125,10 +122,6 @@ int main(int argc, char** argv)
|
||||
cgi->curh->initCursor();
|
||||
cgi->curh->show();
|
||||
tlog0<<"\tScreen handler: "<<pomtime.getDif()<<std::endl;
|
||||
CAbilityHandler * abilh = new CAbilityHandler;
|
||||
abilh->loadAbilities();
|
||||
cgi->abilh = abilh;
|
||||
tlog0<<"\tAbility handler: "<<pomtime.getDif()<<std::endl;
|
||||
cgi->pathf = new CPathfinder();
|
||||
tlog0<<"\tPathfinder: "<<pomtime.getDif()<<std::endl;
|
||||
tlog0<<"Preparing first handlers: "<<tmh.getDif()<<std::endl;
|
||||
|
@ -2092,7 +2092,7 @@ void CPlayerInterface::battleNewRound(int round) //called at the beggining of ea
|
||||
void CPlayerInterface::actionStarted(const BattleAction* action)
|
||||
{
|
||||
boost::unique_lock<boost::recursive_mutex> un(*pim);
|
||||
curAction = action;
|
||||
curAction = new BattleAction(*action);
|
||||
if( (action->actionType==2 || (action->actionType==6 && action->destinationTile!=cb->battleGetPos(action->stackNumber))) )
|
||||
{
|
||||
battleInt->moveStarted = true;
|
||||
@ -2152,6 +2152,7 @@ void CPlayerInterface::actionStarted(const BattleAction* action)
|
||||
void CPlayerInterface::actionFinished(const BattleAction* action)
|
||||
{
|
||||
boost::unique_lock<boost::recursive_mutex> un(*pim);
|
||||
delete curAction;
|
||||
curAction = NULL;
|
||||
//if((action->actionType==2 || (action->actionType==6 && action->destinationTile!=cb->battleGetPos(action->stackNumber)))) //activating interface when move is finished
|
||||
{
|
||||
|
@ -25,12 +25,54 @@
|
||||
#include <boost/thread.hpp>
|
||||
#include <boost/thread/shared_mutex.hpp>
|
||||
#include <sstream>
|
||||
CSharedCond<std::set<IPack*> > mess(new std::set<IPack*>);
|
||||
|
||||
#undef DLL_EXPORT
|
||||
#define DLL_EXPORT
|
||||
#include "../lib/RegisterTypes.h"
|
||||
extern std::string NAME;
|
||||
namespace intpr = boost::interprocess;
|
||||
|
||||
class CBaseForCLApply
|
||||
{
|
||||
public:
|
||||
virtual void applyOnClAfter(CClient *cl, void *pack) const =0;
|
||||
virtual void applyOnClBefore(CClient *cl, void *pack) const =0;
|
||||
};
|
||||
template <typename T> class CApplyOnCL : public CBaseForCLApply
|
||||
{
|
||||
public:
|
||||
void applyOnClAfter(CClient *cl, void *pack) const
|
||||
{
|
||||
T *ptr = static_cast<T*>(pack);
|
||||
ptr->applyCl(cl);
|
||||
}
|
||||
void applyOnClBefore(CClient *cl, void *pack) const
|
||||
{
|
||||
T *ptr = static_cast<T*>(pack);
|
||||
ptr->applyFirstCl(cl);
|
||||
}
|
||||
};
|
||||
|
||||
class CCLApplier
|
||||
{
|
||||
public:
|
||||
std::map<ui16,CBaseForCLApply*> apps;
|
||||
|
||||
CCLApplier()
|
||||
{
|
||||
registerTypes2(*this);
|
||||
}
|
||||
template<typename T> void registerType(const T * t=NULL)
|
||||
{
|
||||
ui16 ID = typeList.registerType(t);
|
||||
apps[ID] = new CApplyOnCL<T>;
|
||||
}
|
||||
|
||||
} *applier = NULL;
|
||||
|
||||
void CClient::init()
|
||||
{
|
||||
applier = new CCLApplier;
|
||||
IObjectInterface::cb = this;
|
||||
serv = NULL;
|
||||
gs = NULL;
|
||||
@ -52,571 +94,9 @@ CClient::CClient(CConnection *con, StartInfo *si)
|
||||
}
|
||||
CClient::~CClient(void)
|
||||
{
|
||||
delete applier;
|
||||
delete shared;
|
||||
}
|
||||
void CClient::process(int what)
|
||||
{
|
||||
static BattleAction curbaction;
|
||||
switch (what)
|
||||
{
|
||||
case 95: //system message
|
||||
{
|
||||
std::string m;
|
||||
*serv >> m;
|
||||
tlog4 << "System message from server: " << m << std::endl;
|
||||
break;
|
||||
}
|
||||
case 100: //one of our interfaces has turn
|
||||
{
|
||||
ui8 player;
|
||||
*serv >> player;//who?
|
||||
tlog5 << "It's turn of "<<(unsigned)player<<" player."<<std::endl;
|
||||
gs->currentPlayer = player;
|
||||
boost::thread(boost::bind(&CGameInterface::yourTurn,playerint[player]));
|
||||
break;
|
||||
}
|
||||
case 101:
|
||||
{
|
||||
NewTurn n;
|
||||
*serv >> n;
|
||||
tlog5 << "New day: "<<(unsigned)n.day<<". Applying changes... ";
|
||||
gs->apply(&n);
|
||||
tlog5 << "done!"<<std::endl;
|
||||
break;
|
||||
}
|
||||
case 102: //set resource amount
|
||||
{
|
||||
SetResource sr;
|
||||
*serv >> sr;
|
||||
tlog5 << "Set amount of "<<CGI->generaltexth->restypes[sr.resid]
|
||||
<< " of player "<<(unsigned)sr.player <<" to "<<sr.val<<std::endl;
|
||||
gs->apply(&sr);
|
||||
playerint[sr.player]->receivedResource(sr.resid,sr.val);
|
||||
break;
|
||||
}
|
||||
case 103: //show info dialog
|
||||
{
|
||||
InfoWindow iw;
|
||||
*serv >> iw;
|
||||
std::vector<Component*> comps;
|
||||
for(size_t i=0;i<iw.components.size();i++) {
|
||||
comps.push_back(&iw.components[i]);
|
||||
}
|
||||
std::string str = toString(iw.text);
|
||||
playerint[iw.player]->showInfoDialog(str,comps);
|
||||
break;
|
||||
}
|
||||
case 104:
|
||||
{
|
||||
SetResources sr;
|
||||
*serv >> sr;
|
||||
tlog5 << "Set amount of resources of player "<<(unsigned)sr.player<<std::endl;
|
||||
gs->apply(&sr);
|
||||
playerint[sr.player]->receivedResource(-1,-1);
|
||||
break;
|
||||
}
|
||||
case 105:
|
||||
{
|
||||
SetPrimSkill sps;
|
||||
*serv >> sps;
|
||||
tlog5 << "Changing hero primary skill"<<std::endl;
|
||||
gs->apply(&sps);
|
||||
playerint[gs->getHero(sps.id)->tempOwner]->heroPrimarySkillChanged(gs->getHero(sps.id),sps.which,sps.val);
|
||||
break;
|
||||
}
|
||||
case 106:
|
||||
{
|
||||
SetSecSkill sr;
|
||||
*serv >> sr;
|
||||
tlog5 << "Changing hero secondary skill"<<std::endl;
|
||||
gs->apply(&sr);
|
||||
//TODO? - maybe inform interfaces
|
||||
break;
|
||||
}
|
||||
case 107:
|
||||
{
|
||||
ShowInInfobox sii;
|
||||
*serv >> sii;
|
||||
SComponent sc(sii.c);
|
||||
sc.description = toString(sii.text);
|
||||
if(playerint[sii.player]->human)
|
||||
static_cast<CPlayerInterface*>(playerint[sii.player])->showComp(sc);
|
||||
break;
|
||||
}
|
||||
case 108:
|
||||
{
|
||||
HeroVisitCastle vc;
|
||||
*serv >> vc;
|
||||
gs->apply(&vc);
|
||||
if(vc.start() && !vc.garrison() && vstd::contains(playerint,gs->getHero(vc.hid)->tempOwner))
|
||||
{
|
||||
playerint[gs->getHero(vc.hid)->tempOwner]->heroVisitsTown(gs->getHero(vc.hid),gs->getTown(vc.tid));
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 109:
|
||||
{
|
||||
ChangeSpells vc;
|
||||
*serv >> vc;
|
||||
tlog5 << "Changing spells of hero "<<vc.hid<<std::endl;
|
||||
gs->apply(&vc);
|
||||
break;
|
||||
}
|
||||
case 110:
|
||||
{
|
||||
SetMana sm;
|
||||
*serv >> sm;
|
||||
tlog5 << "Setting mana value of hero "<<sm.hid<<" to "<<sm.val<<std::endl;
|
||||
gs->apply(&sm);
|
||||
CGHeroInstance *h = gs->getHero(sm.hid);
|
||||
if(vstd::contains(playerint,h->tempOwner))
|
||||
playerint[h->tempOwner]->heroManaPointsChanged(h);
|
||||
break;
|
||||
}
|
||||
case 111:
|
||||
{
|
||||
SetMovePoints smp;
|
||||
*serv >> smp;
|
||||
tlog5 << "Setting movement points of hero "<<smp.hid<<" to "<<smp.val<<std::endl;
|
||||
gs->apply(&smp);
|
||||
CGHeroInstance *h = gs->getHero(smp.hid);
|
||||
if(vstd::contains(playerint,h->tempOwner))
|
||||
playerint[h->tempOwner]->heroMovePointsChanged(h);
|
||||
break;
|
||||
}
|
||||
case 112:
|
||||
{
|
||||
FoWChange fc;
|
||||
*serv >> fc;
|
||||
tlog5 << "Changing FoW of player "<<(int)fc.player<<std::endl;
|
||||
gs->apply(&fc);
|
||||
if(!vstd::contains(playerint,fc.player))
|
||||
break;
|
||||
if(fc.mode)
|
||||
playerint[fc.player]->tileRevealed(fc.tiles);
|
||||
else
|
||||
playerint[fc.player]->tileHidden(fc.tiles);
|
||||
break;
|
||||
}
|
||||
case 113:
|
||||
{
|
||||
SetAvailableHeroes sav;
|
||||
*serv >> sav;
|
||||
tlog5 << "Setting available heroes for player "<<(int)sav.player<<std::endl;
|
||||
gs->apply(&sav);
|
||||
break;
|
||||
}
|
||||
case 115:
|
||||
{
|
||||
GiveBonus gb;
|
||||
*serv >> gb;
|
||||
tlog5 << "Hero receives bonus\n";
|
||||
gs->apply(&gb);
|
||||
CGHeroInstance *h = gs->getHero(gb.hid);
|
||||
if(vstd::contains(playerint,h->tempOwner))
|
||||
playerint[h->tempOwner]->heroBonusChanged(h,h->bonuses.back(),true);
|
||||
break;
|
||||
}
|
||||
case 116:
|
||||
{
|
||||
ChangeObjPos sav;
|
||||
*serv >> sav;
|
||||
tlog5 << "Changing pos of object "<< sav.objid << std::endl;
|
||||
CGObjectInstance *obj = gs->map->objects[sav.objid];
|
||||
//TODO: redraw if neeeded
|
||||
if(sav.flags & 1)
|
||||
CGI->mh->hideObject(obj);
|
||||
|
||||
gs->apply(&sav);
|
||||
|
||||
if(sav.flags & 1)
|
||||
CGI->mh->printObject(obj);
|
||||
break;
|
||||
}
|
||||
case 500:
|
||||
{
|
||||
RemoveObject rh;
|
||||
*serv >> rh;
|
||||
CGObjectInstance *obj = gs->map->objects[rh.id];
|
||||
CGI->mh->removeObject(obj);
|
||||
gs->apply(&rh);
|
||||
if(obj->ID == 34)
|
||||
{
|
||||
CGHeroInstance *h = static_cast<CGHeroInstance*>(obj);
|
||||
tlog5 << "Removing hero with id = "<<(unsigned)rh.id<<std::endl;
|
||||
playerint[h->tempOwner]->heroKilled(h);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 501: //hero movement response - we have to notify interfaces and callback
|
||||
{
|
||||
TryMoveHero *th = new TryMoveHero; //will be deleted by callback after processing
|
||||
*serv >> *th;
|
||||
tlog5 << "HeroMove: id="<<th->id<<"\tResult: "<<(unsigned)th->result<<"\tPosition "<<th->end<<std::endl;
|
||||
|
||||
HeroMoveDetails hmd(th->start,th->end,static_cast<CGHeroInstance*>(gs->map->objects[th->id]));
|
||||
hmd.style = th->result-1;
|
||||
hmd.successful = th->result;
|
||||
if(th->result>1)
|
||||
CGI->mh->removeObject(hmd.ho);
|
||||
|
||||
gs->apply(th);
|
||||
|
||||
if(th->result>1)
|
||||
CGI->mh->printObject(hmd.ho);
|
||||
int player = gs->map->objects[th->id]->getOwner();
|
||||
|
||||
if(playerint[player])
|
||||
{
|
||||
playerint[player]->tileRevealed(th->fowRevealed);
|
||||
//std::for_each(th->fowRevealed.begin(),th->fowRevealed.end(),boost::bind(&CGameInterface::tileRevealed,playerint[player],_1));
|
||||
}
|
||||
|
||||
//notify interfaces about move
|
||||
for(std::map<ui8, CGameInterface*>::iterator i=playerint.begin();i!=playerint.end();i++)
|
||||
{
|
||||
if(i->first >= PLAYER_LIMIT) continue;
|
||||
if(gs->players[i->first].fogOfWarMap[th->start.x-1][th->start.y][th->start.z] || gs->players[i->first].fogOfWarMap[th->end.x-1][th->end.y][th->end.z])
|
||||
{
|
||||
i->second->heroMoved(hmd);
|
||||
}
|
||||
}
|
||||
|
||||
//add info for callback
|
||||
if(th->result<2)
|
||||
{
|
||||
mess.mx->lock();
|
||||
mess.res->insert(th);
|
||||
mess.mx->unlock();
|
||||
mess.cv->notify_all();
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 502:
|
||||
{
|
||||
SetGarrisons sg;
|
||||
*serv >> sg;
|
||||
tlog5 << "Setting garrisons." << std::endl;
|
||||
gs->apply(&sg);
|
||||
for(std::map<ui32,CCreatureSet>::iterator i = sg.garrs.begin(); i!=sg.garrs.end(); i++)
|
||||
playerint[gs->map->objects[i->first]->tempOwner]->garrisonChanged(gs->map->objects[i->first]);
|
||||
break;
|
||||
}
|
||||
case 503:
|
||||
{
|
||||
//SetStrInfo ssi;
|
||||
//*serv >> ssi;
|
||||
//gs->apply(&ssi);
|
||||
//TODO: notify interfaces
|
||||
break;
|
||||
}
|
||||
case 504:
|
||||
{
|
||||
NewStructures ns;
|
||||
*serv >> ns;
|
||||
CGTownInstance *town = static_cast<CGTownInstance*>(gs->map->objects[ns.tid]);
|
||||
tlog5 << "New structure(s) in " << ns.tid <<" " << town->name << " - " << *ns.bid.begin() << std::endl;
|
||||
gs->apply(&ns);
|
||||
BOOST_FOREACH(si32 bid, ns.bid)
|
||||
{
|
||||
if(bid==13) //for or capitol
|
||||
{
|
||||
town->defInfo = gs->capitols[town->subID];
|
||||
}
|
||||
if(bid ==7)
|
||||
{
|
||||
town->defInfo = gs->forts[town->subID];
|
||||
}
|
||||
playerint[town->tempOwner]->buildChanged(town,bid,1);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 506:
|
||||
{
|
||||
SetAvailableCreatures ns;
|
||||
*serv >> ns;
|
||||
tlog5 << "Setting available creatures in " << ns.tid << std::endl;
|
||||
gs->apply(&ns);
|
||||
CGTownInstance *t = gs->getTown(ns.tid);
|
||||
if(vstd::contains(playerint,t->tempOwner))
|
||||
playerint[t->tempOwner]->availableCreaturesChanged(t);
|
||||
break;
|
||||
}
|
||||
case 508:
|
||||
{
|
||||
SetHeroesInTown inTown;
|
||||
*serv >> inTown;
|
||||
tlog5 << "Setting heroes in town " << inTown.tid << std::endl;
|
||||
gs->apply(&inTown);
|
||||
CGTownInstance *t = gs->getTown(inTown.tid);
|
||||
if(vstd::contains(playerint,t->tempOwner))
|
||||
playerint[t->tempOwner]->heroInGarrisonChange(t);
|
||||
break;
|
||||
}
|
||||
case 509:
|
||||
{
|
||||
SetHeroArtifacts sha;
|
||||
*serv >> sha;
|
||||
tlog5 << "Setting artifacts of hero " << sha.hid << std::endl;
|
||||
gs->apply(&sha);
|
||||
CGHeroInstance *t = gs->getHero(sha.hid);
|
||||
if(vstd::contains(playerint,t->tempOwner))
|
||||
playerint[t->tempOwner]->heroArtifactSetChanged(t);
|
||||
break;
|
||||
}
|
||||
case 513:
|
||||
{
|
||||
ui8 color;
|
||||
std::string message;
|
||||
*serv >> color >> message;
|
||||
tlog4 << "Player "<<(int)color<<" sends a message: " << message << std::endl;
|
||||
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:
|
||||
{
|
||||
HeroRecruited hr;
|
||||
*serv >> hr;
|
||||
tlog5 << "New hero bought\n";
|
||||
CGHeroInstance *h = gs->hpool.heroesPool[hr.hid];
|
||||
gs->apply(&hr);
|
||||
CGI->mh->initHeroDef(h);
|
||||
//CGI->mh->printObject(h);
|
||||
playerint[h->tempOwner]->heroCreated(h);
|
||||
playerint[h->tempOwner]->heroInGarrisonChange(gs->getTown(hr.tid));
|
||||
break;
|
||||
}
|
||||
case 516:
|
||||
{
|
||||
GiveHero hr;
|
||||
*serv >> hr;
|
||||
tlog5 << "Players receives hero\n";
|
||||
CGHeroInstance *h = gs->getHero(hr.id);
|
||||
CGI->mh->hideObject(h);
|
||||
gs->apply(&hr);
|
||||
CGI->mh->initHeroDef(h);
|
||||
CGI->mh->printObject(h);
|
||||
playerint[h->tempOwner]->heroCreated(h);
|
||||
break;
|
||||
}
|
||||
case 1001:
|
||||
{
|
||||
SetObjectProperty sop;
|
||||
*serv >> sop;
|
||||
tlog5 << "Setting " << (unsigned)sop.what << " property of " << sop.id <<" object to "<<sop.val<<std::endl;
|
||||
gs->apply(&sop);
|
||||
break;
|
||||
}
|
||||
case 1002:
|
||||
{
|
||||
SetHoverName shn;
|
||||
*serv >> shn;
|
||||
tlog5 << "Setting a name of " << shn.id <<" object to "<< toString(shn.name) <<std::endl;
|
||||
gs->apply(&shn);
|
||||
break;
|
||||
}
|
||||
case 2000:
|
||||
{
|
||||
HeroLevelUp bs;
|
||||
*serv >> bs;
|
||||
tlog5 << "Hero levels up!" <<std::endl;
|
||||
gs->apply(&bs);
|
||||
CGHeroInstance *h = gs->getHero(bs.heroid);
|
||||
if(vstd::contains(playerint,h->tempOwner))
|
||||
{
|
||||
boost::function<void(ui32)> callback = boost::function<void(ui32)>(boost::bind(&CCallback::selectionMade,LOCPLINT->cb,_1,bs.id));
|
||||
playerint[h->tempOwner]->heroGotLevel((const CGHeroInstance *)h,(int)bs.primskill,bs.skills, callback);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 2001:
|
||||
{
|
||||
SelectionDialog sd;
|
||||
*serv >> sd;
|
||||
tlog5 << "Showing selection dialog " <<std::endl;
|
||||
std::vector<Component*> comps;
|
||||
for(size_t i=0; i < sd.components.size(); ++i) {
|
||||
comps.push_back(&sd.components[i]);
|
||||
}
|
||||
std::string str = toString(sd.text);
|
||||
playerint[sd.player]->showSelDialog(str,comps,sd.id);
|
||||
break;
|
||||
}
|
||||
case 2002:
|
||||
{
|
||||
YesNoDialog ynd;
|
||||
*serv >> ynd;
|
||||
tlog5 << "Showing yes/no dialog " <<std::endl;
|
||||
std::vector<Component*> comps;
|
||||
for(size_t i=0; i < ynd.components.size(); ++i) {
|
||||
comps.push_back(&ynd.components[i]);
|
||||
}
|
||||
std::string str = toString(ynd.text);
|
||||
playerint[ynd.player]->showYesNoDialog(str,comps,ynd.id);
|
||||
break;
|
||||
}
|
||||
case 3000:
|
||||
{
|
||||
BattleStart bs;
|
||||
*serv >> bs; //uses new to allocate memory for battleInfo - must be deleted when battle is over
|
||||
tlog5 << "Starting battle!" <<std::endl;
|
||||
gs->apply(&bs);
|
||||
|
||||
if(playerint.find(gs->curB->side1) != playerint.end())
|
||||
playerint[gs->curB->side1]->battleStart(&gs->curB->army1, &gs->curB->army2, gs->curB->tile, gs->getHero(gs->curB->hero1), gs->getHero(gs->curB->hero2), 0);
|
||||
if(playerint.find(gs->curB->side2) != playerint.end())
|
||||
playerint[gs->curB->side2]->battleStart(&gs->curB->army1, &gs->curB->army2, gs->curB->tile, gs->getHero(gs->curB->hero1), gs->getHero(gs->curB->hero2), 1);
|
||||
|
||||
break;
|
||||
}
|
||||
case 3001:
|
||||
{
|
||||
BattleNextRound bnr;
|
||||
*serv >> bnr;
|
||||
tlog5 << "Round nr " << bnr.round <<std::endl;
|
||||
gs->apply(&bnr);
|
||||
|
||||
//tell players about next round
|
||||
if(playerint.find(gs->curB->side1) != playerint.end())
|
||||
playerint[gs->curB->side1]->battleNewRound(bnr.round);
|
||||
if(playerint.find(gs->curB->side2) != playerint.end())
|
||||
playerint[gs->curB->side2]->battleNewRound(bnr.round);
|
||||
break;
|
||||
}
|
||||
case 3002:
|
||||
{
|
||||
BattleSetActiveStack sas;
|
||||
*serv >> sas;
|
||||
tlog5 << "Active stack: " << sas.stack <<std::endl;
|
||||
gs->apply(&sas);
|
||||
int owner = gs->curB->getStack(sas.stack)->owner;
|
||||
boost::thread(boost::bind(&CClient::waitForMoveAndSend,this,owner));
|
||||
break;
|
||||
}
|
||||
case 3003:
|
||||
{
|
||||
BattleResult br;
|
||||
*serv >> br;
|
||||
tlog5 << "Battle ends. Winner: " << (unsigned)br.winner<< ". Type of end: "<< (unsigned)br.result <<std::endl;
|
||||
|
||||
if(playerint.find(gs->curB->side1) != playerint.end())
|
||||
playerint[gs->curB->side1]->battleEnd(&br);
|
||||
if(playerint.find(gs->curB->side2) != playerint.end())
|
||||
playerint[gs->curB->side2]->battleEnd(&br);
|
||||
|
||||
gs->apply(&br);
|
||||
break;
|
||||
}
|
||||
case 3004:
|
||||
{
|
||||
BattleStackMoved br;
|
||||
*serv >> br;
|
||||
tlog5 << "Stack "<<br.stack <<" moves to the tile "<<br.tile<<std::endl;
|
||||
if(playerint.find(gs->curB->side1) != playerint.end())
|
||||
playerint[gs->curB->side1]->battleStackMoved(br.stack, br.tile, br.distance);
|
||||
if(playerint.find(gs->curB->side2) != playerint.end())
|
||||
playerint[gs->curB->side2]->battleStackMoved(br.stack, br.tile, br.distance);
|
||||
gs->apply(&br);
|
||||
break;
|
||||
}
|
||||
case 3005:
|
||||
{
|
||||
BattleStackAttacked bsa;
|
||||
*serv >> bsa;
|
||||
gs->apply(&bsa);
|
||||
if(playerint.find(gs->curB->side1) != playerint.end())
|
||||
playerint[gs->curB->side1]->battleStackAttacked(&bsa);
|
||||
if(playerint.find(gs->curB->side2) != playerint.end())
|
||||
playerint[gs->curB->side2]->battleStackAttacked(&bsa);
|
||||
break;
|
||||
}
|
||||
case 3006:
|
||||
{
|
||||
BattleAttack ba;
|
||||
*serv >> ba;
|
||||
tlog5 << "Stack: " << ba.stackAttacking << " is attacking stack "<< ba.bsa.stackAttacked <<std::endl;
|
||||
if(playerint.find(gs->curB->side1) != playerint.end())
|
||||
playerint[gs->curB->side1]->battleAttack(&ba);
|
||||
if(playerint.find(gs->curB->side2) != playerint.end())
|
||||
playerint[gs->curB->side2]->battleAttack(&ba);
|
||||
gs->apply(&ba);
|
||||
if(playerint.find(gs->curB->side1) != playerint.end())
|
||||
playerint[gs->curB->side1]->battleStackAttacked(&ba.bsa);
|
||||
if(playerint.find(gs->curB->side2) != playerint.end())
|
||||
playerint[gs->curB->side2]->battleStackAttacked(&ba.bsa);
|
||||
break;
|
||||
}
|
||||
case 3007:
|
||||
{
|
||||
*serv >> curbaction;
|
||||
tlog5 << "Action started. ID: " << (int)curbaction.actionType << ". Destination: "<< curbaction.destinationTile <<std::endl;
|
||||
if(playerint.find(gs->curB->side1) != playerint.end())
|
||||
playerint[gs->curB->side1]->actionStarted(&curbaction);
|
||||
if(playerint.find(gs->curB->side2) != playerint.end())
|
||||
playerint[gs->curB->side2]->actionStarted(&curbaction);
|
||||
gs->apply(&StartAction(curbaction));
|
||||
break;
|
||||
}
|
||||
case 3008:
|
||||
{
|
||||
tlog5 << "Action ended!\n";
|
||||
if(!gs->curB)
|
||||
{
|
||||
tlog2 << "There is no battle state!\n";
|
||||
break;
|
||||
}
|
||||
if(playerint.find(gs->curB->side1) != playerint.end())
|
||||
playerint[gs->curB->side1]->actionFinished(&curbaction);
|
||||
if(playerint.find(gs->curB->side2) != playerint.end())
|
||||
playerint[gs->curB->side2]->actionFinished(&curbaction);
|
||||
break;
|
||||
}
|
||||
case 3009:
|
||||
{
|
||||
tlog5 << "Spell casted!\n";
|
||||
SpellCasted sc;
|
||||
*serv >> sc;
|
||||
gs->apply(&sc);
|
||||
if(playerint.find(gs->curB->side1) != playerint.end())
|
||||
playerint[gs->curB->side1]->battleSpellCasted(&sc);
|
||||
if(playerint.find(gs->curB->side2) != playerint.end())
|
||||
playerint[gs->curB->side2]->battleSpellCasted(&sc);
|
||||
break;
|
||||
}
|
||||
case 3010:
|
||||
{
|
||||
tlog5 << "Effect set!\n";
|
||||
SetStackEffect sse;
|
||||
*serv >> sse;
|
||||
gs->apply(&sse);
|
||||
SpellCasted sc;
|
||||
sc.id = sse.effect.id;
|
||||
sc.side = 3; //doesn't matter
|
||||
sc.skill = sse.effect.level;
|
||||
sc.tile = gs->curB->getStack(sse.stack)->position;
|
||||
if(playerint.find(gs->curB->side1) != playerint.end())
|
||||
playerint[gs->curB->side1]->battleSpellCasted(&sc);
|
||||
if(playerint.find(gs->curB->side2) != playerint.end())
|
||||
playerint[gs->curB->side2]->battleSpellCasted(&sc);
|
||||
break;
|
||||
}
|
||||
case 9999:
|
||||
break;
|
||||
default:
|
||||
{
|
||||
std::ostringstream ex;
|
||||
ex << "Not supported server message (type=" << what <<")";
|
||||
throw ex.str();
|
||||
}
|
||||
}
|
||||
}
|
||||
void CClient::waitForMoveAndSend(int color)
|
||||
{
|
||||
try
|
||||
@ -629,15 +109,25 @@ void CClient::waitForMoveAndSend(int color)
|
||||
}
|
||||
void CClient::run()
|
||||
{
|
||||
try
|
||||
CPack *pack;
|
||||
while(1)
|
||||
{
|
||||
ui16 typ;
|
||||
while(1)
|
||||
*serv >> pack;
|
||||
CBaseForCLApply *apply = applier->apps[typeList.getTypeID(pack)];
|
||||
if(apply)
|
||||
{
|
||||
*serv >> typ;
|
||||
process(typ);
|
||||
apply->applyOnClBefore(this,pack);
|
||||
gs->apply(pack);
|
||||
apply->applyOnClAfter(this,pack);
|
||||
tlog5 << "Applied server message of type " << typeid(*pack).name() << std::endl;
|
||||
}
|
||||
} HANDLE_EXCEPTION
|
||||
else
|
||||
{
|
||||
tlog1 << "Unknown server message. Type: " << pack->type << ". Typeinfo: " << typeid(*pack).name() << std::endl;
|
||||
}
|
||||
delete pack;
|
||||
pack = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void CClient::close()
|
||||
|
@ -10,6 +10,7 @@ class CGameState;
|
||||
class CGameInterface;
|
||||
class CConnection;
|
||||
class CCallback;
|
||||
struct BattleAction;
|
||||
struct SharedMem;
|
||||
class CClient;
|
||||
void processCommand(const std::string &message, CClient *&client);
|
||||
@ -41,13 +42,14 @@ struct CSharedCond
|
||||
|
||||
class CClient : public IGameCallback
|
||||
{
|
||||
public:
|
||||
CCallback *cb;
|
||||
std::map<ui8,CGameInterface *> playerint;
|
||||
CConnection *serv;
|
||||
SharedMem *shared;
|
||||
BattleAction *curbaction;
|
||||
|
||||
void waitForMoveAndSend(int color);
|
||||
public:
|
||||
CClient(void);
|
||||
CClient(CConnection *con, StartInfo *si);
|
||||
~CClient(void);
|
||||
@ -57,7 +59,6 @@ public:
|
||||
void newGame(CConnection *con, StartInfo *si); //con - connection to server
|
||||
void save(const std::string & fname);
|
||||
void load(const std::string & fname);
|
||||
void process(int what);
|
||||
void run();
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
//from IGameCallback
|
||||
|
423
client/NetPacksClient.cpp
Normal file
423
client/NetPacksClient.cpp
Normal file
@ -0,0 +1,423 @@
|
||||
#include "../lib/NetPacks.h"
|
||||
#include "../CCallback.h"
|
||||
#include "../client/Client.h"
|
||||
#include "../CPlayerInterface.h"
|
||||
#include "../CGameInfo.h"
|
||||
#include "../hch/CGeneralTextHandler.h"
|
||||
#include "../hch/CDefObjInfoHandler.h"
|
||||
#include "../hch/CHeroHandler.h"
|
||||
#include "../hch/CObjectHandler.h"
|
||||
#include "../lib/VCMI_Lib.h"
|
||||
#include "../map.h"
|
||||
#include "../hch/CSpellHandler.h"
|
||||
#include "../mapHandler.h"
|
||||
#include <boost/bind.hpp>
|
||||
#include <boost/foreach.hpp>
|
||||
#include <boost/thread.hpp>
|
||||
#include <boost/thread/shared_mutex.hpp>
|
||||
|
||||
//macro to avoid code duplication - calls given method with given arguments if interface for specific player is present
|
||||
#define INTERFACE_CALL_IF_PRESENT(player,function,...) \
|
||||
if(vstd::contains(cl->playerint,player)) \
|
||||
cl->playerint[player]->function(__VA_ARGS__);
|
||||
|
||||
|
||||
CSharedCond<std::set<CPack*> > mess(new std::set<CPack*>);
|
||||
|
||||
void SetResources::applyCl( CClient *cl )
|
||||
{
|
||||
cl->playerint[player]->receivedResource(-1,-1);
|
||||
}
|
||||
|
||||
void SetResource::applyCl( CClient *cl )
|
||||
{
|
||||
cl->playerint[player]->receivedResource(resid,val);
|
||||
}
|
||||
|
||||
void SetPrimSkill::applyCl( CClient *cl )
|
||||
{
|
||||
cl->playerint[GS(cl)->getHero(id)->tempOwner]->heroPrimarySkillChanged(GS(cl)->getHero(id),which,val);
|
||||
}
|
||||
|
||||
void SetSecSkill::applyCl( CClient *cl )
|
||||
{
|
||||
//TODO: inform interface?
|
||||
}
|
||||
|
||||
void HeroVisitCastle::applyCl( CClient *cl )
|
||||
{
|
||||
if(start() && !garrison() && vstd::contains(cl->playerint,GS(cl)->getHero(hid)->tempOwner))
|
||||
{
|
||||
cl->playerint[GS(cl)->getHero(hid)->tempOwner]->heroVisitsTown(GS(cl)->getHero(hid),GS(cl)->getTown(tid));
|
||||
}
|
||||
}
|
||||
|
||||
void ChangeSpells::applyCl( CClient *cl )
|
||||
{
|
||||
//TODO: inform interface?
|
||||
}
|
||||
|
||||
void SetMana::applyCl( CClient *cl )
|
||||
{
|
||||
CGHeroInstance *h = GS(cl)->getHero(hid);
|
||||
if(vstd::contains(cl->playerint,h->tempOwner))
|
||||
cl->playerint[h->tempOwner]->heroManaPointsChanged(h);
|
||||
}
|
||||
|
||||
void SetMovePoints::applyCl( CClient *cl )
|
||||
{
|
||||
CGHeroInstance *h = GS(cl)->getHero(hid);
|
||||
if(vstd::contains(cl->playerint,h->tempOwner))
|
||||
cl->playerint[h->tempOwner]->heroMovePointsChanged(h);
|
||||
}
|
||||
|
||||
void FoWChange::applyCl( CClient *cl )
|
||||
{
|
||||
if(!vstd::contains(cl->playerint,player))
|
||||
return;
|
||||
|
||||
if(mode)
|
||||
cl->playerint[player]->tileRevealed(tiles);
|
||||
else
|
||||
cl->playerint[player]->tileHidden(tiles);
|
||||
}
|
||||
|
||||
void SetAvailableHeroes::applyCl( CClient *cl )
|
||||
{
|
||||
//TODO: inform interface?
|
||||
}
|
||||
|
||||
void GiveBonus::applyCl( CClient *cl )
|
||||
{
|
||||
CGHeroInstance *h = GS(cl)->getHero(hid);
|
||||
if(vstd::contains(cl->playerint,h->tempOwner))
|
||||
cl->playerint[h->tempOwner]->heroBonusChanged(h,h->bonuses.back(),true);
|
||||
}
|
||||
|
||||
void ChangeObjPos::applyFirstCl( CClient *cl )
|
||||
{
|
||||
CGObjectInstance *obj = GS(cl)->map->objects[objid];
|
||||
if(flags & 1)
|
||||
CGI->mh->hideObject(obj);
|
||||
}
|
||||
void ChangeObjPos::applyCl( CClient *cl )
|
||||
{
|
||||
CGObjectInstance *obj = GS(cl)->map->objects[objid];
|
||||
if(flags & 1)
|
||||
CGI->mh->printObject(obj);
|
||||
}
|
||||
|
||||
void RemoveObject::applyFirstCl( CClient *cl )
|
||||
{
|
||||
CGI->mh->hideObject(cl->getObj(id));
|
||||
CGHeroInstance *h = GS(cl)->getHero(id);
|
||||
if(h)
|
||||
{
|
||||
if(vstd::contains(cl->playerint,h->tempOwner))
|
||||
cl->playerint[h->tempOwner]->heroKilled(h);
|
||||
}
|
||||
}
|
||||
|
||||
void RemoveObject::applyCl( CClient *cl )
|
||||
{
|
||||
}
|
||||
|
||||
void TryMoveHero::applyFirstCl( CClient *cl )
|
||||
{
|
||||
if(result>1)
|
||||
CGI->mh->removeObject(GS(cl)->getHero(id));
|
||||
}
|
||||
|
||||
void TryMoveHero::applyCl( CClient *cl )
|
||||
{
|
||||
HeroMoveDetails hmd(start,end,GS(cl)->getHero(id));
|
||||
hmd.style = result-1;
|
||||
hmd.successful = result;
|
||||
|
||||
if(result>1)
|
||||
CGI->mh->printObject(hmd.ho);
|
||||
int player = hmd.ho->tempOwner;
|
||||
|
||||
if(vstd::contains(cl->playerint,player))
|
||||
{
|
||||
cl->playerint[player]->tileRevealed(fowRevealed);
|
||||
}
|
||||
|
||||
//notify interfaces about move
|
||||
for(std::map<ui8, CGameInterface*>::iterator i=cl->playerint.begin();i!=cl->playerint.end();i++)
|
||||
{
|
||||
if(i->first >= PLAYER_LIMIT) continue;
|
||||
if(GS(cl)->players[i->first].fogOfWarMap[start.x-1][start.y][start.z] || GS(cl)->players[i->first].fogOfWarMap[end.x-1][end.y][end.z])
|
||||
{
|
||||
i->second->heroMoved(hmd);
|
||||
}
|
||||
}
|
||||
|
||||
//add info for callback
|
||||
if(result<2)
|
||||
{
|
||||
mess.mx->lock();
|
||||
mess.res->insert(new TryMoveHero(*this));
|
||||
mess.mx->unlock();
|
||||
mess.cv->notify_all();
|
||||
}
|
||||
}
|
||||
|
||||
void SetGarrisons::applyCl( CClient *cl )
|
||||
{
|
||||
for(std::map<ui32,CCreatureSet>::iterator i = garrs.begin(); i!=garrs.end(); i++)
|
||||
if(vstd::contains(cl->playerint,cl->getOwner(i->first)))
|
||||
cl->playerint[cl->getOwner(i->first)]->garrisonChanged(cl->getObj(i->first));
|
||||
}
|
||||
|
||||
void NewStructures::applyCl( CClient *cl )
|
||||
{
|
||||
CGTownInstance *town = GS(cl)->getTown(tid);
|
||||
BOOST_FOREACH(si32 id, bid)
|
||||
{
|
||||
if(id==13) //fort or capitol
|
||||
{
|
||||
town->defInfo = GS(cl)->capitols[town->subID];
|
||||
}
|
||||
if(id ==7)
|
||||
{
|
||||
town->defInfo = GS(cl)->forts[town->subID];
|
||||
}
|
||||
if(vstd::contains(cl->playerint,town->tempOwner))
|
||||
cl->playerint[town->tempOwner]->buildChanged(town,id,1);
|
||||
}
|
||||
}
|
||||
|
||||
void SetAvailableCreatures::applyCl( CClient *cl )
|
||||
{
|
||||
CGTownInstance *t = GS(cl)->getTown(tid);
|
||||
if(vstd::contains(cl->playerint,t->tempOwner))
|
||||
cl->playerint[t->tempOwner]->availableCreaturesChanged(t);
|
||||
}
|
||||
|
||||
void SetHeroesInTown::applyCl( CClient *cl )
|
||||
{
|
||||
CGTownInstance *t = GS(cl)->getTown(tid);
|
||||
if(vstd::contains(cl->playerint,t->tempOwner))
|
||||
cl->playerint[t->tempOwner]->heroInGarrisonChange(t);
|
||||
}
|
||||
|
||||
void SetHeroArtifacts::applyCl( CClient *cl )
|
||||
{
|
||||
CGHeroInstance *t = GS(cl)->getHero(hid);
|
||||
if(vstd::contains(cl->playerint,t->tempOwner))
|
||||
cl->playerint[t->tempOwner]->heroArtifactSetChanged(t);
|
||||
}
|
||||
|
||||
void HeroRecruited::applyCl( CClient *cl )
|
||||
{
|
||||
CGHeroInstance *h = GS(cl)->map->heroes.back();
|
||||
if(h->subID != hid)
|
||||
{
|
||||
tlog1 << "Something wrong with hero recruited!\n";
|
||||
}
|
||||
|
||||
CGI->mh->initHeroDef(h);
|
||||
if(vstd::contains(cl->playerint,h->tempOwner))
|
||||
{
|
||||
cl->playerint[h->tempOwner]->heroCreated(h);
|
||||
cl->playerint[h->tempOwner]->heroInGarrisonChange(GS(cl)->getTown(tid));
|
||||
}
|
||||
}
|
||||
|
||||
void GiveHero::applyCl( CClient *cl )
|
||||
{
|
||||
CGHeroInstance *h = GS(cl)->getHero(id);
|
||||
CGI->mh->initHeroDef(h);
|
||||
CGI->mh->printObject(h);
|
||||
cl->playerint[h->tempOwner]->heroCreated(h);
|
||||
}
|
||||
|
||||
void GiveHero::applyFirstCl( CClient *cl )
|
||||
{
|
||||
CGI->mh->hideObject(GS(cl)->getHero(id));
|
||||
}
|
||||
|
||||
void InfoWindow::applyCl( CClient *cl )
|
||||
{
|
||||
std::vector<Component*> comps;
|
||||
for(size_t i=0;i<components.size();i++)
|
||||
{
|
||||
comps.push_back(&components[i]);
|
||||
}
|
||||
std::string str = toString(text);
|
||||
|
||||
if(vstd::contains(cl->playerint,player))
|
||||
cl->playerint[player]->showInfoDialog(str,comps);
|
||||
else
|
||||
tlog2 << "We received InfoWindow for not our player...\n";
|
||||
}
|
||||
|
||||
void HeroLevelUp::applyCl( CClient *cl )
|
||||
{
|
||||
CGHeroInstance *h = GS(cl)->getHero(heroid);
|
||||
if(vstd::contains(cl->playerint,h->tempOwner))
|
||||
{
|
||||
boost::function<void(ui32)> callback = boost::function<void(ui32)>(boost::bind(&CCallback::selectionMade,LOCPLINT->cb,_1,id));
|
||||
cl->playerint[h->tempOwner]->heroGotLevel((const CGHeroInstance *)h,(int)primskill,skills, callback);
|
||||
}
|
||||
}
|
||||
|
||||
void SelectionDialog::applyCl( CClient *cl )
|
||||
{
|
||||
std::vector<Component*> comps;
|
||||
for(size_t i=0; i < components.size(); ++i) {
|
||||
comps.push_back(&components[i]);
|
||||
}
|
||||
std::string str = toString(text);
|
||||
if(vstd::contains(cl->playerint,player))
|
||||
cl->playerint[player]->showSelDialog(str,comps,id);
|
||||
else
|
||||
tlog2 << "We received SelectionDialog for not our player...\n";
|
||||
}
|
||||
|
||||
void YesNoDialog::applyCl( CClient *cl )
|
||||
{
|
||||
std::vector<Component*> comps;
|
||||
for(size_t i=0; i < components.size(); ++i) {
|
||||
comps.push_back(&components[i]);
|
||||
}
|
||||
std::string str = toString(text);
|
||||
if(vstd::contains(cl->playerint,player))
|
||||
cl->playerint[player]->showYesNoDialog(str,comps,id);
|
||||
else
|
||||
tlog2 << "We received YesNoDialog for not our player...\n";
|
||||
}
|
||||
|
||||
void BattleStart::applyCl( CClient *cl )
|
||||
{
|
||||
if(vstd::contains(cl->playerint,info->side1))
|
||||
cl->playerint[info->side1]->battleStart(&info->army1, &info->army2, info->tile, GS(cl)->getHero(info->hero1), GS(cl)->getHero(info->hero2), 0);
|
||||
|
||||
if(vstd::contains(cl->playerint,info->side2))
|
||||
cl->playerint[info->side2]->battleStart(&info->army1, &info->army2, info->tile, GS(cl)->getHero(info->hero1), GS(cl)->getHero(info->hero2), 1);
|
||||
}
|
||||
|
||||
void BattleNextRound::applyCl( CClient *cl )
|
||||
{
|
||||
if(cl->playerint.find(GS(cl)->curB->side1) != cl->playerint.end())
|
||||
cl->playerint[GS(cl)->curB->side1]->battleNewRound(round);
|
||||
if(cl->playerint.find(GS(cl)->curB->side2) != cl->playerint.end())
|
||||
cl->playerint[GS(cl)->curB->side2]->battleNewRound(round);
|
||||
}
|
||||
|
||||
void BattleSetActiveStack::applyCl( CClient *cl )
|
||||
{
|
||||
int owner = GS(cl)->curB->getStack(stack)->owner;
|
||||
if(vstd::contains(cl->playerint,owner))
|
||||
boost::thread(boost::bind(&CClient::waitForMoveAndSend,cl,owner));
|
||||
}
|
||||
|
||||
void BattleResult::applyFirstCl( CClient *cl )
|
||||
{
|
||||
if(cl->playerint.find(GS(cl)->curB->side1) != cl->playerint.end())
|
||||
cl->playerint[GS(cl)->curB->side1]->battleEnd(this);
|
||||
if(cl->playerint.find(GS(cl)->curB->side2) != cl->playerint.end())
|
||||
cl->playerint[GS(cl)->curB->side2]->battleEnd(this);
|
||||
}
|
||||
|
||||
void BattleStackMoved::applyFirstCl( CClient *cl )
|
||||
{
|
||||
INTERFACE_CALL_IF_PRESENT(GS(cl)->curB->side1,battleStackMoved,stack,tile,distance);
|
||||
INTERFACE_CALL_IF_PRESENT(GS(cl)->curB->side2,battleStackMoved,stack,tile,distance);
|
||||
}
|
||||
|
||||
void BattleStackAttacked::applyCl( CClient *cl )
|
||||
{
|
||||
|
||||
if(cl->playerint.find(GS(cl)->curB->side1) != cl->playerint.end())
|
||||
cl->playerint[GS(cl)->curB->side1]->battleStackAttacked(this);
|
||||
if(cl->playerint.find(GS(cl)->curB->side2) != cl->playerint.end())
|
||||
cl->playerint[GS(cl)->curB->side2]->battleStackAttacked(this);
|
||||
}
|
||||
|
||||
void BattleAttack::applyFirstCl( CClient *cl )
|
||||
{
|
||||
if(cl->playerint.find(GS(cl)->curB->side1) != cl->playerint.end())
|
||||
cl->playerint[GS(cl)->curB->side1]->battleAttack(this);
|
||||
if(cl->playerint.find(GS(cl)->curB->side2) != cl->playerint.end())
|
||||
cl->playerint[GS(cl)->curB->side2]->battleAttack(this);
|
||||
}
|
||||
|
||||
void BattleAttack::applyCl( CClient *cl )
|
||||
{
|
||||
if(cl->playerint.find(GS(cl)->curB->side1) != cl->playerint.end())
|
||||
cl->playerint[GS(cl)->curB->side1]->battleStackAttacked(&bsa);
|
||||
if(cl->playerint.find(GS(cl)->curB->side2) != cl->playerint.end())
|
||||
cl->playerint[GS(cl)->curB->side2]->battleStackAttacked(&bsa);
|
||||
}
|
||||
|
||||
void StartAction::applyFirstCl( CClient *cl )
|
||||
{
|
||||
cl->curbaction = new BattleAction(ba);
|
||||
if(cl->playerint.find(GS(cl)->curB->side1) != cl->playerint.end())
|
||||
cl->playerint[GS(cl)->curB->side1]->actionStarted(&ba);
|
||||
if(cl->playerint.find(GS(cl)->curB->side2) != cl->playerint.end())
|
||||
cl->playerint[GS(cl)->curB->side2]->actionStarted(&ba);
|
||||
}
|
||||
|
||||
void SpellCasted::applyCl( CClient *cl )
|
||||
{
|
||||
if(cl->playerint.find(GS(cl)->curB->side1) != cl->playerint.end())
|
||||
cl->playerint[GS(cl)->curB->side1]->battleSpellCasted(this);
|
||||
if(cl->playerint.find(GS(cl)->curB->side2) != cl->playerint.end())
|
||||
cl->playerint[GS(cl)->curB->side2]->battleSpellCasted(this);
|
||||
}
|
||||
|
||||
void SetStackEffect::applyCl( CClient *cl )
|
||||
{
|
||||
SpellCasted sc;
|
||||
sc.id = effect.id;
|
||||
sc.side = 3; //doesn't matter
|
||||
sc.skill = effect.level;
|
||||
sc.tile = GS(cl)->curB->getStack(stack)->position;
|
||||
if(cl->playerint.find(GS(cl)->curB->side1) != cl->playerint.end())
|
||||
cl->playerint[GS(cl)->curB->side1]->battleSpellCasted(&sc);
|
||||
if(cl->playerint.find(GS(cl)->curB->side2) != cl->playerint.end())
|
||||
cl->playerint[GS(cl)->curB->side2]->battleSpellCasted(&sc);
|
||||
}
|
||||
|
||||
CGameState* CPackForClient::GS( CClient *cl )
|
||||
{
|
||||
return cl->gs;
|
||||
}
|
||||
|
||||
void EndAction::applyCl( CClient *cl )
|
||||
{
|
||||
INTERFACE_CALL_IF_PRESENT(GS(cl)->curB->side1,actionFinished,cl->curbaction);
|
||||
INTERFACE_CALL_IF_PRESENT(GS(cl)->curB->side2,actionFinished,cl->curbaction);
|
||||
|
||||
delete cl->curbaction;
|
||||
cl->curbaction = NULL;
|
||||
}
|
||||
|
||||
void SystemMessage::applyCl( CClient *cl )
|
||||
{
|
||||
tlog4 << "System message from server: " << text << std::endl;
|
||||
}
|
||||
|
||||
void YourTurn::applyCl( CClient *cl )
|
||||
{
|
||||
boost::thread(boost::bind(&CGameInterface::yourTurn,cl->playerint[player]));
|
||||
}
|
||||
|
||||
|
||||
void PlayerMessage::applyCl(CClient *cl)
|
||||
{
|
||||
tlog4 << "Player "<<(int)player<<" sends a message: " << text << std::endl;
|
||||
}
|
||||
|
||||
void ShowInInfobox::applyCl(CClient *cl)
|
||||
{
|
||||
SComponent sc(c);
|
||||
sc.description = toString(text);
|
||||
if(cl->playerint[player]->human)
|
||||
{
|
||||
static_cast<CPlayerInterface*>(cl->playerint[player])->showComp(sc);
|
||||
}
|
||||
}
|
@ -274,10 +274,6 @@
|
||||
RelativePath="..\AdventureMapButton.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\hch\CAbilityHandler.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\CAdvmapInterface.cpp"
|
||||
>
|
||||
@ -374,6 +370,10 @@
|
||||
RelativePath="..\mapHandler.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\NetPacksClient.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\SDL_Extensions.cpp"
|
||||
>
|
||||
@ -396,10 +396,6 @@
|
||||
RelativePath="..\AI_Base.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\hch\CAbilityHandler.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\CAdvmapInterface.h"
|
||||
>
|
||||
|
@ -290,7 +290,7 @@ int3 CGHeroInstance::getPosition(bool h3m) const //h3m=true - returns position o
|
||||
}
|
||||
int CGHeroInstance::getSightDistance() const //returns sight distance of this hero
|
||||
{
|
||||
return 6 + getSecSkillLevel(3); //default + scouting
|
||||
return 5 + getSecSkillLevel(3); //default + scouting
|
||||
}
|
||||
|
||||
si32 CGHeroInstance::manaLimit() const
|
||||
@ -302,7 +302,7 @@ si32 CGHeroInstance::manaLimit() const
|
||||
case 2: modifier+=0.5; break;
|
||||
case 3: modifier+=1.0; break;
|
||||
}
|
||||
return 10*getPrimSkillLevel(3)*modifier;
|
||||
return si32(10*getPrimSkillLevel(3)*modifier);
|
||||
}
|
||||
//void CGHeroInstance::setPosition(int3 Pos, bool h3m) //as above, but sets position
|
||||
//{
|
||||
@ -334,19 +334,20 @@ int CGHeroInstance::maxMovePoints(bool onLand) const
|
||||
if (ret>2000)
|
||||
ret=2000;
|
||||
|
||||
double bonus = 0;
|
||||
if(onLand)
|
||||
{
|
||||
//logistics:
|
||||
switch(getSecSkillLevel(2))
|
||||
{
|
||||
case 1:
|
||||
ret *= 1.1f;
|
||||
bonus = 0.1;
|
||||
break;
|
||||
case 2:
|
||||
ret *= 1.2f;
|
||||
bonus = 0.2;
|
||||
break;
|
||||
case 3:
|
||||
ret *= 1.3f;
|
||||
bonus = 0.3;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -356,17 +357,17 @@ int CGHeroInstance::maxMovePoints(bool onLand) const
|
||||
switch(getSecSkillLevel(2))
|
||||
{
|
||||
case 1:
|
||||
ret *= 1.5f;
|
||||
bonus = 0.5;
|
||||
break;
|
||||
case 2:
|
||||
ret *= 2.0f;
|
||||
bonus = 1.0;
|
||||
break;
|
||||
case 3:
|
||||
ret *= 2.5f;
|
||||
bonus = 1.5;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
return int(ret + ret*bonus);
|
||||
}
|
||||
ui32 CGHeroInstance::getArtAtPos(ui16 pos) const
|
||||
{
|
||||
|
@ -4,8 +4,12 @@
|
||||
#include <boost/asio.hpp>
|
||||
#include <boost/thread.hpp>
|
||||
#include <fstream>
|
||||
|
||||
using namespace boost;
|
||||
using namespace boost::asio::ip;
|
||||
template<typename Serializer> DLL_EXPORT void registerTypes(Serializer &s); //defined elsewhere and explicitly instantiated for used serializers
|
||||
|
||||
CTypeList typeList;
|
||||
|
||||
#define LOG(a) \
|
||||
if(logging)\
|
||||
@ -22,6 +26,8 @@ using namespace boost::asio::ip;
|
||||
|
||||
void CConnection::init()
|
||||
{
|
||||
registerTypes(static_cast<CISer<CConnection>&>(*this));
|
||||
registerTypes(static_cast<COSer<CConnection>&>(*this));
|
||||
#ifdef LIL_ENDIAN
|
||||
myEndianess = true;
|
||||
#else
|
||||
@ -148,6 +154,7 @@ void CConnection::close()
|
||||
CSaveFile::CSaveFile( const std::string &fname )
|
||||
:sfile(new std::ofstream(fname.c_str(),std::ios::binary))
|
||||
{
|
||||
registerTypes(*this);
|
||||
if(!(*sfile))
|
||||
{
|
||||
tlog1 << "Error: cannot open to write " << fname << std::endl;
|
||||
@ -169,6 +176,7 @@ int CSaveFile::write( const void * data, unsigned size )
|
||||
CLoadFile::CLoadFile( const std::string &fname )
|
||||
:sfile(new std::ifstream(fname.c_str(),std::ios::binary))
|
||||
{
|
||||
registerTypes(*this);
|
||||
if(!(*sfile))
|
||||
{
|
||||
tlog1 << "Error: cannot open to read " << fname << std::endl;
|
||||
@ -185,4 +193,30 @@ int CLoadFile::read( const void * data, unsigned size )
|
||||
{
|
||||
sfile->read((char *)data,size);
|
||||
return size;
|
||||
}
|
||||
|
||||
CTypeList::CTypeList()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
ui16 CTypeList::registerType( const type_info *type )
|
||||
{
|
||||
TTypeMap::const_iterator i = types.find(type);
|
||||
if(i != types.end())
|
||||
return i->second; //type found, return ID
|
||||
|
||||
//type not found - add it to the list and return given ID
|
||||
ui16 id = types.size() + 1;
|
||||
types.insert(std::make_pair(type,id));
|
||||
return id;
|
||||
}
|
||||
|
||||
ui16 CTypeList::getTypeID( const type_info *type )
|
||||
{
|
||||
TTypeMap::const_iterator i = types.find(type);
|
||||
if(i != types.end())
|
||||
return i->second;
|
||||
else
|
||||
return 0;
|
||||
}
|
169
lib/Connection.h
169
lib/Connection.h
@ -5,6 +5,7 @@
|
||||
#include <vector>
|
||||
#include <set>
|
||||
#include <list>
|
||||
#include <typeinfo>
|
||||
|
||||
#include <boost/type_traits/is_fundamental.hpp>
|
||||
#include <boost/type_traits/is_enum.hpp>
|
||||
@ -20,7 +21,6 @@
|
||||
#include <boost/type_traits/is_array.hpp>
|
||||
const ui32 version = 703;
|
||||
class CConnection;
|
||||
|
||||
namespace mpl = boost::mpl;
|
||||
|
||||
namespace boost
|
||||
@ -53,6 +53,45 @@ enum SerializationLvl
|
||||
Serializable
|
||||
};
|
||||
|
||||
|
||||
struct TypeComparer
|
||||
{
|
||||
bool operator()(const type_info *a, const type_info *b)
|
||||
{
|
||||
return a->before(*b);
|
||||
}
|
||||
};
|
||||
|
||||
class DLL_EXPORT CTypeList
|
||||
{
|
||||
typedef std::multimap<const type_info *,ui16,TypeComparer> TTypeMap;
|
||||
TTypeMap types;
|
||||
public:
|
||||
CTypeList();
|
||||
ui16 registerType(const type_info *type);
|
||||
template <typename T> ui16 registerType(const T * t)
|
||||
{
|
||||
return registerType(getTypeInfo(t));
|
||||
}
|
||||
|
||||
ui16 getTypeID(const type_info *type);
|
||||
template <typename T> ui16 getTypeID(const T * t)
|
||||
{
|
||||
return getTypeID(getTypeInfo(t));
|
||||
}
|
||||
|
||||
|
||||
template <typename T> const type_info * getTypeInfo(const T * t = NULL)
|
||||
{
|
||||
if(t)
|
||||
return &typeid(*t);
|
||||
else
|
||||
return &typeid(T);
|
||||
}
|
||||
};
|
||||
|
||||
extern DLL_EXPORT CTypeList typeList;
|
||||
|
||||
template<typename Ser,typename T>
|
||||
struct SavePrimitive
|
||||
{
|
||||
@ -169,11 +208,51 @@ struct SerializationLevel
|
||||
static const int value = SerializationLevel::type::value;
|
||||
};
|
||||
|
||||
template <typename Serializer> class DLL_EXPORT COSer
|
||||
class DLL_EXPORT CSerializerBase
|
||||
{
|
||||
public:
|
||||
};
|
||||
|
||||
class DLL_EXPORT CSaverBase : public virtual CSerializerBase
|
||||
{
|
||||
};
|
||||
|
||||
class CBasicPointerSaver
|
||||
{
|
||||
public:
|
||||
virtual void savePtr(CSaverBase &ar, const void *data) const =0;
|
||||
};
|
||||
|
||||
template <typename Serializer, typename T> class CPointerSaver : public CBasicPointerSaver
|
||||
{
|
||||
public:
|
||||
void savePtr(CSaverBase &ar, const void *data) const
|
||||
{
|
||||
Serializer &s = static_cast<Serializer&>(ar);
|
||||
const T *ptr = static_cast<const T*>(data);
|
||||
|
||||
//T is most derived known type, it's time to call actual serialize
|
||||
const_cast<T&>(*ptr).serialize(s,version);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Serializer> class DLL_EXPORT COSer : public CSaverBase
|
||||
{
|
||||
public:
|
||||
bool saving;
|
||||
COSer(){saving=true;};
|
||||
std::map<ui16,CBasicPointerSaver*> savers; // typeID => CPointerSaver<serializer,type>
|
||||
|
||||
COSer()
|
||||
{
|
||||
saving=true;
|
||||
}
|
||||
|
||||
template<typename T> void registerType(const T * t=NULL)
|
||||
{
|
||||
ui16 ID = typeList.registerType(t);
|
||||
savers[ID] = new CPointerSaver<COSer<Serializer>,T>;
|
||||
}
|
||||
|
||||
Serializer * This()
|
||||
{
|
||||
return static_cast<Serializer*>(this);
|
||||
@ -185,7 +264,7 @@ public:
|
||||
this->This()->save(t);
|
||||
return * this->This();
|
||||
}
|
||||
|
||||
|
||||
template<class T>
|
||||
COSer & operator&(const T & t)
|
||||
{
|
||||
@ -200,14 +279,28 @@ public:
|
||||
{
|
||||
this->This()->write(&data,sizeof(data));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void savePointer(const T &data)
|
||||
{
|
||||
//write if pointer is not NULL
|
||||
ui8 hlp = (data!=NULL);
|
||||
*this << hlp;
|
||||
if(hlp)
|
||||
*this << *data;
|
||||
|
||||
//if pointer is NULL then we don't need anything more...
|
||||
if(!hlp)
|
||||
return;
|
||||
|
||||
//write type identifier
|
||||
ui16 tid = typeList.getTypeID(data);
|
||||
*this << tid;
|
||||
|
||||
if(!tid)
|
||||
*this << *data; //if type is unregistered simply write all data in a standard way
|
||||
else
|
||||
savers[tid]->savePtr(*this,data); //call serializer specific for our real type
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void saveArray(const T &data)
|
||||
{
|
||||
@ -288,11 +381,53 @@ public:
|
||||
*this << i->first << i->second;
|
||||
}
|
||||
};
|
||||
template <typename Serializer> class DLL_EXPORT CISer
|
||||
|
||||
|
||||
|
||||
class DLL_EXPORT CLoaderBase : public virtual CSerializerBase
|
||||
{};
|
||||
|
||||
class CBasicPointerLoader
|
||||
{
|
||||
public:
|
||||
virtual void loadPtr(CLoaderBase &ar, void *data) const =0; //data is pointer to the ACTUAL POINTER
|
||||
};
|
||||
|
||||
template <typename Serializer, typename T> class CPointerLoader : public CBasicPointerLoader
|
||||
{
|
||||
public:
|
||||
void loadPtr(CLoaderBase &ar, void *data) const //data is pointer to the ACTUAL POINTER
|
||||
{
|
||||
Serializer &s = static_cast<Serializer&>(ar);
|
||||
T *&ptr = *static_cast<T**>(data);
|
||||
|
||||
//create new object under pointer
|
||||
typedef typename boost::remove_pointer<T>::type npT;
|
||||
ptr = new npT;
|
||||
|
||||
//T is most derived known type, it's time to call actual serialize
|
||||
ptr->serialize(s,version);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template <typename Serializer> class DLL_EXPORT CISer : public CLoaderBase
|
||||
{
|
||||
public:
|
||||
bool saving;
|
||||
CISer(){saving = false;};
|
||||
std::map<ui16,CBasicPointerLoader*> loaders; // typeID => CPointerSaver<serializer,type>
|
||||
|
||||
CISer()
|
||||
{
|
||||
saving = false;
|
||||
}
|
||||
|
||||
template<typename T> void registerType(const T * t=NULL)
|
||||
{
|
||||
ui16 ID = typeList.registerType(t);
|
||||
loaders[ID] = new CPointerLoader<CISer<Serializer>,T>;
|
||||
}
|
||||
|
||||
Serializer * This()
|
||||
{
|
||||
return static_cast<Serializer*>(this);
|
||||
@ -364,10 +499,20 @@ public:
|
||||
return;
|
||||
}
|
||||
|
||||
tlog5<<"Allocating memory for pointer!"<<std::endl;
|
||||
typedef typename boost::remove_pointer<T>::type npT;
|
||||
data = new npT;
|
||||
*this >> *data;
|
||||
//get type id
|
||||
ui16 tid;
|
||||
*this >> tid;
|
||||
|
||||
if(!tid)
|
||||
{
|
||||
typedef typename boost::remove_pointer<T>::type npT;
|
||||
data = new npT;
|
||||
*this >> *data;
|
||||
}
|
||||
else
|
||||
{
|
||||
loaders[tid]->loadPtr(*this,&data);
|
||||
}
|
||||
}
|
||||
template <typename T>
|
||||
void loadSerializable(std::vector<T> &data)
|
||||
|
@ -65,5 +65,7 @@ public:
|
||||
virtual void setManaPoints(int hid, int val)=0;
|
||||
virtual void giveHero(int id, int player)=0;
|
||||
virtual void changeObjPos(int objid, int3 newPos, ui8 flags)=0;
|
||||
|
||||
friend struct CPackForClient;
|
||||
};
|
||||
#endif // __IGAMECALLBACK_H__
|
354
lib/NetPacks.h
354
lib/NetPacks.h
@ -1,42 +1,52 @@
|
||||
#ifndef __NETPACKS_H__
|
||||
#define __NETPACKS_H__
|
||||
#include "../global.h"
|
||||
#include "../CGameState.h"
|
||||
#include "BattleAction.h"
|
||||
#include "HeroBonus.h"
|
||||
#include <set>
|
||||
|
||||
struct IPack
|
||||
class CClient;
|
||||
class CGameState;
|
||||
|
||||
struct CPack
|
||||
{
|
||||
virtual ui16 getType()const = 0 ;
|
||||
//template<ui16 Type>
|
||||
//static bool isType(const IPack * ip)
|
||||
//{
|
||||
// return Type == ip->getType();
|
||||
//}
|
||||
template<ui16 Type>
|
||||
static bool isType(IPack * ip)
|
||||
{
|
||||
return Type == ip->getType();
|
||||
}
|
||||
//template<ui16 Type>
|
||||
//static bool isType(const IPack & ip)
|
||||
//{
|
||||
// return Type == ip.getType();
|
||||
//}
|
||||
};
|
||||
template <typename T> struct CPack
|
||||
:public IPack
|
||||
{
|
||||
ui16 type;
|
||||
ui16 type;
|
||||
|
||||
CPack(){};
|
||||
virtual ~CPack(){};
|
||||
ui16 getType() const{return type;}
|
||||
T* This(){return static_cast<T*>(this);};
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{
|
||||
tlog1 << "CPack serialized... this should not happen!\n";
|
||||
}
|
||||
};
|
||||
template <typename T> struct Query
|
||||
:public CPack<T>
|
||||
|
||||
struct CPackForClient : public CPack
|
||||
{
|
||||
CGameState* GS(CClient *cl);
|
||||
CPackForClient(){type = 0;};
|
||||
|
||||
void applyFirstCl(CClient *cl)//called before applying to gs
|
||||
{
|
||||
//tlog1 << "CPackForClient::applyFirstCl - We should not be here!\n";
|
||||
};
|
||||
DLL_EXPORT void applyGs(CGameState *gs)
|
||||
{
|
||||
//tlog1 << "CPackForClient::applyGs - We should not be here!\n";
|
||||
};
|
||||
void applyCl(CClient *cl)//called after applying to gs
|
||||
{
|
||||
//tlog1 << "CPackForClient::applyCl - We should not be here!\n";
|
||||
};
|
||||
};
|
||||
|
||||
struct Query : public CPackForClient
|
||||
{
|
||||
ui32 id;
|
||||
};
|
||||
|
||||
struct MetaString : public CPack<MetaString> //2001 helper for object scrips
|
||||
struct MetaString : public CPack //2001 helper for object scrips
|
||||
{
|
||||
std::vector<std::string> strings;
|
||||
std::vector<std::pair<ui8,ui32> > texts; //pairs<text handler type, text number>; types: 1 - generaltexthandler->all; 2 - objh->xtrainfo; 3 - objh->names; 4 - objh->restypes; 5 - arth->artifacts[id].name; 6 - generaltexth->arraytxt; 7 - creh->creatures[os->subID].namePl; 8 - objh->creGens; 9 - objh->mines[ID].first; 10 - objh->mines[ID].second; 11 - objh->advobtxt
|
||||
@ -70,20 +80,38 @@ struct MetaString : public CPack<MetaString> //2001 helper for object scrips
|
||||
MetaString(){type = 2001;};
|
||||
};
|
||||
|
||||
struct SetResources : public CPack<SetResources> //104
|
||||
struct SystemMessage : public CPackForClient //95
|
||||
{
|
||||
SetResources(){res.resize(RESOURCE_QUANTITY);type = 104;};
|
||||
ui8 player;
|
||||
std::vector<si32> res; //res[resid] => res amount
|
||||
SystemMessage(){type = 95;};
|
||||
void applyCl(CClient *cl);
|
||||
|
||||
std::string text;
|
||||
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{
|
||||
h & player & res;
|
||||
h & text;
|
||||
}
|
||||
};
|
||||
struct SetResource : public CPack<SetResource> //102
|
||||
|
||||
struct YourTurn : public CPackForClient //100
|
||||
{
|
||||
YourTurn(){type = 100;};
|
||||
void applyCl(CClient *cl);
|
||||
DLL_EXPORT void applyGs(CGameState *gs);
|
||||
|
||||
ui8 player;
|
||||
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{
|
||||
h & player;
|
||||
}
|
||||
};
|
||||
|
||||
struct SetResource : public CPackForClient //102
|
||||
{
|
||||
SetResource(){type = 102;};
|
||||
void applyCl(CClient *cl);
|
||||
DLL_EXPORT void applyGs(CGameState *gs);
|
||||
|
||||
ui8 player, resid;
|
||||
si32 val;
|
||||
@ -93,9 +121,27 @@ struct SetResource : public CPack<SetResource> //102
|
||||
h & player & resid & val;
|
||||
}
|
||||
};
|
||||
struct SetPrimSkill : public CPack<SetPrimSkill> //105
|
||||
struct SetResources : public CPackForClient //104
|
||||
{
|
||||
SetResources(){res.resize(RESOURCE_QUANTITY);type = 104;};
|
||||
void applyCl(CClient *cl);
|
||||
DLL_EXPORT void applyGs(CGameState *gs);
|
||||
|
||||
ui8 player;
|
||||
std::vector<si32> res; //res[resid] => res amount
|
||||
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{
|
||||
h & player & res;
|
||||
}
|
||||
};
|
||||
|
||||
struct SetPrimSkill : public CPackForClient //105
|
||||
{
|
||||
SetPrimSkill(){type = 105;};
|
||||
void applyCl(CClient *cl);
|
||||
DLL_EXPORT void applyGs(CGameState *gs);
|
||||
|
||||
ui8 abs; //0 - changes by value; 1 - sets to value
|
||||
si32 id;
|
||||
ui16 which, val;
|
||||
@ -105,9 +151,12 @@ struct SetPrimSkill : public CPack<SetPrimSkill> //105
|
||||
h & abs & id & which & val;
|
||||
}
|
||||
};
|
||||
struct SetSecSkill : public CPack<SetSecSkill> //106
|
||||
struct SetSecSkill : public CPackForClient //106
|
||||
{
|
||||
SetSecSkill(){type = 106;};
|
||||
void applyCl(CClient *cl);
|
||||
DLL_EXPORT void applyGs(CGameState *gs);
|
||||
|
||||
ui8 abs; //0 - changes by value; 1 - sets to value
|
||||
si32 id;
|
||||
ui16 which, val;
|
||||
@ -117,9 +166,12 @@ struct SetSecSkill : public CPack<SetSecSkill> //106
|
||||
h & abs & id & which & val;
|
||||
}
|
||||
};
|
||||
struct HeroVisitCastle : public CPack<HeroVisitCastle> //108
|
||||
struct HeroVisitCastle : public CPackForClient //108
|
||||
{
|
||||
HeroVisitCastle(){flags=0;type = 108;};
|
||||
void applyCl(CClient *cl);
|
||||
DLL_EXPORT void applyGs(CGameState *gs);
|
||||
|
||||
ui8 flags; //1 - start, 2 - garrison
|
||||
ui32 tid, hid;
|
||||
|
||||
@ -136,9 +188,12 @@ struct HeroVisitCastle : public CPack<HeroVisitCastle> //108
|
||||
h & flags & tid & hid;
|
||||
}
|
||||
};
|
||||
struct ChangeSpells : public CPack<ChangeSpells> //109
|
||||
struct ChangeSpells : public CPackForClient //109
|
||||
{
|
||||
ChangeSpells(){type = 109;};
|
||||
void applyCl(CClient *cl);
|
||||
DLL_EXPORT void applyGs(CGameState *gs);
|
||||
|
||||
ui8 learn; //1 - gives spell, 0 - takes
|
||||
ui32 hid;
|
||||
std::set<ui32> spells;
|
||||
@ -149,9 +204,13 @@ struct ChangeSpells : public CPack<ChangeSpells> //109
|
||||
}
|
||||
};
|
||||
|
||||
struct SetMana : public CPack<SetMana> //110
|
||||
struct SetMana : public CPackForClient //110
|
||||
{
|
||||
SetMana(){type = 110;};
|
||||
void applyCl(CClient *cl);
|
||||
DLL_EXPORT void applyGs(CGameState *gs);
|
||||
|
||||
|
||||
ui32 hid, val;
|
||||
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
@ -159,9 +218,12 @@ struct SetMana : public CPack<SetMana> //110
|
||||
h & val & hid;
|
||||
}
|
||||
};
|
||||
struct SetMovePoints : public CPack<SetMovePoints> //111
|
||||
struct SetMovePoints : public CPackForClient //111
|
||||
{
|
||||
SetMovePoints(){type = 111;};
|
||||
void applyCl(CClient *cl);
|
||||
DLL_EXPORT void applyGs(CGameState *gs);
|
||||
|
||||
ui32 hid, val;
|
||||
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
@ -169,9 +231,12 @@ struct SetMovePoints : public CPack<SetMovePoints> //111
|
||||
h & val & hid;
|
||||
}
|
||||
};
|
||||
struct FoWChange : public CPack<FoWChange> //112
|
||||
struct FoWChange : public CPackForClient //112
|
||||
{
|
||||
FoWChange(){type = 112;};
|
||||
void applyCl(CClient *cl);
|
||||
DLL_EXPORT void applyGs(CGameState *gs);
|
||||
|
||||
std::set<int3> tiles;
|
||||
ui8 player, mode; //mode==0 - hide, mode==1 - reveal
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
@ -180,9 +245,12 @@ struct FoWChange : public CPack<FoWChange> //112
|
||||
}
|
||||
};
|
||||
|
||||
struct SetAvailableHeroes : public CPack<SetAvailableHeroes> //113
|
||||
struct SetAvailableHeroes : public CPackForClient //113
|
||||
{
|
||||
SetAvailableHeroes(){type = 113;flags=0;};
|
||||
void applyCl(CClient *cl);
|
||||
DLL_EXPORT void applyGs(CGameState *gs);
|
||||
|
||||
ui8 player;
|
||||
si32 hid1, hid2;
|
||||
ui8 flags; //1 - reset army of hero1; 2 - reset army of hero 2
|
||||
@ -192,9 +260,11 @@ struct SetAvailableHeroes : public CPack<SetAvailableHeroes> //113
|
||||
}
|
||||
};
|
||||
|
||||
struct GiveBonus : public CPack<GiveBonus> //115
|
||||
struct GiveBonus : public CPackForClient //115
|
||||
{
|
||||
GiveBonus(){type = 115;};
|
||||
void applyCl(CClient *cl);
|
||||
DLL_EXPORT void applyGs(CGameState *gs);
|
||||
|
||||
ui32 hid;
|
||||
HeroBonus bonus;
|
||||
@ -206,9 +276,12 @@ struct GiveBonus : public CPack<GiveBonus> //115
|
||||
}
|
||||
};
|
||||
|
||||
struct ChangeObjPos : public CPack<ChangeObjPos> //116
|
||||
struct ChangeObjPos : public CPackForClient //116
|
||||
{
|
||||
ChangeObjPos(){type = 116;};
|
||||
void applyFirstCl(CClient *cl);
|
||||
void applyCl(CClient *cl);
|
||||
DLL_EXPORT void applyGs(CGameState *gs);
|
||||
|
||||
ui32 objid;
|
||||
int3 nPos;
|
||||
@ -220,10 +293,14 @@ struct ChangeObjPos : public CPack<ChangeObjPos> //116
|
||||
}
|
||||
};
|
||||
|
||||
struct RemoveObject : public CPack<RemoveObject> //500
|
||||
struct RemoveObject : public CPackForClient //500
|
||||
{
|
||||
RemoveObject(){type = 500;};
|
||||
RemoveObject(si32 ID){id = ID;type = 500;};
|
||||
void applyFirstCl(CClient *cl);
|
||||
void applyCl(CClient *cl);
|
||||
DLL_EXPORT void applyGs(CGameState *gs);
|
||||
|
||||
si32 id;
|
||||
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
@ -231,9 +308,12 @@ struct RemoveObject : public CPack<RemoveObject> //500
|
||||
h & id;
|
||||
}
|
||||
};
|
||||
struct TryMoveHero : public CPack<TryMoveHero> //501
|
||||
struct TryMoveHero : public CPackForClient //501
|
||||
{
|
||||
TryMoveHero(){type = 501;};
|
||||
void applyFirstCl(CClient *cl);
|
||||
void applyCl(CClient *cl);
|
||||
void applyGs(CGameState *gs);
|
||||
|
||||
ui32 id, movePoints;
|
||||
ui8 result; //0 - failed; 1- succes -normal move; 2 - teleportation, 3 - instant jump
|
||||
@ -245,9 +325,12 @@ struct TryMoveHero : public CPack<TryMoveHero> //501
|
||||
h & id & result & start & end & movePoints & fowRevealed;
|
||||
}
|
||||
};
|
||||
struct SetGarrisons : public CPack<SetGarrisons> //502
|
||||
struct SetGarrisons : public CPackForClient //502
|
||||
{
|
||||
SetGarrisons(){type = 502;};
|
||||
void applyCl(CClient *cl);
|
||||
DLL_EXPORT void applyGs(CGameState *gs);
|
||||
|
||||
std::map<ui32,CCreatureSet> garrs;
|
||||
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
@ -255,9 +338,12 @@ struct SetGarrisons : public CPack<SetGarrisons> //502
|
||||
h & garrs;
|
||||
}
|
||||
};
|
||||
struct NewStructures : public CPack<NewStructures> //504
|
||||
struct NewStructures : public CPackForClient //504
|
||||
{
|
||||
NewStructures(){type = 504;};
|
||||
void applyCl(CClient *cl);
|
||||
DLL_EXPORT void applyGs(CGameState *gs);
|
||||
|
||||
si32 tid;
|
||||
std::set<si32> bid;
|
||||
si16 builded;
|
||||
@ -267,9 +353,12 @@ struct NewStructures : public CPack<NewStructures> //504
|
||||
h & tid & bid & builded;
|
||||
}
|
||||
};
|
||||
struct SetAvailableCreatures : public CPack<SetAvailableCreatures> //506
|
||||
struct SetAvailableCreatures : public CPackForClient //506
|
||||
{
|
||||
SetAvailableCreatures(){type = 506;};
|
||||
void applyCl(CClient *cl);
|
||||
DLL_EXPORT void applyGs(CGameState *gs);
|
||||
|
||||
si32 tid;
|
||||
std::map<si32,ui32> creatures;
|
||||
|
||||
@ -278,9 +367,12 @@ struct SetAvailableCreatures : public CPack<SetAvailableCreatures> //506
|
||||
h & tid & creatures;
|
||||
}
|
||||
};
|
||||
struct SetHeroesInTown : public CPack<SetHeroesInTown> //508
|
||||
struct SetHeroesInTown : public CPackForClient //508
|
||||
{
|
||||
SetHeroesInTown(){type = 508;};
|
||||
void applyCl(CClient *cl);
|
||||
DLL_EXPORT void applyGs(CGameState *gs);
|
||||
|
||||
si32 tid, visiting, garrison; //id of town, visiting hero, hero in garrison
|
||||
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
@ -288,9 +380,12 @@ struct SetHeroesInTown : public CPack<SetHeroesInTown> //508
|
||||
h & tid & visiting & garrison;
|
||||
}
|
||||
};
|
||||
struct SetHeroArtifacts : public CPack<SetHeroArtifacts> //509
|
||||
struct SetHeroArtifacts : public CPackForClient //509
|
||||
{
|
||||
SetHeroArtifacts(){type = 509;};
|
||||
void applyCl(CClient *cl);
|
||||
DLL_EXPORT void applyGs(CGameState *gs);
|
||||
|
||||
si32 hid;
|
||||
std::vector<ui32> artifacts; //hero's artifacts from bag
|
||||
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
|
||||
@ -301,9 +396,28 @@ struct SetHeroArtifacts : public CPack<SetHeroArtifacts> //509
|
||||
}
|
||||
};
|
||||
|
||||
struct SetSelection : public CPack<SetSelection> //514
|
||||
struct PlayerMessage : public CPackForClient //513
|
||||
{
|
||||
PlayerMessage(){type = 513;};
|
||||
PlayerMessage(ui8 Player, const std::string &Text)
|
||||
:player(Player),text(Text)
|
||||
{type = 513;};
|
||||
void applyCl(CClient *cl);
|
||||
|
||||
ui8 player;
|
||||
std::string text;
|
||||
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{
|
||||
h & text & player;
|
||||
}
|
||||
};
|
||||
|
||||
struct SetSelection : public CPackForClient //514
|
||||
{
|
||||
SetSelection(){type = 514;};
|
||||
DLL_EXPORT void applyGs(CGameState *gs);
|
||||
|
||||
ui8 player;
|
||||
ui32 id;
|
||||
|
||||
@ -313,9 +427,12 @@ struct SetSelection : public CPack<SetSelection> //514
|
||||
}
|
||||
};
|
||||
|
||||
struct HeroRecruited : public CPack<HeroRecruited> //515
|
||||
struct HeroRecruited : public CPackForClient //515
|
||||
{
|
||||
HeroRecruited(){type = 515;};
|
||||
void applyCl(CClient *cl);
|
||||
DLL_EXPORT void applyGs(CGameState *gs);
|
||||
|
||||
si32 hid, tid; //subID of hero
|
||||
int3 tile;
|
||||
ui8 player;
|
||||
@ -326,9 +443,13 @@ struct HeroRecruited : public CPack<HeroRecruited> //515
|
||||
}
|
||||
};
|
||||
|
||||
struct GiveHero : public CPack<GiveHero> //516
|
||||
struct GiveHero : public CPackForClient //516
|
||||
{
|
||||
GiveHero(){type = 516;};
|
||||
void applyFirstCl(CClient *cl);
|
||||
void applyCl(CClient *cl);
|
||||
DLL_EXPORT void applyGs(CGameState *gs);
|
||||
|
||||
ui32 id; //object id
|
||||
ui8 player;
|
||||
|
||||
@ -338,8 +459,10 @@ struct GiveHero : public CPack<GiveHero> //516
|
||||
}
|
||||
};
|
||||
|
||||
struct NewTurn : public CPack<NewTurn> //101
|
||||
struct NewTurn : public CPackForClient //101
|
||||
{
|
||||
DLL_EXPORT void applyGs(CGameState *gs);
|
||||
|
||||
struct Hero
|
||||
{
|
||||
ui32 id, move, mana; //id is a general serial id
|
||||
@ -363,17 +486,8 @@ struct NewTurn : public CPack<NewTurn> //101
|
||||
h & heroes & cres & res & day & resetBuilded;
|
||||
}
|
||||
};
|
||||
//struct SetStrInfo : public CPack<SetStrInfo> //503
|
||||
//{
|
||||
// SetStrInfo(){type = 503;};
|
||||
// SetAvailableCreatures sac;
|
||||
//
|
||||
// template <typename Handler> void serialize(Handler &h, const int version)
|
||||
// {
|
||||
// h & sac;
|
||||
// }
|
||||
//};
|
||||
struct Component : public CPack<Component> //2002 helper for object scrips informations
|
||||
|
||||
struct Component : public CPack //2002 helper for object scrips informations
|
||||
{
|
||||
ui16 id, subtype; //ids: 0 - primskill; 1 - secskill; 2 - resource; 3 - creature; 4 - artifact; 5 - experience (sub==0 exp points; sub==1 levels)
|
||||
si32 val; // + give; - take
|
||||
@ -387,8 +501,10 @@ struct Component : public CPack<Component> //2002 helper for object scrips infor
|
||||
Component(ui16 Type, ui16 Subtype, si32 Val, si16 When):id(Type),subtype(Subtype),val(Val),when(When){type = 2002;};
|
||||
};
|
||||
|
||||
struct InfoWindow : public CPack<InfoWindow> //103 - displays simple info window
|
||||
struct InfoWindow : public CPackForClient //103 - displays simple info window
|
||||
{
|
||||
void applyCl(CClient *cl);
|
||||
|
||||
MetaString text;
|
||||
std::vector<Component> components;
|
||||
ui8 player;
|
||||
@ -400,8 +516,10 @@ struct InfoWindow : public CPack<InfoWindow> //103 - displays simple info windo
|
||||
InfoWindow(){type = 103;};
|
||||
};
|
||||
|
||||
struct SetObjectProperty : public CPack<SetObjectProperty>//1001
|
||||
struct SetObjectProperty : public CPackForClient//1001
|
||||
{
|
||||
DLL_EXPORT void applyGs(CGameState *gs);
|
||||
|
||||
ui32 id;
|
||||
ui8 what; //1 - owner; 2 - blockvis; 3 - first stack count; 4 - visitors; 5 - visited; 6 - ID (if 34 then also def is replaced)
|
||||
ui32 val;
|
||||
@ -414,8 +532,10 @@ struct SetObjectProperty : public CPack<SetObjectProperty>//1001
|
||||
}
|
||||
};
|
||||
|
||||
struct SetHoverName : public CPack<SetHoverName>//1002
|
||||
struct SetHoverName : public CPackForClient//1002
|
||||
{
|
||||
DLL_EXPORT void applyGs(CGameState *gs);
|
||||
|
||||
ui32 id;
|
||||
MetaString name;
|
||||
SetHoverName(){type = 1002;};
|
||||
@ -426,8 +546,11 @@ struct SetHoverName : public CPack<SetHoverName>//1002
|
||||
h & id & name;
|
||||
}
|
||||
};
|
||||
struct HeroLevelUp : public Query<HeroLevelUp>//2000
|
||||
struct HeroLevelUp : public Query//2000
|
||||
{
|
||||
void applyCl(CClient *cl);
|
||||
DLL_EXPORT void applyGs(CGameState *gs);
|
||||
|
||||
si32 heroid;
|
||||
ui8 primskill, level;
|
||||
std::vector<ui16> skills;
|
||||
@ -440,8 +563,10 @@ struct HeroLevelUp : public Query<HeroLevelUp>//2000
|
||||
}
|
||||
};
|
||||
|
||||
struct SelectionDialog : public Query<SelectionDialog>//2001
|
||||
struct SelectionDialog : public Query//2001
|
||||
{
|
||||
void applyCl(CClient *cl);
|
||||
|
||||
MetaString text;
|
||||
std::vector<Component> components;
|
||||
ui8 player;
|
||||
@ -454,8 +579,10 @@ struct SelectionDialog : public Query<SelectionDialog>//2001
|
||||
}
|
||||
};
|
||||
|
||||
struct YesNoDialog : public Query<YesNoDialog>//2002
|
||||
struct YesNoDialog : public Query//2002
|
||||
{
|
||||
void applyCl(CClient *cl);
|
||||
|
||||
MetaString text;
|
||||
std::vector<Component> components;
|
||||
ui8 player;
|
||||
@ -469,40 +596,52 @@ struct YesNoDialog : public Query<YesNoDialog>//2002
|
||||
};
|
||||
|
||||
struct BattleInfo;
|
||||
struct BattleStart : public CPack<BattleStart>//3000
|
||||
struct BattleStart : public CPackForClient//3000
|
||||
{
|
||||
BattleStart(){type = 3000;};
|
||||
void applyCl(CClient *cl);
|
||||
DLL_EXPORT void applyGs(CGameState *gs);
|
||||
|
||||
BattleInfo * info;
|
||||
|
||||
BattleStart(){type = 3000;};
|
||||
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{
|
||||
h & info;
|
||||
}
|
||||
};
|
||||
struct BattleNextRound : public CPack<BattleNextRound>//3001
|
||||
{
|
||||
struct BattleNextRound : public CPackForClient//3001
|
||||
{
|
||||
BattleNextRound(){type = 3001;};
|
||||
void applyCl(CClient *cl);
|
||||
DLL_EXPORT void applyGs(CGameState *gs);
|
||||
|
||||
si32 round;
|
||||
|
||||
BattleNextRound(){type = 3001;};
|
||||
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{
|
||||
h & round;
|
||||
}
|
||||
};
|
||||
struct BattleSetActiveStack : public CPack<BattleSetActiveStack>//3002
|
||||
struct BattleSetActiveStack : public CPackForClient//3002
|
||||
{
|
||||
BattleSetActiveStack(){type = 3002;};
|
||||
void applyCl(CClient *cl);
|
||||
DLL_EXPORT void applyGs(CGameState *gs);
|
||||
|
||||
ui32 stack;
|
||||
|
||||
BattleSetActiveStack(){type = 3002;};
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{
|
||||
h & stack;
|
||||
}
|
||||
};
|
||||
struct BattleResult : public CPack<BattleResult>//3003
|
||||
struct BattleResult : public CPackForClient//3003
|
||||
{
|
||||
BattleResult(){type = 3003;};
|
||||
void applyFirstCl(CClient *cl);
|
||||
void applyGs(CGameState *gs);
|
||||
|
||||
ui8 result; //0 - normal victory; 1 - escape; 2 - surrender
|
||||
ui8 winner; //0 - attacker, 1 - defender, [2 - draw (should be possible?)]
|
||||
std::set<std::pair<ui32,si32> > casualties[2]; //first => casualties of attackers - set of pairs crid<>number
|
||||
@ -511,32 +650,35 @@ struct BattleResult : public CPack<BattleResult>//3003
|
||||
|
||||
|
||||
|
||||
BattleResult(){type = 3003;};
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{
|
||||
h & result & winner & casualties[0] & casualties[1] & exp & artifacts;
|
||||
}
|
||||
};
|
||||
|
||||
struct BattleStackMoved : public CPack<BattleStackMoved>//3004
|
||||
struct BattleStackMoved : public CPackForClient//3004
|
||||
{
|
||||
ui32 stack, tile, distance;
|
||||
BattleStackMoved(){type = 3004;};
|
||||
void applyFirstCl(CClient *cl);
|
||||
void applyGs(CGameState *gs);
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{
|
||||
h & stack & tile & distance;
|
||||
}
|
||||
};
|
||||
|
||||
struct BattleStackAttacked : public CPack<BattleStackAttacked>//3005
|
||||
struct BattleStackAttacked : public CPackForClient//3005
|
||||
{
|
||||
BattleStackAttacked(){flags = 0; type = 3005;};
|
||||
void applyCl(CClient *cl);
|
||||
DLL_EXPORT void applyGs(CGameState *gs);
|
||||
|
||||
ui32 stackAttacked;
|
||||
ui32 newAmount, newHP, killedAmount, damageAmount;
|
||||
ui8 flags; //1 - is stack killed; 2 - is there special effect to be shown; 4 - lucky hit
|
||||
ui32 effect; //set only if flag 2 is present
|
||||
|
||||
|
||||
BattleStackAttacked(){flags = 0; type = 3005;};
|
||||
bool killed() //if target stack was killed
|
||||
{
|
||||
return flags & 1;
|
||||
@ -555,15 +697,17 @@ struct BattleStackAttacked : public CPack<BattleStackAttacked>//3005
|
||||
}
|
||||
};
|
||||
|
||||
struct BattleAttack : public CPack<BattleAttack>//3006
|
||||
struct BattleAttack : public CPackForClient//3006
|
||||
{
|
||||
BattleAttack(){flags = 0; type = 3006;};
|
||||
void applyFirstCl(CClient *cl);
|
||||
DLL_EXPORT void applyGs(CGameState *gs);
|
||||
void applyCl(CClient *cl);
|
||||
|
||||
BattleStackAttacked bsa;
|
||||
ui32 stackAttacking;
|
||||
ui8 flags;
|
||||
|
||||
|
||||
|
||||
BattleAttack(){flags = 0; type = 3006;};
|
||||
bool shot()//distance attack - decrease number of shots
|
||||
{
|
||||
return flags & 1;
|
||||
@ -582,48 +726,68 @@ struct BattleAttack : public CPack<BattleAttack>//3006
|
||||
}
|
||||
};
|
||||
|
||||
struct StartAction : public CPack<StartAction>//3007
|
||||
struct StartAction : public CPackForClient//3007
|
||||
{
|
||||
BattleAction ba;
|
||||
StartAction(){type = 3007;};
|
||||
StartAction(const BattleAction &act){ba = act; type = 3007;};
|
||||
void applyFirstCl(CClient *cl);
|
||||
DLL_EXPORT void applyGs(CGameState *gs);
|
||||
|
||||
BattleAction ba;
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{
|
||||
h & ba;
|
||||
}
|
||||
};
|
||||
|
||||
struct SpellCasted : public CPack<SpellCasted>//3009
|
||||
struct EndAction : public CPackForClient//3008
|
||||
{
|
||||
EndAction(){type = 3008;};
|
||||
void applyCl(CClient *cl);
|
||||
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
struct SpellCasted : public CPackForClient//3009
|
||||
{
|
||||
SpellCasted(){type = 3009;};
|
||||
DLL_EXPORT void applyGs(CGameState *gs);
|
||||
void applyCl(CClient *cl);
|
||||
|
||||
ui8 side; //which hero casted spell: 0 - attacker, 1 - defender
|
||||
ui32 id;
|
||||
ui8 skill;
|
||||
ui16 tile; //destination tile (may not be set in some global/mass spells
|
||||
SpellCasted(){type = 3009;};
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{
|
||||
h & side & id & skill & tile;
|
||||
}
|
||||
};
|
||||
|
||||
struct SetStackEffect : public CPack<SetStackEffect> //3010
|
||||
struct SetStackEffect : public CPackForClient //3010
|
||||
{
|
||||
SetStackEffect(){type = 3010;};
|
||||
DLL_EXPORT void applyGs(CGameState *gs);
|
||||
void applyCl(CClient *cl);
|
||||
|
||||
ui32 stack;
|
||||
CStack::StackEffect effect;
|
||||
SetStackEffect(){type = 3010;};
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{
|
||||
h & stack & effect;
|
||||
}
|
||||
};
|
||||
|
||||
struct ShowInInfobox : public CPack<ShowInInfobox> //107
|
||||
struct ShowInInfobox : public CPackForClient //107
|
||||
{
|
||||
ShowInInfobox(){type = 107;};
|
||||
ui8 player;
|
||||
Component c;
|
||||
MetaString text;
|
||||
|
||||
void applyCl(CClient *cl);
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{
|
||||
h & player & c & text;
|
||||
|
480
lib/NetPacksLib.cpp
Normal file
480
lib/NetPacksLib.cpp
Normal file
@ -0,0 +1,480 @@
|
||||
#define VCMI_DLL
|
||||
#include "../lib/NetPacks.h"
|
||||
#include "../hch/CGeneralTextHandler.h"
|
||||
#include "../hch/CDefObjInfoHandler.h"
|
||||
#include "../hch/CHeroHandler.h"
|
||||
#include "../hch/CObjectHandler.h"
|
||||
#include "../lib/VCMI_Lib.h"
|
||||
#include "../map.h"
|
||||
#include "../hch/CSpellHandler.h"
|
||||
#include <boost/bind.hpp>
|
||||
#include <boost/foreach.hpp>
|
||||
#include <boost/thread.hpp>
|
||||
#include <boost/thread/shared_mutex.hpp>
|
||||
|
||||
DLL_EXPORT void SetResource::applyGs( CGameState *gs )
|
||||
{
|
||||
gs->players[player].resources[resid] = val;
|
||||
}
|
||||
|
||||
DLL_EXPORT void SetResources::applyGs( CGameState *gs )
|
||||
{
|
||||
for(int i=0;i<res.size();i++)
|
||||
gs->players[player].resources[i] = res[i];
|
||||
}
|
||||
|
||||
DLL_EXPORT void SetPrimSkill::applyGs( CGameState *gs )
|
||||
{
|
||||
CGHeroInstance *hero = gs->getHero(id);
|
||||
if(which <4)
|
||||
{
|
||||
if(abs)
|
||||
hero->primSkills[which] = val;
|
||||
else
|
||||
hero->primSkills[which] += val;
|
||||
}
|
||||
else if(which == 4) //XP
|
||||
{
|
||||
if(abs)
|
||||
hero->exp = val;
|
||||
else
|
||||
hero->exp += val;
|
||||
}
|
||||
}
|
||||
|
||||
DLL_EXPORT void SetSecSkill::applyGs( CGameState *gs )
|
||||
{
|
||||
CGHeroInstance *hero = gs->getHero(id);
|
||||
if(hero->getSecSkillLevel(which) == 0)
|
||||
{
|
||||
hero->secSkills.push_back(std::pair<int,int>(which, val));
|
||||
}
|
||||
else
|
||||
{
|
||||
for(unsigned i=0;i<hero->secSkills.size();i++)
|
||||
{
|
||||
if(hero->secSkills[i].first == which)
|
||||
{
|
||||
if(abs)
|
||||
hero->secSkills[i].second = val;
|
||||
else
|
||||
hero->secSkills[i].second += val;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DLL_EXPORT void HeroVisitCastle::applyGs( CGameState *gs )
|
||||
{
|
||||
CGHeroInstance *h = gs->getHero(hid);
|
||||
CGTownInstance *t = gs->getTown(tid);
|
||||
if(start())
|
||||
{
|
||||
if(garrison())
|
||||
{
|
||||
t->garrisonHero = h;
|
||||
h->visitedTown = t;
|
||||
h->inTownGarrison = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
t->visitingHero = h;
|
||||
h->visitedTown = t;
|
||||
h->inTownGarrison = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(garrison())
|
||||
{
|
||||
t->garrisonHero = NULL;
|
||||
h->visitedTown = NULL;
|
||||
h->inTownGarrison = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
t->visitingHero = NULL;
|
||||
h->visitedTown = NULL;
|
||||
h->inTownGarrison = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DLL_EXPORT void ChangeSpells::applyGs( CGameState *gs )
|
||||
{
|
||||
CGHeroInstance *hero = gs->getHero(hid);
|
||||
|
||||
if(learn)
|
||||
BOOST_FOREACH(ui32 sid, spells)
|
||||
hero->spells.insert(sid);
|
||||
else
|
||||
BOOST_FOREACH(ui32 sid, spells)
|
||||
hero->spells.erase(sid);
|
||||
}
|
||||
|
||||
DLL_EXPORT void SetMana::applyGs( CGameState *gs )
|
||||
{
|
||||
CGHeroInstance *hero = gs->getHero(hid);
|
||||
hero->mana = val;
|
||||
}
|
||||
|
||||
DLL_EXPORT void SetMovePoints::applyGs( CGameState *gs )
|
||||
{
|
||||
CGHeroInstance *hero = gs->getHero(hid);
|
||||
hero->movement = val;
|
||||
}
|
||||
|
||||
DLL_EXPORT void FoWChange::applyGs( CGameState *gs )
|
||||
{
|
||||
BOOST_FOREACH(int3 t, tiles)
|
||||
gs->players[player].fogOfWarMap[t.x][t.y][t.z] = mode;
|
||||
}
|
||||
|
||||
DLL_EXPORT void SetAvailableHeroes::applyGs( CGameState *gs )
|
||||
{
|
||||
gs->players[player].availableHeroes.clear();
|
||||
|
||||
CGHeroInstance *h = (hid1>=0 ? gs->hpool.heroesPool[hid1] : NULL);
|
||||
gs->players[player].availableHeroes.push_back(h);
|
||||
if(h && flags & 1)
|
||||
{
|
||||
h->army.slots.clear();
|
||||
h->army.slots[0] = std::pair<ui32,si32>(VLC->creh->nameToID[h->type->refTypeStack[0]],1);
|
||||
}
|
||||
|
||||
h = (hid2>=0 ? gs->hpool.heroesPool[hid2] : NULL);
|
||||
gs->players[player].availableHeroes.push_back(h);
|
||||
if(flags & 2)
|
||||
{
|
||||
h->army.slots.clear();
|
||||
h->army.slots[0] = std::pair<ui32,si32>(VLC->creh->nameToID[h->type->refTypeStack[0]],1);
|
||||
}
|
||||
}
|
||||
|
||||
DLL_EXPORT void GiveBonus::applyGs( CGameState *gs )
|
||||
{
|
||||
CGHeroInstance *h = gs->getHero(hid);
|
||||
h->bonuses.push_back(bonus);
|
||||
h->bonuses.back().description = toString(bdescr);
|
||||
}
|
||||
|
||||
DLL_EXPORT void ChangeObjPos::applyGs( CGameState *gs )
|
||||
{
|
||||
CGObjectInstance *obj = gs->map->objects[objid];
|
||||
if(!obj)
|
||||
{
|
||||
tlog1 << "Wrong ChangeObjPos: object " << objid << " doesn't exist!\n";
|
||||
return;
|
||||
}
|
||||
gs->map->removeBlockVisTiles(obj);
|
||||
obj->pos = nPos;
|
||||
gs->map->addBlockVisTiles(obj);
|
||||
}
|
||||
|
||||
DLL_EXPORT void RemoveObject::applyGs( CGameState *gs )
|
||||
{
|
||||
CGObjectInstance *obj = gs->map->objects[id];
|
||||
if(obj->ID==HEROI_TYPE)
|
||||
{
|
||||
CGHeroInstance *h = static_cast<CGHeroInstance*>(obj);
|
||||
std::vector<CGHeroInstance*>::iterator nitr = std::find(gs->map->heroes.begin(), gs->map->heroes.end(),h);
|
||||
gs->map->heroes.erase(nitr);
|
||||
int player = h->tempOwner;
|
||||
nitr = std::find(gs->players[player].heroes.begin(), gs->players[player].heroes.end(), h);
|
||||
gs->players[player].heroes.erase(nitr);
|
||||
if(h->visitedTown)
|
||||
{
|
||||
if(h->inTownGarrison)
|
||||
h->visitedTown->garrisonHero = NULL;
|
||||
else
|
||||
h->visitedTown->visitingHero = NULL;
|
||||
h->visitedTown = NULL;
|
||||
}
|
||||
|
||||
//TODO: add to the pool?
|
||||
}
|
||||
gs->map->objects[id] = NULL;
|
||||
|
||||
//unblock tiles
|
||||
if(obj->defInfo)
|
||||
{
|
||||
gs->map->removeBlockVisTiles(obj);
|
||||
}
|
||||
}
|
||||
|
||||
void TryMoveHero::applyGs( CGameState *gs )
|
||||
{
|
||||
CGHeroInstance *h = gs->getHero(id);
|
||||
h->movement = movePoints;
|
||||
if(start!=end && result)
|
||||
{
|
||||
gs->map->removeBlockVisTiles(h);
|
||||
h->pos = end;
|
||||
gs->map->addBlockVisTiles(h);
|
||||
}
|
||||
BOOST_FOREACH(int3 t, fowRevealed)
|
||||
gs->players[h->getOwner()].fogOfWarMap[t.x][t.y][t.z] = 1;
|
||||
}
|
||||
|
||||
DLL_EXPORT void SetGarrisons::applyGs( CGameState *gs )
|
||||
{
|
||||
for(std::map<ui32,CCreatureSet>::iterator i = garrs.begin(); i!=garrs.end(); i++)
|
||||
{
|
||||
CArmedInstance *ai = static_cast<CArmedInstance*>(gs->map->objects[i->first]);
|
||||
ai->army = i->second;
|
||||
if(ai->ID==TOWNI_TYPE && (static_cast<CGTownInstance*>(ai))->garrisonHero) //if there is a hero in garrison then we must update also his army
|
||||
const_cast<CGHeroInstance*>((static_cast<CGTownInstance*>(ai))->garrisonHero)->army = i->second;
|
||||
else if(ai->ID==HEROI_TYPE)
|
||||
{
|
||||
CGHeroInstance *h = static_cast<CGHeroInstance*>(ai);
|
||||
if(h->visitedTown && h->inTownGarrison)
|
||||
h->visitedTown->army = i->second;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DLL_EXPORT void NewStructures::applyGs( CGameState *gs )
|
||||
{
|
||||
CGTownInstance*t = gs->getTown(tid);
|
||||
BOOST_FOREACH(si32 id,bid)
|
||||
t->builtBuildings.insert(id);
|
||||
t->builded = builded;
|
||||
}
|
||||
|
||||
DLL_EXPORT void SetAvailableCreatures::applyGs( CGameState *gs )
|
||||
{
|
||||
gs->getTown(tid)->strInfo.creatures = creatures;
|
||||
}
|
||||
|
||||
DLL_EXPORT void SetHeroesInTown::applyGs( CGameState *gs )
|
||||
{
|
||||
CGTownInstance *t = gs->getTown(tid);
|
||||
|
||||
CGHeroInstance *v = gs->getHero(visiting),
|
||||
*g = gs->getHero(garrison);
|
||||
|
||||
t->visitingHero = v;
|
||||
t->garrisonHero = g;
|
||||
if(v)
|
||||
{
|
||||
v->visitedTown = t;
|
||||
v->inTownGarrison = false;
|
||||
gs->map->addBlockVisTiles(v);
|
||||
}
|
||||
if(g)
|
||||
{
|
||||
g->visitedTown = t;
|
||||
g->inTownGarrison = true;
|
||||
gs->map->removeBlockVisTiles(g);
|
||||
}
|
||||
}
|
||||
|
||||
DLL_EXPORT void SetHeroArtifacts::applyGs( CGameState *gs )
|
||||
{
|
||||
CGHeroInstance *h = gs->getHero(hid);
|
||||
h->artifacts = artifacts;
|
||||
h->artifWorn = artifWorn;
|
||||
}
|
||||
|
||||
DLL_EXPORT void HeroRecruited::applyGs( CGameState *gs )
|
||||
{
|
||||
CGHeroInstance *h = gs->hpool.heroesPool[hid];
|
||||
CGTownInstance *t = gs->getTown(tid);
|
||||
h->setOwner(player);
|
||||
h->pos = tile;
|
||||
h->movement = h->maxMovePoints(true);
|
||||
|
||||
gs->hpool.heroesPool.erase(hid);
|
||||
if(h->id < 0)
|
||||
{
|
||||
h->id = gs->map->objects.size();
|
||||
gs->map->objects.push_back(h);
|
||||
}
|
||||
else
|
||||
gs->map->objects[h->id] = h;
|
||||
|
||||
h->initHeroDefInfo();
|
||||
gs->map->heroes.push_back(h);
|
||||
gs->players[h->tempOwner].heroes.push_back(h);
|
||||
gs->map->addBlockVisTiles(h);
|
||||
t->visitingHero = h;
|
||||
h->visitedTown = t;
|
||||
h->inTownGarrison = false;
|
||||
}
|
||||
|
||||
DLL_EXPORT void GiveHero::applyGs( CGameState *gs )
|
||||
{
|
||||
CGHeroInstance *h = gs->getHero(id);
|
||||
gs->map->removeBlockVisTiles(h,true);
|
||||
h->setOwner(player);
|
||||
h->movement = h->maxMovePoints(true);
|
||||
h->initHeroDefInfo();
|
||||
gs->map->heroes.push_back(h);
|
||||
gs->players[h->tempOwner].heroes.push_back(h);
|
||||
gs->map->addBlockVisTiles(h);
|
||||
h->inTownGarrison = false;
|
||||
}
|
||||
|
||||
DLL_EXPORT void NewTurn::applyGs( CGameState *gs )
|
||||
{
|
||||
gs->day = day;
|
||||
BOOST_FOREACH(NewTurn::Hero h, heroes) //give mana/movement point
|
||||
{
|
||||
static_cast<CGHeroInstance*>(gs->map->objects[h.id])->movement = h.move;
|
||||
static_cast<CGHeroInstance*>(gs->map->objects[h.id])->mana = h.mana;
|
||||
}
|
||||
|
||||
BOOST_FOREACH(SetResources h, res) //give resources
|
||||
h.applyGs(gs);
|
||||
|
||||
BOOST_FOREACH(SetAvailableCreatures h, cres) //set available creatures in towns
|
||||
h.applyGs(gs);
|
||||
|
||||
if(resetBuilded) //reset amount of structures set in this turn in towns
|
||||
BOOST_FOREACH(CGTownInstance* t, gs->map->towns)
|
||||
t->builded = 0;
|
||||
|
||||
BOOST_FOREACH(CGHeroInstance *h, gs->map->heroes)
|
||||
h->bonuses.remove_if(HeroBonus::OneDay);
|
||||
|
||||
if(gs->getDate(1) == 7) //new week
|
||||
BOOST_FOREACH(CGHeroInstance *h, gs->map->heroes)
|
||||
h->bonuses.remove_if(HeroBonus::OneWeek);
|
||||
}
|
||||
|
||||
DLL_EXPORT void SetObjectProperty::applyGs( CGameState *gs )
|
||||
{
|
||||
CGObjectInstance *obj = gs->map->objects[id];
|
||||
if(!obj)
|
||||
tlog1 << "Wrong object ID - property cannot be set!\n";
|
||||
else
|
||||
obj->setProperty(what,val);
|
||||
}
|
||||
|
||||
DLL_EXPORT void SetHoverName::applyGs( CGameState *gs )
|
||||
{
|
||||
gs->map->objects[id]->hoverName = toString(name);
|
||||
}
|
||||
|
||||
DLL_EXPORT void HeroLevelUp::applyGs( CGameState *gs )
|
||||
{
|
||||
gs->getHero(heroid)->level = level;
|
||||
}
|
||||
|
||||
DLL_EXPORT void BattleStart::applyGs( CGameState *gs )
|
||||
{
|
||||
gs->curB = info;
|
||||
}
|
||||
|
||||
DLL_EXPORT void BattleNextRound::applyGs( CGameState *gs )
|
||||
{
|
||||
gs->curB->castedSpells[0] = gs->curB->castedSpells[1] = 0;
|
||||
gs->curB->round = round;
|
||||
|
||||
BOOST_FOREACH(CStack *s, gs->curB->stacks)
|
||||
{
|
||||
s->state -= DEFENDING;
|
||||
s->state -= WAITING;
|
||||
s->state -= MOVED;
|
||||
s->state -= HAD_MORALE;
|
||||
s->counterAttacks = 1;
|
||||
}
|
||||
}
|
||||
|
||||
DLL_EXPORT void BattleSetActiveStack::applyGs( CGameState *gs )
|
||||
{
|
||||
gs->curB->activeStack = stack;
|
||||
CStack *st = gs->curB->getStack(stack);
|
||||
if(vstd::contains(st->state,MOVED)) //if stack is moving second time this turn it must had a high morale bonus
|
||||
st->state.insert(HAD_MORALE);
|
||||
}
|
||||
|
||||
void BattleResult::applyGs( CGameState *gs )
|
||||
{
|
||||
for(unsigned i=0;i<gs->curB->stacks.size();i++)
|
||||
delete gs->curB->stacks[i];
|
||||
|
||||
//remove any "until next battle" bonuses
|
||||
CGHeroInstance *h;
|
||||
h = gs->getHero(gs->curB->hero1);
|
||||
if(h)
|
||||
h->bonuses.remove_if(HeroBonus::OneBattle);
|
||||
h = gs->getHero(gs->curB->hero2);
|
||||
if(h)
|
||||
h->bonuses.remove_if(HeroBonus::OneBattle);
|
||||
|
||||
delete gs->curB;
|
||||
gs->curB = NULL;
|
||||
}
|
||||
|
||||
void BattleStackMoved::applyGs( CGameState *gs )
|
||||
{
|
||||
gs->curB->getStack(stack)->position = tile;
|
||||
}
|
||||
|
||||
DLL_EXPORT void BattleStackAttacked::applyGs( CGameState *gs )
|
||||
{
|
||||
CStack * at = gs->curB->getStack(stackAttacked);
|
||||
at->amount = newAmount;
|
||||
at->firstHPleft = newHP;
|
||||
if(killed())
|
||||
at->state -= ALIVE;
|
||||
}
|
||||
|
||||
DLL_EXPORT void BattleAttack::applyGs( CGameState *gs )
|
||||
{
|
||||
CStack *attacker = gs->curB->getStack(stackAttacking);
|
||||
if(counter())
|
||||
attacker->counterAttacks--;
|
||||
if(shot())
|
||||
attacker->shots--;
|
||||
bsa.applyGs(gs);
|
||||
}
|
||||
|
||||
DLL_EXPORT void StartAction::applyGs( CGameState *gs )
|
||||
{
|
||||
CStack *st = gs->curB->getStack(ba.stackNumber);
|
||||
switch(ba.actionType)
|
||||
{
|
||||
case 3:
|
||||
st->state.insert(DEFENDING);
|
||||
break;
|
||||
case 8:
|
||||
st->state.insert(WAITING);
|
||||
break;
|
||||
case 2: case 6: case 7: case 9: case 10: case 11:
|
||||
st->state.insert(MOVED);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
DLL_EXPORT void SpellCasted::applyGs( CGameState *gs )
|
||||
{
|
||||
CGHeroInstance *h = (side) ? gs->getHero(gs->curB->hero2) : gs->getHero(gs->curB->hero1);
|
||||
if(h)
|
||||
{
|
||||
h->mana -= VLC->spellh->spells[id].costs[skill];
|
||||
if(h->mana < 0) h->mana = 0;
|
||||
}
|
||||
if(side >= 0 && side < 2)
|
||||
{
|
||||
gs->curB->castedSpells[side]++;
|
||||
}
|
||||
}
|
||||
|
||||
DLL_EXPORT void SetStackEffect::applyGs( CGameState *gs )
|
||||
{
|
||||
CStack *s = gs->curB->getStack(stack);
|
||||
s->effects.push_back(effect);
|
||||
}
|
||||
|
||||
DLL_EXPORT void YourTurn::applyGs( CGameState *gs )
|
||||
{
|
||||
gs->currentPlayer = player;
|
||||
}
|
||||
|
||||
|
||||
DLL_EXPORT void SetSelection::applyGs( CGameState *gs )
|
||||
{
|
||||
gs->players[player].currentSelection = id;
|
||||
}
|
19
lib/RegisterTypes.cpp
Normal file
19
lib/RegisterTypes.cpp
Normal file
@ -0,0 +1,19 @@
|
||||
#define VCMI_DLL
|
||||
#include "Connection.h"
|
||||
#include "NetPacks.h"
|
||||
#include "VCMI_Lib.h"
|
||||
#include "../hch./CObjectHandler.h"
|
||||
#include "../hch/CHeroHandler.h"
|
||||
#include "../hch/CTownHandler.h"
|
||||
#include "RegisterTypes.h"
|
||||
|
||||
|
||||
void foofoofoo()
|
||||
{
|
||||
//never called function to force instantation of templates
|
||||
int *ccc = NULL;
|
||||
registerTypes((CISer<CConnection>&)*ccc);
|
||||
registerTypes((COSer<CConnection>&)*ccc);
|
||||
registerTypes((CSaveFile&)*ccc);
|
||||
registerTypes((CLoadFile&)*ccc);
|
||||
}
|
85
lib/RegisterTypes.h
Normal file
85
lib/RegisterTypes.h
Normal file
@ -0,0 +1,85 @@
|
||||
#pragma once
|
||||
//templates for registering object types
|
||||
|
||||
//first set of types - derivatives of CGObjectInstance
|
||||
template<typename Serializer> DLL_EXPORT void registerTypes1(Serializer &s)
|
||||
{
|
||||
s.registerType<CGHeroInstance>();
|
||||
s.registerType<CGTownInstance>();
|
||||
s.registerType<CGEvent>();
|
||||
s.registerType<CGVisitableOPH>();
|
||||
s.registerType<CGVisitableOPW>();
|
||||
s.registerType<CGTeleport>();
|
||||
s.registerType<CGPickable>();
|
||||
s.registerType<CGCreature>();
|
||||
s.registerType<CGSignBottle>();
|
||||
s.registerType<CGSeerHut>();
|
||||
s.registerType<CGWitchHut>();
|
||||
s.registerType<CGScholar>();
|
||||
s.registerType<CGGarrison>();
|
||||
s.registerType<CGArtifact>();
|
||||
s.registerType<CGResource>();
|
||||
s.registerType<CGMine>();
|
||||
s.registerType<CGShrine>();
|
||||
s.registerType<CGPandoraBox>();
|
||||
s.registerType<CGQuestGuard>();
|
||||
s.registerType<CGBonusingObject>();
|
||||
s.registerType<CGMagicWell>();
|
||||
s.registerType<CGObjectInstance>();
|
||||
}
|
||||
|
||||
|
||||
//second set of types - derivatives of CPack (network VCMI packages)
|
||||
template<typename Serializer> DLL_EXPORT void registerTypes2(Serializer &s)
|
||||
{
|
||||
s.registerType<SystemMessage>();
|
||||
s.registerType<YourTurn>();
|
||||
s.registerType<SetResource>();
|
||||
s.registerType<SetResources>();
|
||||
s.registerType<SetPrimSkill>();
|
||||
s.registerType<SetSecSkill>();
|
||||
s.registerType<HeroVisitCastle>();
|
||||
s.registerType<ChangeSpells>();
|
||||
s.registerType<SetMana>();
|
||||
s.registerType<SetMovePoints>();
|
||||
s.registerType<FoWChange>();
|
||||
s.registerType<SetAvailableHeroes>();
|
||||
s.registerType<GiveBonus>();
|
||||
s.registerType<ChangeObjPos>();
|
||||
s.registerType<RemoveObject>();
|
||||
s.registerType<TryMoveHero>();
|
||||
s.registerType<SetGarrisons>();
|
||||
s.registerType<NewStructures>();
|
||||
s.registerType<SetAvailableCreatures>();
|
||||
s.registerType<SetHeroesInTown>();
|
||||
s.registerType<SetHeroArtifacts>();
|
||||
s.registerType<SetSelection>();
|
||||
s.registerType<HeroRecruited>();
|
||||
s.registerType<GiveHero>();
|
||||
s.registerType<NewTurn>();
|
||||
s.registerType<InfoWindow>();
|
||||
s.registerType<SetObjectProperty>();
|
||||
s.registerType<SetHoverName>();
|
||||
s.registerType<HeroLevelUp>();
|
||||
s.registerType<SelectionDialog>();
|
||||
s.registerType<YesNoDialog>();
|
||||
s.registerType<BattleStart>();
|
||||
s.registerType<BattleNextRound>();
|
||||
s.registerType<BattleSetActiveStack>();
|
||||
s.registerType<BattleResult>();
|
||||
s.registerType<BattleStackMoved>();
|
||||
s.registerType<BattleStackAttacked>();
|
||||
s.registerType<BattleAttack>();
|
||||
s.registerType<StartAction>();
|
||||
s.registerType<EndAction>();
|
||||
s.registerType<SpellCasted>();
|
||||
s.registerType<SetStackEffect>();
|
||||
s.registerType<ShowInInfobox>();
|
||||
}
|
||||
|
||||
//register all
|
||||
template<typename Serializer> DLL_EXPORT void registerTypes(Serializer &s)
|
||||
{
|
||||
registerTypes1(s);
|
||||
registerTypes2(s);
|
||||
}
|
@ -322,6 +322,14 @@
|
||||
RelativePath="..\map.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\NetPacksLib.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\RegisterTypes.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\stdafx.cpp"
|
||||
>
|
||||
@ -416,6 +424,10 @@
|
||||
RelativePath=".\NetPacks.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\RegisterTypes.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\VCMI_Lib.h"
|
||||
>
|
||||
|
118
map.h
118
map.h
@ -329,10 +329,6 @@ struct DLL_EXPORT Mapa : public CMapHeader
|
||||
TerrainTile &getTile(int3 tile);
|
||||
CGHeroInstance * getHero(int ID, int mode=0);
|
||||
bool isInTheMap(int3 pos);
|
||||
template <typename TObject, typename Handler> void serializeObj(Handler &h, const int version, TObject ** obj)
|
||||
{
|
||||
h & *obj;
|
||||
}
|
||||
template <typename Handler> void serialize(Handler &h, const int formatVersion)
|
||||
{
|
||||
h & static_cast<CMapHeader&>(*this);
|
||||
@ -404,119 +400,9 @@ struct DLL_EXPORT Mapa : public CMapHeader
|
||||
for(int i=0; i<objects.size(); i++)
|
||||
{
|
||||
CGObjectInstance *&obj = objects[i];
|
||||
ui8 exists = (obj!=NULL);
|
||||
ui32 hlp;
|
||||
h & obj;
|
||||
|
||||
si32 shlp;
|
||||
h & exists;
|
||||
if(!exists)
|
||||
{
|
||||
if(!h.saving)
|
||||
obj = 0;
|
||||
continue;
|
||||
}
|
||||
h & (h.saving ? (hlp=obj->ID) : hlp);
|
||||
switch(hlp)
|
||||
{
|
||||
#define SERIALIZE(TYPE) ( serializeObj<TYPE>( h,version,(TYPE**) (&obj) ) )
|
||||
case 34: case 70: case 62:
|
||||
SERIALIZE(CGHeroInstance);
|
||||
break;
|
||||
case 98: case 77:
|
||||
SERIALIZE(CGTownInstance);
|
||||
break;
|
||||
case 26: //for event objects
|
||||
SERIALIZE(CGEvent);
|
||||
break;
|
||||
case 4: //arena
|
||||
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
|
||||
SERIALIZE(CGVisitableOPH);
|
||||
break;
|
||||
case 55: //mystical garden
|
||||
case 112://windmill
|
||||
case 109://water wheel
|
||||
SERIALIZE(CGVisitableOPW);
|
||||
break;
|
||||
case 43: //teleport
|
||||
case 44: //teleport
|
||||
case 45: //teleport
|
||||
case 103://subterranean gate
|
||||
SERIALIZE(CGTeleport);
|
||||
break;
|
||||
case 12: //campfire
|
||||
case 101: //treasure chest
|
||||
SERIALIZE(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:
|
||||
SERIALIZE(CGCreature);
|
||||
break;
|
||||
case 59: case 91: //ocean bottle and sign
|
||||
SERIALIZE(CGSignBottle);
|
||||
break;
|
||||
case 83: //seer's hut
|
||||
SERIALIZE(CGSeerHut);
|
||||
break;
|
||||
case 113: //witch hut
|
||||
SERIALIZE(CGWitchHut);
|
||||
break;
|
||||
case 81: //scholar
|
||||
SERIALIZE(CGScholar);
|
||||
break;
|
||||
case 33: case 219: //garrison
|
||||
SERIALIZE(CGGarrison);
|
||||
break;
|
||||
case 5: //artifact
|
||||
case 65: case 66: case 67: case 68: case 69: //random artifact
|
||||
case 93: //spell scroll
|
||||
SERIALIZE(CGArtifact);
|
||||
break;
|
||||
case 76: case 79: //random resource; resource
|
||||
SERIALIZE(CGResource);
|
||||
break;
|
||||
case 53:
|
||||
SERIALIZE(CGMine);
|
||||
break;
|
||||
case 88: case 89: case 90: //spell shrine
|
||||
SERIALIZE(CGShrine);
|
||||
break;
|
||||
case 6:
|
||||
SERIALIZE(CGPandoraBox);
|
||||
break;
|
||||
case 217:
|
||||
case 216:
|
||||
case 218:
|
||||
//TODO cregen
|
||||
SERIALIZE(CGObjectInstance);
|
||||
break;
|
||||
case 215:
|
||||
SERIALIZE(CGQuestGuard);
|
||||
break;
|
||||
case 28: //faerie ring
|
||||
case 14: //Swan pond
|
||||
case 38: //idol of fortune
|
||||
case 30: //Fountain of Fortune
|
||||
case 64: //Rally Flag
|
||||
case 56: //oasis
|
||||
case 96: //temple
|
||||
case 110://Watering Hole
|
||||
case 31: //Fountain of Youth
|
||||
SERIALIZE(CGBonusingObject);
|
||||
break;
|
||||
case 49: //Magic Well
|
||||
SERIALIZE(CGMagicWell);
|
||||
break;
|
||||
default:
|
||||
SERIALIZE(CGObjectInstance);
|
||||
}
|
||||
|
||||
#undef SERIALIZE
|
||||
|
||||
//definfo
|
||||
h & (h.saving ? (shlp=obj->defInfo->serial) : shlp); //read / write pos of definfo in defs vector
|
||||
if(!h.saving)
|
||||
|
@ -9,8 +9,8 @@
|
||||
#include "../hch/CTownHandler.h"
|
||||
#include "../CGameState.h"
|
||||
#include "../lib/CondSh.h"
|
||||
#include "../lib/Connection.h"
|
||||
#include "../lib/NetPacks.h"
|
||||
#include "../lib/Connection.h"
|
||||
#include "../lib/VCMI_Lib.h"
|
||||
#include "../map.h"
|
||||
#include "CGameHandler.h"
|
||||
@ -24,7 +24,6 @@
|
||||
#include <boost/thread/xtime.hpp>
|
||||
#endif
|
||||
extern bool end2;
|
||||
#include "../lib/BattleAction.h"
|
||||
#ifdef min
|
||||
#undef min
|
||||
#endif
|
||||
@ -343,7 +342,7 @@ void CGameHandler::startBattle(CCreatureSet army1, CCreatureSet army2, int3 tile
|
||||
ba.side = !next->attackerOwned;
|
||||
ba.stackNumber = next->ID;
|
||||
sendAndApply(&StartAction(ba));
|
||||
sendDataToClients(ui16(3008));
|
||||
sendAndApply(&EndAction());
|
||||
checkForBattleEnd(stacks); //check if this "action" ended the battle (not likely but who knows...)
|
||||
continue;
|
||||
}
|
||||
@ -988,9 +987,7 @@ upgend:
|
||||
std::string message;
|
||||
c >> message;
|
||||
bool cheated=true;
|
||||
sendDataToClients(ui16(513));
|
||||
sendDataToClients(ui8(*players.begin()));
|
||||
sendDataToClients(message);
|
||||
sendAndApply(&PlayerMessage(*players.begin(),message));
|
||||
if(message == "vcmiistari") //give all spells and 999 mana
|
||||
{
|
||||
SetMana sm;
|
||||
@ -1084,9 +1081,7 @@ upgend:
|
||||
if(cheated)
|
||||
{
|
||||
message = "CHEATER!!!";
|
||||
sendDataToClients(ui16(513));
|
||||
sendDataToClients(ui8(*players.begin()));
|
||||
sendDataToClients(message);
|
||||
sendAndApply(&PlayerMessage(*players.begin(),message));
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -1154,14 +1149,14 @@ upgend:
|
||||
{
|
||||
sendAndApply(&StartAction(ba)); //start movement
|
||||
moveStack(ba.stackNumber,ba.destinationTile); //move
|
||||
sendDataToClients(ui16(3008)); //end movement
|
||||
sendAndApply(&EndAction());
|
||||
break;
|
||||
}
|
||||
case 3: //defend
|
||||
case 8: //wait
|
||||
{
|
||||
sendAndApply(&StartAction(ba));
|
||||
sendDataToClients(ui16(3008));
|
||||
sendAndApply(&EndAction());
|
||||
break;
|
||||
}
|
||||
case 4: //retreat/flee
|
||||
@ -1211,7 +1206,7 @@ upgend:
|
||||
)
|
||||
{
|
||||
tlog3 << "Attack cannot be performed!";
|
||||
sendDataToClients(ui16(3008)); //end movement and attack
|
||||
sendAndApply(&EndAction());
|
||||
break;
|
||||
}
|
||||
|
||||
@ -1240,7 +1235,7 @@ upgend:
|
||||
prepareAttack(bat,curStack,stackAtEnd);
|
||||
sendAndApply(&bat);
|
||||
}
|
||||
sendDataToClients(ui16(3008)); //end movement and attack
|
||||
sendAndApply(&EndAction());
|
||||
break;
|
||||
}
|
||||
case 7: //shoot
|
||||
@ -1277,7 +1272,7 @@ upgend:
|
||||
sendAndApply(&bat);
|
||||
}
|
||||
|
||||
sendDataToClients(ui16(3008)); //end shooting
|
||||
sendAndApply(&EndAction());
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -1519,7 +1514,7 @@ upgend:
|
||||
- Weakness
|
||||
- Death Ripple */
|
||||
|
||||
sendDataToClients(ui16(3008)); //end casting
|
||||
sendAndApply(&EndAction());
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -1824,7 +1819,11 @@ void CGameHandler::run(bool resume)
|
||||
if((i->second.towns.size()==0 && i->second.heroes.size()==0) || i->second.color<0 || i->first>=PLAYER_LIMIT ) continue; //players has not towns/castle - loser
|
||||
states.setFlag(i->first,&PlayerStatus::makingTurn,true);
|
||||
gs->currentPlayer = i->first;
|
||||
*connections[i->first] << ui16(100) << i->first;
|
||||
{
|
||||
YourTurn yt;
|
||||
yt.player = i->first;
|
||||
*connections[i->first] << &yt;
|
||||
}
|
||||
|
||||
//wait till turn is done
|
||||
boost::unique_lock<boost::mutex> lock(states.mx);
|
||||
@ -2305,9 +2304,11 @@ void CGameHandler::setObjProperty( int objid, int prop, int val )
|
||||
sendAndApply(&sob);
|
||||
}
|
||||
|
||||
void CGameHandler::sendMessageTo( CConnection &c, std::string message )
|
||||
void CGameHandler::sendMessageTo( CConnection &c, const std::string &message )
|
||||
{
|
||||
c << ui16(95) << message;
|
||||
SystemMessage sm;
|
||||
sm.text = message;
|
||||
c << &sm;
|
||||
}
|
||||
|
||||
void CGameHandler::giveHeroBonus( GiveBonus * bonus )
|
||||
@ -2343,4 +2344,42 @@ void CGameHandler::changeObjPos( int objid, int3 newPos, ui8 flags )
|
||||
cop.nPos = newPos;
|
||||
cop.flags = flags;
|
||||
sendAndApply(&cop);
|
||||
}
|
||||
|
||||
void CGameHandler::applyAndAsk( Query * sel, ui8 player, boost::function<void(ui32)> &callback )
|
||||
{
|
||||
gsm.lock();
|
||||
sel->id = QID;
|
||||
callbacks[QID] = callback;
|
||||
states.addQuery(player,QID);
|
||||
QID++;
|
||||
sendAndApply(sel);
|
||||
gsm.unlock();
|
||||
}
|
||||
|
||||
void CGameHandler::ask( Query * sel, ui8 player, const CFunctionList<void(ui32)> &callback )
|
||||
{
|
||||
gsm.lock();
|
||||
sel->id = QID;
|
||||
callbacks[QID] = callback;
|
||||
states.addQuery(player,QID);
|
||||
sendToAllClients(sel);
|
||||
QID++;
|
||||
gsm.unlock();
|
||||
}
|
||||
|
||||
void CGameHandler::sendToAllClients( CPack * info )
|
||||
{
|
||||
for(std::set<CConnection*>::iterator i=conns.begin(); i!=conns.end();i++)
|
||||
{
|
||||
(*i)->wmx->lock();
|
||||
**i << info;
|
||||
(*i)->wmx->unlock();
|
||||
}
|
||||
}
|
||||
|
||||
void CGameHandler::sendAndApply( CPack * info )
|
||||
{
|
||||
gs->apply(info);
|
||||
sendToAllClients(info);
|
||||
}
|
@ -17,8 +17,8 @@ class CScriptCallback;
|
||||
struct BattleResult;
|
||||
struct BattleAttack;
|
||||
struct BattleStackAttacked;
|
||||
template <typename T> struct CPack;
|
||||
template <typename T> struct Query;
|
||||
struct CPack;
|
||||
struct Query;
|
||||
class CGHeroInstance;
|
||||
extern std::map<ui32, CFunctionList<void(ui32)> > callbacks; //question id => callback functions - for selection dialogs
|
||||
extern boost::mutex gsm;
|
||||
@ -62,7 +62,7 @@ class CGameHandler : public IGameCallback
|
||||
PlayerStatuses states; //player color -> player state
|
||||
std::set<CConnection*> conns;
|
||||
|
||||
void sendMessageTo(CConnection &c, std::string message);
|
||||
void sendMessageTo(CConnection &c, const std::string &message);
|
||||
void giveSpells(const CGTownInstance *t, const CGHeroInstance *h);
|
||||
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
|
||||
@ -116,50 +116,54 @@ public:
|
||||
{
|
||||
h & QID & states;
|
||||
}
|
||||
template <typename T> void applyAndAsk(Query<T> * sel, ui8 player, boost::function<void(ui32)> &callback)
|
||||
{
|
||||
gsm.lock();
|
||||
sel->id = QID;
|
||||
callbacks[QID] = callback;
|
||||
states.addQuery(player,QID);
|
||||
QID++;
|
||||
sendAndApply(sel);
|
||||
gsm.unlock();
|
||||
}
|
||||
template <typename T> void ask(Query<T> * sel, ui8 player, const CFunctionList<void(ui32)> &callback)
|
||||
{
|
||||
gsm.lock();
|
||||
sel->id = QID;
|
||||
callbacks[QID] = callback;
|
||||
states.addQuery(player,QID);
|
||||
sendToAllClients(sel);
|
||||
QID++;
|
||||
gsm.unlock();
|
||||
}
|
||||
//template <typename T> void applyAndAsk(Query<T> * sel, ui8 player, boost::function<void(ui32)> &callback)
|
||||
//{
|
||||
// gsm.lock();
|
||||
// sel->id = QID;
|
||||
// callbacks[QID] = callback;
|
||||
// states.addQuery(player,QID);
|
||||
// QID++;
|
||||
// sendAndApply(sel);
|
||||
// gsm.unlock();
|
||||
//}
|
||||
//template <typename T> void ask(Query<T> * sel, ui8 player, const CFunctionList<void(ui32)> &callback)
|
||||
//{
|
||||
// gsm.lock();
|
||||
// sel->id = QID;
|
||||
// callbacks[QID] = callback;
|
||||
// states.addQuery(player,QID);
|
||||
// sendToAllClients(sel);
|
||||
// QID++;
|
||||
// gsm.unlock();
|
||||
//}
|
||||
|
||||
template <typename T>void sendDataToClients(const T & data)
|
||||
{
|
||||
for(std::set<CConnection*>::iterator i=conns.begin(); i!=conns.end();i++)
|
||||
{
|
||||
(*i)->wmx->lock();
|
||||
**i << data;
|
||||
(*i)->wmx->unlock();
|
||||
}
|
||||
}
|
||||
template <typename T>void sendToAllClients(CPack<T> * info)
|
||||
{
|
||||
for(std::set<CConnection*>::iterator i=conns.begin(); i!=conns.end();i++)
|
||||
{
|
||||
(*i)->wmx->lock();
|
||||
**i << info->getType() << *info->This();
|
||||
(*i)->wmx->unlock();
|
||||
}
|
||||
}
|
||||
template <typename T>void sendAndApply(CPack<T> * info)
|
||||
{
|
||||
gs->apply(info);
|
||||
sendToAllClients(info);
|
||||
}
|
||||
//template <typename T>void sendToAllClients(CPack<T> * info)
|
||||
//{
|
||||
// for(std::set<CConnection*>::iterator i=conns.begin(); i!=conns.end();i++)
|
||||
// {
|
||||
// (*i)->wmx->lock();
|
||||
// **i << info->getType() << *info->This();
|
||||
// (*i)->wmx->unlock();
|
||||
// }
|
||||
//}
|
||||
//template <typename T>void sendAndApply(CPack<T> * info)
|
||||
//{
|
||||
// gs->apply(info);
|
||||
// sendToAllClients(info);
|
||||
//}
|
||||
void applyAndAsk(Query * sel, ui8 player, boost::function<void(ui32)> &callback);
|
||||
void ask(Query * sel, ui8 player, const CFunctionList<void(ui32)> &callback);
|
||||
//template <typename T>void sendDataToClients(const T & data)
|
||||
//{
|
||||
// for(std::set<CConnection*>::iterator i=conns.begin(); i!=conns.end();i++)
|
||||
// {
|
||||
// (*i)->wmx->lock();
|
||||
// **i << data;
|
||||
// (*i)->wmx->unlock();
|
||||
// }
|
||||
//}
|
||||
void sendToAllClients(CPack * info);
|
||||
void sendAndApply(CPack * info);
|
||||
void run(bool resume);
|
||||
void newTurn();
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user