1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-06-23 00:28:08 +02:00

Fix crashes on game start, gamestate now derives from GameCallbackHolder

This commit is contained in:
Ivan Savenko
2025-04-01 15:59:08 +03:00
parent d34b47bb20
commit d1d2cf4189
21 changed files with 99 additions and 81 deletions

View File

@ -118,7 +118,7 @@ void CClient::newGame(std::shared_ptr<CGameState> initializedGameState)
CMapService mapService; CMapService mapService;
assert(initializedGameState); assert(initializedGameState);
gamestate = initializedGameState; gamestate = initializedGameState;
gamestate->preInit(LIBRARY, this); gamestate->preInit(LIBRARY);
logNetwork->trace("\tCreating gamestate: %i", GAME->server().th->getDiff()); logNetwork->trace("\tCreating gamestate: %i", GAME->server().th->getDiff());
initMapHandler(); initMapHandler();
@ -133,7 +133,7 @@ void CClient::loadGame(std::shared_ptr<CGameState> initializedGameState)
logNetwork->info("Game state was transferred over network, loading."); logNetwork->info("Game state was transferred over network, loading.");
gamestate = initializedGameState; gamestate = initializedGameState;
gamestate->preInit(LIBRARY, this); gamestate->preInit(LIBRARY);
gamestate->updateOnLoad(GAME->server().si.get()); gamestate->updateOnLoad(GAME->server().si.get());
logNetwork->info("Game loaded, initialize interfaces."); logNetwork->info("Game loaded, initialize interfaces.");

View File

@ -949,9 +949,9 @@ bool CArtifactSet::isPositionFree(const ArtifactPosition & pos, bool onlyLockChe
void CArtifactSet::artDeserializationFix(CBonusSystemNode *node) void CArtifactSet::artDeserializationFix(CBonusSystemNode *node)
{ {
for(auto & elem : artifactsWorn) //for(auto & elem : artifactsWorn)
if(elem.second.getArt() && !elem.second.locked) // if(elem.second.getArt() && !elem.second.locked)
node->attachToSource(*elem.second.getArt()); // node->attachToSource(*elem.second.getArt());
} }
void CArtifactSet::serializeJsonArtifacts(JsonSerializeFormat & handler, const std::string & fieldName, CMap * map) void CArtifactSet::serializeJsonArtifacts(JsonSerializeFormat & handler, const std::string & fieldName, CMap * map)

View File

@ -184,9 +184,9 @@ bool CArtifactInstance::isScroll() const
void CArtifactInstance::deserializationFix() void CArtifactInstance::deserializationFix()
{ {
setType(artTypeID.toArtifact()); // setType(artTypeID.toArtifact());
for(PartInfo & part : partsInfo) // for(PartInfo & part : partsInfo)
attachToSource(*part.getArtifact()); // attachToSource(*part.getArtifact());
} }
VCMI_LIB_NAMESPACE_END VCMI_LIB_NAMESPACE_END

View File

@ -334,6 +334,15 @@ void CCreatureSet::addToSlot(const SlotID & slot, std::unique_ptr<CStackInstance
} }
} }
void CCreatureSet::deserializationFix()
{
for(const auto & elem : stacks)
{
elem.second->attachTo(*getArmy());
elem.second->artDeserializationFix(elem.second.get());
}
}
bool CCreatureSet::validTypes(bool allowUnrandomized) const bool CCreatureSet::validTypes(bool allowUnrandomized) const
{ {
for(const auto & elem : stacks) for(const auto & elem : stacks)
@ -517,7 +526,7 @@ void CCreatureSet::putStack(const SlotID & slot, std::unique_ptr<CStackInstance>
assert(slot.getNum() < GameConstants::ARMY_SIZE); assert(slot.getNum() < GameConstants::ARMY_SIZE);
assert(!hasStackAtSlot(slot)); assert(!hasStackAtSlot(slot));
stacks[slot] = std::move(stack); stacks[slot] = std::move(stack);
stack->setArmy(getArmy()); stacks[slot]->setArmy(getArmy());
armyChanged(); armyChanged();
} }
@ -536,10 +545,7 @@ void CCreatureSet::changeStackCount(const SlotID & slot, TQuantity toAdd)
setStackCount(slot, getStackCount(slot) + toAdd); setStackCount(slot, getStackCount(slot) + toAdd);
} }
CCreatureSet::~CCreatureSet() CCreatureSet::~CCreatureSet() = default;
{
clearSlots();
}
void CCreatureSet::setToArmy(CSimpleArmy &src) void CCreatureSet::setToArmy(CSimpleArmy &src)
{ {
@ -864,19 +870,11 @@ TerrainId CStackInstance::getNativeTerrain() const
return getFactionID().toEntity(LIBRARY)->getNativeTerrain(); return getFactionID().toEntity(LIBRARY)->getNativeTerrain();
} }
TerrainId CStackInstance::getCurrentTerrain() const TerrainId CStackInstance::getCurrentTerrain() const
{ {
return getArmy()->getCurrentTerrain(); return getArmy()->getCurrentTerrain();
} }
void CStackInstance::deserializationFix()
{
const CArmedInstance *armyBackup = getArmy();
armyInstanceID = {};
setArmy(armyBackup);
artDeserializationFix(this);
}
CreatureID CStackInstance::getCreatureID() const CreatureID CStackInstance::getCreatureID() const
{ {

View File

@ -100,9 +100,6 @@ public:
h & static_cast<CArtifactSet&>(*this); h & static_cast<CArtifactSet&>(*this);
h & armyInstanceID; h & armyInstanceID;
h & experience; h & experience;
if(!h.saving)
deserializationFix();
} }
void serializeJson(JsonSerializeFormat & handler); void serializeJson(JsonSerializeFormat & handler);
@ -137,7 +134,6 @@ public:
void removeArtifact(const ArtifactPosition & pos) override; void removeArtifact(const ArtifactPosition & pos) override;
ArtBearer::ArtBearer bearerType() const override; //from CArtifactSet ArtBearer::ArtBearer bearerType() const override; //from CArtifactSet
std::string nodeName() const override; //from CBonusSystemnode std::string nodeName() const override; //from CBonusSystemnode
void deserializationFix();
PlayerColor getOwner() const override; PlayerColor getOwner() const override;
int32_t getInitiative(int turn = 0) const final; int32_t getInitiative(int turn = 0) const final;
@ -225,6 +221,9 @@ class DLL_LINKAGE CCreatureSet : public IArmyDescriptor, public virtual Serializ
CCreatureSet(const CCreatureSet &) = delete; CCreatureSet(const CCreatureSet &) = delete;
CCreatureSet &operator=(const CCreatureSet&); CCreatureSet &operator=(const CCreatureSet&);
void deserializationFix();
public: public:
TSlots stacks; //slots[slot_id]->> pair(creature_id,creature_quantity) TSlots stacks; //slots[slot_id]->> pair(creature_id,creature_quantity)
EArmyFormation formation = EArmyFormation::LOOSE; //0 - wide, 1 - tight EArmyFormation formation = EArmyFormation::LOOSE; //0 - wide, 1 - tight
@ -297,6 +296,9 @@ public:
{ {
h & stacks; h & stacks;
h & formation; h & formation;
if(!h.saving)
deserializationFix();
} }
void serializeJson(JsonSerializeFormat & handler, const std::string & armyFieldName, const std::optional<int> fixedSize = std::nullopt); void serializeJson(JsonSerializeFormat & handler, const std::string & armyFieldName, const std::optional<int> fixedSize = std::nullopt);

View File

@ -131,6 +131,13 @@ TurnTimerInfo CGameInfoCallback::getPlayerTurnTime(PlayerColor color) const
const CGObjectInstance* CGameInfoCallback::getObj(ObjectInstanceID objid, bool verbose) const const CGObjectInstance* CGameInfoCallback::getObj(ObjectInstanceID objid, bool verbose) const
{ {
if (!objid.hasValue())
{
if(verbose)
logGlobal->error("Cannot get object with id %d. No such object", objid.getNum());
return nullptr;
}
const CGObjectInstance *ret = gameState()->getMap().getObject(objid); const CGObjectInstance *ret = gameState()->getMap().getObject(objid);
if(!ret) if(!ret)
{ {

View File

@ -139,7 +139,8 @@ int CGameState::getDate(Date mode) const
return getDate(day, mode); return getDate(day, mode);
} }
CGameState::CGameState() CGameState::CGameState(IGameCallback * callback)
: GameCallbackHolder(callback)
{ {
heroesPool = std::make_unique<TavernHeroesPool>(this); heroesPool = std::make_unique<TavernHeroesPool>(this);
globalEffects.setNodeType(CBonusSystemNode::GLOBAL_EFFECTS); globalEffects.setNodeType(CBonusSystemNode::GLOBAL_EFFECTS);
@ -156,16 +157,15 @@ const IGameSettings & CGameState::getSettings() const
return map->getSettings(); return map->getSettings();
} }
void CGameState::preInit(Services * newServices, IGameCallback * newCallback) void CGameState::preInit(Services * newServices)
{ {
services = newServices; services = newServices;
callback = newCallback;
} }
void CGameState::init(const IMapService * mapService, StartInfo * si, Load::ProgressAccumulator & progressTracking, bool allowSavingRandomMap) void CGameState::init(const IMapService * mapService, StartInfo * si, Load::ProgressAccumulator & progressTracking, bool allowSavingRandomMap)
{ {
assert(services); assert(services);
assert(callback); assert(cb);
scenarioOps = CMemorySerializer::deepCopy(*si); scenarioOps = CMemorySerializer::deepCopy(*si);
initialOpts = CMemorySerializer::deepCopy(*si); initialOpts = CMemorySerializer::deepCopy(*si);
si = nullptr; si = nullptr;
@ -271,7 +271,7 @@ void CGameState::updateEntity(Metatype metatype, int32_t index, const JsonNode &
void CGameState::updateOnLoad(StartInfo * si) void CGameState::updateOnLoad(StartInfo * si)
{ {
assert(services); assert(services);
assert(callback); assert(cb);
scenarioOps->playerInfos = si->playerInfos; scenarioOps->playerInfos = si->playerInfos;
for(auto & i : si->playerInfos) for(auto & i : si->playerInfos)
players.at(i.first).human = i.second.isControlledByHuman(); players.at(i.first).human = i.second.isControlledByHuman();
@ -288,7 +288,7 @@ void CGameState::initNewGame(const IMapService * mapService, bool allowSavingRan
CStopWatch sw; CStopWatch sw;
// Gen map // Gen map
CMapGenerator mapGenerator(*scenarioOps->mapGenOptions, callback, getRandomGenerator().nextInt()); CMapGenerator mapGenerator(*scenarioOps->mapGenOptions, cb, getRandomGenerator().nextInt());
progressTracking.include(mapGenerator); progressTracking.include(mapGenerator);
std::unique_ptr<CMap> randomMap = mapGenerator.generate(); std::unique_ptr<CMap> randomMap = mapGenerator.generate();
@ -351,7 +351,7 @@ void CGameState::initNewGame(const IMapService * mapService, bool allowSavingRan
{ {
logGlobal->info("Open map file: %s", scenarioOps->mapname); logGlobal->info("Open map file: %s", scenarioOps->mapname);
const ResourcePath mapURI(scenarioOps->mapname, EResType::MAP); const ResourcePath mapURI(scenarioOps->mapname, EResType::MAP);
map = mapService->loadMap(mapURI, callback); map = mapService->loadMap(mapURI, cb);
} }
} }
@ -514,6 +514,7 @@ void CGameState::initPlayerStates()
logGlobal->debug("\tCreating player entries in gs"); logGlobal->debug("\tCreating player entries in gs");
for(auto & elem : scenarioOps->playerInfos) for(auto & elem : scenarioOps->playerInfos)
{ {
players.try_emplace(elem.first, cb);
PlayerState & p = players.at(elem.first); PlayerState & p = players.at(elem.first);
p.color=elem.first; p.color=elem.first;
p.human = elem.second.isControlledByHuman(); p.human = elem.second.isControlledByHuman();
@ -536,7 +537,7 @@ void CGameState::placeStartingHero(const PlayerColor & playerColor, const HeroTy
} }
auto handler = LIBRARY->objtypeh->getHandlerFor(Obj::HERO, heroTypeId.toHeroType()->heroClass->getIndex()); auto handler = LIBRARY->objtypeh->getHandlerFor(Obj::HERO, heroTypeId.toHeroType()->heroClass->getIndex());
auto object = handler->create(callback, handler->getTemplates().front()); auto object = handler->create(cb, handler->getTemplates().front());
auto hero = std::dynamic_pointer_cast<CGHeroInstance>(object); auto hero = std::dynamic_pointer_cast<CGHeroInstance>(object);
hero->ID = Obj::HERO; hero->ID = Obj::HERO;
@ -604,7 +605,7 @@ void CGameState::initHeroes()
if (tile.isWater()) if (tile.isWater())
{ {
auto handler = LIBRARY->objtypeh->getHandlerFor(Obj::BOAT, hero->getBoatType().getNum()); auto handler = LIBRARY->objtypeh->getHandlerFor(Obj::BOAT, hero->getBoatType().getNum());
auto boat = std::dynamic_pointer_cast<CGBoat>(handler->create(callback, nullptr)); auto boat = std::dynamic_pointer_cast<CGBoat>(handler->create(cb, nullptr));
handler->configureObject(boat.get(), getRandomGenerator()); handler->configureObject(boat.get(), getRandomGenerator());
boat->setAnchorPos(hero->anchorPos()); boat->setAnchorPos(hero->anchorPos());
@ -632,7 +633,7 @@ void CGameState::initHeroes()
} }
else else
{ {
auto vhi = std::make_shared<CGHeroInstance>(callback); vhi = std::make_shared<CGHeroInstance>(cb);
vhi->initHero(getRandomGenerator(), htype); vhi->initHero(getRandomGenerator(), htype);
} }
@ -924,7 +925,7 @@ void CGameState::initMapObjects()
if (q->ID ==Obj::QUEST_GUARD || q->ID ==Obj::SEER_HUT) if (q->ID ==Obj::QUEST_GUARD || q->ID ==Obj::SEER_HUT)
q->setObjToKill(); q->setObjToKill();
} }
CGSubterraneanGate::postInit(callback); //pairing subterranean gates CGSubterraneanGate::postInit(cb); //pairing subterranean gates
map->calculateGuardingGreaturePositions(); //calculate once again when all the guards are placed and initialized map->calculateGuardingGreaturePositions(); //calculate once again when all the guards are placed and initialized
} }
@ -1572,8 +1573,10 @@ void CGameState::buildBonusSystemTree()
void CGameState::deserializationFix() void CGameState::deserializationFix()
{ {
assert(cb != nullptr);
for(auto & player : players) for(auto & player : players)
player.second.cb = callback; player.second.cb = cb;
buildGlobalTeamPlayerTree(); buildGlobalTeamPlayerTree();
attachArmedObjects(); attachArmedObjects();
@ -1668,7 +1671,7 @@ TeamState::TeamState()
vstd::RNG & CGameState::getRandomGenerator() vstd::RNG & CGameState::getRandomGenerator()
{ {
return callback->getRandomGenerator(); return cb->getRandomGenerator();
} }
ArtifactID CGameState::pickRandomArtifact(vstd::RNG & rand, int flags, std::function<bool(ArtifactID)> accepts) ArtifactID CGameState::pickRandomArtifact(vstd::RNG & rand, int flags, std::function<bool(ArtifactID)> accepts)

View File

@ -11,6 +11,7 @@
#include "../bonuses/CBonusSystemNode.h" #include "../bonuses/CBonusSystemNode.h"
#include "../IGameCallback.h" #include "../IGameCallback.h"
#include "../GameCallbackHolder.h"
#include "../LoadProgress.h" #include "../LoadProgress.h"
#include "RumorState.h" #include "RumorState.h"
@ -42,7 +43,7 @@ class UpgradeInfo;
DLL_LINKAGE std::ostream & operator<<(std::ostream & os, const EVictoryLossCheckResult & victoryLossCheckResult); DLL_LINKAGE std::ostream & operator<<(std::ostream & os, const EVictoryLossCheckResult & victoryLossCheckResult);
class DLL_LINKAGE CGameState : public CNonConstInfoCallback, public Serializeable class DLL_LINKAGE CGameState : public CNonConstInfoCallback, public Serializeable, public GameCallbackHolder
{ {
friend class CGameStateCampaign; friend class CGameStateCampaign;
@ -64,15 +65,13 @@ public:
/// list of players currently making turn. Usually - just one, except for simturns /// list of players currently making turn. Usually - just one, except for simturns
std::set<PlayerColor> actingPlayers; std::set<PlayerColor> actingPlayers;
IGameCallback * callback; CGameState(IGameCallback * callback);
CGameState();
virtual ~CGameState(); virtual ~CGameState();
CGameState * gameState() final { return this; } CGameState * gameState() final { return this; }
const CGameState * gameState() const final { return this; } const CGameState * gameState() const final { return this; }
void preInit(Services * services, IGameCallback * callback); void preInit(Services * services);
void init(const IMapService * mapService, StartInfo * si, Load::ProgressAccumulator &, bool allowSavingRandomMap = true); void init(const IMapService * mapService, StartInfo * si, Load::ProgressAccumulator &, bool allowSavingRandomMap = true);
void updateOnLoad(StartInfo * si); void updateOnLoad(StartInfo * si);

View File

@ -684,7 +684,7 @@ bool CGameStateCampaign::playerHasStartingHero(PlayerColor playerColor) const
std::unique_ptr<CMap> CGameStateCampaign::getCurrentMap() std::unique_ptr<CMap> CGameStateCampaign::getCurrentMap()
{ {
return gameState->scenarioOps->campState->getMap(CampaignScenarioID::NONE, gameState->callback); return gameState->scenarioOps->campState->getMap(CampaignScenarioID::NONE, gameState->cb);
} }
VCMI_LIB_NAMESPACE_END VCMI_LIB_NAMESPACE_END

View File

@ -110,7 +110,7 @@ std::shared_ptr<CGHeroInstance> TavernHeroesPool::takeHeroFromPool(HeroTypeID he
return entry.hero == hero; return entry.hero == hero;
}); });
return owner->getMap().tryTakeFromHeroPool(hero);; return owner->getMap().tryTakeFromHeroPool(hero);
} }
void TavernHeroesPool::onNewDay() void TavernHeroesPool::onNewDay()

View File

@ -1324,9 +1324,9 @@ void CGHeroInstance::deserializationFix()
void CGHeroInstance::boatDeserializationFix() void CGHeroInstance::boatDeserializationFix()
{ {
auto boat = cb->gameState()->getObjInstance(boardedBoat); // auto boat = cb->gameState()->getObjInstance(boardedBoat);
if (boat) // if (boat)
attachTo(dynamic_cast<CGBoat&>(*boat)); // attachTo(dynamic_cast<CGBoat&>(*boat));
} }
CBonusSystemNode * CGHeroInstance::whereShouldBeAttachedOnSiege(const bool isBattleOutsideTown) const CBonusSystemNode * CGHeroInstance::whereShouldBeAttachedOnSiege(const bool isBattleOutsideTown) const
@ -1349,14 +1349,14 @@ CBonusSystemNode * CGHeroInstance::whereShouldBeAttachedOnSiege(CGameState * gs)
CBonusSystemNode & CGHeroInstance::whereShouldBeAttached(CGameState * gs) CBonusSystemNode & CGHeroInstance::whereShouldBeAttached(CGameState * gs)
{ {
if(getVisitedTown()) // if(getVisitedTown())
{ // {
if(isGarrisoned()) // if(isGarrisoned())
return *getVisitedTown(); // return *getVisitedTown();
else // else
return getVisitedTown()->townAndVis; // return getVisitedTown()->townAndVis;
} // }
else // else
return CArmedInstance::whereShouldBeAttached(gs); return CArmedInstance::whereShouldBeAttached(gs);
} }

View File

@ -708,13 +708,6 @@ std::string CGTownInstance::nodeName() const
void CGTownInstance::deserializationFix() void CGTownInstance::deserializationFix()
{ {
attachTo(townAndVis); attachTo(townAndVis);
//Hero is already handled by CGameState::attachArmedObjects
// if(getVisitingHero())
// getVisitingHero()->attachTo(&townAndVis);
// if(getGarrisonHero())
// getGarrisonHero()->attachTo(this);
} }
void CGTownInstance::updateMoraleBonusFromArmy() void CGTownInstance::updateMoraleBonusFromArmy()

View File

@ -505,7 +505,10 @@ void CMap::generateUniqueInstanceName(CGObjectInstance * target)
void CMap::addNewObject(std::shared_ptr<CGObjectInstance> obj) void CMap::addNewObject(std::shared_ptr<CGObjectInstance> obj)
{ {
if(obj->id != ObjectInstanceID(static_cast<si32>(objects.size()))) if (!obj->id.hasValue())
obj->id = ObjectInstanceID(objects.size());
if(obj->id != ObjectInstanceID(objects.size()) && objects.at(obj->id.getNum()) != nullptr)
throw std::runtime_error("Invalid object instance id"); throw std::runtime_error("Invalid object instance id");
if(obj->instanceName.empty()) if(obj->instanceName.empty())
@ -766,17 +769,27 @@ CArtifactInstance * CMap::createScroll(const SpellID & spellId)
CArtifactInstance * CMap::createSingleArtifact(const ArtifactID & artId, const SpellID & spellId) CArtifactInstance * CMap::createSingleArtifact(const ArtifactID & artId, const SpellID & spellId)
{ {
return new CArtifactInstance(cb); auto newArtifact = artId.hasValue() ?
std::make_shared<CArtifactInstance>(cb, artId.toArtifact()):
std::make_shared<CArtifactInstance>(cb);
newArtifact->setId(ArtifactInstanceID(artInstances.size()));
artInstances.push_back(newArtifact);
return newArtifact.get();
} }
CArtifactInstance * CMap::createArtifact(const ArtifactID & artID, const SpellID & spellId) CArtifactInstance * CMap::createArtifact(const ArtifactID & artID, const SpellID & spellId)
{ {
if(!artID.hasValue()) if(!artID.hasValue())
return new CArtifactInstance(cb); // random, empty //TODO: make this illegal & remove? {
// random, empty
// TODO: make this illegal & remove? Such artifact can't be randomized as combined artifact later
return createSingleArtifact(artID, spellId);
}
auto art = artID.toArtifact(); auto art = artID.toArtifact();
auto artInst = new CArtifactInstance(cb, art); auto artInst = createSingleArtifact(artID, spellId);
if(art->isCombined() && !art->isFused()) if(art->isCombined() && !art->isFused())
{ {
for(const auto & part : art->getConstituents()) for(const auto & part : art->getConstituents())

View File

@ -254,6 +254,7 @@ public:
h & objects; h & objects;
h & heroesOnMap; h & heroesOnMap;
h & heroesPool;
h & teleportChannels; h & teleportChannels;
h & towns; h & towns;
h & artInstances; h & artInstances;

View File

@ -1555,7 +1555,7 @@ void SwapStacks::applyGs(CGameState *gs)
void InsertNewStack::applyGs(CGameState *gs) void InsertNewStack::applyGs(CGameState *gs)
{ {
if(auto * obj = gs->getArmyInstance(army)) if(auto * obj = gs->getArmyInstance(army))
obj->putStack(slot, std::make_unique<CStackInstance>(gs->callback, type, count)); obj->putStack(slot, std::make_unique<CStackInstance>(gs->cb, type, count));
else else
throw std::runtime_error("InsertNewStack: invalid army object " + std::to_string(army.getNum()) + ", possible game state corruption."); throw std::runtime_error("InsertNewStack: invalid army object " + std::to_string(army.getNum()) + ", possible game state corruption.");
} }

View File

@ -132,7 +132,7 @@ void CConnection::setCallback(IGameCallback * cb)
void CConnection::enterGameplayConnectionMode(CGameState * gs) void CConnection::enterGameplayConnectionMode(CGameState * gs)
{ {
setCallback(gs->callback); setCallback(gs->cb);
} }
void CConnection::setSerializationVersion(ESerializationVersion version) void CConnection::setSerializationVersion(ESerializationVersion version)

View File

@ -544,8 +544,8 @@ void CGameHandler::init(StartInfo *si, Load::ProgressAccumulator & progressTrack
logGlobal->info("Using random seed: %d", randomNumberGenerator->nextInt()); logGlobal->info("Using random seed: %d", randomNumberGenerator->nextInt());
CMapService mapService; CMapService mapService;
gs = std::make_shared<CGameState>(); gs = std::make_shared<CGameState>(this);
gs->preInit(LIBRARY, this); gs->preInit(LIBRARY);
logGlobal->info("Gamestate created!"); logGlobal->info("Gamestate created!");
gs->init(&mapService, si, progressTracking); gs->init(&mapService, si, progressTracking);
logGlobal->info("Gamestate initialized!"); logGlobal->info("Gamestate initialized!");
@ -1613,7 +1613,7 @@ bool CGameHandler::load(const std::string & filename)
gameLobby().announceMessage(str); gameLobby().announceMessage(str);
return false; return false;
} }
gameState()->preInit(LIBRARY, this); gameState()->preInit(LIBRARY);
gameState()->updateOnLoad(gameLobby().si.get()); gameState()->updateOnLoad(gameLobby().si.get());
return true; return true;
} }
@ -2678,7 +2678,7 @@ bool CGameHandler::bulkMoveArtifacts(const PlayerColor & player, ObjectInstanceI
auto & slotsDstSrc = ma.artsPack1; auto & slotsDstSrc = ma.artsPack1;
// Temporary fitting set for artifacts. Used to select available slots before sending data. // Temporary fitting set for artifacts. Used to select available slots before sending data.
CArtifactFittingSet artFittingSet(gameState()->callback, pdstSet->bearerType()); CArtifactFittingSet artFittingSet(gameState()->cb, pdstSet->bearerType());
auto moveArtifact = [this, &artFittingSet, dstId](const CArtifactInstance * artifact, auto moveArtifact = [this, &artFittingSet, dstId](const CArtifactInstance * artifact,
ArtifactPosition srcSlot, std::vector<MoveArtifactInfo> & slots) -> void ArtifactPosition srcSlot, std::vector<MoveArtifactInfo> & slots) -> void
@ -4259,7 +4259,7 @@ std::shared_ptr<CGObjectInstance> CGameHandler::createNewObject(const int3 & vis
auto handler = LIBRARY->objtypeh->getHandlerFor(objectID, subID); auto handler = LIBRARY->objtypeh->getHandlerFor(objectID, subID);
auto o = handler->create(gameState()->callback, nullptr); auto o = handler->create(gameState()->cb, nullptr);
handler->configureObject(o.get(), getRandomGenerator()); handler->configureObject(o.get(), getRandomGenerator());
assert(o->ID == objectID); assert(o->ID == objectID);
@ -4290,7 +4290,7 @@ void CGameHandler::createWanderingMonster(const int3 & visitablePosition, Creatu
cre->character = 2; cre->character = 2;
cre->gainedArtifact = ArtifactID::NONE; cre->gainedArtifact = ArtifactID::NONE;
cre->identifier = -1; cre->identifier = -1;
cre->addToSlot(SlotID(0), std::make_unique<CStackInstance>(gameState()->callback, creature, -1)); //add placeholder stack cre->addToSlot(SlotID(0), std::make_unique<CStackInstance>(gameState()->cb, creature, -1)); //add placeholder stack
newObject(createdObject, PlayerColor::NEUTRAL); newObject(createdObject, PlayerColor::NEUTRAL);
} }

View File

@ -175,7 +175,7 @@ BattleID BattleProcessor::setupBattle(int3 tile, BattleSideArray<const CArmedIns
//send info about battles //send info about battles
BattleStart bs; BattleStart bs;
bs.info = BattleInfo::setupBattle(gameHandler->gameState()->callback, tile, terrain, battlefieldType, armies, heroes, layout, town); bs.info = BattleInfo::setupBattle(gameHandler->gameState()->cb, tile, terrain, battlefieldType, armies, heroes, layout, town);
bs.battleID = gameHandler->gameState()->nextBattleID; bs.battleID = gameHandler->gameState()->nextBattleID;
engageIntoBattle(bs.info->getSide(BattleSide::ATTACKER).color); engageIntoBattle(bs.info->getSide(BattleSide::ATTACKER).color);

View File

@ -48,9 +48,9 @@ public:
void SetUp() override void SetUp() override
{ {
gameState = std::make_shared<CGameState>(); gameState = std::make_shared<CGameState>(gameCallback.get());
gameCallback->setGameState(gameState); gameCallback->setGameState(gameState);
gameState->preInit(&services, gameCallback.get()); gameState->preInit(&services);
} }
void TearDown() override void TearDown() override
@ -196,11 +196,11 @@ public:
auto terrain = t.getTerrainID(); auto terrain = t.getTerrainID();
BattleField terType(0); BattleField terType(0);
BattleLayout layout = BattleLayout::createDefaultLayout(gameState->callback, attacker, defender); BattleLayout layout = BattleLayout::createDefaultLayout(gameState->cb, attacker, defender);
//send info about battles //send info about battles
auto battle = BattleInfo::setupBattle(gameState->callback, tile, terrain, terType, armedInstancies, heroes, layout, nullptr); auto battle = BattleInfo::setupBattle(gameState->cb, tile, terrain, terType, armedInstancies, heroes, layout, nullptr);
BattleStart bs; BattleStart bs;
bs.info = std::move(battle); bs.info = std::move(battle);

View File

@ -24,7 +24,7 @@ NetPackFixture::~NetPackFixture() = default;
void NetPackFixture::setUp() void NetPackFixture::setUp()
{ {
gameState = std::make_shared<GameStateFake>(); gameState = std::make_shared<GameStateFake>(nullptr);
} }

View File

@ -18,6 +18,8 @@ namespace test
class GameStateFake : public CGameState class GameStateFake : public CGameState
{ {
public: public:
using CGameState::CGameState;
MOCK_METHOD3(updateEntity, void(Metatype, int32_t, const JsonNode &)); MOCK_METHOD3(updateEntity, void(Metatype, int32_t, const JsonNode &));
}; };