1
0
mirror of https://github.com/vcmi/vcmi.git synced 2024-11-24 08:32:34 +02:00

Replaced CGHeroInstance and CGObjectInstance with ObjectInstanceID in NetPacks

This commit is contained in:
AlexVinS 2018-03-10 22:19:55 +03:00 committed by ArseniyShestakov
parent 0f00dbf8cf
commit 8cec07afbd
12 changed files with 137 additions and 104 deletions

View File

@ -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.marketId = market->id;
pack.hero = hero; 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.marketId = market->id;
pack.hero = hero; pack.heroId = hero->id;
pack.mode = mode; pack.mode = mode;
pack.r1 = id1; pack.r1 = id1;
pack.r2 = id2; pack.r2 = id2;

View File

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

View File

@ -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, player, &IGameEventsReceiver::heroExchangeStarted, hero1, hero2, queryID);
callInterfaceIfPresent(cl, heroes[0]->tempOwner, &IGameEventsReceiver::heroExchangeStarted, heroes[0]->id, heroes[1]->id, 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? auto caster = cl->getHero(casterID);
callInterfaceIfPresent(cl, caster->getOwner(), &IGameEventsReceiver::advmapSpellCast, caster, spellID); 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)

View File

@ -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; PlayerColor player;
const CGObjectInstance *obj; ObjectInstanceID heroId;
PlayerColor player; //if hero was killed during the visit, its color is already reset ObjectInstanceID objId;
bool starting; //false -> ending bool starting; //false -> ending
void applyCl(CClient *cl); void applyCl(CClient * cl);
DLL_LINKAGE void applyGs(CGameState *gs); 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); ObjectInstanceID heroId;
const CGHeroInstance *hero;
/// 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); PlayerColor player;
DLL_LINKAGE void applyGs(CGameState *gs); 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); PlayerColor player;
DLL_LINKAGE void applyGs(CGameState *gs); ObjectInstanceID heroId;
const CGHeroInstance *hero;
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() ExchangeDialog() {}
{
heroes = {nullptr,nullptr};
}
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) TeleportDialog(PlayerColor Player, TeleportChannelID Channel)
: hero(Hero), channel(Channel), impassable(false) : 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){} AdvmapSpellCast():casterID(){}
const CGHeroInstance * caster;//todo: replace with ObjectInstanceID 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 ObjectInstanceID marketId;
const CGHeroInstance *hero; //needed when trading artifacts / creatures 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 & marketId;
h & hero; h & heroId;
h & mode; h & mode;
h & r1; h & r1;
h & r2; h & r2;

View File

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

View File

@ -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 hero = gs->getHero(heroId);
auto proposedSkills = h->getLevelUpProposedSecondarySkills(); 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); auto hero = gs->getHero(heroId);
h->levelUp(skills); 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; auto hero = gs->getHero(heroId);
assert (commander); assert(hero);
auto commander = hero->commander;
assert(commander);
commander->levelUp(); commander->levelUp();
} }

View File

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

View File

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

View File

@ -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) if(hero)
clu.hero = 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.player = h1->getOwner();
hex.heroes[1] = getHero(hero2); 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.objId = obj->id;
hv.hero = h; 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.heroId = query.visitingHero->id;
hv.hero = query.visitingHero;
assert(hv.hero);
hv.starting = false; hv.starting = false;
sendAndApply(&hv); sendAndApply(&hv);
} }

View File

@ -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): CHeroLevelUpDialogQuery::CHeroLevelUpDialogQuery(CGameHandler * owner, const HeroLevelUp & Hlu, const CGHeroInstance * Hero):
CDialogQuery(owner) 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()); logGlobal->trace("Completing hero level-up query. %s gains skill %d", hero->getObjectName(), answer.get());
gh->levelUpHero(hlu.hero, hlu.skills[*answer]); 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): CCommanderLevelUpDialogQuery::CCommanderLevelUpDialogQuery(CGameHandler * owner, const CommanderLevelUp & Clu, const CGHeroInstance * Hero):
CDialogQuery(owner) 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()); logGlobal->trace("Completing commander level-up query. Commander of hero %s gains skill %s", hero->getObjectName(), answer.get());
gh->levelUpCommander(clu.hero->commander, clu.skills[*answer]); gh->levelUpCommander(hero->commander, clu.skills[*answer]);
} }
void CCommanderLevelUpDialogQuery::notifyObjectAboutRemoval(const CObjectVisitQuery & objectVisit) const void CCommanderLevelUpDialogQuery::notifyObjectAboutRemoval(const CObjectVisitQuery & objectVisit) const

View File

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

View File

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