Преглед изворни кода

Replaced CGHeroInstance and CGObjectInstance with ObjectInstanceID in NetPacks

AlexVinS пре 7 година
родитељ
комит
8cec07afbd

+ 4 - 4
CCallback.cpp

@@ -215,8 +215,8 @@ void CCallback::buyArtifact(const CGHeroInstance *hero, ArtifactID aid)
 void CCallback::trade(const CGObjectInstance * market, EMarketMode::EMarketMode mode, ui32 id1, ui32 id2, ui32 val1, const CGHeroInstance * hero)
 void CCallback::trade(const CGObjectInstance * market, EMarketMode::EMarketMode mode, ui32 id1, ui32 id2, ui32 val1, const CGHeroInstance * hero)
 {
 {
 	TradeOnMarketplace pack;
 	TradeOnMarketplace pack;
-	pack.market = market;
-	pack.hero = hero;
+	pack.marketId = market->id;
+	pack.heroId = hero->id;
 	pack.mode = mode;
 	pack.mode = mode;
 	pack.r1 = {id1};
 	pack.r1 = {id1};
 	pack.r2 = {id2};
 	pack.r2 = {id2};
@@ -227,8 +227,8 @@ void CCallback::trade(const CGObjectInstance * market, EMarketMode::EMarketMode
 void CCallback::trade(const CGObjectInstance * market, EMarketMode::EMarketMode mode, const std::vector<ui32> & id1, const std::vector<ui32> & id2, const std::vector<ui32> & val1, const CGHeroInstance * hero)
 void CCallback::trade(const CGObjectInstance * market, EMarketMode::EMarketMode mode, const std::vector<ui32> & id1, const std::vector<ui32> & id2, const std::vector<ui32> & val1, const CGHeroInstance * hero)
 {
 {
 	TradeOnMarketplace pack;
 	TradeOnMarketplace pack;
-	pack.market = market;
-	pack.hero = hero;
+	pack.marketId = market->id;
+	pack.heroId = hero->id;
 	pack.mode = mode;
 	pack.mode = mode;
 	pack.r1 = id1;
 	pack.r1 = id1;
 	pack.r2 = id2;
 	pack.r2 = id2;

+ 3 - 2
client/CPlayerInterface.cpp

@@ -452,9 +452,10 @@ void CPlayerInterface::heroKilled(const CGHeroInstance* hero)
 void CPlayerInterface::heroVisit(const CGHeroInstance * visitor, const CGObjectInstance * visitedObj, bool start)
 void CPlayerInterface::heroVisit(const CGHeroInstance * visitor, const CGObjectInstance * visitedObj, bool start)
 {
 {
 	EVENT_HANDLER_CALLED_BY_CLIENT;
 	EVENT_HANDLER_CALLED_BY_CLIENT;
-	if(start && visitedObj->getVisitSound())
+	if(start && visitedObj)
 	{
 	{
-		CCS->soundh->playSound(visitedObj->getVisitSound().get());
+		if(visitedObj->getVisitSound())
+			CCS->soundh->playSound(visitedObj->getVisitSound().get());
 	}
 	}
 }
 }
 
 

+ 17 - 9
client/NetPacksClient.cpp

@@ -260,9 +260,11 @@ void DisassembledArtifact::applyCl(CClient *cl)
 	callInterfaceIfPresent(cl, al.owningPlayer(), &IGameEventsReceiver::artifactDisassembled, al);
 	callInterfaceIfPresent(cl, al.owningPlayer(), &IGameEventsReceiver::artifactDisassembled, al);
 }
 }
 
 
-void HeroVisit::applyCl(CClient *cl)
+void HeroVisit::applyCl(CClient * cl)
 {
 {
+	auto hero = cl->getHero(heroId);
 	assert(hero);
 	assert(hero);
+	auto obj = cl->getObj(objId, false);
 	callInterfaceIfPresent(cl, player, &IGameEventsReceiver::heroVisit, hero, obj, starting);
 	callInterfaceIfPresent(cl, player, &IGameEventsReceiver::heroVisit, hero, obj, starting);
 }
 }
 
 
@@ -271,7 +273,6 @@ void NewTurn::applyCl(CClient *cl)
 	cl->invalidatePaths();
 	cl->invalidatePaths();
 }
 }
 
 
-
 void GiveBonus::applyCl(CClient *cl)
 void GiveBonus::applyCl(CClient *cl)
 {
 {
 	cl->invalidatePaths();
 	cl->invalidatePaths();
@@ -547,15 +548,19 @@ void SetObjectProperty::applyCl(CClient *cl)
 
 
 void HeroLevelUp::applyCl(CClient *cl)
 void HeroLevelUp::applyCl(CClient *cl)
 {
 {
-	callOnlyThatInterface(cl, hero->tempOwner, &CGameInterface::heroGotLevel, hero, primskill, skills, queryID);
+	const CGHeroInstance * hero = cl->getHero(heroId);
+	assert(hero);
+	callOnlyThatInterface(cl, player, &CGameInterface::heroGotLevel, hero, primskill, skills, queryID);
 }
 }
 
 
 void CommanderLevelUp::applyCl(CClient *cl)
 void CommanderLevelUp::applyCl(CClient *cl)
 {
 {
+	const CGHeroInstance * hero = cl->getHero(heroId);
+	assert(hero);
 	const CCommanderInstance * commander = hero->commander;
 	const CCommanderInstance * commander = hero->commander;
 	assert(commander);
 	assert(commander);
 	assert(commander->armyObj); //is it possible for Commander to exist beyond armed instance?
 	assert(commander->armyObj); //is it possible for Commander to exist beyond armed instance?
-	callOnlyThatInterface(cl, hero->tempOwner, &CGameInterface::commanderGotLevel, commander, skills, queryID);
+	callOnlyThatInterface(cl, player, &CGameInterface::commanderGotLevel, commander, skills, queryID);
 }
 }
 
 
 void BlockingDialog::applyCl(CClient *cl)
 void BlockingDialog::applyCl(CClient *cl)
@@ -577,13 +582,12 @@ void GarrisonDialog::applyCl(CClient *cl)
 
 
 void ExchangeDialog::applyCl(CClient *cl)
 void ExchangeDialog::applyCl(CClient *cl)
 {
 {
-	assert(heroes[0] && heroes[1]);
-	callInterfaceIfPresent(cl, heroes[0]->tempOwner, &IGameEventsReceiver::heroExchangeStarted, heroes[0]->id, heroes[1]->id, queryID);
+	callInterfaceIfPresent(cl, player, &IGameEventsReceiver::heroExchangeStarted, hero1, hero2, queryID);
 }
 }
 
 
 void TeleportDialog::applyCl(CClient *cl)
 void TeleportDialog::applyCl(CClient *cl)
 {
 {
-	callOnlyThatInterface(cl, hero->tempOwner, &CGameInterface::showTeleportDialog, channel, exits, impassable, queryID);
+	callOnlyThatInterface(cl, player, &CGameInterface::showTeleportDialog, channel, exits, impassable, queryID);
 }
 }
 
 
 void MapObjectSelectDialog::applyCl(CClient * cl)
 void MapObjectSelectDialog::applyCl(CClient * cl)
@@ -795,8 +799,12 @@ void ShowInInfobox::applyCl(CClient *cl)
 void AdvmapSpellCast::applyCl(CClient *cl)
 void AdvmapSpellCast::applyCl(CClient *cl)
 {
 {
 	cl->invalidatePaths();
 	cl->invalidatePaths();
-	//consider notifying other interfaces that see hero?
-	callInterfaceIfPresent(cl, caster->getOwner(), &IGameEventsReceiver::advmapSpellCast, caster, spellID);
+	auto caster = cl->getHero(casterID);
+	if(caster)
+		//consider notifying other interfaces that see hero?
+		callInterfaceIfPresent(cl, caster->getOwner(), &IGameEventsReceiver::advmapSpellCast, caster, spellID);
+	else
+		logNetwork->error("Invalid hero instance");
 }
 }
 
 
 void ShowWorldViewEx::applyCl(CClient * cl)
 void ShowWorldViewEx::applyCl(CClient * cl)

+ 56 - 48
lib/NetPacks.h

@@ -777,7 +777,7 @@ struct SetAvailableArtifacts  : public CPackForClient
 struct NewArtifact : public CPackForClient
 struct NewArtifact : public CPackForClient
 {
 {
 	NewArtifact(){}
 	NewArtifact(){}
-	//void applyCl(CClient *cl);
+
 	DLL_LINKAGE void applyGs(CGameState *gs);
 	DLL_LINKAGE void applyGs(CGameState *gs);
 
 
 	ConstTransitivePtr<CArtifactInstance> art;
 	ConstTransitivePtr<CArtifactInstance> art;
@@ -971,21 +971,22 @@ struct DisassembledArtifact : CArtifactOperationPack
 	}
 	}
 };
 };
 
 
-struct HeroVisit : CPackForClient
+struct HeroVisit : public CPackForClient
 {
 {
-	const CGHeroInstance *hero;
-	const CGObjectInstance *obj;
-	PlayerColor player; //if hero was killed during the visit, its color is already reset
+	PlayerColor player;
+	ObjectInstanceID heroId;
+	ObjectInstanceID objId;
+
 	bool starting; //false -> ending
 	bool starting; //false -> ending
 
 
-	void applyCl(CClient *cl);
-	DLL_LINKAGE void applyGs(CGameState *gs);
+	void applyCl(CClient * cl);
+	DLL_LINKAGE void applyGs(CGameState * gs);
 
 
-	template <typename Handler> void serialize(Handler &h, const int version)
+	template <typename Handler> void serialize(Handler & h, const int version)
 	{
 	{
-		h & hero;
-		h & obj;
 		h & player;
 		h & player;
+		h & heroId;
+		h & objId;
 		h & starting;
 		h & starting;
 	}
 	}
 };
 };
@@ -1123,36 +1124,39 @@ struct ChangeObjectVisitors : public CPackForClient
 
 
 struct PrepareHeroLevelUp : public CPackForClient
 struct PrepareHeroLevelUp : public CPackForClient
 {
 {
-	DLL_LINKAGE void applyGs(CGameState *gs);
-
-	const CGHeroInstance *hero;
+	ObjectInstanceID heroId;
 
 
 	/// Do not serialize, used by server only
 	/// Do not serialize, used by server only
 	std::vector<SecondarySkill> skills;
 	std::vector<SecondarySkill> skills;
 
 
-	PrepareHeroLevelUp():hero(nullptr){}
+	PrepareHeroLevelUp(){}
+
+	DLL_LINKAGE void applyGs(CGameState * gs);
 
 
 	template <typename Handler> void serialize(Handler &h, const int version)
 	template <typename Handler> void serialize(Handler &h, const int version)
 	{
 	{
-		h & hero;
+		h & heroId;
 	}
 	}
 };
 };
 
 
 struct HeroLevelUp : public Query
 struct HeroLevelUp : public Query
 {
 {
-	void applyCl(CClient *cl);
-	DLL_LINKAGE void applyGs(CGameState *gs);
+	PlayerColor player;
+	ObjectInstanceID heroId;
 
 
-	const CGHeroInstance *hero;
 	PrimarySkill::PrimarySkill primskill;
 	PrimarySkill::PrimarySkill primskill;
 	std::vector<SecondarySkill> skills;
 	std::vector<SecondarySkill> skills;
 
 
-	HeroLevelUp():hero(nullptr),primskill(PrimarySkill::ATTACK){}
+	HeroLevelUp(): primskill(PrimarySkill::ATTACK){}
 
 
-	template <typename Handler> void serialize(Handler &h, const int version)
+	void applyCl(CClient * cl);
+	DLL_LINKAGE void applyGs(CGameState * gs);
+
+	template <typename Handler> void serialize(Handler & h, const int version)
 	{
 	{
 		h & queryID;
 		h & queryID;
-		h & hero;
+		h & player;
+		h & heroId;
 		h & primskill;
 		h & primskill;
 		h & skills;
 		h & skills;
 	}
 	}
@@ -1160,19 +1164,21 @@ struct HeroLevelUp : public Query
 
 
 struct CommanderLevelUp : public Query
 struct CommanderLevelUp : public Query
 {
 {
-	void applyCl(CClient *cl);
-	DLL_LINKAGE void applyGs(CGameState *gs);
-
-	const CGHeroInstance *hero;
+	PlayerColor player;
+	ObjectInstanceID heroId;
 
 
 	std::vector<ui32> skills; //0-5 - secondary skills, val-100 - special skill
 	std::vector<ui32> skills; //0-5 - secondary skills, val-100 - special skill
 
 
-	CommanderLevelUp():hero(nullptr){}
+	CommanderLevelUp(){}
 
 
-	template <typename Handler> void serialize(Handler &h, const int version)
+	void applyCl(CClient * cl);
+	DLL_LINKAGE void applyGs(CGameState * gs);
+
+	template <typename Handler> void serialize(Handler & h, const int version)
 	{
 	{
 		h & queryID;
 		h & queryID;
-		h & hero;
+		h & player;
+		h & heroId;
 		h & skills;
 		h & skills;
 	}
 	}
 };
 };
@@ -1243,34 +1249,36 @@ struct GarrisonDialog : public Query
 
 
 struct ExchangeDialog : public Query
 struct ExchangeDialog : public Query
 {
 {
-	ExchangeDialog()
-	{
-		heroes = {nullptr,nullptr};
-	}
+	ExchangeDialog() {}
 	void applyCl(CClient *cl);
 	void applyCl(CClient *cl);
 
 
-	std::array<const CGHeroInstance*, 2> heroes;
+	PlayerColor player;
+
+	ObjectInstanceID hero1;
+	ObjectInstanceID hero2;
 
 
 	template <typename Handler> void serialize(Handler &h, const int version)
 	template <typename Handler> void serialize(Handler &h, const int version)
 	{
 	{
 		h & queryID;
 		h & queryID;
-		h & heroes;
+		h & player;
+		h & hero1;
+		h & hero2;
 	}
 	}
 };
 };
 
 
 struct TeleportDialog : public Query
 struct TeleportDialog : public Query
 {
 {
 	TeleportDialog()
 	TeleportDialog()
-		: hero(nullptr), impassable(false)
+		: impassable(false)
 	{}
 	{}
 
 
-	TeleportDialog(const CGHeroInstance *Hero, TeleportChannelID Channel)
-		: hero(Hero), channel(Channel), impassable(false)
+	TeleportDialog(PlayerColor Player, TeleportChannelID Channel)
+		: player(Player), channel(Channel), impassable(false)
 	{}
 	{}
 
 
 	void applyCl(CClient *cl);
 	void applyCl(CClient *cl);
 
 
-	const CGHeroInstance *hero;
+	PlayerColor player;
 	TeleportChannelID channel;
 	TeleportChannelID channel;
 	TTeleportExitsList exits;
 	TTeleportExitsList exits;
 	bool impassable;
 	bool impassable;
@@ -1278,7 +1286,7 @@ struct TeleportDialog : public Query
 	template <typename Handler> void serialize(Handler &h, const int version)
 	template <typename Handler> void serialize(Handler &h, const int version)
 	{
 	{
 		h & queryID;
 		h & queryID;
-		h & hero;
+		h & player;
 		h & channel;
 		h & channel;
 		h & exits;
 		h & exits;
 		h & impassable;
 		h & impassable;
@@ -1805,14 +1813,14 @@ struct ShowInInfobox : public CPackForClient
 
 
 struct AdvmapSpellCast : public CPackForClient
 struct AdvmapSpellCast : public CPackForClient
 {
 {
-	AdvmapSpellCast():caster(nullptr){}
-	const CGHeroInstance * caster;//todo: replace with ObjectInstanceID
+	AdvmapSpellCast():casterID(){}
+	ObjectInstanceID casterID;
 	SpellID spellID;
 	SpellID spellID;
 
 
 	void applyCl(CClient *cl);
 	void applyCl(CClient *cl);
 	template <typename Handler> void serialize(Handler &h, const int version)
 	template <typename Handler> void serialize(Handler &h, const int version)
 	{
 	{
-		h & caster;
+		h & casterID;
 		h & spellID;
 		h & spellID;
 	}
 	}
 };
 };
@@ -2038,7 +2046,6 @@ struct GarrisonHeroSwap : public CPackForServer
 };
 };
 
 
 struct ExchangeArtifacts : public CPackForServer
 struct ExchangeArtifacts : public CPackForServer
-//TODO: allow exchange between heroes, stacks and commanders
 {
 {
 	ArtifactLocation src, dst;
 	ArtifactLocation src, dst;
 	ExchangeArtifacts(){};
 	ExchangeArtifacts(){};
@@ -2089,11 +2096,12 @@ struct BuyArtifact : public CPackForServer
 struct TradeOnMarketplace : public CPackForServer
 struct TradeOnMarketplace : public CPackForServer
 {
 {
 	TradeOnMarketplace()
 	TradeOnMarketplace()
-		:market(nullptr), hero(nullptr), mode(EMarketMode::RESOURCE_RESOURCE)
+		:marketId(), heroId(), mode(EMarketMode::RESOURCE_RESOURCE)
 	{};
 	{};
 
 
-	const CGObjectInstance *market; //todo: replace with ObjectInstanceID
-	const CGHeroInstance *hero; //needed when trading artifacts / creatures
+	ObjectInstanceID marketId;
+	ObjectInstanceID heroId;
+
 	EMarketMode::EMarketMode mode;
 	EMarketMode::EMarketMode mode;
 	std::vector<ui32> r1, r2; //mode 0: r1 - sold resource, r2 - bought res (exception: when sacrificing art r1 is art id [todo: make r2 preferred slot?]
 	std::vector<ui32> r1, r2; //mode 0: r1 - sold resource, r2 - bought res (exception: when sacrificing art r1 is art id [todo: make r2 preferred slot?]
 	std::vector<ui32> val; //units of sold resource
 	std::vector<ui32> val; //units of sold resource
@@ -2101,8 +2109,8 @@ struct TradeOnMarketplace : public CPackForServer
 	bool applyGh(CGameHandler *gh);
 	bool applyGh(CGameHandler *gh);
 	template <typename Handler> void serialize(Handler &h, const int version)
 	template <typename Handler> void serialize(Handler &h, const int version)
 	{
 	{
-		h & market;
-		h & hero;
+		h & marketId;
+		h & heroId;
 		h & mode;
 		h & mode;
 		h & r1;
 		h & r1;
 		h & r2;
 		h & r2;

+ 1 - 1
lib/NetPacksBase.h

@@ -190,7 +190,7 @@ typedef boost::variant<ConstTransitivePtr<CGHeroInstance>, ConstTransitivePtr<CS
 
 
 struct ArtifactLocation
 struct ArtifactLocation
 {
 {
-	TArtHolder artHolder;
+	TArtHolder artHolder;//TODO: identify holder by id
 	ArtifactPosition slot;
 	ArtifactPosition slot;
 
 
 	ArtifactLocation()
 	ArtifactLocation()

+ 15 - 10
lib/NetPacksLib.cpp

@@ -1188,14 +1188,16 @@ DLL_LINKAGE void SetObjectProperty::applyGs(CGameState *gs)
 	}
 	}
 }
 }
 
 
-DLL_LINKAGE void PrepareHeroLevelUp::applyGs(CGameState *gs)
+DLL_LINKAGE void PrepareHeroLevelUp::applyGs(CGameState * gs)
 {
 {
-	CGHeroInstance * h = gs->getHero(hero->id);
-	auto proposedSkills = h->getLevelUpProposedSecondarySkills();
+	auto hero = gs->getHero(heroId);
+	assert(hero);
+
+	auto proposedSkills = hero->getLevelUpProposedSecondarySkills();
 
 
 	if(skills.size() == 1 || hero->tempOwner == PlayerColor::NEUTRAL) //choose skill automatically
 	if(skills.size() == 1 || hero->tempOwner == PlayerColor::NEUTRAL) //choose skill automatically
 	{
 	{
-		skills.push_back(*RandomGeneratorUtil::nextItem(proposedSkills, h->skillsInfo.rand));
+		skills.push_back(*RandomGeneratorUtil::nextItem(proposedSkills, hero->skillsInfo.rand));
 	}
 	}
 	else
 	else
 	{
 	{
@@ -1203,16 +1205,19 @@ DLL_LINKAGE void PrepareHeroLevelUp::applyGs(CGameState *gs)
 	}
 	}
 }
 }
 
 
-DLL_LINKAGE void HeroLevelUp::applyGs(CGameState *gs)
+DLL_LINKAGE void HeroLevelUp::applyGs(CGameState * gs)
 {
 {
-	CGHeroInstance * h = gs->getHero(hero->id);
-	h->levelUp(skills);
+	auto hero = gs->getHero(heroId);
+	assert(hero);
+	hero->levelUp(skills);
 }
 }
 
 
-DLL_LINKAGE void CommanderLevelUp::applyGs (CGameState *gs)
+DLL_LINKAGE void CommanderLevelUp::applyGs(CGameState * gs)
 {
 {
-	CCommanderInstance * commander = gs->getHero(hero->id)->commander;
-	assert (commander);
+	auto hero = gs->getHero(heroId);
+	assert(hero);
+	auto commander = hero->commander;
+	assert(commander);
 	commander->levelUp();
 	commander->levelUp();
 }
 }
 
 

+ 3 - 3
lib/mapObjects/MiscObjects.cpp

@@ -1061,7 +1061,7 @@ TeleportChannelID CGMonolith::findMeChannel(std::vector<Obj> IDs, int SubID) con
 
 
 void CGMonolith::onHeroVisit( const CGHeroInstance * h ) const
 void CGMonolith::onHeroVisit( const CGHeroInstance * h ) const
 {
 {
-	TeleportDialog td(h, channel);
+	TeleportDialog td(h->tempOwner, channel);
 	if(isEntrance())
 	if(isEntrance())
 	{
 	{
 		if(cb->isTeleportChannelBidirectional(channel) && 1 < cb->getTeleportChannelExits(channel).size())
 		if(cb->isTeleportChannelBidirectional(channel) && 1 < cb->getTeleportChannelExits(channel).size())
@@ -1135,7 +1135,7 @@ void CGMonolith::initObj(CRandomGenerator & rand)
 
 
 void CGSubterraneanGate::onHeroVisit( const CGHeroInstance * h ) const
 void CGSubterraneanGate::onHeroVisit( const CGHeroInstance * h ) const
 {
 {
-	TeleportDialog td(h, channel);
+	TeleportDialog td(h->tempOwner, channel);
 	if(cb->isTeleportChannelImpassable(channel))
 	if(cb->isTeleportChannelImpassable(channel))
 	{
 	{
 		showInfoDialog(h,153,0);//Just inside the entrance you find a large pile of rubble blocking the tunnel. You leave discouraged.
 		showInfoDialog(h,153,0);//Just inside the entrance you find a large pile of rubble blocking the tunnel. You leave discouraged.
@@ -1219,7 +1219,7 @@ void CGSubterraneanGate::postInit() //matches subterranean gates into pairs
 
 
 void CGWhirlpool::onHeroVisit( const CGHeroInstance * h ) const
 void CGWhirlpool::onHeroVisit( const CGHeroInstance * h ) const
 {
 {
-	TeleportDialog td(h, channel);
+	TeleportDialog td(h->tempOwner, channel);
 	if(cb->isTeleportChannelImpassable(channel))
 	if(cb->isTeleportChannelImpassable(channel))
 	{
 	{
 		logGlobal->debug("Cannot find exit whirlpool for %d at %s", id.getNum(), pos.toString());
 		logGlobal->debug("Cannot find exit whirlpool for %d at %s", id.getNum(), pos.toString());

+ 1 - 1
lib/spells/AdventureSpellMechanics.cpp

@@ -102,7 +102,7 @@ ESpellCastResult AdventureSpellMechanics::beginCast(const SpellCastEnvironment *
 void AdventureSpellMechanics::performCast(const SpellCastEnvironment * env, const AdventureSpellCastParameters & parameters) const
 void AdventureSpellMechanics::performCast(const SpellCastEnvironment * env, const AdventureSpellCastParameters & parameters) const
 {
 {
 	AdvmapSpellCast asc;
 	AdvmapSpellCast asc;
-	asc.caster = parameters.caster;
+	asc.casterID = parameters.caster->id;
 	asc.spellID = owner->id;
 	asc.spellID = owner->id;
 	env->sendAndApply(&asc);
 	env->sendAndApply(&asc);
 
 

+ 17 - 13
server/CGameHandler.cpp

@@ -393,11 +393,12 @@ void CGameHandler::levelUpHero(const CGHeroInstance * hero)
 	sendAndApply(&sps);
 	sendAndApply(&sps);
 
 
 	PrepareHeroLevelUp pre;
 	PrepareHeroLevelUp pre;
-	pre.hero = hero;
+	pre.heroId = hero->id;
 	sendAndApply(&pre);
 	sendAndApply(&pre);
 
 
 	HeroLevelUp hlu;
 	HeroLevelUp hlu;
-	hlu.hero = hero;
+	hlu.player = hero->tempOwner;
+	hlu.heroId = hero->id;
 	hlu.primskill = primarySkill;
 	hlu.primskill = primarySkill;
 	hlu.skills = pre.skills;
 	hlu.skills = pre.skills;
 
 
@@ -413,7 +414,7 @@ void CGameHandler::levelUpHero(const CGHeroInstance * hero)
 	}
 	}
 	else if (hlu.skills.size() > 1)
 	else if (hlu.skills.size() > 1)
 	{
 	{
-		auto levelUpQuery = std::make_shared<CHeroLevelUpDialogQuery>(this, hlu);
+		auto levelUpQuery = std::make_shared<CHeroLevelUpDialogQuery>(this, hlu, hero);
 		hlu.queryID = levelUpQuery->queryID;
 		hlu.queryID = levelUpQuery->queryID;
 		queries.addQuery(levelUpQuery);
 		queries.addQuery(levelUpQuery);
 		sendAndApply(&hlu);
 		sendAndApply(&hlu);
@@ -513,8 +514,11 @@ void CGameHandler::levelUpCommander(const CCommanderInstance * c)
 	CommanderLevelUp clu;
 	CommanderLevelUp clu;
 
 
 	auto hero = dynamic_cast<const CGHeroInstance *>(c->armyObj);
 	auto hero = dynamic_cast<const CGHeroInstance *>(c->armyObj);
-	if (hero)
-		clu.hero = hero;
+	if(hero)
+	{
+		clu.heroId = hero->id;
+		clu.player = hero->tempOwner;
+	}
 	else
 	else
 	{
 	{
 		complain ("Commander is not led by hero!");
 		complain ("Commander is not led by hero!");
@@ -551,7 +555,7 @@ void CGameHandler::levelUpCommander(const CCommanderInstance * c)
 	}
 	}
 	else if (skillAmount > 1) //apply and ask for secondary skill
 	else if (skillAmount > 1) //apply and ask for secondary skill
 	{
 	{
-		auto commanderLevelUp = std::make_shared<CCommanderLevelUpDialogQuery>(this, clu);
+		auto commanderLevelUp = std::make_shared<CCommanderLevelUpDialogQuery>(this, clu, hero);
 		clu.queryID = commanderLevelUp->queryID;
 		clu.queryID = commanderLevelUp->queryID;
 		queries.addQuery(commanderLevelUp);
 		queries.addQuery(commanderLevelUp);
 		sendAndApply(&clu);
 		sendAndApply(&clu);
@@ -2759,9 +2763,11 @@ void CGameHandler::heroExchange(ObjectInstanceID hero1, ObjectInstanceID hero2)
 		auto exchange = std::make_shared<CGarrisonDialogQuery>(this, h1, h2);
 		auto exchange = std::make_shared<CGarrisonDialogQuery>(this, h1, h2);
 		ExchangeDialog hex;
 		ExchangeDialog hex;
 		hex.queryID = exchange->queryID;
 		hex.queryID = exchange->queryID;
-		hex.heroes[0] = getHero(hero1);
-		hex.heroes[1] = getHero(hero2);
+		hex.player = h1->getOwner();
+		hex.hero1 = hero1;
+		hex.hero2 = hero2;
 		sendAndApply(&hex);
 		sendAndApply(&hex);
+
 		useScholarSkill(hero1,hero2);
 		useScholarSkill(hero1,hero2);
 		queries.addQuery(exchange);
 		queries.addQuery(exchange);
 	}
 	}
@@ -5161,8 +5167,8 @@ void CGameHandler::objectVisited(const CGObjectInstance * obj, const CGHeroInsta
 	queries.addQuery(visitQuery); //TODO real visit pos
 	queries.addQuery(visitQuery); //TODO real visit pos
 
 
 	HeroVisit hv;
 	HeroVisit hv;
-	hv.obj = obj;
-	hv.hero = h;
+	hv.objId = obj->id;
+	hv.heroId = h->id;
 	hv.player = h->tempOwner;
 	hv.player = h->tempOwner;
 	hv.starting = true;
 	hv.starting = true;
 	sendAndApply(&hv);
 	sendAndApply(&hv);
@@ -5178,9 +5184,7 @@ void CGameHandler::objectVisitEnded(const CObjectVisitQuery &query)
 
 
 	HeroVisit hv;
 	HeroVisit hv;
 	hv.player = query.players.front();
 	hv.player = query.players.front();
-	hv.obj = nullptr; //not necessary, moreover may have been deleted in the meantime
-	hv.hero = query.visitingHero;
-	assert(hv.hero);
+	hv.heroId = query.visitingHero->id;
 	hv.starting = false;
 	hv.starting = false;
 	sendAndApply(&hv);
 	sendAndApply(&hv);
 }
 }

+ 11 - 11
server/CQuery.cpp

@@ -367,21 +367,21 @@ CTeleportDialogQuery::CTeleportDialogQuery(CGameHandler * owner, const TeleportD
 	CDialogQuery(owner)
 	CDialogQuery(owner)
 {
 {
 	this->td = td;
 	this->td = td;
-	addPlayer(td.hero->tempOwner);
+	addPlayer(td.player);
 }
 }
 
 
-CHeroLevelUpDialogQuery::CHeroLevelUpDialogQuery(CGameHandler * owner, const HeroLevelUp & Hlu):
-	CDialogQuery(owner)
+CHeroLevelUpDialogQuery::CHeroLevelUpDialogQuery(CGameHandler * owner, const HeroLevelUp & Hlu, const CGHeroInstance * Hero):
+	CDialogQuery(owner), hero(Hero)
 {
 {
 	hlu = Hlu;
 	hlu = Hlu;
-	addPlayer(hlu.hero->tempOwner);
+	addPlayer(hero->tempOwner);
 }
 }
 
 
 void CHeroLevelUpDialogQuery::onRemoval(PlayerColor color)
 void CHeroLevelUpDialogQuery::onRemoval(PlayerColor color)
 {
 {
 	assert(answer);
 	assert(answer);
-	logGlobal->trace("Completing hero level-up query. %s gains skill %d", hlu.hero->getObjectName(), answer.get());
-	gh->levelUpHero(hlu.hero, hlu.skills[*answer]);
+	logGlobal->trace("Completing hero level-up query. %s gains skill %d", hero->getObjectName(), answer.get());
+	gh->levelUpHero(hero, hlu.skills[*answer]);
 }
 }
 
 
 void CHeroLevelUpDialogQuery::notifyObjectAboutRemoval(const CObjectVisitQuery & objectVisit) const
 void CHeroLevelUpDialogQuery::notifyObjectAboutRemoval(const CObjectVisitQuery & objectVisit) const
@@ -389,18 +389,18 @@ void CHeroLevelUpDialogQuery::notifyObjectAboutRemoval(const CObjectVisitQuery &
 	objectVisit.visitedObject->heroLevelUpDone(objectVisit.visitingHero);
 	objectVisit.visitedObject->heroLevelUpDone(objectVisit.visitingHero);
 }
 }
 
 
-CCommanderLevelUpDialogQuery::CCommanderLevelUpDialogQuery(CGameHandler * owner, const CommanderLevelUp & Clu):
-	CDialogQuery(owner)
+CCommanderLevelUpDialogQuery::CCommanderLevelUpDialogQuery(CGameHandler * owner, const CommanderLevelUp & Clu, const CGHeroInstance * Hero):
+	CDialogQuery(owner), hero(Hero)
 {
 {
 	clu = Clu;
 	clu = Clu;
-	addPlayer(clu.hero->tempOwner);
+	addPlayer(hero->tempOwner);
 }
 }
 
 
 void CCommanderLevelUpDialogQuery::onRemoval(PlayerColor color)
 void CCommanderLevelUpDialogQuery::onRemoval(PlayerColor color)
 {
 {
 	assert(answer);
 	assert(answer);
-	logGlobal->trace("Completing commander level-up query. Commander of hero %s gains skill %s", clu.hero->getObjectName(), answer.get());
-	gh->levelUpCommander(clu.hero->commander, clu.skills[*answer]);
+	logGlobal->trace("Completing commander level-up query. Commander of hero %s gains skill %s", hero->getObjectName(), answer.get());
+	gh->levelUpCommander(hero->commander, clu.skills[*answer]);
 }
 }
 
 
 void CCommanderLevelUpDialogQuery::notifyObjectAboutRemoval(const CObjectVisitQuery & objectVisit) const
 void CCommanderLevelUpDialogQuery::notifyObjectAboutRemoval(const CObjectVisitQuery & objectVisit) const

+ 4 - 2
server/CQuery.h

@@ -165,23 +165,25 @@ public:
 class CHeroLevelUpDialogQuery : public CDialogQuery
 class CHeroLevelUpDialogQuery : public CDialogQuery
 {
 {
 public:
 public:
-	CHeroLevelUpDialogQuery(CGameHandler * owner, const HeroLevelUp &Hlu);
+	CHeroLevelUpDialogQuery(CGameHandler * owner, const HeroLevelUp &Hlu, const CGHeroInstance * Hero);
 
 
 	virtual void onRemoval(PlayerColor color) override;
 	virtual void onRemoval(PlayerColor color) override;
 	virtual void notifyObjectAboutRemoval(const CObjectVisitQuery &objectVisit) const override;
 	virtual void notifyObjectAboutRemoval(const CObjectVisitQuery &objectVisit) const override;
 
 
 	HeroLevelUp hlu;
 	HeroLevelUp hlu;
+	const CGHeroInstance * hero;
 };
 };
 
 
 class CCommanderLevelUpDialogQuery : public CDialogQuery
 class CCommanderLevelUpDialogQuery : public CDialogQuery
 {
 {
 public:
 public:
-	CCommanderLevelUpDialogQuery(CGameHandler * owner, const CommanderLevelUp &Clu);
+	CCommanderLevelUpDialogQuery(CGameHandler * owner, const CommanderLevelUp &Clu, const CGHeroInstance * Hero);
 
 
 	virtual void onRemoval(PlayerColor color) override;
 	virtual void onRemoval(PlayerColor color) override;
 	virtual void notifyObjectAboutRemoval(const CObjectVisitQuery &objectVisit) const override;
 	virtual void notifyObjectAboutRemoval(const CObjectVisitQuery &objectVisit) const override;
 
 
 	CommanderLevelUp clu;
 	CommanderLevelUp clu;
+	const CGHeroInstance * hero;
 };
 };
 
 
 class CGenericQuery : public CQuery
 class CGenericQuery : public CQuery

+ 5 - 0
server/NetPacksServer.cpp

@@ -191,6 +191,11 @@ bool BuyArtifact::applyGh(CGameHandler * gh)
 
 
 bool TradeOnMarketplace::applyGh(CGameHandler * gh)
 bool TradeOnMarketplace::applyGh(CGameHandler * gh)
 {
 {
+	const CGObjectInstance * market = gh->getObj(marketId);
+	if(!market)
+		throwAndCompain(gh, "Invalid market object");
+	const CGHeroInstance * hero = gh->getHero(heroId);
+
 	//market must be owned or visited
 	//market must be owned or visited
 	const IMarket * m = IMarket::castFrom(market);
 	const IMarket * m = IMarket::castFrom(market);