mirror of
				https://github.com/vcmi/vcmi.git
				synced 2025-10-31 00:07:39 +02:00 
			
		
		
		
	This commit is contained in:
		| @@ -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) | ||||
|   | ||||
| @@ -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() | ||||
| //{ | ||||
| //} | ||||
|   | ||||
							
								
								
									
										513
									
								
								CGameState.cpp
									
									
									
									
									
								
							
							
						
						
									
										513
									
								
								CGameState.cpp
									
									
									
									
									
								
							| @@ -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; | ||||
|   | ||||
| @@ -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); | ||||
|   | ||||
							
								
								
									
										2
									
								
								CMT.cpp
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								CMT.cpp
									
									
									
									
									
								
							| @@ -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; | ||||
|   | ||||
| @@ -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: | ||||
|   | ||||
| @@ -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); | ||||
|   | ||||
| @@ -374,6 +374,10 @@ | ||||
| 				RelativePath="..\mapHandler.cpp" | ||||
| 				> | ||||
| 			</File> | ||||
| 			<File | ||||
| 				RelativePath=".\NetPacksClient.cpp" | ||||
| 				> | ||||
| 			</File> | ||||
| 			<File | ||||
| 				RelativePath="..\SDL_Extensions.cpp" | ||||
| 				> | ||||
|   | ||||
| @@ -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; | ||||
| @@ -185,4 +190,28 @@ 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; | ||||
| } | ||||
							
								
								
									
										153
									
								
								lib/Connection.h
									
									
									
									
									
								
							
							
						
						
									
										153
									
								
								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,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); | ||||
| @@ -185,7 +247,7 @@ public: | ||||
| 		this->This()->save(t); | ||||
| 		return * this->This(); | ||||
| 	} | ||||
| 	 | ||||
|  | ||||
| 	template<class T> | ||||
| 	COSer & operator&(const T & t) | ||||
| 	{ | ||||
| @@ -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,10 +481,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 class CPackForClient; | ||||
| }; | ||||
| #endif // __IGAMECALLBACK_H__ | ||||
							
								
								
									
										320
									
								
								lib/NetPacks.h
									
									
									
									
									
								
							
							
						
						
									
										320
									
								
								lib/NetPacks.h
									
									
									
									
									
								
							| @@ -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 | ||||
| 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(){}; | ||||
| 	~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 | ||||
| {	 | ||||
| 	BattleNextRound(){type = 3001;}; | ||||
| 	void applyCl(CClient *cl); | ||||
| 	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); | ||||
| 	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; | ||||
|   | ||||
| @@ -322,6 +322,10 @@ | ||||
| 				RelativePath="..\map.cpp" | ||||
| 				> | ||||
| 			</File> | ||||
| 			<File | ||||
| 				RelativePath=".\RegisterTypes.cpp" | ||||
| 				> | ||||
| 			</File> | ||||
| 			<File | ||||
| 				RelativePath="..\stdafx.cpp" | ||||
| 				> | ||||
|   | ||||
							
								
								
									
										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) | ||||
|   | ||||
| @@ -2327,4 +2327,26 @@ 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(); | ||||
| } | ||||
| @@ -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(); | ||||
|   | ||||
		Reference in New Issue
	
	Block a user