1
0
mirror of https://github.com/vcmi/vcmi.git synced 2024-12-24 22:14:36 +02:00
This commit is contained in:
Michał W. Urbańczyk 2009-03-06 22:11:17 +00:00
parent f835ea9033
commit b1c0d10ece
16 changed files with 493 additions and 1327 deletions

View File

@ -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,9 +114,9 @@ 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>);
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)

View File

@ -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()
//{
//}

View File

@ -491,512 +491,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;

View File

@ -33,7 +33,6 @@ struct StartInfo;
struct SDL_Surface;
class CMapHandler;
class CPathfinder;
struct IPack;
struct SetObjectProperty;
struct MetaString;
@ -198,7 +197,7 @@ struct UpgradeInfo
class DLL_EXPORT CGameState
{
private:
public:
StartInfo* scenarioOps;
ui32 seed;
ui8 currentPlayer; //ID of player currently having turn
@ -226,9 +225,6 @@ 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);
@ -243,7 +239,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);

View File

@ -47,9 +47,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;

View File

@ -25,7 +25,6 @@
#include <boost/thread.hpp>
#include <boost/thread/shared_mutex.hpp>
#include <sstream>
CSharedCond<std::set<IPack*> > mess(new std::set<IPack*>);
extern std::string NAME;
namespace intpr = boost::interprocess;
@ -56,83 +55,8 @@ CClient::~CClient(void)
}
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;
@ -143,227 +67,6 @@ void CClient::process(int what)
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;
@ -372,241 +75,6 @@ void CClient::process(int what)
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);
if(playerint.find(gs->curB->side2) != playerint.end())
playerint[gs->curB->side2]->battleStackMoved(br.stack,br.tile);
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:

View File

@ -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);

View File

@ -374,6 +374,10 @@
RelativePath="..\mapHandler.cpp"
>
</File>
<File
RelativePath=".\NetPacksClient.cpp"
>
</File>
<File
RelativePath="..\SDL_Extensions.cpp"
>

View File

@ -4,9 +4,12 @@
#include <boost/asio.hpp>
#include <boost/thread.hpp>
#include <fstream>
using namespace boost;
using namespace boost::asio::ip;
CTypeList typeList;
#define LOG(a) \
if(logging)\
out << a
@ -148,6 +151,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 +173,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;
@ -186,3 +191,27 @@ int CLoadFile::read( const void * data, unsigned size )
sfile->read((char *)data,size);
return size;
}
CTypeList::CTypeList()
{
}
ui16 CTypeList::registerType( const type_info *type )
{
std::map<const type_info *,ui16>::const_iterator i = types.find(type);
if(i != types.end())
return i->second;
ui16 id = types.size() + 1;
types[type] = id;
return id;
}
ui16 CTypeList::getTypeID( const type_info *type )
{
if(vstd::contains(types,type))
return types[type];
else
return 0;
}

View File

@ -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,28 @@ enum SerializationLvl
Serializable
};
template<typename Serializer> DLL_EXPORT void registerTypes(Serializer &s); //defined in .cpp and explicitly instantiated for used serializers
class DLL_EXPORT CTypeList
{
std::map<const type_info *,ui16> types;
public:
CTypeList();
ui16 registerType(const type_info *type);
template <typename T> ui16 registerType(const T * t)
{
return registerType(&typeid(*t));
}
ui16 getTypeID(const type_info *type);
template <typename T> ui16 getTypeID(const T * t)
{
return getTypeID(&typeid(*t));
}
};
extern DLL_EXPORT CTypeList typeList;
template<typename Ser,typename T>
struct SavePrimitive
{
@ -169,11 +191,51 @@ struct SerializationLevel
static const int value = SerializationLevel::type::value;
};
template <typename Serializer> class DLL_EXPORT COSer
class DLL_EXPORT CSerializerBase
{
public:
bool saving;
COSer(){saving=true;};
};
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:
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(&typeid(T));
savers[ID] = new CPointerSaver<Serializer,T>;
}
Serializer * This()
{
return static_cast<Serializer*>(this);
@ -200,14 +262,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 +364,52 @@ public:
*this << i->first << i->second;
}
};
template <typename Serializer> class DLL_EXPORT CISer
class DLL_EXPORT CLoaderBase : public virtual CSerializerBase
{};
class CBasicPointerLoader
{
public:
bool saving;
CISer(){saving = false;};
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:
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(&typeid(T));
loaders[ID] = new CPointerLoader<Serializer,T>;
}
Serializer * This()
{
return static_cast<Serializer*>(this);
@ -364,11 +481,21 @@ public:
return;
}
tlog5<<"Allocating memory for pointer!"<<std::endl;
//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)
{

View File

@ -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 class CPackForClient;
};
#endif // __IGAMECALLBACK_H__

View File

@ -1,42 +1,38 @@
#ifndef __NETPACKS_H__
#define __NETPACKS_H__
#include "../global.h"
#include "../CGameState.h"
#include "BattleAction.h"
#include "HeroBonus.h"
#include <set>
struct IPack
{
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
class CClient;
class CGameState;
struct CPack
{
ui16 type;
CPack(){};
~CPack(){};
ui16 getType() const{return type;}
T* This(){return static_cast<T*>(this);};
};
template <typename T> struct Query
:public CPack<T>
struct CPackForClient : public CPack
{
CGameState* GS(CClient *cl);
//virtual void applyFirstCl(CClient *cl){}; //called before applying to gs
//virtual void applyGs(CGameState *gs){};
//virtual void applyCl(CClient *cl){}; //called after applying to gs
};
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 +66,34 @@ 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;
}
};
struct SetResource : public CPack<SetResource> //102
struct YourTurn : public CPackForClient //100
{
YourTurn(){type = 100;};
void applyCl(CClient *cl);
void applyGs(CGameState *gs);
ui8 player;
template <typename Handler> void serialize(Handler &h, const int version)
{
}
};
struct SetResource : public CPackForClient //102
{
SetResource(){type = 102;};
void applyCl(CClient *cl);
void applyGs(CGameState *gs);
ui8 player, resid;
si32 val;
@ -93,9 +103,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);
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);
void applyGs(CGameState *gs);
ui8 abs; //0 - changes by value; 1 - sets to value
si32 id;
ui16 which, val;
@ -105,9 +133,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);
void applyGs(CGameState *gs);
ui8 abs; //0 - changes by value; 1 - sets to value
si32 id;
ui16 which, val;
@ -117,9 +148,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);
void applyGs(CGameState *gs);
ui8 flags; //1 - start, 2 - garrison
ui32 tid, hid;
@ -136,9 +170,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);
void applyGs(CGameState *gs);
ui8 learn; //1 - gives spell, 0 - takes
ui32 hid;
std::set<ui32> spells;
@ -149,9 +186,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);
void applyGs(CGameState *gs);
ui32 hid, val;
template <typename Handler> void serialize(Handler &h, const int version)
@ -159,9 +200,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);
void applyGs(CGameState *gs);
ui32 hid, val;
template <typename Handler> void serialize(Handler &h, const int version)
@ -169,9 +213,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);
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 +227,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);
void applyGs(CGameState *gs);
ui8 player;
si32 hid1, hid2;
ui8 flags; //1 - reset army of hero1; 2 - reset army of hero 2
@ -192,9 +242,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);
void applyGs(CGameState *gs);
ui32 hid;
HeroBonus bonus;
@ -206,9 +258,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);
void applyGs(CGameState *gs);
ui32 objid;
int3 nPos;
@ -220,10 +275,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);
void applyGs(CGameState *gs);
si32 id;
template <typename Handler> void serialize(Handler &h, const int version)
@ -231,9 +290,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 applyqGs(CGameState *gs);
ui32 id, movePoints;
ui8 result; //0 - failed; 1- succes -normal move; 2 - teleportation, 3 - instant jump
@ -245,9 +307,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);
void applyGs(CGameState *gs);
std::map<ui32,CCreatureSet> garrs;
template <typename Handler> void serialize(Handler &h, const int version)
@ -255,9 +320,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);
void applyGs(CGameState *gs);
si32 tid;
std::set<si32> bid;
si16 builded;
@ -267,9 +335,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);
void applyGs(CGameState *gs);
si32 tid;
std::map<si32,ui32> creatures;
@ -278,9 +349,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);
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 +362,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);
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 +378,11 @@ struct SetHeroArtifacts : public CPack<SetHeroArtifacts> //509
}
};
struct SetSelection : public CPack<SetSelection> //514
struct SetSelection : public CPackForClient //514
{
SetSelection(){type = 514;};
void applyGs(CGameState *gs);
ui8 player;
ui32 id;
@ -313,9 +392,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);
void applyGs(CGameState *gs);
si32 hid, tid; //subID of hero
int3 tile;
ui8 player;
@ -326,9 +408,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);
void applyGs(CGameState *gs);
ui32 id; //object id
ui8 player;
@ -338,8 +424,10 @@ struct GiveHero : public CPack<GiveHero> //516
}
};
struct NewTurn : public CPack<NewTurn> //101
struct NewTurn : public CPackForClient //101
{
void applyGs(CGameState *gs);
struct Hero
{
ui32 id, move, mana; //id is a general serial id
@ -363,17 +451,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 +466,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 +481,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
{
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 +497,10 @@ struct SetObjectProperty : public CPack<SetObjectProperty>//1001
}
};
struct SetHoverName : public CPack<SetHoverName>//1002
struct SetHoverName : public CPackForClient//1002
{
void applyGs(CGameState *gs);
ui32 id;
MetaString name;
SetHoverName(){type = 1002;};
@ -426,8 +511,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);
void applyGs(CGameState *gs);
si32 heroid;
ui8 primskill, level;
std::vector<ui16> skills;
@ -440,8 +528,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 +544,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 +561,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);
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
{
si32 round;
BattleNextRound(){type = 3001;};
void applyCl(CClient *cl);
void applyGs(CGameState *gs);
si32 round;
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);
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 applyqGs(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 +615,36 @@ 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;
BattleStackMoved(){type = 3004;};
void applyFirstCl(CClient *cl);
void applyqGs(CGameState *gs);
ui32 stack, tile;
template <typename Handler> void serialize(Handler &h, const int version)
{
h & stack & tile;
}
};
struct BattleStackAttacked : public CPack<BattleStackAttacked>//3005
struct BattleStackAttacked : public CPackForClient//3005
{
BattleStackAttacked(){flags = 0; type = 3005;};
void applyCl(CClient *cl);
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 +663,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);
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,42 +692,60 @@ 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);
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;};
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;};
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;

View File

@ -322,6 +322,10 @@
RelativePath="..\map.cpp"
>
</File>
<File
RelativePath=".\RegisterTypes.cpp"
>
</File>
<File
RelativePath="..\stdafx.cpp"
>

118
map.h
View File

@ -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)

View File

@ -2328,3 +2328,25 @@ void CGameHandler::changeObjPos( int objid, int3 newPos, ui8 flags )
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();
}

View File

@ -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;
@ -116,27 +116,43 @@ 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 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++)
@ -146,19 +162,14 @@ public:
(*i)->wmx->unlock();
}
}
template <typename T>void sendToAllClients(CPack<T> * info)
void sendToAllClients(CPack * 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)
void sendAndApply(CPack * info)
{
gs->apply(info);
sendToAllClients(info);
//gs->apply(info);
//sendToAllClients(info);
}
void run(bool resume);
void newTurn();