mirror of
https://github.com/vcmi/vcmi.git
synced 2025-11-25 22:42:04 +02:00
Map objects now use shared_ptr (game)
This commit is contained in:
@@ -625,18 +625,18 @@ void ApplyClientNetPackVisitor::visitSetHeroesInTown(SetHeroesInTown & pack)
|
|||||||
|
|
||||||
void ApplyClientNetPackVisitor::visitHeroRecruited(HeroRecruited & pack)
|
void ApplyClientNetPackVisitor::visitHeroRecruited(HeroRecruited & pack)
|
||||||
{
|
{
|
||||||
CGHeroInstance *h = gs.getMap().heroesOnMap.back();
|
auto & h = gs.getMap().heroesOnMap.back();
|
||||||
if(h->getHeroTypeID() != pack.hid)
|
if(h->getHeroTypeID() != pack.hid)
|
||||||
{
|
{
|
||||||
logNetwork->error("Something wrong with hero recruited!");
|
logNetwork->error("Something wrong with hero recruited!");
|
||||||
}
|
}
|
||||||
|
|
||||||
if(callInterfaceIfPresent(cl, h->tempOwner, &IGameEventsReceiver::heroCreated, h))
|
if(callInterfaceIfPresent(cl, h->tempOwner, &IGameEventsReceiver::heroCreated, h.get()))
|
||||||
{
|
{
|
||||||
if(const CGTownInstance *t = gs.getTown(pack.tid))
|
if(const CGTownInstance *t = gs.getTown(pack.tid))
|
||||||
callInterfaceIfPresent(cl, h->getOwner(), &IGameEventsReceiver::heroInGarrisonChange, t);
|
callInterfaceIfPresent(cl, h->getOwner(), &IGameEventsReceiver::heroInGarrisonChange, t);
|
||||||
}
|
}
|
||||||
GAME->map().onObjectInstantAdd(h, h->getOwner());
|
GAME->map().onObjectInstantAdd(h.get(), h->getOwner());
|
||||||
}
|
}
|
||||||
|
|
||||||
void ApplyClientNetPackVisitor::visitGiveHero(GiveHero & pack)
|
void ApplyClientNetPackVisitor::visitGiveHero(GiveHero & pack)
|
||||||
@@ -1054,7 +1054,7 @@ void ApplyClientNetPackVisitor::visitNewObject(NewObject & pack)
|
|||||||
{
|
{
|
||||||
callAllInterfaces(cl, &CGameInterface::invalidatePaths);
|
callAllInterfaces(cl, &CGameInterface::invalidatePaths);
|
||||||
|
|
||||||
const CGObjectInstance *obj = pack.newObject;
|
const CGObjectInstance * obj = pack.newObject.get();
|
||||||
GAME->map().onObjectFadeIn(obj, pack.initiator);
|
GAME->map().onObjectFadeIn(obj, pack.initiator);
|
||||||
|
|
||||||
for(auto i=cl.playerint.begin(); i!=cl.playerint.end(); i++)
|
for(auto i=cl.playerint.begin(); i!=cl.playerint.end(); i++)
|
||||||
|
|||||||
@@ -209,7 +209,7 @@ MapAudioPlayer::MapAudioPlayer()
|
|||||||
for(const auto & obj : GAME->map().getMap()->objects)
|
for(const auto & obj : GAME->map().getMap()->objects)
|
||||||
{
|
{
|
||||||
if (obj)
|
if (obj)
|
||||||
addObject(obj);
|
addObject(obj.get());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -103,7 +103,7 @@ const MapRendererBaseContext::MapObjectsList & MapRendererBaseContext::getObject
|
|||||||
|
|
||||||
const CGObjectInstance * MapRendererBaseContext::getObject(ObjectInstanceID objectID) const
|
const CGObjectInstance * MapRendererBaseContext::getObject(ObjectInstanceID objectID) const
|
||||||
{
|
{
|
||||||
return GAME->map().getMap()->objects.at(objectID.getNum());
|
return GAME->map().getMap()->objects.at(objectID.getNum()).get();
|
||||||
}
|
}
|
||||||
|
|
||||||
const CGPath * MapRendererBaseContext::currentPath() const
|
const CGPath * MapRendererBaseContext::currentPath() const
|
||||||
|
|||||||
@@ -25,7 +25,7 @@
|
|||||||
static bool compareObjectBlitOrder(ObjectInstanceID left, ObjectInstanceID right)
|
static bool compareObjectBlitOrder(ObjectInstanceID left, ObjectInstanceID right)
|
||||||
{
|
{
|
||||||
//FIXME: remove mh access
|
//FIXME: remove mh access
|
||||||
return GAME->map().compareObjectBlitOrder(GAME->map().getMap()->objects[left.getNum()], GAME->map().getMap()->objects[right.getNum()]);
|
return GAME->map().compareObjectBlitOrder(GAME->map().getMap()->objects.at(left.getNum()).get(), GAME->map().getMap()->objects.at(right.getNum()).get());
|
||||||
}
|
}
|
||||||
|
|
||||||
MapRendererContextState::MapRendererContextState()
|
MapRendererContextState::MapRendererContextState()
|
||||||
@@ -36,7 +36,7 @@ MapRendererContextState::MapRendererContextState()
|
|||||||
|
|
||||||
logGlobal->debug("Loading map objects");
|
logGlobal->debug("Loading map objects");
|
||||||
for(const auto & obj : GAME->map().getMap()->objects)
|
for(const auto & obj : GAME->map().getMap()->objects)
|
||||||
addObject(obj);
|
addObject(obj.get());
|
||||||
logGlobal->debug("Done loading map objects");
|
logGlobal->debug("Done loading map objects");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -139,7 +139,7 @@ const CGObjectInstance* CGameInfoCallback::getObj(ObjectInstanceID objid, bool v
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
const CGObjectInstance *ret = gs->getMap().objects[oid];
|
const CGObjectInstance *ret = gs->getMap().objects[oid].get();
|
||||||
if(!ret)
|
if(!ret)
|
||||||
{
|
{
|
||||||
if(verbose)
|
if(verbose)
|
||||||
@@ -484,8 +484,8 @@ std::vector<const CGObjectInstance *> CGameInfoCallback::getAllVisitableObjs() c
|
|||||||
{
|
{
|
||||||
std::vector<const CGObjectInstance *> ret;
|
std::vector<const CGObjectInstance *> ret;
|
||||||
for(auto & obj : gs->getMap().objects)
|
for(auto & obj : gs->getMap().objects)
|
||||||
if(obj && obj->isVisitable() && obj->ID != Obj::EVENT && isVisible(obj))
|
if(obj && obj->isVisitable() && obj->ID != Obj::EVENT && isVisible(obj.get()))
|
||||||
ret.push_back(obj);
|
ret.push_back(obj.get());
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@@ -784,7 +784,7 @@ std::vector < const CGHeroInstance *> CPlayerSpecificInfoCallback::getHeroesInfo
|
|||||||
if((hero->tempOwner == *getPlayerID()) ||
|
if((hero->tempOwner == *getPlayerID()) ||
|
||||||
(isVisible(hero->visitablePos(), getPlayerID()) && !onlyOur) )
|
(isVisible(hero->visitablePos(), getPlayerID()) && !onlyOur) )
|
||||||
{
|
{
|
||||||
ret.push_back(hero);
|
ret.push_back(hero.get());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
@@ -956,7 +956,7 @@ const CArtifactInstance * CGameInfoCallback::getArtInstance( ArtifactInstanceID
|
|||||||
|
|
||||||
const CGObjectInstance * CGameInfoCallback::getObjInstance( ObjectInstanceID oid ) const
|
const CGObjectInstance * CGameInfoCallback::getObjInstance( ObjectInstanceID oid ) const
|
||||||
{
|
{
|
||||||
return gs->getMap().objects.at(oid.num);
|
return gs->getMap().objects.at(oid.num).get();
|
||||||
}
|
}
|
||||||
|
|
||||||
const CArtifactSet * CGameInfoCallback::getArtSet(const ArtifactLocation & loc) const
|
const CArtifactSet * CGameInfoCallback::getArtSet(const ArtifactLocation & loc) const
|
||||||
|
|||||||
@@ -700,7 +700,6 @@ set(lib_MAIN_HEADERS
|
|||||||
CGameInfoCallback.h
|
CGameInfoCallback.h
|
||||||
CGameInterface.h
|
CGameInterface.h
|
||||||
ConditionalWait.h
|
ConditionalWait.h
|
||||||
ConstTransitivePtr.h
|
|
||||||
Color.h
|
Color.h
|
||||||
CPlayerState.h
|
CPlayerState.h
|
||||||
CRandomGenerator.h
|
CRandomGenerator.h
|
||||||
|
|||||||
@@ -1,80 +0,0 @@
|
|||||||
/*
|
|
||||||
* ConstTransitivePtr.h, part of VCMI engine
|
|
||||||
*
|
|
||||||
* Authors: listed in file AUTHORS in main folder
|
|
||||||
*
|
|
||||||
* License: GNU General Public License v2.0 or later
|
|
||||||
* Full text of license available in license.txt file, in main folder
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
class CGameHandler;
|
|
||||||
|
|
||||||
VCMI_LIB_NAMESPACE_BEGIN
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
class ConstTransitivePtr
|
|
||||||
{
|
|
||||||
T *ptr = nullptr;
|
|
||||||
ConstTransitivePtr(const T *Ptr)
|
|
||||||
: ptr(const_cast<T*>(Ptr))
|
|
||||||
{}
|
|
||||||
public:
|
|
||||||
ConstTransitivePtr(T *Ptr = nullptr)
|
|
||||||
: ptr(Ptr)
|
|
||||||
{}
|
|
||||||
ConstTransitivePtr(std::nullptr_t)
|
|
||||||
{}
|
|
||||||
const T& operator*() const
|
|
||||||
{
|
|
||||||
return *ptr;
|
|
||||||
}
|
|
||||||
T& operator*()
|
|
||||||
{
|
|
||||||
return *ptr;
|
|
||||||
}
|
|
||||||
operator const T*() const
|
|
||||||
{
|
|
||||||
return ptr;
|
|
||||||
}
|
|
||||||
T* get()
|
|
||||||
{
|
|
||||||
return ptr;
|
|
||||||
}
|
|
||||||
const T* get() const
|
|
||||||
{
|
|
||||||
return ptr;
|
|
||||||
}
|
|
||||||
operator T*()
|
|
||||||
{
|
|
||||||
return ptr;
|
|
||||||
}
|
|
||||||
T *operator->()
|
|
||||||
{
|
|
||||||
return ptr;
|
|
||||||
}
|
|
||||||
const T *operator->() const
|
|
||||||
{
|
|
||||||
return ptr;
|
|
||||||
}
|
|
||||||
const T*operator=(T *t)
|
|
||||||
{
|
|
||||||
return ptr = t;
|
|
||||||
}
|
|
||||||
|
|
||||||
void dellNull()
|
|
||||||
{
|
|
||||||
delete ptr;
|
|
||||||
ptr = nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename Handler> void serialize(Handler &h)
|
|
||||||
{
|
|
||||||
h & ptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
friend class ::CGameHandler;
|
|
||||||
};
|
|
||||||
|
|
||||||
VCMI_LIB_NAMESPACE_END
|
|
||||||
@@ -256,7 +256,7 @@ CArtifactInstance * CNonConstInfoCallback::getArtInstance(const ArtifactInstance
|
|||||||
|
|
||||||
CGObjectInstance * CNonConstInfoCallback::getObjInstance(const ObjectInstanceID & oid)
|
CGObjectInstance * CNonConstInfoCallback::getObjInstance(const ObjectInstanceID & oid)
|
||||||
{
|
{
|
||||||
return gs->getMap().objects.at(oid.num);
|
return gs->getMap().objects.at(oid.num).get();
|
||||||
}
|
}
|
||||||
|
|
||||||
CArmedInstance * CNonConstInfoCallback::getArmyInstance(const ObjectInstanceID & oid)
|
CArmedInstance * CNonConstInfoCallback::getArmyInstance(const ObjectInstanceID & oid)
|
||||||
|
|||||||
@@ -327,13 +327,12 @@ std::set<HeroTypeID> CampaignState::getReservedHeroes() const
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
const CGHeroInstance * CampaignState::strongestHero(CampaignScenarioID scenarioId, const PlayerColor & owner) const
|
std::shared_ptr<CGHeroInstance> CampaignState::strongestHero(CampaignScenarioID scenarioId, const PlayerColor & owner) const
|
||||||
{
|
{
|
||||||
std::function<bool(const JsonNode & node)> isOwned = [&](const JsonNode & node)
|
std::function<bool(const JsonNode & node)> isOwned = [&](const JsonNode & node)
|
||||||
{
|
{
|
||||||
auto * h = CampaignState::crossoverDeserialize(node, nullptr);
|
auto h = CampaignState::crossoverDeserialize(node, nullptr);
|
||||||
bool result = h->tempOwner == owner;
|
bool result = h->tempOwner == owner;
|
||||||
vstd::clear_pointer(h);
|
|
||||||
return result;
|
return result;
|
||||||
};
|
};
|
||||||
auto ownedHeroes = scenarioHeroPool.at(scenarioId) | boost::adaptors::filtered(isOwned);
|
auto ownedHeroes = scenarioHeroPool.at(scenarioId) | boost::adaptors::filtered(isOwned);
|
||||||
@@ -475,10 +474,10 @@ JsonNode CampaignState::crossoverSerialize(CGHeroInstance * hero) const
|
|||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
CGHeroInstance * CampaignState::crossoverDeserialize(const JsonNode & node, CMap * map) const
|
std::shared_ptr<CGHeroInstance> CampaignState::crossoverDeserialize(const JsonNode & node, CMap * map) const
|
||||||
{
|
{
|
||||||
JsonDeserializer handler(nullptr, const_cast<JsonNode&>(node));
|
JsonDeserializer handler(nullptr, const_cast<JsonNode&>(node));
|
||||||
auto * hero = new CGHeroInstance(map ? map->cb : nullptr);
|
auto hero = std::make_shared<CGHeroInstance>(map ? map->cb : nullptr);
|
||||||
hero->ID = Obj::HERO;
|
hero->ID = Obj::HERO;
|
||||||
hero->serializeJsonOptions(handler);
|
hero->serializeJsonOptions(handler);
|
||||||
if (map)
|
if (map)
|
||||||
|
|||||||
@@ -350,7 +350,7 @@ public:
|
|||||||
std::set<HeroTypeID> getReservedHeroes() const;
|
std::set<HeroTypeID> getReservedHeroes() const;
|
||||||
|
|
||||||
/// Returns strongest hero from specified scenario, or null if none found
|
/// Returns strongest hero from specified scenario, or null if none found
|
||||||
const CGHeroInstance * strongestHero(CampaignScenarioID scenarioId, const PlayerColor & owner) const;
|
std::shared_ptr<CGHeroInstance> strongestHero(CampaignScenarioID scenarioId, const PlayerColor & owner) const;
|
||||||
|
|
||||||
/// Returns heroes that can be instantiated as hero placeholders by power
|
/// Returns heroes that can be instantiated as hero placeholders by power
|
||||||
const std::vector<JsonNode> & getHeroesByPower(CampaignScenarioID scenarioId) const;
|
const std::vector<JsonNode> & getHeroesByPower(CampaignScenarioID scenarioId) const;
|
||||||
@@ -360,7 +360,7 @@ public:
|
|||||||
const JsonNode & getHeroByType(HeroTypeID heroID) const;
|
const JsonNode & getHeroByType(HeroTypeID heroID) const;
|
||||||
|
|
||||||
JsonNode crossoverSerialize(CGHeroInstance * hero) const;
|
JsonNode crossoverSerialize(CGHeroInstance * hero) const;
|
||||||
CGHeroInstance * crossoverDeserialize(const JsonNode & node, CMap * map) const;
|
std::shared_ptr<CGHeroInstance> crossoverDeserialize(const JsonNode & node, CMap * map) const;
|
||||||
|
|
||||||
std::string campaignSet;
|
std::string campaignSet;
|
||||||
|
|
||||||
|
|||||||
@@ -233,7 +233,7 @@ void CGameState::updateEntity(Metatype metatype, int32_t index, const JsonNode &
|
|||||||
//index is hero type
|
//index is hero type
|
||||||
if(index >= 0 && index < map->allHeroes.size())
|
if(index >= 0 && index < map->allHeroes.size())
|
||||||
{
|
{
|
||||||
CGHeroInstance * hero = map->allHeroes.at(index);
|
const auto & hero = map->allHeroes.at(index);
|
||||||
hero->updateFrom(data);
|
hero->updateFrom(data);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -471,7 +471,7 @@ void CGameState::initRandomFactionsForPlayers()
|
|||||||
void CGameState::randomizeMapObjects()
|
void CGameState::randomizeMapObjects()
|
||||||
{
|
{
|
||||||
logGlobal->debug("\tRandomizing objects");
|
logGlobal->debug("\tRandomizing objects");
|
||||||
for(CGObjectInstance *object : map->objects)
|
for(const auto & object : map->objects)
|
||||||
{
|
{
|
||||||
if(!object)
|
if(!object)
|
||||||
continue;
|
continue;
|
||||||
@@ -495,10 +495,10 @@ void CGameState::randomizeMapObjects()
|
|||||||
|
|
||||||
void CGameState::initOwnedObjects()
|
void CGameState::initOwnedObjects()
|
||||||
{
|
{
|
||||||
for(CGObjectInstance *object : map->objects)
|
for(const auto & object : map->objects)
|
||||||
{
|
{
|
||||||
if (object && object->getOwner().isValidPlayer())
|
if (object && object->getOwner().isValidPlayer())
|
||||||
getPlayerState(object->getOwner())->addOwnedObject(object);
|
getPlayerState(object->getOwner())->addOwnedObject(object.get());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -528,8 +528,8 @@ 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());
|
||||||
CGObjectInstance * obj = handler->create(callback, handler->getTemplates().front());
|
auto object = handler->create(callback, handler->getTemplates().front());
|
||||||
CGHeroInstance * hero = dynamic_cast<CGHeroInstance *>(obj);
|
auto hero = std::dynamic_pointer_cast<CGHeroInstance>(object);
|
||||||
|
|
||||||
hero->ID = Obj::HERO;
|
hero->ID = Obj::HERO;
|
||||||
hero->setHeroType(heroTypeId);
|
hero->setHeroType(heroTypeId);
|
||||||
@@ -587,9 +587,7 @@ void CGameState::initHeroes()
|
|||||||
logGlobal->warn("Hero with uninitialized owner!");
|
logGlobal->warn("Hero with uninitialized owner!");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
hero->initHero(getRandomGenerator());
|
hero->initHero(getRandomGenerator());
|
||||||
map->allHeroes[hero->getHeroTypeID().getNum()] = hero;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// generate boats for all heroes on water
|
// generate boats for all heroes on water
|
||||||
@@ -600,8 +598,8 @@ 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 = dynamic_cast<CGBoat*>(handler->create(callback, nullptr));
|
auto boat = std::dynamic_pointer_cast<CGBoat>(handler->create(callback, nullptr));
|
||||||
handler->configureObject(boat, gs->getRandomGenerator());
|
handler->configureObject(boat.get(), gs->getRandomGenerator());
|
||||||
|
|
||||||
boat->setAnchorPos(hero->anchorPos());
|
boat->setAnchorPos(hero->anchorPos());
|
||||||
boat->appearance = handler->getTemplates().front();
|
boat->appearance = handler->getTemplates().front();
|
||||||
@@ -609,7 +607,7 @@ void CGameState::initHeroes()
|
|||||||
|
|
||||||
map->objects.emplace_back(boat);
|
map->objects.emplace_back(boat);
|
||||||
|
|
||||||
hero->attachToBoat(boat);
|
hero->attachToBoat(boat.get());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -619,7 +617,6 @@ void CGameState::initHeroes()
|
|||||||
{
|
{
|
||||||
auto * hero = dynamic_cast<CGHeroInstance*>(obj.get());
|
auto * hero = dynamic_cast<CGHeroInstance*>(obj.get());
|
||||||
hero->initHero(getRandomGenerator());
|
hero->initHero(getRandomGenerator());
|
||||||
map->allHeroes[hero->getHeroTypeID().getNum()] = hero;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -629,20 +626,18 @@ void CGameState::initHeroes()
|
|||||||
if(!vstd::contains(heroesToCreate, ph->getHeroTypeID()))
|
if(!vstd::contains(heroesToCreate, ph->getHeroTypeID()))
|
||||||
continue;
|
continue;
|
||||||
ph->initHero(getRandomGenerator());
|
ph->initHero(getRandomGenerator());
|
||||||
heroesPool->addHeroToPool(ph);
|
heroesPool->addHeroToPool(ph.get());
|
||||||
heroesToCreate.erase(ph->getHeroTypeID());
|
heroesToCreate.erase(ph->getHeroTypeID());
|
||||||
|
|
||||||
map->allHeroes[ph->getHeroTypeID().getNum()] = ph;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for(const HeroTypeID & htype : heroesToCreate) //all not used allowed heroes go with default state into the pool
|
for(const HeroTypeID & htype : heroesToCreate) //all not used allowed heroes go with default state into the pool
|
||||||
{
|
{
|
||||||
auto * vhi = new CGHeroInstance(callback);
|
auto vhi = std::make_shared<CGHeroInstance>(callback);
|
||||||
vhi->initHero(getRandomGenerator(), htype);
|
vhi->initHero(getRandomGenerator(), htype);
|
||||||
|
|
||||||
int typeID = htype.getNum();
|
int typeID = htype.getNum();
|
||||||
map->allHeroes[typeID] = vhi;
|
map->allHeroes[typeID] = vhi;
|
||||||
heroesPool->addHeroToPool(vhi);
|
heroesPool->addHeroToPool(vhi.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
for(auto & elem : map->disposedHeroes)
|
for(auto & elem : map->disposedHeroes)
|
||||||
@@ -663,7 +658,7 @@ void CGameState::initFogOfWar()
|
|||||||
fow.resize(boost::extents[layers][map->width][map->height]);
|
fow.resize(boost::extents[layers][map->width][map->height]);
|
||||||
std::fill(fow.data(), fow.data() + fow.num_elements(), 0);
|
std::fill(fow.data(), fow.data() + fow.num_elements(), 0);
|
||||||
|
|
||||||
for(CGObjectInstance *obj : map->objects)
|
for(const auto & obj : map->objects)
|
||||||
{
|
{
|
||||||
if(!obj || !vstd::contains(elem.second.players, obj->tempOwner)) continue; //not a flagged object
|
if(!obj || !vstd::contains(elem.second.players, obj->tempOwner)) continue; //not a flagged object
|
||||||
|
|
||||||
@@ -918,14 +913,13 @@ void CGameState::initMapObjects()
|
|||||||
{
|
{
|
||||||
logGlobal->debug("\tObject initialization");
|
logGlobal->debug("\tObject initialization");
|
||||||
|
|
||||||
// objCaller->preInit();
|
for(auto & obj : map->objects)
|
||||||
for(CGObjectInstance *obj : map->objects)
|
|
||||||
{
|
{
|
||||||
if(obj)
|
if(obj)
|
||||||
obj->initObj(getRandomGenerator());
|
obj->initObj(getRandomGenerator());
|
||||||
}
|
}
|
||||||
logGlobal->debug("\tObject initialization done");
|
logGlobal->debug("\tObject initialization done");
|
||||||
for(CGObjectInstance *obj : map->objects)
|
for(auto & obj : map->objects)
|
||||||
{
|
{
|
||||||
if(!obj)
|
if(!obj)
|
||||||
continue;
|
continue;
|
||||||
@@ -935,7 +929,7 @@ void CGameState::initMapObjects()
|
|||||||
case Obj::QUEST_GUARD:
|
case Obj::QUEST_GUARD:
|
||||||
case Obj::SEER_HUT:
|
case Obj::SEER_HUT:
|
||||||
{
|
{
|
||||||
auto * q = dynamic_cast<CGSeerHut *>(obj);
|
auto * q = dynamic_cast<CGSeerHut *>(obj.get());
|
||||||
assert (q);
|
assert (q);
|
||||||
q->setObjToKill();
|
q->setObjToKill();
|
||||||
}
|
}
|
||||||
@@ -1001,9 +995,7 @@ void CGameState::initVisitingAndGarrisonedHeroes()
|
|||||||
for (auto hero : map->heroesOnMap)
|
for (auto hero : map->heroesOnMap)
|
||||||
{
|
{
|
||||||
if (hero->getVisitedTown())
|
if (hero->getVisitedTown())
|
||||||
{
|
assert(hero->getVisitedTown()->getVisitingHero() == hero.get());
|
||||||
assert (hero->getVisitedTown()->getVisitingHero() == hero);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1577,7 +1569,7 @@ void CGameState::buildBonusSystemTree()
|
|||||||
buildGlobalTeamPlayerTree();
|
buildGlobalTeamPlayerTree();
|
||||||
attachArmedObjects();
|
attachArmedObjects();
|
||||||
|
|
||||||
for(CGTownInstance *t : map->towns)
|
for(auto & t : map->towns)
|
||||||
{
|
{
|
||||||
t->deserializationFix();
|
t->deserializationFix();
|
||||||
}
|
}
|
||||||
@@ -1607,9 +1599,9 @@ void CGameState::buildGlobalTeamPlayerTree()
|
|||||||
|
|
||||||
void CGameState::attachArmedObjects()
|
void CGameState::attachArmedObjects()
|
||||||
{
|
{
|
||||||
for(CGObjectInstance *obj : map->objects)
|
for(auto & obj : map->objects)
|
||||||
{
|
{
|
||||||
if(auto * armed = dynamic_cast<CArmedInstance *>(obj))
|
if(auto * armed = dynamic_cast<CArmedInstance *>(obj.get()))
|
||||||
{
|
{
|
||||||
armed->whatShouldBeAttached().attachTo(armed->whereShouldBeAttached(this));
|
armed->whatShouldBeAttached().attachTo(armed->whereShouldBeAttached(this));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -34,7 +34,7 @@
|
|||||||
|
|
||||||
VCMI_LIB_NAMESPACE_BEGIN
|
VCMI_LIB_NAMESPACE_BEGIN
|
||||||
|
|
||||||
CampaignHeroReplacement::CampaignHeroReplacement(CGHeroInstance * hero, const ObjectInstanceID & heroPlaceholderId):
|
CampaignHeroReplacement::CampaignHeroReplacement(std::shared_ptr<CGHeroInstance> hero, const ObjectInstanceID & heroPlaceholderId):
|
||||||
hero(hero),
|
hero(hero),
|
||||||
heroPlaceholderId(heroPlaceholderId)
|
heroPlaceholderId(heroPlaceholderId)
|
||||||
{
|
{
|
||||||
@@ -227,7 +227,7 @@ void CGameStateCampaign::placeCampaignHeroes()
|
|||||||
// remove same heroes on the map which will be added through crossover heroes
|
// remove same heroes on the map which will be added through crossover heroes
|
||||||
// INFO: we will remove heroes because later it may be possible that the API doesn't allow having heroes
|
// INFO: we will remove heroes because later it may be possible that the API doesn't allow having heroes
|
||||||
// with the same hero type id
|
// with the same hero type id
|
||||||
std::vector<CGHeroInstance *> removedHeroes;
|
std::vector<std::shared_ptr<CGObjectInstance>> removedHeroes;
|
||||||
|
|
||||||
std::set<HeroTypeID> reservedHeroes = campaignState->getReservedHeroes();
|
std::set<HeroTypeID> reservedHeroes = campaignState->getReservedHeroes();
|
||||||
std::set<HeroTypeID> heroesToRemove;
|
std::set<HeroTypeID> heroesToRemove;
|
||||||
@@ -248,10 +248,7 @@ void CGameStateCampaign::placeCampaignHeroes()
|
|||||||
auto * hero = gameState->getUsedHero(heroID);
|
auto * hero = gameState->getUsedHero(heroID);
|
||||||
if(hero)
|
if(hero)
|
||||||
{
|
{
|
||||||
removedHeroes.push_back(hero);
|
removedHeroes.push_back(gameState->map->eraseObject(hero->id));
|
||||||
gameState->map->heroesOnMap -= hero;
|
|
||||||
gameState->map->objects[hero->id.getNum()] = nullptr;
|
|
||||||
gameState->map->removeBlockVisTiles(hero, true);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -259,8 +256,9 @@ void CGameStateCampaign::placeCampaignHeroes()
|
|||||||
replaceHeroesPlaceholders();
|
replaceHeroesPlaceholders();
|
||||||
|
|
||||||
// now add removed heroes again with unused type ID
|
// now add removed heroes again with unused type ID
|
||||||
for(auto * hero : removedHeroes)
|
for(auto object : removedHeroes)
|
||||||
{
|
{
|
||||||
|
auto hero = dynamic_cast<CGHeroInstance*>(object.get());
|
||||||
HeroTypeID heroTypeId;
|
HeroTypeID heroTypeId;
|
||||||
if(hero->ID == Obj::HERO)
|
if(hero->ID == Obj::HERO)
|
||||||
{
|
{
|
||||||
@@ -285,7 +283,7 @@ void CGameStateCampaign::placeCampaignHeroes()
|
|||||||
}
|
}
|
||||||
|
|
||||||
hero->setHeroType(heroTypeId);
|
hero->setHeroType(heroTypeId);
|
||||||
gameState->map->getEditManager()->insertObject(hero);
|
gameState->map->getEditManager()->insertObject(object);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -363,26 +361,18 @@ void CGameStateCampaign::replaceHeroesPlaceholders()
|
|||||||
if (!campaignHeroReplacement.heroPlaceholderId.hasValue())
|
if (!campaignHeroReplacement.heroPlaceholderId.hasValue())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
auto * heroPlaceholder = dynamic_cast<CGHeroPlaceholder *>(gameState->getObjInstance(campaignHeroReplacement.heroPlaceholderId));
|
auto heroPlaceholder = gameState->map->objects.at(campaignHeroReplacement.heroPlaceholderId.getNum());
|
||||||
|
auto heroToPlace = campaignHeroReplacement.hero;
|
||||||
|
|
||||||
CGHeroInstance *heroToPlace = campaignHeroReplacement.hero;
|
|
||||||
heroToPlace->id = campaignHeroReplacement.heroPlaceholderId;
|
|
||||||
if(heroPlaceholder->tempOwner.isValidPlayer())
|
if(heroPlaceholder->tempOwner.isValidPlayer())
|
||||||
heroToPlace->tempOwner = heroPlaceholder->tempOwner;
|
heroToPlace->tempOwner = heroPlaceholder->tempOwner;
|
||||||
|
|
||||||
|
// FIXME: consider whether to move these actions to CMap::replaceObject method
|
||||||
heroToPlace->setAnchorPos(heroPlaceholder->anchorPos());
|
heroToPlace->setAnchorPos(heroPlaceholder->anchorPos());
|
||||||
heroToPlace->setHeroType(heroToPlace->getHeroTypeID());
|
heroToPlace->setHeroType(heroToPlace->getHeroTypeID());
|
||||||
heroToPlace->appearance = heroToPlace->getObjectHandler()->getTemplates().front();
|
heroToPlace->appearance = heroToPlace->getObjectHandler()->getTemplates().front();
|
||||||
|
|
||||||
gameState->map->removeBlockVisTiles(heroPlaceholder, true);
|
gameState->map->replaceObject(campaignHeroReplacement.heroPlaceholderId, heroToPlace);
|
||||||
gameState->map->objects[heroPlaceholder->id.getNum()] = nullptr;
|
|
||||||
gameState->map->instanceNames.erase(heroPlaceholder->instanceName);
|
|
||||||
|
|
||||||
gameState->map->heroesOnMap.emplace_back(heroToPlace);
|
|
||||||
gameState->map->objects[heroToPlace->id.getNum()] = heroToPlace;
|
|
||||||
gameState->map->addBlockVisTiles(heroToPlace);
|
|
||||||
gameState->map->instanceNames[heroToPlace->instanceName] = heroToPlace;
|
|
||||||
|
|
||||||
delete heroPlaceholder;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -413,7 +403,7 @@ void CGameStateCampaign::transferMissingArtifacts(const CampaignTravel & travelO
|
|||||||
if (campaignHeroReplacement.heroPlaceholderId.hasValue())
|
if (campaignHeroReplacement.heroPlaceholderId.hasValue())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
auto * donorHero = campaignHeroReplacement.hero;
|
auto donorHero = campaignHeroReplacement.hero;
|
||||||
|
|
||||||
if (!donorHero)
|
if (!donorHero)
|
||||||
throw std::runtime_error("Failed to find hero to take artifacts from! Scenario: " + gameState->map->name.toString());
|
throw std::runtime_error("Failed to find hero to take artifacts from! Scenario: " + gameState->map->name.toString());
|
||||||
@@ -440,7 +430,8 @@ void CGameStateCampaign::transferMissingArtifacts(const CampaignTravel & travelO
|
|||||||
logGlobal->error("Cannot transfer artifact - no receiver hero!");
|
logGlobal->error("Cannot transfer artifact - no receiver hero!");
|
||||||
}
|
}
|
||||||
|
|
||||||
delete donorHero;
|
// FIXME: erase entry from array? clear entire campaignHeroReplacements?
|
||||||
|
//campaignHeroReplacement.hero.reset();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -484,7 +475,7 @@ void CGameStateCampaign::generateCampaignHeroesToReplace()
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
CGHeroInstance * hero = campaignState->crossoverDeserialize(node, gameState->map.get());
|
auto hero = campaignState->crossoverDeserialize(node, gameState->map.get());
|
||||||
|
|
||||||
logGlobal->info("Hero crossover: Loading placeholder for %d (%s)", hero->getHeroType(), hero->getNameTranslated());
|
logGlobal->info("Hero crossover: Loading placeholder for %d (%s)", hero->getHeroType(), hero->getNameTranslated());
|
||||||
|
|
||||||
@@ -509,7 +500,7 @@ void CGameStateCampaign::generateCampaignHeroesToReplace()
|
|||||||
if (nodeListIter == nodeList.end())
|
if (nodeListIter == nodeList.end())
|
||||||
break;
|
break;
|
||||||
|
|
||||||
CGHeroInstance * hero = campaignState->crossoverDeserialize(*nodeListIter, gameState->map.get());
|
auto hero = campaignState->crossoverDeserialize(*nodeListIter, gameState->map.get());
|
||||||
nodeListIter++;
|
nodeListIter++;
|
||||||
|
|
||||||
logGlobal->info("Hero crossover: Loading placeholder as %d (%s)", hero->getHeroType(), hero->getNameTranslated());
|
logGlobal->info("Hero crossover: Loading placeholder as %d (%s)", hero->getHeroType(), hero->getNameTranslated());
|
||||||
@@ -520,7 +511,7 @@ void CGameStateCampaign::generateCampaignHeroesToReplace()
|
|||||||
// Add remaining heroes without placeholders - to transfer their artifacts to placed heroes
|
// Add remaining heroes without placeholders - to transfer their artifacts to placed heroes
|
||||||
for (;nodeListIter != nodeList.end(); ++nodeListIter)
|
for (;nodeListIter != nodeList.end(); ++nodeListIter)
|
||||||
{
|
{
|
||||||
CGHeroInstance * hero = campaignState->crossoverDeserialize(*nodeListIter, gameState->map.get());
|
auto hero = campaignState->crossoverDeserialize(*nodeListIter, gameState->map.get());
|
||||||
campaignHeroReplacements.emplace_back(hero, ObjectInstanceID::NONE);
|
campaignHeroReplacements.emplace_back(hero, ObjectInstanceID::NONE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -645,7 +636,7 @@ void CGameStateCampaign::initTowns()
|
|||||||
|
|
||||||
for (int g=0; g<gameState->map->towns.size(); ++g)
|
for (int g=0; g<gameState->map->towns.size(); ++g)
|
||||||
{
|
{
|
||||||
CGTownInstance * town = gameState->map->towns[g];
|
auto town = gameState->map->towns[g];
|
||||||
|
|
||||||
PlayerState * owner = gameState->getPlayerState(town->getOwner());
|
PlayerState * owner = gameState->getPlayerState(town->getOwner());
|
||||||
if (!owner)
|
if (!owner)
|
||||||
|
|||||||
@@ -23,8 +23,8 @@ class CMap;
|
|||||||
|
|
||||||
struct CampaignHeroReplacement
|
struct CampaignHeroReplacement
|
||||||
{
|
{
|
||||||
CampaignHeroReplacement(CGHeroInstance * hero, const ObjectInstanceID & heroPlaceholderId);
|
CampaignHeroReplacement(std::shared_ptr<CGHeroInstance> hero, const ObjectInstanceID & heroPlaceholderId);
|
||||||
CGHeroInstance * hero;
|
std::shared_ptr<CGHeroInstance> hero;
|
||||||
ObjectInstanceID heroPlaceholderId;
|
ObjectInstanceID heroPlaceholderId;
|
||||||
std::vector<ArtifactPosition> transferrableArtifacts;
|
std::vector<ArtifactPosition> transferrableArtifacts;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -188,34 +188,6 @@ std::string StatisticDataSet::writeCsv()
|
|||||||
return filePath.string();
|
return filePath.string();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<const CGMine *> Statistic::getMines(const CGameState * gs, const PlayerState * ps)
|
|
||||||
{
|
|
||||||
std::vector<const CGMine *> tmp;
|
|
||||||
|
|
||||||
std::vector<const CGObjectInstance *> ownedObjects;
|
|
||||||
for(const CGObjectInstance * obj : gs->getMap().objects)
|
|
||||||
{
|
|
||||||
if(obj && obj->tempOwner == ps->color)
|
|
||||||
ownedObjects.push_back(obj);
|
|
||||||
}
|
|
||||||
/// This is code from CPlayerSpecificInfoCallback::getMyObjects
|
|
||||||
/// I'm really need to find out about callback interface design...
|
|
||||||
|
|
||||||
for(const auto * object : ownedObjects)
|
|
||||||
{
|
|
||||||
//Mines
|
|
||||||
if ( object->ID == Obj::MINE )
|
|
||||||
{
|
|
||||||
const auto * mine = dynamic_cast<const CGMine *>(object);
|
|
||||||
assert(mine);
|
|
||||||
|
|
||||||
tmp.push_back(mine);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return tmp;
|
|
||||||
}
|
|
||||||
|
|
||||||
//calculates total number of artifacts that belong to given player
|
//calculates total number of artifacts that belong to given player
|
||||||
int Statistic::getNumberOfArts(const PlayerState * ps)
|
int Statistic::getNumberOfArts(const PlayerState * ps)
|
||||||
{
|
{
|
||||||
@@ -267,15 +239,8 @@ int Statistic::getIncome(const CGameState * gs, const PlayerState * ps)
|
|||||||
int totalIncome = 0;
|
int totalIncome = 0;
|
||||||
|
|
||||||
//Heroes can produce gold as well - skill, specialty or arts
|
//Heroes can produce gold as well - skill, specialty or arts
|
||||||
for(const auto & h : ps->getHeroes())
|
for(const auto & object : ps->getOwnedObjects())
|
||||||
totalIncome += h->dailyIncome()[EGameResID::GOLD];
|
totalIncome += object->asOwnable()->dailyIncome()[EGameResID::GOLD];
|
||||||
|
|
||||||
//Add town income of all towns
|
|
||||||
for(const auto & t : ps->getTowns())
|
|
||||||
totalIncome += t->dailyIncome()[EGameResID::GOLD];
|
|
||||||
|
|
||||||
for(const CGMine * mine : getMines(gs, ps))
|
|
||||||
totalIncome += mine->dailyIncome()[EGameResID::GOLD];
|
|
||||||
|
|
||||||
return totalIncome;
|
return totalIncome;
|
||||||
}
|
}
|
||||||
@@ -366,9 +331,16 @@ std::map<EGameResID, int> Statistic::getNumMines(const CGameState * gs, const Pl
|
|||||||
for(auto & res : EGameResID::ALL_RESOURCES())
|
for(auto & res : EGameResID::ALL_RESOURCES())
|
||||||
tmp[res] = 0;
|
tmp[res] = 0;
|
||||||
|
|
||||||
for(const CGMine * mine : getMines(gs, ps))
|
for(const auto * object : ps->getOwnedObjects())
|
||||||
|
{
|
||||||
|
//Mines
|
||||||
|
if ( object->ID == Obj::MINE )
|
||||||
|
{
|
||||||
|
const auto * mine = dynamic_cast<const CGMine *>(object);
|
||||||
|
assert(mine);
|
||||||
tmp[mine->producedResource]++;
|
tmp[mine->producedResource]++;
|
||||||
|
}
|
||||||
|
}
|
||||||
return tmp;
|
return tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -148,7 +148,6 @@ public:
|
|||||||
|
|
||||||
class DLL_LINKAGE Statistic
|
class DLL_LINKAGE Statistic
|
||||||
{
|
{
|
||||||
static std::vector<const CGMine *> getMines(const CGameState * gs, const PlayerState * ps);
|
|
||||||
public:
|
public:
|
||||||
static int getNumberOfArts(const PlayerState * ps);
|
static int getNumberOfArts(const PlayerState * ps);
|
||||||
static int getNumberOfDwellings(const PlayerState * ps);
|
static int getNumberOfDwellings(const PlayerState * ps);
|
||||||
|
|||||||
@@ -116,7 +116,7 @@ public:
|
|||||||
|
|
||||||
/// Creates object and set up core properties (like ID/subID). Object is NOT initialized
|
/// Creates object and set up core properties (like ID/subID). Object is NOT initialized
|
||||||
/// to allow creating objects before game start (e.g. map loading)
|
/// to allow creating objects before game start (e.g. map loading)
|
||||||
virtual CGObjectInstance * create(IGameCallback * cb, std::shared_ptr<const ObjectTemplate> tmpl) const = 0;
|
virtual std::shared_ptr<CGObjectInstance> create(IGameCallback * cb, std::shared_ptr<const ObjectTemplate> tmpl) const = 0;
|
||||||
|
|
||||||
/// Configures object properties. Should be re-entrable, resetting state of the object if necessarily
|
/// Configures object properties. Should be re-entrable, resetting state of the object if necessarily
|
||||||
/// This should set remaining properties, including randomized or depending on map
|
/// This should set remaining properties, including randomized or depending on map
|
||||||
|
|||||||
@@ -27,16 +27,16 @@ class CDefaultObjectTypeHandler : public AObjectTypeHandler
|
|||||||
randomizeObject(castedObject, rng);
|
randomizeObject(castedObject, rng);
|
||||||
}
|
}
|
||||||
|
|
||||||
CGObjectInstance * create(IGameCallback * cb, std::shared_ptr<const ObjectTemplate> tmpl) const final
|
std::shared_ptr<CGObjectInstance> create(IGameCallback * cb, std::shared_ptr<const ObjectTemplate> tmpl) const final
|
||||||
{
|
{
|
||||||
ObjectType * result = createObject(cb);
|
auto result = createObject(cb);
|
||||||
|
|
||||||
preInitObject(result);
|
preInitObject(result.get());
|
||||||
|
|
||||||
if(tmpl)
|
if(tmpl)
|
||||||
result->appearance = tmpl;
|
result->appearance = tmpl;
|
||||||
|
|
||||||
initializeObject(result);
|
initializeObject(result.get());
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@@ -44,9 +44,9 @@ class CDefaultObjectTypeHandler : public AObjectTypeHandler
|
|||||||
protected:
|
protected:
|
||||||
virtual void initializeObject(ObjectType * object) const {}
|
virtual void initializeObject(ObjectType * object) const {}
|
||||||
virtual void randomizeObject(ObjectType * object, vstd::RNG & rng) const {}
|
virtual void randomizeObject(ObjectType * object, vstd::RNG & rng) const {}
|
||||||
virtual ObjectType * createObject(IGameCallback * cb) const
|
virtual std::shared_ptr<ObjectType> createObject(IGameCallback * cb) const
|
||||||
{
|
{
|
||||||
return new ObjectType(cb);
|
return std::make_shared<ObjectType>(cb);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -37,10 +37,10 @@ bool CRewardableConstructor::hasNameTextID() const
|
|||||||
return !objectInfo.getParameters()["name"].isNull();
|
return !objectInfo.getParameters()["name"].isNull();
|
||||||
}
|
}
|
||||||
|
|
||||||
CGObjectInstance * CRewardableConstructor::create(IGameCallback * cb, std::shared_ptr<const ObjectTemplate> tmpl) const
|
std::shared_ptr<CGObjectInstance> CRewardableConstructor::create(IGameCallback * cb, std::shared_ptr<const ObjectTemplate> tmpl) const
|
||||||
{
|
{
|
||||||
auto * ret = new CRewardableObject(cb);
|
auto ret = std::make_shared<CRewardableObject>(cb);
|
||||||
preInitObject(ret);
|
preInitObject(ret.get());
|
||||||
ret->appearance = tmpl;
|
ret->appearance = tmpl;
|
||||||
ret->blockVisit = blockVisit;
|
ret->blockVisit = blockVisit;
|
||||||
return ret;
|
return ret;
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ class DLL_LINKAGE CRewardableConstructor : public AObjectTypeHandler
|
|||||||
public:
|
public:
|
||||||
bool hasNameTextID() const override;
|
bool hasNameTextID() const override;
|
||||||
|
|
||||||
CGObjectInstance * create(IGameCallback * cb, std::shared_ptr<const ObjectTemplate> tmpl = nullptr) const override;
|
std::shared_ptr<CGObjectInstance> create(IGameCallback * cb, std::shared_ptr<const ObjectTemplate> tmpl = nullptr) const override;
|
||||||
|
|
||||||
void configureObject(CGObjectInstance * object, vstd::RNG & rng) const override;
|
void configureObject(CGObjectInstance * object, vstd::RNG & rng) const override;
|
||||||
|
|
||||||
|
|||||||
@@ -320,7 +320,7 @@ bool MarketInstanceConstructor::hasDescription() const
|
|||||||
return !descriptionTextID.empty();
|
return !descriptionTextID.empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
CGMarket * MarketInstanceConstructor::createObject(IGameCallback * cb) const
|
std::shared_ptr<CGMarket> MarketInstanceConstructor::createObject(IGameCallback * cb) const
|
||||||
{
|
{
|
||||||
if(marketModes.size() == 1)
|
if(marketModes.size() == 1)
|
||||||
{
|
{
|
||||||
@@ -328,13 +328,13 @@ CGMarket * MarketInstanceConstructor::createObject(IGameCallback * cb) const
|
|||||||
{
|
{
|
||||||
case EMarketMode::ARTIFACT_RESOURCE:
|
case EMarketMode::ARTIFACT_RESOURCE:
|
||||||
case EMarketMode::RESOURCE_ARTIFACT:
|
case EMarketMode::RESOURCE_ARTIFACT:
|
||||||
return new CGBlackMarket(cb);
|
return std::make_shared<CGBlackMarket>(cb);
|
||||||
|
|
||||||
case EMarketMode::RESOURCE_SKILL:
|
case EMarketMode::RESOURCE_SKILL:
|
||||||
return new CGUniversity(cb);
|
return std::make_shared<CGUniversity>(cb);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return new CGMarket(cb);
|
return std::make_shared<CGMarket>(cb);
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::set<EMarketMode> & MarketInstanceConstructor::availableModes() const
|
const std::set<EMarketMode> & MarketInstanceConstructor::availableModes() const
|
||||||
|
|||||||
@@ -137,7 +137,7 @@ class MarketInstanceConstructor : public CDefaultObjectTypeHandler<CGMarket>
|
|||||||
|
|
||||||
void initTypeData(const JsonNode & config) override;
|
void initTypeData(const JsonNode & config) override;
|
||||||
public:
|
public:
|
||||||
CGMarket * createObject(IGameCallback * cb) const override;
|
std::shared_ptr<CGMarket> createObject(IGameCallback * cb) const override;
|
||||||
void randomizeObject(CGMarket * object, vstd::RNG & rng) const override;
|
void randomizeObject(CGMarket * object, vstd::RNG & rng) const override;
|
||||||
|
|
||||||
const std::set<EMarketMode> & availableModes() const;
|
const std::set<EMarketMode> & availableModes() const;
|
||||||
|
|||||||
@@ -1604,13 +1604,12 @@ std::string CGHeroInstance::getHeroTypeName() const
|
|||||||
|
|
||||||
void CGHeroInstance::afterAddToMap(CMap * map)
|
void CGHeroInstance::afterAddToMap(CMap * map)
|
||||||
{
|
{
|
||||||
if(ID != Obj::PRISON)
|
map->heroAddedToMap(this);
|
||||||
map->heroesOnMap.emplace_back(this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CGHeroInstance::afterRemoveFromMap(CMap* map)
|
void CGHeroInstance::afterRemoveFromMap(CMap* map)
|
||||||
{
|
{
|
||||||
if (ID == Obj::PRISON)
|
map->heroRemovedFromMap(this);
|
||||||
vstd::erase_if_present(map->heroesOnMap, this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CGHeroInstance::setHeroTypeName(const std::string & identifier)
|
void CGHeroInstance::setHeroTypeName(const std::string & identifier)
|
||||||
|
|||||||
@@ -1058,12 +1058,12 @@ void CGTownInstance::onTownCaptured(const PlayerColor & winner) const
|
|||||||
|
|
||||||
void CGTownInstance::afterAddToMap(CMap * map)
|
void CGTownInstance::afterAddToMap(CMap * map)
|
||||||
{
|
{
|
||||||
map->towns.emplace_back(this);
|
map->townAddedToMap(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CGTownInstance::afterRemoveFromMap(CMap * map)
|
void CGTownInstance::afterRemoveFromMap(CMap * map)
|
||||||
{
|
{
|
||||||
vstd::erase_if_present(map->towns, this);
|
map->townRemovedFromMap(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CGTownInstance::serializeJsonOptions(JsonSerializeFormat & handler)
|
void CGTownInstance::serializeJsonOptions(JsonSerializeFormat & handler)
|
||||||
|
|||||||
@@ -948,10 +948,10 @@ void CGMagi::onHeroVisit(const CGHeroInstance * h) const
|
|||||||
|
|
||||||
std::vector<const CGObjectInstance *> eyes;
|
std::vector<const CGObjectInstance *> eyes;
|
||||||
|
|
||||||
for (auto object : cb->gameState()->getMap().objects)
|
for (const auto & object : cb->gameState()->getMap().objects)
|
||||||
{
|
{
|
||||||
if (object && object->ID == Obj::EYE_OF_MAGI && object->subID == this->subID)
|
if (object && object->ID == Obj::EYE_OF_MAGI && object->subID == this->subID)
|
||||||
eyes.push_back(object);
|
eyes.push_back(object.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!eyes.empty())
|
if (!eyes.empty())
|
||||||
|
|||||||
@@ -191,9 +191,6 @@ CMap::~CMap()
|
|||||||
{
|
{
|
||||||
getEditManager()->getUndoManager().clearAll();
|
getEditManager()->getUndoManager().clearAll();
|
||||||
|
|
||||||
for(auto obj : objects)
|
|
||||||
obj.dellNull();
|
|
||||||
|
|
||||||
resetStaticData();
|
resetStaticData();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -260,7 +257,7 @@ CGHeroInstance * CMap::getHero(HeroTypeID heroID)
|
|||||||
{
|
{
|
||||||
for(auto & elem : heroesOnMap)
|
for(auto & elem : heroesOnMap)
|
||||||
if(elem->getHeroTypeID() == heroID)
|
if(elem->getHeroTypeID() == heroID)
|
||||||
return elem;
|
return elem.get();
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -377,16 +374,16 @@ const CGObjectInstance * CMap::getObjectiveObjectFrom(const int3 & pos, Obj type
|
|||||||
logGlobal->error("Will try to find closest matching object");
|
logGlobal->error("Will try to find closest matching object");
|
||||||
|
|
||||||
CGObjectInstance * bestMatch = nullptr;
|
CGObjectInstance * bestMatch = nullptr;
|
||||||
for (CGObjectInstance * object : objects)
|
for (const auto & object : objects)
|
||||||
{
|
{
|
||||||
if (object && object->ID == type)
|
if (object && object->ID == type)
|
||||||
{
|
{
|
||||||
if (bestMatch == nullptr)
|
if (bestMatch == nullptr)
|
||||||
bestMatch = object;
|
bestMatch = object.get();
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (object->anchorPos().dist2dSQ(pos) < bestMatch->anchorPos().dist2dSQ(pos))
|
if (object->anchorPos().dist2dSQ(pos) < bestMatch->anchorPos().dist2dSQ(pos))
|
||||||
bestMatch = object;// closer than one we already found
|
bestMatch = object.get();// closer than one we already found
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -424,32 +421,32 @@ void CMap::checkForObjectives()
|
|||||||
cond.objectID = getObjectiveObjectFrom(cond.position, Obj::TOWN)->id;
|
cond.objectID = getObjectiveObjectFrom(cond.position, Obj::TOWN)->id;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case EventCondition::CONTROL:
|
// case EventCondition::CONTROL:
|
||||||
if (isInTheMap(cond.position))
|
// if (isInTheMap(cond.position))
|
||||||
cond.objectID = getObjectiveObjectFrom(cond.position, cond.objectType.as<MapObjectID>())->id;
|
// cond.objectID = getObjectiveObjectFrom(cond.position, cond.objectType.as<MapObjectID>())->id;
|
||||||
|
//
|
||||||
if (cond.objectID != ObjectInstanceID::NONE)
|
// if (cond.objectID != ObjectInstanceID::NONE)
|
||||||
{
|
// {
|
||||||
const auto * town = dynamic_cast<const CGTownInstance *>(objects[cond.objectID].get());
|
// const auto * town = dynamic_cast<const CGTownInstance *>(objects[cond.objectID].get());
|
||||||
if (town)
|
// if (town)
|
||||||
event.onFulfill.replaceRawString(town->getNameTranslated());
|
// event.onFulfill.replaceRawString(town->getNameTranslated());
|
||||||
const auto * hero = dynamic_cast<const CGHeroInstance *>(objects[cond.objectID].get());
|
// const auto * hero = dynamic_cast<const CGHeroInstance *>(objects[cond.objectID].get());
|
||||||
if (hero)
|
// if (hero)
|
||||||
event.onFulfill.replaceRawString(hero->getNameTranslated());
|
// event.onFulfill.replaceRawString(hero->getNameTranslated());
|
||||||
}
|
// }
|
||||||
break;
|
// break;
|
||||||
|
//
|
||||||
case EventCondition::DESTROY:
|
// case EventCondition::DESTROY:
|
||||||
if (isInTheMap(cond.position))
|
// if (isInTheMap(cond.position))
|
||||||
cond.objectID = getObjectiveObjectFrom(cond.position, cond.objectType.as<MapObjectID>())->id;
|
// cond.objectID = getObjectiveObjectFrom(cond.position, cond.objectType.as<MapObjectID>())->id;
|
||||||
|
//
|
||||||
if (cond.objectID != ObjectInstanceID::NONE)
|
// if (cond.objectID != ObjectInstanceID::NONE)
|
||||||
{
|
// {
|
||||||
const auto * hero = dynamic_cast<const CGHeroInstance *>(objects[cond.objectID].get());
|
// const auto * hero = dynamic_cast<const CGHeroInstance *>(objects[cond.objectID].get());
|
||||||
if (hero)
|
// if (hero)
|
||||||
event.onFulfill.replaceRawString(hero->getNameTranslated());
|
// event.onFulfill.replaceRawString(hero->getNameTranslated());
|
||||||
}
|
// }
|
||||||
break;
|
// break;
|
||||||
case EventCondition::TRANSPORT:
|
case EventCondition::TRANSPORT:
|
||||||
cond.objectID = getObjectiveObjectFrom(cond.position, Obj::TOWN)->id;
|
cond.objectID = getObjectiveObjectFrom(cond.position, Obj::TOWN)->id;
|
||||||
break;
|
break;
|
||||||
@@ -527,63 +524,89 @@ void CMap::clearQuestInstance(const CQuest * quest)
|
|||||||
quests.at(quest->qid) = nullptr;
|
quests.at(quest->qid) = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CMap::setUniqueInstanceName(CGObjectInstance * obj)
|
//void CMap::setUniqueInstanceName(CGObjectInstance * obj)
|
||||||
{
|
//{
|
||||||
//this gives object unique name even if objects are removed later
|
// //this gives object unique name even if objects are removed later
|
||||||
|
//
|
||||||
|
// auto uid = uidCounter++;
|
||||||
|
//
|
||||||
|
// boost::format fmt("%s_%d");
|
||||||
|
// fmt % obj->getTypeName() % uid;
|
||||||
|
// obj->instanceName = fmt.str();
|
||||||
|
//}
|
||||||
|
|
||||||
auto uid = uidCounter++;
|
//void CMap::addNewObject(CGObjectInstance * obj)
|
||||||
|
//{
|
||||||
|
// if(obj->id != ObjectInstanceID(static_cast<si32>(objects.size())))
|
||||||
|
// throw std::runtime_error("Invalid object instance id");
|
||||||
|
//
|
||||||
|
// if(obj->instanceName.empty())
|
||||||
|
// throw std::runtime_error("Object instance name missing");
|
||||||
|
//
|
||||||
|
// if (vstd::contains(instanceNames, obj->instanceName))
|
||||||
|
// throw std::runtime_error("Object instance name duplicated: "+obj->instanceName);
|
||||||
|
//
|
||||||
|
// objects.emplace_back(obj);
|
||||||
|
// instanceNames[obj->instanceName] = obj;
|
||||||
|
// addBlockVisTiles(obj);
|
||||||
|
//
|
||||||
|
// //TODO: how about defeated heroes recruited again?
|
||||||
|
//
|
||||||
|
// obj->afterAddToMap(this);
|
||||||
|
//}
|
||||||
|
//
|
||||||
|
//void CMap::moveObject(CGObjectInstance * obj, const int3 & pos)
|
||||||
|
//{
|
||||||
|
// removeBlockVisTiles(obj);
|
||||||
|
// obj->setAnchorPos(pos);
|
||||||
|
// addBlockVisTiles(obj);
|
||||||
|
//}
|
||||||
|
//
|
||||||
|
//void CMap::removeObject(CGObjectInstance * obj)
|
||||||
|
//{
|
||||||
|
// removeBlockVisTiles(obj);
|
||||||
|
// instanceNames.erase(obj->instanceName);
|
||||||
|
//
|
||||||
|
// //update indices
|
||||||
|
//
|
||||||
|
// auto iter = std::next(objects.begin(), obj->id.getNum());
|
||||||
|
// iter = objects.erase(iter);
|
||||||
|
// for(int i = obj->id.getNum(); iter != objects.end(); ++i, ++iter)
|
||||||
|
// {
|
||||||
|
// (*iter)->id = ObjectInstanceID(i);
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// obj->afterRemoveFromMap(this);
|
||||||
|
//
|
||||||
|
// //TODO: Clean artifact instances (mostly worn by hero?) and quests related to this object
|
||||||
|
// //This causes crash with undo/redo in editor
|
||||||
|
//}
|
||||||
|
|
||||||
boost::format fmt("%s_%d");
|
//void CMap::replaceObject(ObjectInstanceID oldObjectID, const std::shared_ptr<CGObjectInstance> & newObject)
|
||||||
fmt % obj->getTypeName() % uid;
|
//{
|
||||||
obj->instanceName = fmt.str();
|
// auto oldObject = objects.at(oldObjectID.getNum());
|
||||||
}
|
//
|
||||||
|
// newObject->id = oldObjectID;
|
||||||
void CMap::addNewObject(CGObjectInstance * obj)
|
//
|
||||||
{
|
// removeBlockVisTiles(oldObject.get(), true);
|
||||||
if(obj->id != ObjectInstanceID(static_cast<si32>(objects.size())))
|
// instanceNames.erase(oldObject->instanceName);
|
||||||
throw std::runtime_error("Invalid object instance id");
|
//
|
||||||
|
// objects.at(oldObjectID.getNum()) = newObject;
|
||||||
if(obj->instanceName.empty())
|
// addBlockVisTiles(newObject.get());
|
||||||
throw std::runtime_error("Object instance name missing");
|
// instanceNames[newObject->instanceName] = newObject;
|
||||||
|
//
|
||||||
if (vstd::contains(instanceNames, obj->instanceName))
|
// oldObject->afterRemoveFromMap(this);
|
||||||
throw std::runtime_error("Object instance name duplicated: "+obj->instanceName);
|
// newObject->afterAddToMap(this);
|
||||||
|
//}
|
||||||
objects.emplace_back(obj);
|
//
|
||||||
instanceNames[obj->instanceName] = obj;
|
//void CMap::eraseObject(ObjectInstanceID oldObjectID)
|
||||||
addBlockVisTiles(obj);
|
//{
|
||||||
|
// auto oldObject = objects.at(oldObjectID.getNum());
|
||||||
//TODO: how about defeated heroes recruited again?
|
//
|
||||||
|
// objects.at(oldObjectID) = nullptr;
|
||||||
obj->afterAddToMap(this);
|
// removeBlockVisTiles(oldObject.get(), true);
|
||||||
}
|
// oldObject->afterRemoveFromMap(this);
|
||||||
|
//}
|
||||||
void CMap::moveObject(CGObjectInstance * obj, const int3 & pos)
|
|
||||||
{
|
|
||||||
removeBlockVisTiles(obj);
|
|
||||||
obj->setAnchorPos(pos);
|
|
||||||
addBlockVisTiles(obj);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CMap::removeObject(CGObjectInstance * obj)
|
|
||||||
{
|
|
||||||
removeBlockVisTiles(obj);
|
|
||||||
instanceNames.erase(obj->instanceName);
|
|
||||||
|
|
||||||
//update indices
|
|
||||||
|
|
||||||
auto iter = std::next(objects.begin(), obj->id.getNum());
|
|
||||||
iter = objects.erase(iter);
|
|
||||||
for(int i = obj->id.getNum(); iter != objects.end(); ++i, ++iter)
|
|
||||||
{
|
|
||||||
(*iter)->id = ObjectInstanceID(i);
|
|
||||||
}
|
|
||||||
|
|
||||||
obj->afterRemoveFromMap(this);
|
|
||||||
|
|
||||||
//TODO: Clean artifact instances (mostly worn by hero?) and quests related to this object
|
|
||||||
//This causes crash with undo/redo in editor
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CMap::isWaterMap() const
|
bool CMap::isWaterMap() const
|
||||||
{
|
{
|
||||||
@@ -709,7 +732,7 @@ void CMap::reindexObjects()
|
|||||||
{
|
{
|
||||||
// Only reindex at editor / RMG operations
|
// Only reindex at editor / RMG operations
|
||||||
|
|
||||||
std::sort(objects.begin(), objects.end(), [](const CGObjectInstance * lhs, const CGObjectInstance * rhs)
|
std::sort(objects.begin(), objects.end(), [](const auto & lhs, const auto & rhs)
|
||||||
{
|
{
|
||||||
// Obstacles first, then visitable, at the end - removable
|
// Obstacles first, then visitable, at the end - removable
|
||||||
|
|
||||||
|
|||||||
@@ -13,7 +13,6 @@
|
|||||||
#include "CMapDefines.h"
|
#include "CMapDefines.h"
|
||||||
#include "CMapHeader.h"
|
#include "CMapHeader.h"
|
||||||
|
|
||||||
#include "../ConstTransitivePtr.h"
|
|
||||||
#include "../GameCallbackHolder.h"
|
#include "../GameCallbackHolder.h"
|
||||||
#include "../networkPacks/TradeItem.h"
|
#include "../networkPacks/TradeItem.h"
|
||||||
|
|
||||||
@@ -101,11 +100,28 @@ public:
|
|||||||
void removeQuestInstance(std::shared_ptr<CQuest> quest);
|
void removeQuestInstance(std::shared_ptr<CQuest> quest);
|
||||||
void clearQuestInstance(const CQuest * quest);
|
void clearQuestInstance(const CQuest * quest);
|
||||||
|
|
||||||
void setUniqueInstanceName(CGObjectInstance * obj);
|
void setUniqueInstanceName(ObjectInstanceID target){};
|
||||||
///Use only this method when creating new map object instances
|
///Use only this method when creating new map object instances
|
||||||
void addNewObject(CGObjectInstance * obj);
|
void addNewObject(std::shared_ptr<CGObjectInstance> obj){}
|
||||||
void moveObject(CGObjectInstance * obj, const int3 & dst);
|
void moveObject(ObjectInstanceID target, const int3 & dst){}
|
||||||
void removeObject(CGObjectInstance * obj);
|
|
||||||
|
/// Remove objects and shifts object indicies.
|
||||||
|
/// Only for use in map editor / RMG
|
||||||
|
std::shared_ptr<CGObjectInstance> removeObject(ObjectInstanceID oldObject){return nullptr;}
|
||||||
|
|
||||||
|
/// Replaced map object with specified ID with new object
|
||||||
|
/// Old object must exist and will be removed from map
|
||||||
|
/// Returns pointer to old object, which can be manipulated or dropped
|
||||||
|
std::shared_ptr<CGObjectInstance> replaceObject(ObjectInstanceID oldObject, const std::shared_ptr<CGObjectInstance> & newObject){return nullptr;}
|
||||||
|
|
||||||
|
/// Erases object from map without shifting indices
|
||||||
|
/// Returns pointer to old object, which can be manipulated or dropped
|
||||||
|
std::shared_ptr<CGObjectInstance> eraseObject(ObjectInstanceID oldObject){return nullptr;}
|
||||||
|
|
||||||
|
void heroAddedToMap(const CGHeroInstance * hero) {}
|
||||||
|
void heroRemovedFromMap(const CGHeroInstance * hero) {}
|
||||||
|
void townAddedToMap(const CGTownInstance * town) {}
|
||||||
|
void townRemovedFromMap(const CGTownInstance * town) {}
|
||||||
|
|
||||||
bool isWaterMap() const;
|
bool isWaterMap() const;
|
||||||
bool calculateWaterContent();
|
bool calculateWaterContent();
|
||||||
@@ -130,7 +146,6 @@ public:
|
|||||||
void reindexObjects();
|
void reindexObjects();
|
||||||
|
|
||||||
std::vector<Rumor> rumors;
|
std::vector<Rumor> rumors;
|
||||||
std::vector<ConstTransitivePtr<CGHeroInstance> > predefinedHeroes;
|
|
||||||
std::set<SpellID> allowedSpells;
|
std::set<SpellID> allowedSpells;
|
||||||
std::set<ArtifactID> allowedArtifact;
|
std::set<ArtifactID> allowedArtifact;
|
||||||
std::set<SecondarySkill> allowedAbilities;
|
std::set<SecondarySkill> allowedAbilities;
|
||||||
@@ -139,13 +154,14 @@ public:
|
|||||||
int grailRadius;
|
int grailRadius;
|
||||||
|
|
||||||
//Central lists of items in game. Position of item in the vectors below is their (instance) id.
|
//Central lists of items in game. Position of item in the vectors below is their (instance) id.
|
||||||
std::vector< ConstTransitivePtr<CGObjectInstance> > objects;
|
std::vector< std::shared_ptr<CGObjectInstance> > objects;
|
||||||
std::vector< ConstTransitivePtr<CGTownInstance> > towns;
|
std::vector< std::shared_ptr<CGTownInstance> > towns;
|
||||||
std::vector< ConstTransitivePtr<CGHeroInstance> > allHeroes; //indexed by [hero_type_id]; on map, disposed, prisons, etc.
|
std::vector< std::shared_ptr<CGHeroInstance> > allHeroes; //indexed by [hero_type_id]; on map, disposed, prisons, etc.
|
||||||
|
|
||||||
//Helper lists
|
//Helper lists
|
||||||
std::vector< ConstTransitivePtr<CGHeroInstance> > heroesOnMap;
|
std::vector< std::shared_ptr<CGHeroInstance> > heroesOnMap;
|
||||||
std::map<TeleportChannelID, std::shared_ptr<TeleportChannel> > teleportChannels;
|
std::map<TeleportChannelID, std::shared_ptr<TeleportChannel> > teleportChannels;
|
||||||
|
std::vector<std::shared_ptr<CGHeroInstance> > predefinedHeroes;
|
||||||
|
|
||||||
/// associative list to identify which hero/creature id belongs to which object id(index for objects)
|
/// associative list to identify which hero/creature id belongs to which object id(index for objects)
|
||||||
std::map<si32, ObjectInstanceID> questIdentifierToId;
|
std::map<si32, ObjectInstanceID> questIdentifierToId;
|
||||||
@@ -153,7 +169,7 @@ public:
|
|||||||
std::unique_ptr<CMapEditManager> editManager;
|
std::unique_ptr<CMapEditManager> editManager;
|
||||||
boost::multi_array<int3, 3> guardingCreaturePositions;
|
boost::multi_array<int3, 3> guardingCreaturePositions;
|
||||||
|
|
||||||
std::map<std::string, ConstTransitivePtr<CGObjectInstance> > instanceNames;
|
std::map<std::string, std::shared_ptr<CGObjectInstance> > instanceNames;
|
||||||
|
|
||||||
bool waterMap;
|
bool waterMap;
|
||||||
|
|
||||||
|
|||||||
@@ -147,15 +147,15 @@ void CMapEditManager::drawRiver(RiverId riverType, vstd::RNG* customGen)
|
|||||||
terrainSel.clearSelection();
|
terrainSel.clearSelection();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CMapEditManager::insertObject(CGObjectInstance * obj)
|
void CMapEditManager::insertObject(std::shared_ptr<CGObjectInstance> obj)
|
||||||
{
|
{
|
||||||
execute(std::make_unique<CInsertObjectOperation>(map, obj));
|
execute(std::make_unique<CInsertObjectOperation>(map, obj));
|
||||||
}
|
}
|
||||||
|
|
||||||
void CMapEditManager::insertObjects(std::set<CGObjectInstance*>& objects)
|
void CMapEditManager::insertObjects(std::set<std::shared_ptr<CGObjectInstance>>& objects)
|
||||||
{
|
{
|
||||||
auto composedOperation = std::make_unique<CComposedOperation>(map);
|
auto composedOperation = std::make_unique<CComposedOperation>(map);
|
||||||
for(auto * obj : objects)
|
for(auto obj : objects)
|
||||||
{
|
{
|
||||||
composedOperation->addOperation(std::make_unique<CInsertObjectOperation>(map, obj));
|
composedOperation->addOperation(std::make_unique<CInsertObjectOperation>(map, obj));
|
||||||
}
|
}
|
||||||
@@ -175,7 +175,7 @@ void CMapEditManager::removeObject(CGObjectInstance * obj)
|
|||||||
void CMapEditManager::removeObjects(std::set<CGObjectInstance *> & objects)
|
void CMapEditManager::removeObjects(std::set<CGObjectInstance *> & objects)
|
||||||
{
|
{
|
||||||
auto composedOperation = std::make_unique<CComposedOperation>(map);
|
auto composedOperation = std::make_unique<CComposedOperation>(map);
|
||||||
for(auto * obj : objects)
|
for(auto obj : objects)
|
||||||
{
|
{
|
||||||
composedOperation->addOperation(std::make_unique<CRemoveObjectOperation>(map, obj));
|
composedOperation->addOperation(std::make_unique<CRemoveObjectOperation>(map, obj));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -83,8 +83,8 @@ public:
|
|||||||
/// Draws rivers at the current terrain selection. The selection will be cleared automatically.
|
/// Draws rivers at the current terrain selection. The selection will be cleared automatically.
|
||||||
void drawRiver(RiverId riverType, vstd::RNG * gen);
|
void drawRiver(RiverId riverType, vstd::RNG * gen);
|
||||||
|
|
||||||
void insertObject(CGObjectInstance * obj);
|
void insertObject(std::shared_ptr<CGObjectInstance> obj);
|
||||||
void insertObjects(std::set<CGObjectInstance *> & objects);
|
void insertObjects(std::set<std::shared_ptr<CGObjectInstance>> & objects);
|
||||||
void moveObject(CGObjectInstance* obj, const int3 & pos);
|
void moveObject(CGObjectInstance* obj, const int3 & pos);
|
||||||
void removeObject(CGObjectInstance* obj);
|
void removeObject(CGObjectInstance* obj);
|
||||||
void removeObjects(std::set<CGObjectInstance*> & objects);
|
void removeObjects(std::set<CGObjectInstance*> & objects);
|
||||||
|
|||||||
@@ -579,7 +579,7 @@ std::string CClearTerrainOperation::getLabel() const
|
|||||||
return "Clear Terrain";
|
return "Clear Terrain";
|
||||||
}
|
}
|
||||||
|
|
||||||
CInsertObjectOperation::CInsertObjectOperation(CMap* map, CGObjectInstance* obj)
|
CInsertObjectOperation::CInsertObjectOperation(CMap* map, std::shared_ptr<CGObjectInstance> obj)
|
||||||
: CMapOperation(map), obj(obj)
|
: CMapOperation(map), obj(obj)
|
||||||
{
|
{
|
||||||
|
|
||||||
@@ -591,7 +591,7 @@ void CInsertObjectOperation::execute()
|
|||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
map->setUniqueInstanceName(obj);
|
map->setUniqueInstanceName(obj->id);
|
||||||
} while(vstd::contains(map->instanceNames, obj->instanceName));
|
} while(vstd::contains(map->instanceNames, obj->instanceName));
|
||||||
|
|
||||||
map->addNewObject(obj);
|
map->addNewObject(obj);
|
||||||
@@ -599,7 +599,7 @@ void CInsertObjectOperation::execute()
|
|||||||
|
|
||||||
void CInsertObjectOperation::undo()
|
void CInsertObjectOperation::undo()
|
||||||
{
|
{
|
||||||
map->removeObject(obj);
|
map->removeObject(obj->id);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CInsertObjectOperation::redo()
|
void CInsertObjectOperation::redo()
|
||||||
@@ -622,12 +622,12 @@ CMoveObjectOperation::CMoveObjectOperation(CMap* map, CGObjectInstance* obj, con
|
|||||||
|
|
||||||
void CMoveObjectOperation::execute()
|
void CMoveObjectOperation::execute()
|
||||||
{
|
{
|
||||||
map->moveObject(obj, targetPos);
|
map->moveObject(obj->id, targetPos);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CMoveObjectOperation::undo()
|
void CMoveObjectOperation::undo()
|
||||||
{
|
{
|
||||||
map->moveObject(obj, initialPos);
|
map->moveObject(obj->id, initialPos);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CMoveObjectOperation::redo()
|
void CMoveObjectOperation::redo()
|
||||||
@@ -641,45 +641,22 @@ std::string CMoveObjectOperation::getLabel() const
|
|||||||
}
|
}
|
||||||
|
|
||||||
CRemoveObjectOperation::CRemoveObjectOperation(CMap* map, CGObjectInstance * obj)
|
CRemoveObjectOperation::CRemoveObjectOperation(CMap* map, CGObjectInstance * obj)
|
||||||
: CMapOperation(map), obj(obj)
|
: CMapOperation(map), targetedObject(obj)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CRemoveObjectOperation::~CRemoveObjectOperation()
|
|
||||||
{
|
|
||||||
//when operation is destroyed and wasn't undone, the object is lost forever
|
|
||||||
|
|
||||||
if(!obj)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
//do not destroy an object that belongs to map
|
|
||||||
if(!vstd::contains(map->instanceNames, obj->instanceName))
|
|
||||||
{
|
|
||||||
delete obj;
|
|
||||||
obj = nullptr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void CRemoveObjectOperation::execute()
|
void CRemoveObjectOperation::execute()
|
||||||
{
|
{
|
||||||
map->removeObject(obj);
|
removedObject = map->removeObject(targetedObject->id);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CRemoveObjectOperation::undo()
|
void CRemoveObjectOperation::undo()
|
||||||
{
|
{
|
||||||
try
|
assert(removedObject != nullptr);
|
||||||
{
|
|
||||||
//set new id, but do not rename object
|
//set new id, but do not rename object
|
||||||
obj->id = ObjectInstanceID(static_cast<si32>(map->objects.size()));
|
removedObject->id = ObjectInstanceID(static_cast<si32>(map->objects.size()));
|
||||||
map->addNewObject(obj);
|
map->addNewObject(removedObject);
|
||||||
}
|
|
||||||
catch(const std::exception& e)
|
|
||||||
{
|
|
||||||
logGlobal->error(e.what());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CRemoveObjectOperation::redo()
|
void CRemoveObjectOperation::redo()
|
||||||
|
|||||||
@@ -124,7 +124,7 @@ public:
|
|||||||
class CInsertObjectOperation : public CMapOperation
|
class CInsertObjectOperation : public CMapOperation
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CInsertObjectOperation(CMap * map, CGObjectInstance * obj);
|
CInsertObjectOperation(CMap * map, std::shared_ptr<CGObjectInstance> obj);
|
||||||
|
|
||||||
void execute() override;
|
void execute() override;
|
||||||
void undo() override;
|
void undo() override;
|
||||||
@@ -132,7 +132,7 @@ public:
|
|||||||
std::string getLabel() const override;
|
std::string getLabel() const override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
CGObjectInstance * obj;
|
std::shared_ptr<CGObjectInstance> obj;
|
||||||
};
|
};
|
||||||
|
|
||||||
/// The CMoveObjectOperation class moves object to another position
|
/// The CMoveObjectOperation class moves object to another position
|
||||||
@@ -157,7 +157,6 @@ class CRemoveObjectOperation : public CMapOperation
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CRemoveObjectOperation(CMap* map, CGObjectInstance * obj);
|
CRemoveObjectOperation(CMap* map, CGObjectInstance * obj);
|
||||||
~CRemoveObjectOperation();
|
|
||||||
|
|
||||||
void execute() override;
|
void execute() override;
|
||||||
void undo() override;
|
void undo() override;
|
||||||
@@ -165,7 +164,8 @@ public:
|
|||||||
std::string getLabel() const override;
|
std::string getLabel() const override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
CGObjectInstance* obj;
|
CGObjectInstance * targetedObject;
|
||||||
|
std::shared_ptr<CGObjectInstance> removedObject;
|
||||||
};
|
};
|
||||||
|
|
||||||
VCMI_LIB_NAMESPACE_END
|
VCMI_LIB_NAMESPACE_END
|
||||||
|
|||||||
@@ -1067,11 +1067,11 @@ void CMapLoaderH3M::readObjectTemplates()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CGObjectInstance * CMapLoaderH3M::readEvent(const int3 & mapPosition, const ObjectInstanceID & idToBeGiven)
|
std::shared_ptr<CGObjectInstance> CMapLoaderH3M::readEvent(const int3 & mapPosition, const ObjectInstanceID & idToBeGiven)
|
||||||
{
|
{
|
||||||
auto * object = new CGEvent(map->cb);
|
auto object = std::make_shared<CGEvent>(map->cb);
|
||||||
|
|
||||||
readBoxContent(object, mapPosition, idToBeGiven);
|
readBoxContent(object.get(), mapPosition, idToBeGiven);
|
||||||
|
|
||||||
reader->readBitmaskPlayers(object->availableFor, false);
|
reader->readBitmaskPlayers(object->availableFor, false);
|
||||||
object->computerActivate = reader->readBool();
|
object->computerActivate = reader->readBool();
|
||||||
@@ -1084,20 +1084,20 @@ CGObjectInstance * CMapLoaderH3M::readEvent(const int3 & mapPosition, const Obje
|
|||||||
else
|
else
|
||||||
object->humanActivate = true;
|
object->humanActivate = true;
|
||||||
|
|
||||||
readBoxHotaContent(object, mapPosition, idToBeGiven);
|
readBoxHotaContent(object.get(), mapPosition, idToBeGiven);
|
||||||
|
|
||||||
return object;
|
return object;
|
||||||
}
|
}
|
||||||
|
|
||||||
CGObjectInstance * CMapLoaderH3M::readPandora(const int3 & mapPosition, const ObjectInstanceID & idToBeGiven)
|
std::shared_ptr<CGObjectInstance> CMapLoaderH3M::readPandora(const int3 & mapPosition, const ObjectInstanceID & idToBeGiven)
|
||||||
{
|
{
|
||||||
auto * object = new CGPandoraBox(map->cb);
|
auto object = std::make_shared<CGPandoraBox>(map->cb);
|
||||||
readBoxContent(object, mapPosition, idToBeGiven);
|
readBoxContent(object.get(), mapPosition, idToBeGiven);
|
||||||
|
|
||||||
if(features.levelHOTA5)
|
if(features.levelHOTA5)
|
||||||
reader->skipZero(1); // Unknown value, always 0 so far
|
reader->skipZero(1); // Unknown value, always 0 so far
|
||||||
|
|
||||||
readBoxHotaContent(object, mapPosition, idToBeGiven);
|
readBoxHotaContent(object.get(), mapPosition, idToBeGiven);
|
||||||
|
|
||||||
return object;
|
return object;
|
||||||
}
|
}
|
||||||
@@ -1179,9 +1179,9 @@ void CMapLoaderH3M::readBoxHotaContent(CGPandoraBox * object, const int3 & mapPo
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CGObjectInstance * CMapLoaderH3M::readMonster(const int3 & mapPosition, const ObjectInstanceID & objectInstanceID)
|
std::shared_ptr<CGObjectInstance> CMapLoaderH3M::readMonster(const int3 & mapPosition, const ObjectInstanceID & objectInstanceID)
|
||||||
{
|
{
|
||||||
auto * object = new CGCreature(map->cb);
|
auto object = std::make_shared<CGCreature>(map->cb);
|
||||||
|
|
||||||
if(features.levelAB)
|
if(features.levelAB)
|
||||||
{
|
{
|
||||||
@@ -1243,18 +1243,18 @@ CGObjectInstance * CMapLoaderH3M::readMonster(const int3 & mapPosition, const Ob
|
|||||||
return object;
|
return object;
|
||||||
}
|
}
|
||||||
|
|
||||||
CGObjectInstance * CMapLoaderH3M::readSign(const int3 & mapPosition)
|
std::shared_ptr<CGObjectInstance> CMapLoaderH3M::readSign(const int3 & mapPosition)
|
||||||
{
|
{
|
||||||
auto * object = new CGSignBottle(map->cb);
|
auto object = std::make_shared<CGSignBottle>(map->cb);
|
||||||
object->message.appendTextID(readLocalizedString(TextIdentifier("sign", mapPosition.x, mapPosition.y, mapPosition.z, "message")));
|
object->message.appendTextID(readLocalizedString(TextIdentifier("sign", mapPosition.x, mapPosition.y, mapPosition.z, "message")));
|
||||||
reader->skipZero(4);
|
reader->skipZero(4);
|
||||||
return object;
|
return object;
|
||||||
}
|
}
|
||||||
|
|
||||||
CGObjectInstance * CMapLoaderH3M::readWitchHut(const int3 & position, std::shared_ptr<const ObjectTemplate> objectTemplate)
|
std::shared_ptr<CGObjectInstance> CMapLoaderH3M::readWitchHut(const int3 & position, std::shared_ptr<const ObjectTemplate> objectTemplate)
|
||||||
{
|
{
|
||||||
auto * object = readGeneric(position, objectTemplate);
|
auto object = readGeneric(position, objectTemplate);
|
||||||
auto * rewardable = dynamic_cast<CRewardableObject*>(object);
|
auto rewardable = std::dynamic_pointer_cast<CRewardableObject>(object);
|
||||||
|
|
||||||
// AB and later maps have allowed abilities defined in H3M
|
// AB and later maps have allowed abilities defined in H3M
|
||||||
if(features.levelAB)
|
if(features.levelAB)
|
||||||
@@ -1301,7 +1301,7 @@ CGObjectInstance * CMapLoaderH3M::readWitchHut(const int3 & position, std::share
|
|||||||
return object;
|
return object;
|
||||||
}
|
}
|
||||||
|
|
||||||
CGObjectInstance * CMapLoaderH3M::readScholar(const int3 & position, std::shared_ptr<const ObjectTemplate> objectTemplate)
|
std::shared_ptr<CGObjectInstance> CMapLoaderH3M::readScholar(const int3 & position, std::shared_ptr<const ObjectTemplate> objectTemplate)
|
||||||
{
|
{
|
||||||
enum class ScholarBonusType : int8_t {
|
enum class ScholarBonusType : int8_t {
|
||||||
RANDOM = -1,
|
RANDOM = -1,
|
||||||
@@ -1310,8 +1310,8 @@ CGObjectInstance * CMapLoaderH3M::readScholar(const int3 & position, std::shared
|
|||||||
SPELL = 2,
|
SPELL = 2,
|
||||||
};
|
};
|
||||||
|
|
||||||
auto * object = readGeneric(position, objectTemplate);
|
auto object = readGeneric(position, objectTemplate);
|
||||||
auto * rewardable = dynamic_cast<CRewardableObject*>(object);
|
auto rewardable = std::dynamic_pointer_cast<CRewardableObject>(object);
|
||||||
|
|
||||||
uint8_t bonusTypeRaw = reader->readInt8Checked(-1, 2);
|
uint8_t bonusTypeRaw = reader->readInt8Checked(-1, 2);
|
||||||
auto bonusType = static_cast<ScholarBonusType>(bonusTypeRaw);
|
auto bonusType = static_cast<ScholarBonusType>(bonusTypeRaw);
|
||||||
@@ -1369,12 +1369,12 @@ CGObjectInstance * CMapLoaderH3M::readScholar(const int3 & position, std::shared
|
|||||||
return object;
|
return object;
|
||||||
}
|
}
|
||||||
|
|
||||||
CGObjectInstance * CMapLoaderH3M::readGarrison(const int3 & mapPosition)
|
std::shared_ptr<CGObjectInstance> CMapLoaderH3M::readGarrison(const int3 & mapPosition)
|
||||||
{
|
{
|
||||||
auto * object = new CGGarrison(map->cb);
|
auto object = std::make_shared<CGGarrison>(map->cb);
|
||||||
|
|
||||||
setOwnerAndValidate(mapPosition, object, reader->readPlayer32());
|
setOwnerAndValidate(mapPosition, object.get(), reader->readPlayer32());
|
||||||
readCreatureSet(object, 7);
|
readCreatureSet(object.get(), 7);
|
||||||
if(features.levelAB)
|
if(features.levelAB)
|
||||||
object->removableUnits = reader->readBool();
|
object->removableUnits = reader->readBool();
|
||||||
else
|
else
|
||||||
@@ -1384,12 +1384,12 @@ CGObjectInstance * CMapLoaderH3M::readGarrison(const int3 & mapPosition)
|
|||||||
return object;
|
return object;
|
||||||
}
|
}
|
||||||
|
|
||||||
CGObjectInstance * CMapLoaderH3M::readArtifact(const int3 & mapPosition, std::shared_ptr<const ObjectTemplate> objectTemplate)
|
std::shared_ptr<CGObjectInstance> CMapLoaderH3M::readArtifact(const int3 & mapPosition, std::shared_ptr<const ObjectTemplate> objectTemplate)
|
||||||
{
|
{
|
||||||
ArtifactID artID = ArtifactID::NONE; //random, set later
|
ArtifactID artID = ArtifactID::NONE; //random, set later
|
||||||
auto * object = new CGArtifact(map->cb);
|
auto object = std::make_shared<CGArtifact>(map->cb);
|
||||||
|
|
||||||
readMessageAndGuards(object->message, object, mapPosition);
|
readMessageAndGuards(object->message, object.get(), mapPosition);
|
||||||
|
|
||||||
//specific artifact
|
//specific artifact
|
||||||
if(objectTemplate->id == Obj::ARTIFACT)
|
if(objectTemplate->id == Obj::ARTIFACT)
|
||||||
@@ -1410,21 +1410,21 @@ CGObjectInstance * CMapLoaderH3M::readArtifact(const int3 & mapPosition, std::sh
|
|||||||
return object;
|
return object;
|
||||||
}
|
}
|
||||||
|
|
||||||
CGObjectInstance * CMapLoaderH3M::readScroll(const int3 & mapPosition, std::shared_ptr<const ObjectTemplate> objectTemplate)
|
std::shared_ptr<CGObjectInstance> CMapLoaderH3M::readScroll(const int3 & mapPosition, std::shared_ptr<const ObjectTemplate> objectTemplate)
|
||||||
{
|
{
|
||||||
auto * object = new CGArtifact(map->cb);
|
auto object = std::make_shared<CGArtifact>(map->cb);
|
||||||
readMessageAndGuards(object->message, object, mapPosition);
|
readMessageAndGuards(object->message, object.get(), mapPosition);
|
||||||
SpellID spellID = reader->readSpell32();
|
SpellID spellID = reader->readSpell32();
|
||||||
|
|
||||||
object->storedArtifact = map->createArtifact(ArtifactID::SPELL_SCROLL, spellID.getNum());
|
object->storedArtifact = map->createArtifact(ArtifactID::SPELL_SCROLL, spellID.getNum());
|
||||||
return object;
|
return object;
|
||||||
}
|
}
|
||||||
|
|
||||||
CGObjectInstance * CMapLoaderH3M::readResource(const int3 & mapPosition, std::shared_ptr<const ObjectTemplate> objectTemplate)
|
std::shared_ptr<CGObjectInstance> CMapLoaderH3M::readResource(const int3 & mapPosition, std::shared_ptr<const ObjectTemplate> objectTemplate)
|
||||||
{
|
{
|
||||||
auto * object = new CGResource(map->cb);
|
auto object = std::make_shared<CGResource>(map->cb);
|
||||||
|
|
||||||
readMessageAndGuards(object->message, object, mapPosition);
|
readMessageAndGuards(object->message, object.get(), mapPosition);
|
||||||
|
|
||||||
object->amount = reader->readUInt32();
|
object->amount = reader->readUInt32();
|
||||||
|
|
||||||
@@ -1440,16 +1440,16 @@ CGObjectInstance * CMapLoaderH3M::readResource(const int3 & mapPosition, std::sh
|
|||||||
return object;
|
return object;
|
||||||
}
|
}
|
||||||
|
|
||||||
CGObjectInstance * CMapLoaderH3M::readMine(const int3 & mapPosition)
|
std::shared_ptr<CGObjectInstance> CMapLoaderH3M::readMine(const int3 & mapPosition)
|
||||||
{
|
{
|
||||||
auto * object = new CGMine(map->cb);
|
auto object = std::make_shared<CGMine>(map->cb);
|
||||||
setOwnerAndValidate(mapPosition, object, reader->readPlayer32());
|
setOwnerAndValidate(mapPosition, object.get(), reader->readPlayer32());
|
||||||
return object;
|
return object;
|
||||||
}
|
}
|
||||||
|
|
||||||
CGObjectInstance * CMapLoaderH3M::readAbandonedMine(const int3 & mapPosition)
|
std::shared_ptr<CGObjectInstance> CMapLoaderH3M::readAbandonedMine(const int3 & mapPosition)
|
||||||
{
|
{
|
||||||
auto * object = new CGMine(map->cb);
|
auto object = std::make_shared<CGMine>(map->cb);
|
||||||
object->setOwner(PlayerColor::NEUTRAL);
|
object->setOwner(PlayerColor::NEUTRAL);
|
||||||
reader->readBitmaskResources(object->abandonedMineResources, false);
|
reader->readBitmaskResources(object->abandonedMineResources, false);
|
||||||
|
|
||||||
@@ -1470,18 +1470,18 @@ CGObjectInstance * CMapLoaderH3M::readAbandonedMine(const int3 & mapPosition)
|
|||||||
return object;
|
return object;
|
||||||
}
|
}
|
||||||
|
|
||||||
CGObjectInstance * CMapLoaderH3M::readDwelling(const int3 & position)
|
std::shared_ptr<CGObjectInstance> CMapLoaderH3M::readDwelling(const int3 & position)
|
||||||
{
|
{
|
||||||
auto * object = new CGDwelling(map->cb);
|
auto object = std::make_shared<CGDwelling>(map->cb);
|
||||||
setOwnerAndValidate(position, object, reader->readPlayer32());
|
setOwnerAndValidate(position, object.get(), reader->readPlayer32());
|
||||||
return object;
|
return object;
|
||||||
}
|
}
|
||||||
|
|
||||||
CGObjectInstance * CMapLoaderH3M::readDwellingRandom(const int3 & mapPosition, std::shared_ptr<const ObjectTemplate> objectTemplate)
|
std::shared_ptr<CGObjectInstance> CMapLoaderH3M::readDwellingRandom(const int3 & mapPosition, std::shared_ptr<const ObjectTemplate> objectTemplate)
|
||||||
{
|
{
|
||||||
auto * object = new CGDwelling(map->cb);
|
auto object = std::make_shared<CGDwelling>(map->cb);
|
||||||
|
|
||||||
setOwnerAndValidate(mapPosition, object, reader->readPlayer32());
|
setOwnerAndValidate(mapPosition, object.get(), reader->readPlayer32());
|
||||||
|
|
||||||
object->randomizationInfo = CGDwellingRandomizationInfo();
|
object->randomizationInfo = CGDwellingRandomizationInfo();
|
||||||
|
|
||||||
@@ -1512,10 +1512,10 @@ CGObjectInstance * CMapLoaderH3M::readDwellingRandom(const int3 & mapPosition, s
|
|||||||
return object;
|
return object;
|
||||||
}
|
}
|
||||||
|
|
||||||
CGObjectInstance * CMapLoaderH3M::readShrine(const int3 & position, std::shared_ptr<const ObjectTemplate> objectTemplate)
|
std::shared_ptr<CGObjectInstance> CMapLoaderH3M::readShrine(const int3 & position, std::shared_ptr<const ObjectTemplate> objectTemplate)
|
||||||
{
|
{
|
||||||
auto * object = readGeneric(position, objectTemplate);
|
auto object = readGeneric(position, objectTemplate);
|
||||||
auto * rewardable = dynamic_cast<CRewardableObject*>(object);
|
auto rewardable = std::dynamic_pointer_cast<CRewardableObject>(object);
|
||||||
|
|
||||||
SpellID spell = reader->readSpell32();
|
SpellID spell = reader->readSpell32();
|
||||||
|
|
||||||
@@ -1536,11 +1536,11 @@ CGObjectInstance * CMapLoaderH3M::readShrine(const int3 & position, std::shared_
|
|||||||
return object;
|
return object;
|
||||||
}
|
}
|
||||||
|
|
||||||
CGObjectInstance * CMapLoaderH3M::readHeroPlaceholder(const int3 & mapPosition)
|
std::shared_ptr<CGObjectInstance> CMapLoaderH3M::readHeroPlaceholder(const int3 & mapPosition)
|
||||||
{
|
{
|
||||||
auto * object = new CGHeroPlaceholder(map->cb);
|
auto object = std::make_shared<CGHeroPlaceholder>(map->cb);
|
||||||
|
|
||||||
setOwnerAndValidate(mapPosition, object, reader->readPlayer());
|
setOwnerAndValidate(mapPosition, object.get(), reader->readPlayer());
|
||||||
|
|
||||||
HeroTypeID htid = reader->readHero(); //hero type id
|
HeroTypeID htid = reader->readHero(); //hero type id
|
||||||
|
|
||||||
@@ -1586,51 +1586,51 @@ CGObjectInstance * CMapLoaderH3M::readHeroPlaceholder(const int3 & mapPosition)
|
|||||||
return object;
|
return object;
|
||||||
}
|
}
|
||||||
|
|
||||||
CGObjectInstance * CMapLoaderH3M::readGrail(const int3 & mapPosition)
|
std::shared_ptr<CGObjectInstance> CMapLoaderH3M::readGrail(const int3 & mapPosition)
|
||||||
{
|
{
|
||||||
map->grailPos = mapPosition;
|
map->grailPos = mapPosition;
|
||||||
map->grailRadius = reader->readInt32();
|
map->grailRadius = reader->readInt32();
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
CGObjectInstance * CMapLoaderH3M::readHotaBattleLocation(const int3 & mapPosition)
|
std::shared_ptr<CGObjectInstance> CMapLoaderH3M::readHotaBattleLocation(const int3 & mapPosition)
|
||||||
{
|
{
|
||||||
// Battle location for arena mode in HotA
|
// Battle location for arena mode in HotA
|
||||||
logGlobal->warn("Map '%s': Arena mode is not supported!", mapName);
|
logGlobal->warn("Map '%s': Arena mode is not supported!", mapName);
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
CGObjectInstance * CMapLoaderH3M::readGeneric(const int3 & mapPosition, std::shared_ptr<const ObjectTemplate> objectTemplate)
|
std::shared_ptr<CGObjectInstance> CMapLoaderH3M::readGeneric(const int3 & mapPosition, std::shared_ptr<const ObjectTemplate> objectTemplate)
|
||||||
{
|
{
|
||||||
if(LIBRARY->objtypeh->knownSubObjects(objectTemplate->id).count(objectTemplate->subid))
|
if(LIBRARY->objtypeh->knownSubObjects(objectTemplate->id).count(objectTemplate->subid))
|
||||||
return LIBRARY->objtypeh->getHandlerFor(objectTemplate->id, objectTemplate->subid)->create(map->cb, objectTemplate);
|
return LIBRARY->objtypeh->getHandlerFor(objectTemplate->id, objectTemplate->subid)->create(map->cb, objectTemplate);
|
||||||
|
|
||||||
logGlobal->warn("Map '%s': Unrecognized object %d:%d ('%s') at %s found!", mapName, objectTemplate->id.toEnum(), objectTemplate->subid, objectTemplate->animationFile.getOriginalName(), mapPosition.toString());
|
logGlobal->warn("Map '%s': Unrecognized object %d:%d ('%s') at %s found!", mapName, objectTemplate->id.toEnum(), objectTemplate->subid, objectTemplate->animationFile.getOriginalName(), mapPosition.toString());
|
||||||
return new CGObjectInstance(map->cb);
|
return std::make_shared<CGObjectInstance>(map->cb);
|
||||||
}
|
}
|
||||||
|
|
||||||
CGObjectInstance * CMapLoaderH3M::readQuestGuard(const int3 & mapPosition)
|
std::shared_ptr<CGObjectInstance> CMapLoaderH3M::readQuestGuard(const int3 & mapPosition)
|
||||||
{
|
{
|
||||||
auto * guard = new CGQuestGuard(map->cb);
|
auto guard = std::make_shared<CGQuestGuard>(map->cb);
|
||||||
readQuest(guard, mapPosition);
|
readQuest(guard.get(), mapPosition);
|
||||||
return guard;
|
return guard;
|
||||||
}
|
}
|
||||||
|
|
||||||
CGObjectInstance * CMapLoaderH3M::readShipyard(const int3 & mapPosition, std::shared_ptr<const ObjectTemplate> objectTemplate)
|
std::shared_ptr<CGObjectInstance> CMapLoaderH3M::readShipyard(const int3 & mapPosition, std::shared_ptr<const ObjectTemplate> objectTemplate)
|
||||||
{
|
{
|
||||||
auto * object = readGeneric(mapPosition, objectTemplate);
|
auto object = readGeneric(mapPosition, objectTemplate);
|
||||||
setOwnerAndValidate(mapPosition, object, reader->readPlayer32());
|
setOwnerAndValidate(mapPosition, object.get(), reader->readPlayer32());
|
||||||
return object;
|
return object;
|
||||||
}
|
}
|
||||||
|
|
||||||
CGObjectInstance * CMapLoaderH3M::readLighthouse(const int3 & mapPosition, std::shared_ptr<const ObjectTemplate> objectTemplate)
|
std::shared_ptr<CGObjectInstance> CMapLoaderH3M::readLighthouse(const int3 & mapPosition, std::shared_ptr<const ObjectTemplate> objectTemplate)
|
||||||
{
|
{
|
||||||
auto * object = readGeneric(mapPosition, objectTemplate);
|
auto object = readGeneric(mapPosition, objectTemplate);
|
||||||
setOwnerAndValidate(mapPosition, object, reader->readPlayer32());
|
setOwnerAndValidate(mapPosition, object.get(), reader->readPlayer32());
|
||||||
return object;
|
return object;
|
||||||
}
|
}
|
||||||
|
|
||||||
CGObjectInstance * CMapLoaderH3M::readBank(const int3 & mapPosition, std::shared_ptr<const ObjectTemplate> objectTemplate)
|
std::shared_ptr<CGObjectInstance> CMapLoaderH3M::readBank(const int3 & mapPosition, std::shared_ptr<const ObjectTemplate> objectTemplate)
|
||||||
{
|
{
|
||||||
if(features.levelHOTA3)
|
if(features.levelHOTA3)
|
||||||
{
|
{
|
||||||
@@ -1669,7 +1669,7 @@ CGObjectInstance * CMapLoaderH3M::readBank(const int3 & mapPosition, std::shared
|
|||||||
return readGeneric(mapPosition, objectTemplate);
|
return readGeneric(mapPosition, objectTemplate);
|
||||||
}
|
}
|
||||||
|
|
||||||
CGObjectInstance * CMapLoaderH3M::readRewardWithArtifact(const int3 & mapPosition, std::shared_ptr<const ObjectTemplate> objectTemplate)
|
std::shared_ptr<CGObjectInstance> CMapLoaderH3M::readRewardWithArtifact(const int3 & mapPosition, std::shared_ptr<const ObjectTemplate> objectTemplate)
|
||||||
{
|
{
|
||||||
if(features.levelHOTA5)
|
if(features.levelHOTA5)
|
||||||
{
|
{
|
||||||
@@ -1697,7 +1697,7 @@ CGObjectInstance * CMapLoaderH3M::readRewardWithArtifact(const int3 & mapPositio
|
|||||||
return readGeneric(mapPosition, objectTemplate);
|
return readGeneric(mapPosition, objectTemplate);
|
||||||
}
|
}
|
||||||
|
|
||||||
CGObjectInstance * CMapLoaderH3M::readBlackMarket(const int3 & mapPosition, std::shared_ptr<const ObjectTemplate> objectTemplate)
|
std::shared_ptr<CGObjectInstance> CMapLoaderH3M::readBlackMarket(const int3 & mapPosition, std::shared_ptr<const ObjectTemplate> objectTemplate)
|
||||||
{
|
{
|
||||||
if(features.levelHOTA5)
|
if(features.levelHOTA5)
|
||||||
{
|
{
|
||||||
@@ -1718,7 +1718,7 @@ CGObjectInstance * CMapLoaderH3M::readBlackMarket(const int3 & mapPosition, std:
|
|||||||
return readGeneric(mapPosition, objectTemplate);
|
return readGeneric(mapPosition, objectTemplate);
|
||||||
}
|
}
|
||||||
|
|
||||||
CGObjectInstance * CMapLoaderH3M::readUniversity(const int3 & mapPosition, std::shared_ptr<const ObjectTemplate> objectTemplate)
|
std::shared_ptr<CGObjectInstance> CMapLoaderH3M::readUniversity(const int3 & mapPosition, std::shared_ptr<const ObjectTemplate> objectTemplate)
|
||||||
{
|
{
|
||||||
if(features.levelHOTA5)
|
if(features.levelHOTA5)
|
||||||
{
|
{
|
||||||
@@ -1735,7 +1735,7 @@ CGObjectInstance * CMapLoaderH3M::readUniversity(const int3 & mapPosition, std::
|
|||||||
return readGeneric(mapPosition, objectTemplate);
|
return readGeneric(mapPosition, objectTemplate);
|
||||||
}
|
}
|
||||||
|
|
||||||
CGObjectInstance * CMapLoaderH3M::readRewardWithArtifactAndResources(const int3 & mapPosition, std::shared_ptr<const ObjectTemplate> objectTemplate)
|
std::shared_ptr<CGObjectInstance> CMapLoaderH3M::readRewardWithArtifactAndResources(const int3 & mapPosition, std::shared_ptr<const ObjectTemplate> objectTemplate)
|
||||||
{
|
{
|
||||||
if(features.levelHOTA5)
|
if(features.levelHOTA5)
|
||||||
{
|
{
|
||||||
@@ -1761,7 +1761,7 @@ CGObjectInstance * CMapLoaderH3M::readRewardWithArtifactAndResources(const int3
|
|||||||
return readGeneric(mapPosition, objectTemplate);
|
return readGeneric(mapPosition, objectTemplate);
|
||||||
}
|
}
|
||||||
|
|
||||||
CGObjectInstance * CMapLoaderH3M::readObject(MapObjectID id, MapObjectSubID subid, std::shared_ptr<const ObjectTemplate> objectTemplate, const int3 & mapPosition, const ObjectInstanceID & objectInstanceID)
|
std::shared_ptr<CGObjectInstance> CMapLoaderH3M::readObject(MapObjectID id, MapObjectSubID subid, std::shared_ptr<const ObjectTemplate> objectTemplate, const int3 & mapPosition, const ObjectInstanceID & objectInstanceID)
|
||||||
{
|
{
|
||||||
switch(id.toEnum())
|
switch(id.toEnum())
|
||||||
{
|
{
|
||||||
@@ -1935,7 +1935,7 @@ void CMapLoaderH3M::readObjects()
|
|||||||
auto originalSubID = originalTemplate->subid;
|
auto originalSubID = originalTemplate->subid;
|
||||||
reader->skipZero(5);
|
reader->skipZero(5);
|
||||||
|
|
||||||
CGObjectInstance * newObject = readObject(originalID, originalSubID, remappedTemplate, mapPosition, objectInstanceID);
|
auto newObject = readObject(originalID, originalSubID, remappedTemplate, mapPosition, objectInstanceID);
|
||||||
|
|
||||||
if(!newObject)
|
if(!newObject)
|
||||||
continue;
|
continue;
|
||||||
@@ -1967,7 +1967,7 @@ void CMapLoaderH3M::readObjects()
|
|||||||
std::sort(
|
std::sort(
|
||||||
map->heroesOnMap.begin(),
|
map->heroesOnMap.begin(),
|
||||||
map->heroesOnMap.end(),
|
map->heroesOnMap.end(),
|
||||||
[](const ConstTransitivePtr<CGHeroInstance> & a, const ConstTransitivePtr<CGHeroInstance> & b)
|
[](const std::shared_ptr<CGHeroInstance> & a, const std::shared_ptr<CGHeroInstance> & b)
|
||||||
{
|
{
|
||||||
return a->subID < b->subID;
|
return a->subID < b->subID;
|
||||||
}
|
}
|
||||||
@@ -2037,9 +2037,9 @@ void CMapLoaderH3M::setOwnerAndValidate(const int3 & mapPosition, CGObjectInstan
|
|||||||
object->setOwner(owner);
|
object->setOwner(owner);
|
||||||
}
|
}
|
||||||
|
|
||||||
CGObjectInstance * CMapLoaderH3M::readHero(const int3 & mapPosition, const ObjectInstanceID & objectInstanceID)
|
std::shared_ptr<CGObjectInstance> CMapLoaderH3M::readHero(const int3 & mapPosition, const ObjectInstanceID & objectInstanceID)
|
||||||
{
|
{
|
||||||
auto * object = new CGHeroInstance(map->cb);
|
auto object = std::make_shared<CGHeroInstance>(map->cb);
|
||||||
|
|
||||||
if(features.levelAB)
|
if(features.levelAB)
|
||||||
{
|
{
|
||||||
@@ -2057,13 +2057,12 @@ CGObjectInstance * CMapLoaderH3M::readHero(const int3 & mapPosition, const Objec
|
|||||||
if(elem->subID == object->subID)
|
if(elem->subID == object->subID)
|
||||||
{
|
{
|
||||||
logGlobal->debug("Hero %d will be taken from the predefined heroes list.", object->subID);
|
logGlobal->debug("Hero %d will be taken from the predefined heroes list.", object->subID);
|
||||||
delete object;
|
|
||||||
object = elem;
|
object = elem;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
setOwnerAndValidate(mapPosition, object, owner);
|
setOwnerAndValidate(mapPosition, object.get(), owner);
|
||||||
|
|
||||||
for(auto & elem : map->disposedHeroes)
|
for(auto & elem : map->disposedHeroes)
|
||||||
{
|
{
|
||||||
@@ -2119,12 +2118,12 @@ CGObjectInstance * CMapLoaderH3M::readHero(const int3 & mapPosition, const Objec
|
|||||||
|
|
||||||
bool hasGarison = reader->readBool();
|
bool hasGarison = reader->readBool();
|
||||||
if(hasGarison)
|
if(hasGarison)
|
||||||
readCreatureSet(object, 7);
|
readCreatureSet(object.get(), 7);
|
||||||
|
|
||||||
object->formation = static_cast<EArmyFormation>(reader->readInt8Checked(0, 1));
|
object->formation = static_cast<EArmyFormation>(reader->readInt8Checked(0, 1));
|
||||||
assert(object->formation == EArmyFormation::LOOSE || object->formation == EArmyFormation::TIGHT);
|
assert(object->formation == EArmyFormation::LOOSE || object->formation == EArmyFormation::TIGHT);
|
||||||
|
|
||||||
loadArtifactsOfHero(object);
|
loadArtifactsOfHero(object.get());
|
||||||
object->patrol.patrolRadius = reader->readUInt8();
|
object->patrol.patrolRadius = reader->readUInt8();
|
||||||
object->patrol.patrolling = (object->patrol.patrolRadius != 0xff);
|
object->patrol.patrolling = (object->patrol.patrolRadius != 0xff);
|
||||||
|
|
||||||
@@ -2218,9 +2217,9 @@ CGObjectInstance * CMapLoaderH3M::readHero(const int3 & mapPosition, const Objec
|
|||||||
return object;
|
return object;
|
||||||
}
|
}
|
||||||
|
|
||||||
CGObjectInstance * CMapLoaderH3M::readSeerHut(const int3 & position, const ObjectInstanceID & idToBeGiven)
|
std::shared_ptr<CGObjectInstance> CMapLoaderH3M::readSeerHut(const int3 & position, const ObjectInstanceID & idToBeGiven)
|
||||||
{
|
{
|
||||||
auto * hut = new CGSeerHut(map->cb);
|
auto hut = std::make_shared<CGSeerHut>(map->cb);
|
||||||
|
|
||||||
uint32_t questsCount = 1;
|
uint32_t questsCount = 1;
|
||||||
|
|
||||||
@@ -2232,7 +2231,7 @@ CGObjectInstance * CMapLoaderH3M::readSeerHut(const int3 & position, const Objec
|
|||||||
logGlobal->warn("Map '%s': Seer Hut at %s - %d quests are not implemented!", mapName, position.toString(), questsCount);
|
logGlobal->warn("Map '%s': Seer Hut at %s - %d quests are not implemented!", mapName, position.toString(), questsCount);
|
||||||
|
|
||||||
for(size_t i = 0; i < questsCount; ++i)
|
for(size_t i = 0; i < questsCount; ++i)
|
||||||
readSeerHutQuest(hut, position, idToBeGiven);
|
readSeerHutQuest(hut.get(), position, idToBeGiven);
|
||||||
|
|
||||||
if(features.levelHOTA3)
|
if(features.levelHOTA3)
|
||||||
{
|
{
|
||||||
@@ -2243,7 +2242,7 @@ CGObjectInstance * CMapLoaderH3M::readSeerHut(const int3 & position, const Objec
|
|||||||
logGlobal->warn("Map '%s': Seer Hut at %s - %d repeatable quests are not implemented!", mapName, position.toString(), repeateableQuestsCount);
|
logGlobal->warn("Map '%s': Seer Hut at %s - %d repeatable quests are not implemented!", mapName, position.toString(), repeateableQuestsCount);
|
||||||
|
|
||||||
for(size_t i = 0; i < repeateableQuestsCount; ++i)
|
for(size_t i = 0; i < repeateableQuestsCount; ++i)
|
||||||
readSeerHutQuest(hut, position, idToBeGiven);
|
readSeerHutQuest(hut.get(), position, idToBeGiven);
|
||||||
}
|
}
|
||||||
|
|
||||||
reader->skipZero(2);
|
reader->skipZero(2);
|
||||||
@@ -2506,13 +2505,13 @@ EQuestMission CMapLoaderH3M::readQuest(IQuestObject * guard, const int3 & positi
|
|||||||
return missionId;
|
return missionId;
|
||||||
}
|
}
|
||||||
|
|
||||||
CGObjectInstance * CMapLoaderH3M::readTown(const int3 & position, std::shared_ptr<const ObjectTemplate> objectTemplate)
|
std::shared_ptr<CGObjectInstance> CMapLoaderH3M::readTown(const int3 & position, std::shared_ptr<const ObjectTemplate> objectTemplate)
|
||||||
{
|
{
|
||||||
auto * object = new CGTownInstance(map->cb);
|
auto object = std::make_shared<CGTownInstance>(map->cb);
|
||||||
if(features.levelAB)
|
if(features.levelAB)
|
||||||
object->identifier = reader->readUInt32();
|
object->identifier = reader->readUInt32();
|
||||||
|
|
||||||
setOwnerAndValidate(position, object, reader->readPlayer());
|
setOwnerAndValidate(position, object.get(), reader->readPlayer());
|
||||||
|
|
||||||
std::optional<FactionID> faction;
|
std::optional<FactionID> faction;
|
||||||
if (objectTemplate->id == Obj::TOWN)
|
if (objectTemplate->id == Obj::TOWN)
|
||||||
@@ -2524,7 +2523,7 @@ CGObjectInstance * CMapLoaderH3M::readTown(const int3 & position, std::shared_pt
|
|||||||
|
|
||||||
bool hasGarrison = reader->readBool();
|
bool hasGarrison = reader->readBool();
|
||||||
if(hasGarrison)
|
if(hasGarrison)
|
||||||
readCreatureSet(object, 7);
|
readCreatureSet(object.get(), 7);
|
||||||
|
|
||||||
object->formation = static_cast<EArmyFormation>(reader->readInt8Checked(0, 1));
|
object->formation = static_cast<EArmyFormation>(reader->readInt8Checked(0, 1));
|
||||||
assert(object->formation == EArmyFormation::LOOSE || object->formation == EArmyFormation::TIGHT);
|
assert(object->formation == EArmyFormation::LOOSE || object->formation == EArmyFormation::TIGHT);
|
||||||
|
|||||||
@@ -187,38 +187,37 @@ private:
|
|||||||
void readObjects();
|
void readObjects();
|
||||||
|
|
||||||
/// Reads single object from input stream based on template
|
/// Reads single object from input stream based on template
|
||||||
CGObjectInstance * readObject(MapObjectID id, MapObjectSubID subid, std::shared_ptr<const ObjectTemplate> objectTemplate, const int3 & objectPosition, const ObjectInstanceID & idToBeGiven);
|
std::shared_ptr<CGObjectInstance> readObject(MapObjectID id, MapObjectSubID subid, std::shared_ptr<const ObjectTemplate> objectTemplate, const int3 & objectPosition, const ObjectInstanceID & idToBeGiven);
|
||||||
|
std::shared_ptr<CGObjectInstance> readEvent(const int3 & objectPosition, const ObjectInstanceID & idToBeGiven);
|
||||||
CGObjectInstance * readEvent(const int3 & objectPosition, const ObjectInstanceID & idToBeGiven);
|
std::shared_ptr<CGObjectInstance> readMonster(const int3 & objectPosition, const ObjectInstanceID & idToBeGiven);
|
||||||
CGObjectInstance * readMonster(const int3 & objectPosition, const ObjectInstanceID & idToBeGiven);
|
std::shared_ptr<CGObjectInstance> readHero(const int3 & initialPos, const ObjectInstanceID & idToBeGiven);
|
||||||
CGObjectInstance * readHero(const int3 & initialPos, const ObjectInstanceID & idToBeGiven);
|
std::shared_ptr<CGObjectInstance> readSeerHut(const int3 & initialPos, const ObjectInstanceID & idToBeGiven);
|
||||||
CGObjectInstance * readSeerHut(const int3 & initialPos, const ObjectInstanceID & idToBeGiven);
|
std::shared_ptr<CGObjectInstance> readTown(const int3 & position, std::shared_ptr<const ObjectTemplate> objTempl);
|
||||||
CGObjectInstance * readTown(const int3 & position, std::shared_ptr<const ObjectTemplate> objTempl);
|
std::shared_ptr<CGObjectInstance> readSign(const int3 & position);
|
||||||
CGObjectInstance * readSign(const int3 & position);
|
std::shared_ptr<CGObjectInstance> readWitchHut(const int3 & position, std::shared_ptr<const ObjectTemplate> objectTemplate);
|
||||||
CGObjectInstance * readWitchHut(const int3 & position, std::shared_ptr<const ObjectTemplate> objectTemplate);
|
std::shared_ptr<CGObjectInstance> readScholar(const int3 & position, std::shared_ptr<const ObjectTemplate> objectTemplate);
|
||||||
CGObjectInstance * readScholar(const int3 & position, std::shared_ptr<const ObjectTemplate> objectTemplate);
|
std::shared_ptr<CGObjectInstance> readGarrison(const int3 & mapPosition);
|
||||||
CGObjectInstance * readGarrison(const int3 & mapPosition);
|
std::shared_ptr<CGObjectInstance> readArtifact(const int3 & position, std::shared_ptr<const ObjectTemplate> objTempl);
|
||||||
CGObjectInstance * readArtifact(const int3 & position, std::shared_ptr<const ObjectTemplate> objTempl);
|
std::shared_ptr<CGObjectInstance> readScroll(const int3 & position, std::shared_ptr<const ObjectTemplate> objTempl);
|
||||||
CGObjectInstance * readScroll(const int3 & position, std::shared_ptr<const ObjectTemplate> objTempl);
|
std::shared_ptr<CGObjectInstance> readResource(const int3 & position, std::shared_ptr<const ObjectTemplate> objTempl);
|
||||||
CGObjectInstance * readResource(const int3 & position, std::shared_ptr<const ObjectTemplate> objTempl);
|
std::shared_ptr<CGObjectInstance> readMine(const int3 & position);
|
||||||
CGObjectInstance * readMine(const int3 & position);
|
std::shared_ptr<CGObjectInstance> readAbandonedMine(const int3 & position);
|
||||||
CGObjectInstance * readAbandonedMine(const int3 & position);
|
std::shared_ptr<CGObjectInstance> readPandora(const int3 & position, const ObjectInstanceID & idToBeGiven);
|
||||||
CGObjectInstance * readPandora(const int3 & position, const ObjectInstanceID & idToBeGiven);
|
std::shared_ptr<CGObjectInstance> readDwelling(const int3 & position);
|
||||||
CGObjectInstance * readDwelling(const int3 & position);
|
std::shared_ptr<CGObjectInstance> readDwellingRandom(const int3 & position, std::shared_ptr<const ObjectTemplate> objTempl);
|
||||||
CGObjectInstance * readDwellingRandom(const int3 & position, std::shared_ptr<const ObjectTemplate> objTempl);
|
std::shared_ptr<CGObjectInstance> readShrine(const int3 & position, std::shared_ptr<const ObjectTemplate> objectTemplate);
|
||||||
CGObjectInstance * readShrine(const int3 & position, std::shared_ptr<const ObjectTemplate> objectTemplate);
|
std::shared_ptr<CGObjectInstance> readHeroPlaceholder(const int3 & position);
|
||||||
CGObjectInstance * readHeroPlaceholder(const int3 & position);
|
std::shared_ptr<CGObjectInstance> readGrail(const int3 & position);
|
||||||
CGObjectInstance * readGrail(const int3 & position);
|
std::shared_ptr<CGObjectInstance> readHotaBattleLocation(const int3 & position);
|
||||||
CGObjectInstance * readHotaBattleLocation(const int3 & position);
|
std::shared_ptr<CGObjectInstance> readQuestGuard(const int3 & position);
|
||||||
CGObjectInstance * readQuestGuard(const int3 & position);
|
std::shared_ptr<CGObjectInstance> readShipyard(const int3 & mapPosition, std::shared_ptr<const ObjectTemplate> objectTemplate);
|
||||||
CGObjectInstance * readShipyard(const int3 & mapPosition, std::shared_ptr<const ObjectTemplate> objectTemplate);
|
std::shared_ptr<CGObjectInstance> readLighthouse(const int3 & mapPosition, std::shared_ptr<const ObjectTemplate> objectTemplate);
|
||||||
CGObjectInstance * readLighthouse(const int3 & mapPosition, std::shared_ptr<const ObjectTemplate> objectTemplate);
|
std::shared_ptr<CGObjectInstance> readGeneric(const int3 & position, std::shared_ptr<const ObjectTemplate> objectTemplate);
|
||||||
CGObjectInstance * readGeneric(const int3 & position, std::shared_ptr<const ObjectTemplate> objectTemplate);
|
std::shared_ptr<CGObjectInstance> readBank(const int3 & position, std::shared_ptr<const ObjectTemplate> objectTemplate);
|
||||||
CGObjectInstance * readBank(const int3 & position, std::shared_ptr<const ObjectTemplate> objectTemplate);
|
std::shared_ptr<CGObjectInstance> readRewardWithArtifact(const int3 & position, std::shared_ptr<const ObjectTemplate> objectTemplate);
|
||||||
CGObjectInstance * readRewardWithArtifact(const int3 & position, std::shared_ptr<const ObjectTemplate> objectTemplate);
|
std::shared_ptr<CGObjectInstance> readRewardWithArtifactAndResources(const int3 & position, std::shared_ptr<const ObjectTemplate> objectTemplate);
|
||||||
CGObjectInstance * readRewardWithArtifactAndResources(const int3 & position, std::shared_ptr<const ObjectTemplate> objectTemplate);
|
std::shared_ptr<CGObjectInstance> readBlackMarket(const int3 & position, std::shared_ptr<const ObjectTemplate> objectTemplate);
|
||||||
CGObjectInstance * readBlackMarket(const int3 & position, std::shared_ptr<const ObjectTemplate> objectTemplate);
|
std::shared_ptr<CGObjectInstance> readUniversity(const int3 & position, std::shared_ptr<const ObjectTemplate> objectTemplate);
|
||||||
CGObjectInstance * readUniversity(const int3 & position, std::shared_ptr<const ObjectTemplate> objectTemplate);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reads a creature set.
|
* Reads a creature set.
|
||||||
|
|||||||
@@ -1084,7 +1084,7 @@ void CMapLoaderJson::MapObjectLoader::configure()
|
|||||||
//artifact instance serialization requires access to Map object, handle it here for now
|
//artifact instance serialization requires access to Map object, handle it here for now
|
||||||
//todo: find better solution for artifact instance serialization
|
//todo: find better solution for artifact instance serialization
|
||||||
|
|
||||||
if(auto * art = dynamic_cast<CGArtifact *>(instance))
|
if(auto art = std::dynamic_pointer_cast<CGArtifact>(instance))
|
||||||
{
|
{
|
||||||
ArtifactID artID = ArtifactID::NONE;
|
ArtifactID artID = ArtifactID::NONE;
|
||||||
SpellID spellID = SpellID::NONE;
|
SpellID spellID = SpellID::NONE;
|
||||||
@@ -1108,7 +1108,7 @@ void CMapLoaderJson::MapObjectLoader::configure()
|
|||||||
art->storedArtifact = owner->map->createArtifact(artID, spellID.getNum());
|
art->storedArtifact = owner->map->createArtifact(artID, spellID.getNum());
|
||||||
}
|
}
|
||||||
|
|
||||||
if(auto * hero = dynamic_cast<CGHeroInstance *>(instance))
|
if(auto hero = std::dynamic_pointer_cast<CGHeroInstance>(instance))
|
||||||
{
|
{
|
||||||
auto o = handler.enterStruct("options");
|
auto o = handler.enterStruct("options");
|
||||||
hero->serializeJsonArtifacts(handler, "artifacts", owner->map);
|
hero->serializeJsonArtifacts(handler, "artifacts", owner->map);
|
||||||
@@ -1134,7 +1134,7 @@ void CMapLoaderJson::readObjects()
|
|||||||
for(auto & ptr : loaders)
|
for(auto & ptr : loaders)
|
||||||
ptr->configure();
|
ptr->configure();
|
||||||
|
|
||||||
std::sort(map->heroesOnMap.begin(), map->heroesOnMap.end(), [](const ConstTransitivePtr<CGHeroInstance> & a, const ConstTransitivePtr<CGHeroInstance> & b)
|
std::sort(map->heroesOnMap.begin(), map->heroesOnMap.end(), [](const std::shared_ptr<CGHeroInstance> & a, const std::shared_ptr<CGHeroInstance> & b)
|
||||||
{
|
{
|
||||||
return a->getObjTypeIndex() < b->getObjTypeIndex();
|
return a->getObjTypeIndex() < b->getObjTypeIndex();
|
||||||
});
|
});
|
||||||
@@ -1305,7 +1305,7 @@ void CMapSaverJson::writeObjects()
|
|||||||
|
|
||||||
JsonSerializer handler(mapObjectResolver.get(), data);
|
JsonSerializer handler(mapObjectResolver.get(), data);
|
||||||
|
|
||||||
for(CGObjectInstance * obj : map->objects)
|
for(const auto & obj : map->objects)
|
||||||
{
|
{
|
||||||
//logGlobal->trace("\t%s", obj->instanceName);
|
//logGlobal->trace("\t%s", obj->instanceName);
|
||||||
auto temp = handler.enterStruct(obj->instanceName);
|
auto temp = handler.enterStruct(obj->instanceName);
|
||||||
|
|||||||
@@ -180,7 +180,7 @@ public:
|
|||||||
{
|
{
|
||||||
MapObjectLoader(CMapLoaderJson * _owner, JsonMap::value_type & json);
|
MapObjectLoader(CMapLoaderJson * _owner, JsonMap::value_type & json);
|
||||||
CMapLoaderJson * owner;
|
CMapLoaderJson * owner;
|
||||||
CGObjectInstance * instance;
|
std::shared_ptr<CGObjectInstance> instance;
|
||||||
ObjectInstanceID id;
|
ObjectInstanceID id;
|
||||||
std::string jsonKey;//full id defined by map creator
|
std::string jsonKey;//full id defined by map creator
|
||||||
JsonNode & configuration;
|
JsonNode & configuration;
|
||||||
|
|||||||
@@ -244,8 +244,8 @@ int ObstacleProxy::getWeightedObjects(const int3 & tile, vstd::RNG & rand, IGame
|
|||||||
for(const auto & temp : shuffledObstacles)
|
for(const auto & temp : shuffledObstacles)
|
||||||
{
|
{
|
||||||
auto handler = LIBRARY->objtypeh->getHandlerFor(temp->id, temp->subid);
|
auto handler = LIBRARY->objtypeh->getHandlerFor(temp->id, temp->subid);
|
||||||
auto * obj = handler->create(nullptr, temp);
|
auto obj = handler->create(nullptr, temp);
|
||||||
allObjects.emplace_back(*obj);
|
allObjects.emplace_back(obj);
|
||||||
rmg::Object * rmgObject = &allObjects.back();
|
rmg::Object * rmgObject = &allObjects.back();
|
||||||
for(const auto & offset : obj->getBlockedOffsets())
|
for(const auto & offset : obj->getBlockedOffsets())
|
||||||
{
|
{
|
||||||
@@ -311,12 +311,12 @@ int ObstacleProxy::getWeightedObjects(const int3 & tile, vstd::RNG & rand, IGame
|
|||||||
return maxWeight;
|
return maxWeight;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::set<CGObjectInstance*> ObstacleProxy::createObstacles(vstd::RNG & rand, IGameCallback * cb)
|
std::set<std::shared_ptr<CGObjectInstance>> ObstacleProxy::createObstacles(vstd::RNG & rand, IGameCallback * cb)
|
||||||
{
|
{
|
||||||
//reverse order, since obstacles begin in bottom-right corner, while the map coordinates begin in top-left
|
//reverse order, since obstacles begin in bottom-right corner, while the map coordinates begin in top-left
|
||||||
auto blockedTiles = blockedArea.getTilesVector();
|
auto blockedTiles = blockedArea.getTilesVector();
|
||||||
int tilePos = 0;
|
int tilePos = 0;
|
||||||
std::set<CGObjectInstance*> objs;
|
std::set<std::shared_ptr<CGObjectInstance>> objs;
|
||||||
|
|
||||||
while(!blockedArea.empty() && tilePos < blockedArea.getTilesVector().size())
|
while(!blockedArea.empty() && tilePos < blockedArea.getTilesVector().size())
|
||||||
{
|
{
|
||||||
@@ -356,7 +356,7 @@ std::set<CGObjectInstance*> ObstacleProxy::createObstacles(vstd::RNG & rand, IGa
|
|||||||
|
|
||||||
//FIXME: Only editor placer obstacles directly
|
//FIXME: Only editor placer obstacles directly
|
||||||
|
|
||||||
void ObstacleProxy::finalInsertion(CMapEditManager * manager, std::set<CGObjectInstance*> & instances)
|
void ObstacleProxy::finalInsertion(CMapEditManager * manager, std::set<std::shared_ptr<CGObjectInstance>> & instances)
|
||||||
{
|
{
|
||||||
manager->insertObjects(instances); //insert as one operation - for undo purposes
|
manager->insertObjects(instances); //insert as one operation - for undo purposes
|
||||||
}
|
}
|
||||||
@@ -366,11 +366,11 @@ std::pair<bool, bool> ObstacleProxy::verifyCoverage(const int3 & t) const
|
|||||||
return {blockedArea.contains(t), false};
|
return {blockedArea.contains(t), false};
|
||||||
}
|
}
|
||||||
|
|
||||||
void ObstacleProxy::placeObject(rmg::Object & object, std::set<CGObjectInstance*> & instances)
|
void ObstacleProxy::placeObject(rmg::Object & object, std::set<std::shared_ptr<CGObjectInstance>> & instances)
|
||||||
{
|
{
|
||||||
for (auto * instance : object.instances())
|
for (auto * instance : object.instances())
|
||||||
{
|
{
|
||||||
instances.insert(&instance->object());
|
instances.insert(instance->object());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -384,7 +384,7 @@ bool EditorObstaclePlacer::isInTheMap(const int3& tile)
|
|||||||
return map->isInTheMap(tile);
|
return map->isInTheMap(tile);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::set<CGObjectInstance*> EditorObstaclePlacer::placeObstacles(vstd::RNG & rand)
|
std::set<std::shared_ptr<CGObjectInstance>> EditorObstaclePlacer::placeObstacles(vstd::RNG & rand)
|
||||||
{
|
{
|
||||||
auto obstacles = createObstacles(rand, map->cb);
|
auto obstacles = createObstacles(rand, map->cb);
|
||||||
finalInsertion(map->getEditManager(), obstacles);
|
finalInsertion(map->getEditManager(), obstacles);
|
||||||
|
|||||||
@@ -41,13 +41,13 @@ public:
|
|||||||
|
|
||||||
virtual std::pair<bool, bool> verifyCoverage(const int3 & t) const;
|
virtual std::pair<bool, bool> verifyCoverage(const int3 & t) const;
|
||||||
|
|
||||||
virtual void placeObject(rmg::Object & object, std::set<CGObjectInstance*> & instances);
|
virtual void placeObject(rmg::Object & object, std::set<std::shared_ptr<CGObjectInstance>> & instances);
|
||||||
|
|
||||||
virtual std::set<CGObjectInstance*> createObstacles(vstd::RNG & rand, IGameCallback * cb);
|
virtual std::set<std::shared_ptr<CGObjectInstance>> createObstacles(vstd::RNG & rand, IGameCallback * cb);
|
||||||
|
|
||||||
virtual bool isInTheMap(const int3& tile) = 0;
|
virtual bool isInTheMap(const int3& tile) = 0;
|
||||||
|
|
||||||
void finalInsertion(CMapEditManager * manager, std::set<CGObjectInstance*> & instances);
|
void finalInsertion(CMapEditManager * manager, std::set<std::shared_ptr<CGObjectInstance>> & instances);
|
||||||
|
|
||||||
virtual void postProcess(const rmg::Object& object) {};
|
virtual void postProcess(const rmg::Object& object) {};
|
||||||
|
|
||||||
@@ -70,7 +70,7 @@ public:
|
|||||||
|
|
||||||
bool isInTheMap(const int3& tile) override;
|
bool isInTheMap(const int3& tile) override;
|
||||||
|
|
||||||
std::set<CGObjectInstance*> placeObstacles(vstd::RNG& rand);
|
std::set<std::shared_ptr<CGObjectInstance>> placeObstacles(vstd::RNG& rand);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
CMap* map;
|
CMap* map;
|
||||||
|
|||||||
@@ -992,9 +992,8 @@ void FoWChange::applyGs(CGameState *gs)
|
|||||||
if (mode == ETileVisibility::HIDDEN) //do not hide too much
|
if (mode == ETileVisibility::HIDDEN) //do not hide too much
|
||||||
{
|
{
|
||||||
std::unordered_set<int3> tilesRevealed;
|
std::unordered_set<int3> tilesRevealed;
|
||||||
for (auto & elem : gs->getMap().objects)
|
for (auto & o : gs->getMap().objects)
|
||||||
{
|
{
|
||||||
const CGObjectInstance *o = elem;
|
|
||||||
if (o)
|
if (o)
|
||||||
{
|
{
|
||||||
switch(o->ID.toEnum())
|
switch(o->ID.toEnum())
|
||||||
@@ -1074,7 +1073,7 @@ void ChangeObjectVisitors::applyGs(CGameState *gs)
|
|||||||
break;
|
break;
|
||||||
case VISITOR_CLEAR:
|
case VISITOR_CLEAR:
|
||||||
// remove visit info from all heroes, including those that are not present on map
|
// remove visit info from all heroes, including those that are not present on map
|
||||||
for (CGHeroInstance * hero : gs->getMap().allHeroes)
|
for (auto hero : gs->getMap().allHeroes)
|
||||||
if (hero)
|
if (hero)
|
||||||
hero->visitedObjects.erase(object);
|
hero->visitedObjects.erase(object);
|
||||||
|
|
||||||
@@ -1119,9 +1118,9 @@ void PlayerEndsGame::applyGs(CGameState *gs)
|
|||||||
if(p->human && gs->getStartInfo()->campState)
|
if(p->human && gs->getStartInfo()->campState)
|
||||||
{
|
{
|
||||||
std::vector<CGHeroInstance *> crossoverHeroes;
|
std::vector<CGHeroInstance *> crossoverHeroes;
|
||||||
for (CGHeroInstance * hero : gs->getMap().heroesOnMap)
|
for (auto hero : gs->getMap().heroesOnMap)
|
||||||
if (hero->tempOwner == player)
|
if (hero->tempOwner == player)
|
||||||
crossoverHeroes.push_back(hero);
|
crossoverHeroes.push_back(hero.get());
|
||||||
|
|
||||||
gs->getStartInfo()->campState->setCurrentMapAsConquered(crossoverHeroes);
|
gs->getStartInfo()->campState->setCurrentMapAsConquered(crossoverHeroes);
|
||||||
}
|
}
|
||||||
@@ -1203,7 +1202,7 @@ void RemoveObject::applyGs(CGameState *gs)
|
|||||||
{
|
{
|
||||||
auto * beatenHero = dynamic_cast<CGHeroInstance *>(obj);
|
auto * beatenHero = dynamic_cast<CGHeroInstance *>(obj);
|
||||||
assert(beatenHero);
|
assert(beatenHero);
|
||||||
gs->getMap().heroesOnMap -= beatenHero;
|
gs->getMap().eraseObject(beatenHero->id);
|
||||||
|
|
||||||
auto * siegeNode = beatenHero->whereShouldBeAttachedOnSiege(gs);
|
auto * siegeNode = beatenHero->whereShouldBeAttachedOnSiege(gs);
|
||||||
|
|
||||||
@@ -1237,8 +1236,7 @@ void RemoveObject::applyGs(CGameState *gs)
|
|||||||
if(beatenHero->boat)
|
if(beatenHero->boat)
|
||||||
{
|
{
|
||||||
beatenHero->detachFrom(const_cast<CGBoat&>(*beatenHero->boat));
|
beatenHero->detachFrom(const_cast<CGBoat&>(*beatenHero->boat));
|
||||||
gs->getMap().instanceNames.erase(beatenHero->boat->instanceName);
|
gs->getMap().eraseObject(beatenHero->boat->id);
|
||||||
gs->getMap().objects[beatenHero->boat->id.getNum()].dellNull();
|
|
||||||
beatenHero->boat = nullptr;
|
beatenHero->boat = nullptr;
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
@@ -1257,7 +1255,7 @@ void RemoveObject::applyGs(CGameState *gs)
|
|||||||
}
|
}
|
||||||
|
|
||||||
gs->getMap().instanceNames.erase(obj->instanceName);
|
gs->getMap().instanceNames.erase(obj->instanceName);
|
||||||
gs->getMap().objects[objectID.getNum()].dellNull();
|
gs->getMap().eraseObject(objectID);
|
||||||
gs->getMap().calculateGuardingGreaturePositions();//FIXME: excessive, update only affected tiles
|
gs->getMap().calculateGuardingGreaturePositions();//FIXME: excessive, update only affected tiles
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1445,13 +1443,14 @@ void HeroRecruited::applyGs(CGameState *gs)
|
|||||||
h->pos = tile;
|
h->pos = tile;
|
||||||
h->updateAppearance();
|
h->updateAppearance();
|
||||||
|
|
||||||
|
assert(h->id == ObjectInstanceID());
|
||||||
if(h->id == ObjectInstanceID())
|
if(h->id == ObjectInstanceID())
|
||||||
{
|
{
|
||||||
h->id = ObjectInstanceID(static_cast<si32>(gs->getMap().objects.size()));
|
h->id = ObjectInstanceID(static_cast<si32>(gs->getMap().objects.size()));
|
||||||
gs->getMap().objects.emplace_back(h);
|
gs->getMap().objects.emplace_back(h);
|
||||||
}
|
}
|
||||||
else
|
// else
|
||||||
gs->getMap().objects[h->id.getNum()] = h;
|
// gs->getMap().replaceObject(h->id, h);
|
||||||
|
|
||||||
gs->getMap().heroesOnMap.emplace_back(h);
|
gs->getMap().heroesOnMap.emplace_back(h);
|
||||||
p->addOwnedObject(h);
|
p->addOwnedObject(h);
|
||||||
@@ -1499,12 +1498,11 @@ void NewObject::applyGs(CGameState *gs)
|
|||||||
{
|
{
|
||||||
newObject->id = ObjectInstanceID(static_cast<si32>(gs->getMap().objects.size()));
|
newObject->id = ObjectInstanceID(static_cast<si32>(gs->getMap().objects.size()));
|
||||||
|
|
||||||
gs->getMap().objects.emplace_back(newObject);
|
gs->getMap().addNewObject(newObject);
|
||||||
gs->getMap().addBlockVisTiles(newObject);
|
|
||||||
gs->getMap().calculateGuardingGreaturePositions();
|
gs->getMap().calculateGuardingGreaturePositions();
|
||||||
|
|
||||||
// attach newly spawned wandering monster to global bonus system node
|
// attach newly spawned wandering monster to global bonus system node
|
||||||
auto newArmy = dynamic_cast<CArmedInstance*>(newObject);
|
auto newArmy = std::dynamic_pointer_cast<CArmedInstance>(newObject);
|
||||||
if (newArmy)
|
if (newArmy)
|
||||||
newArmy->whatShouldBeAttached().attachTo(newArmy->whereShouldBeAttached(gs));
|
newArmy->whatShouldBeAttached().attachTo(newArmy->whereShouldBeAttached(gs));
|
||||||
|
|
||||||
@@ -1518,27 +1516,6 @@ void NewArtifact::applyGs(CGameState *gs)
|
|||||||
pa.applyGs(gs);
|
pa.applyGs(gs);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct ObjectRetriever
|
|
||||||
{
|
|
||||||
const CArmedInstance * operator()(const ConstTransitivePtr<CGHeroInstance> &h) const
|
|
||||||
{
|
|
||||||
return h;
|
|
||||||
}
|
|
||||||
const CArmedInstance * operator()(const ConstTransitivePtr<CStackInstance> &s) const
|
|
||||||
{
|
|
||||||
return s->armyObj;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
template<typename T>
|
|
||||||
struct GetBase
|
|
||||||
{
|
|
||||||
template <typename TArg>
|
|
||||||
T * operator()(TArg &arg) const
|
|
||||||
{
|
|
||||||
return arg;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
void ChangeStackCount::applyGs(CGameState *gs)
|
void ChangeStackCount::applyGs(CGameState *gs)
|
||||||
{
|
{
|
||||||
auto * srcObj = gs->getArmyInstance(army);
|
auto * srcObj = gs->getArmyInstance(army);
|
||||||
@@ -1953,7 +1930,7 @@ void NewTurn::applyGs(CGameState *gs)
|
|||||||
for(auto & creatureSet : availableCreatures) //set available creatures in towns
|
for(auto & creatureSet : availableCreatures) //set available creatures in towns
|
||||||
creatureSet.applyGs(gs);
|
creatureSet.applyGs(gs);
|
||||||
|
|
||||||
for(CGTownInstance* t : gs->getMap().towns)
|
for(auto & t : gs->getMap().towns)
|
||||||
{
|
{
|
||||||
t->built = 0;
|
t->built = 0;
|
||||||
t->spellResearchCounterDay = 0;
|
t->spellResearchCounterDay = 0;
|
||||||
|
|||||||
@@ -806,7 +806,7 @@ struct DLL_LINKAGE NewObject : public CPackForClient
|
|||||||
void applyGs(CGameState * gs) override;
|
void applyGs(CGameState * gs) override;
|
||||||
|
|
||||||
/// Object ID to create
|
/// Object ID to create
|
||||||
CGObjectInstance * newObject;
|
std::shared_ptr<CGObjectInstance> newObject;
|
||||||
/// Which player initiated creation of this object
|
/// Which player initiated creation of this object
|
||||||
PlayerColor initiator;
|
PlayerColor initiator;
|
||||||
|
|
||||||
|
|||||||
@@ -40,6 +40,17 @@ public:
|
|||||||
mem.iser & ret;
|
mem.iser & ret;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
static std::shared_ptr<T> deepCopyShared(const T &data)
|
||||||
|
{
|
||||||
|
CMemorySerializer mem;
|
||||||
|
mem.oser & &data;
|
||||||
|
|
||||||
|
std::shared_ptr<T> ret;
|
||||||
|
mem.iser & ret;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
VCMI_LIB_NAMESPACE_END
|
VCMI_LIB_NAMESPACE_END
|
||||||
|
|||||||
@@ -23,15 +23,14 @@ CSerializer::~CSerializer() = default;
|
|||||||
|
|
||||||
void CSerializer::addStdVecItems(CGameState *gs, GameLibrary *lib)
|
void CSerializer::addStdVecItems(CGameState *gs, GameLibrary *lib)
|
||||||
{
|
{
|
||||||
registerVectoredType<CGObjectInstance, ObjectInstanceID>(&gs->getMap().objects,
|
// registerVectoredType<CGObjectInstance, ObjectInstanceID>(&gs->getMap().objects,
|
||||||
[](const CGObjectInstance &obj){ return obj.id; });
|
// [](const CGObjectInstance &obj){ return obj.id; });
|
||||||
registerVectoredType<CGHeroInstance, HeroTypeID>(&gs->getMap().allHeroes,
|
registerVectoredType<CGHeroInstance, HeroTypeID>(&gs->getMap().allHeroes,
|
||||||
[](const CGHeroInstance &h){ return h.getHeroType()->getId(); });
|
[](const CGHeroInstance &h){ return h.getHeroType()->getId(); });
|
||||||
// registerVectoredType<CArtifactInstance, ArtifactInstanceID>(&gs->getMap().artInstances,
|
registerVectoredType<CArtifactInstance, ArtifactInstanceID>(&gs->getMap().artInstances,
|
||||||
// [](const CArtifactInstance &artInst){ return artInst.getId(); });
|
[](const CArtifactInstance &artInst){ return artInst.getId(); });
|
||||||
// TODO
|
registerVectoredType<CQuest, si32>(&gs->getMap().quests,
|
||||||
// registerVectoredType<CQuest, si32>(&gs->getMap().quests,
|
[](const CQuest &q){ return q.qid; });
|
||||||
// [](const CQuest &q){ return q.qid; });
|
|
||||||
|
|
||||||
smartVectorMembersSerialization = true;
|
smartVectorMembersSerialization = true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,7 +9,6 @@
|
|||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "../ConstTransitivePtr.h"
|
|
||||||
#include "../GameConstants.h"
|
#include "../GameConstants.h"
|
||||||
|
|
||||||
VCMI_LIB_NAMESPACE_BEGIN
|
VCMI_LIB_NAMESPACE_BEGIN
|
||||||
@@ -39,10 +38,10 @@ struct TypeComparer
|
|||||||
template <typename ObjType, typename IdType>
|
template <typename ObjType, typename IdType>
|
||||||
struct VectorizedObjectInfo
|
struct VectorizedObjectInfo
|
||||||
{
|
{
|
||||||
const std::vector<ConstTransitivePtr<ObjType> > *vector; //pointer to the appropriate vector
|
const std::vector<std::shared_ptr<ObjType> > *vector; //pointer to the appropriate vector
|
||||||
std::function<IdType(const ObjType &)> idRetriever;
|
std::function<IdType(const ObjType &)> idRetriever;
|
||||||
|
|
||||||
VectorizedObjectInfo(const std::vector< ConstTransitivePtr<ObjType> > *Vector, std::function<IdType(const ObjType &)> IdGetter)
|
VectorizedObjectInfo(const std::vector< std::shared_ptr<ObjType> > *Vector, std::function<IdType(const ObjType &)> IdGetter)
|
||||||
:vector(Vector), idRetriever(IdGetter)
|
:vector(Vector), idRetriever(IdGetter)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@@ -69,7 +68,7 @@ class DLL_LINKAGE CSerializer : boost::noncopyable
|
|||||||
vectors[&typeid(T)] = VectorizedObjectInfo<T, U>(Vector, idRetriever);
|
vectors[&typeid(T)] = VectorizedObjectInfo<T, U>(Vector, idRetriever);
|
||||||
}
|
}
|
||||||
template <typename T, typename U>
|
template <typename T, typename U>
|
||||||
void registerVectoredType(const std::vector<ConstTransitivePtr<T> > *Vector, const std::function<U(const T&)> &idRetriever)
|
void registerVectoredType(const std::vector<std::shared_ptr<T> > *Vector, const std::function<U(const T&)> &idRetriever)
|
||||||
{
|
{
|
||||||
vectors[&typeid(T)] = VectorizedObjectInfo<T, U>(Vector, idRetriever);
|
vectors[&typeid(T)] = VectorizedObjectInfo<T, U>(Vector, idRetriever);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -201,11 +201,11 @@ ESpellCastResult SummonBoatMechanics::applyAdventureEffects(SpellCastEnvironment
|
|||||||
//try to find unoccupied boat to summon
|
//try to find unoccupied boat to summon
|
||||||
const CGBoat * nearest = nullptr;
|
const CGBoat * nearest = nullptr;
|
||||||
double dist = 0;
|
double dist = 0;
|
||||||
for(const CGObjectInstance * obj : env->getMap()->objects)
|
for(const auto & obj : env->getMap()->objects)
|
||||||
{
|
{
|
||||||
if(obj && obj->ID == Obj::BOAT)
|
if(obj && obj->ID == Obj::BOAT)
|
||||||
{
|
{
|
||||||
const auto * b = dynamic_cast<const CGBoat *>(obj);
|
const auto * b = dynamic_cast<const CGBoat *>(obj.get());
|
||||||
if(b->hero || b->layer != EPathfindingLayer::SAIL)
|
if(b->hero || b->layer != EPathfindingLayer::SAIL)
|
||||||
continue; //we're looking for unoccupied boat
|
continue; //we're looking for unoccupied boat
|
||||||
|
|
||||||
@@ -726,12 +726,12 @@ ESpellCastResult ViewMechanics::applyAdventureEffects(SpellCastEnvironment * env
|
|||||||
|
|
||||||
const auto & fowMap = env->getCb()->getPlayerTeam(parameters.caster->getCasterOwner())->fogOfWarMap;
|
const auto & fowMap = env->getCb()->getPlayerTeam(parameters.caster->getCasterOwner())->fogOfWarMap;
|
||||||
|
|
||||||
for(const CGObjectInstance * obj : env->getMap()->objects)
|
for(const auto & obj : env->getMap()->objects)
|
||||||
{
|
{
|
||||||
//deleted object remain as empty pointer
|
//deleted object remain as empty pointer
|
||||||
if(obj && filterObject(obj, spellLevel))
|
if(obj && filterObject(obj.get(), spellLevel))
|
||||||
{
|
{
|
||||||
ObjectPosInfo posInfo(obj);
|
ObjectPosInfo posInfo(obj.get());
|
||||||
|
|
||||||
if(fowMap[posInfo.pos.z][posInfo.pos.x][posInfo.pos.y] == 0)
|
if(fowMap[posInfo.pos.z][posInfo.pos.x][posInfo.pos.y] == 0)
|
||||||
pack.objectPositions.push_back(posInfo);
|
pack.objectPositions.push_back(posInfo);
|
||||||
|
|||||||
@@ -657,7 +657,7 @@ void CGameHandler::onNewTurn()
|
|||||||
addStatistics(gameState()->statistic); // write at end of turn
|
addStatistics(gameState()->statistic); // write at end of turn
|
||||||
}
|
}
|
||||||
|
|
||||||
for (CGTownInstance *t : gs->getMap().towns)
|
for (const auto & t : gs->getMap().towns)
|
||||||
{
|
{
|
||||||
PlayerColor player = t->tempOwner;
|
PlayerColor player = t->tempOwner;
|
||||||
|
|
||||||
@@ -671,7 +671,7 @@ void CGameHandler::onNewTurn()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (CGTownInstance *t : gs->getMap().towns)
|
for (const auto & t : gs->getMap().towns)
|
||||||
{
|
{
|
||||||
if (t->hasBonusOfType (BonusType::DARKNESS))
|
if (t->hasBonusOfType (BonusType::DARKNESS))
|
||||||
{
|
{
|
||||||
@@ -2682,7 +2682,7 @@ bool CGameHandler::bulkMoveArtifacts(const PlayerColor & player, ObjectInstanceI
|
|||||||
auto dstSlot = ArtifactUtils::getArtAnyPosition(&artFittingSet, artifact->getTypeId());
|
auto dstSlot = ArtifactUtils::getArtAnyPosition(&artFittingSet, artifact->getTypeId());
|
||||||
if(dstSlot != ArtifactPosition::PRE_FIRST)
|
if(dstSlot != ArtifactPosition::PRE_FIRST)
|
||||||
{
|
{
|
||||||
artFittingSet.putArtifact(dstSlot, static_cast<ConstTransitivePtr<CArtifactInstance>>(artifact));
|
artFittingSet.putArtifact(dstSlot, artifact);
|
||||||
slots.emplace_back(srcSlot, dstSlot);
|
slots.emplace_back(srcSlot, dstSlot);
|
||||||
|
|
||||||
// TODO Shouldn't be here. Possibly in callback after equipping the artifact
|
// TODO Shouldn't be here. Possibly in callback after equipping the artifact
|
||||||
@@ -3570,8 +3570,8 @@ void CGameHandler::checkVictoryLossConditionsForPlayer(PlayerColor player)
|
|||||||
//player lost -> all his objects become unflagged (neutral)
|
//player lost -> all his objects become unflagged (neutral)
|
||||||
for (auto obj : gs->getMap().objects) //unflag objs
|
for (auto obj : gs->getMap().objects) //unflag objs
|
||||||
{
|
{
|
||||||
if (obj.get() && obj->tempOwner == player)
|
if (obj && obj->tempOwner == player)
|
||||||
setOwner(obj, PlayerColor::NEUTRAL);
|
setOwner(obj.get(), PlayerColor::NEUTRAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
//eliminating one player may cause victory of another:
|
//eliminating one player may cause victory of another:
|
||||||
@@ -4059,11 +4059,6 @@ void CGameHandler::synchronizeArtifactHandlerLists()
|
|||||||
sendAndApply(uahl);
|
sendAndApply(uahl);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CGameHandler::isValidObject(const CGObjectInstance *obj) const
|
|
||||||
{
|
|
||||||
return vstd::contains(gs->getMap().objects, obj);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CGameHandler::isBlockedByQueries(const CPackForServer *pack, PlayerColor player)
|
bool CGameHandler::isBlockedByQueries(const CPackForServer *pack, PlayerColor player)
|
||||||
{
|
{
|
||||||
if (dynamic_cast<const PlayerMessage *>(pack) != nullptr)
|
if (dynamic_cast<const PlayerMessage *>(pack) != nullptr)
|
||||||
@@ -4093,7 +4088,7 @@ void CGameHandler::removeAfterVisit(const ObjectInstanceID & id)
|
|||||||
{
|
{
|
||||||
if (auto someVistQuery = std::dynamic_pointer_cast<MapObjectVisitQuery>(query))
|
if (auto someVistQuery = std::dynamic_pointer_cast<MapObjectVisitQuery>(query))
|
||||||
{
|
{
|
||||||
if(someVistQuery->visitedObject->id == id)
|
if (someVistQuery->visitedObject == id)
|
||||||
{
|
{
|
||||||
someVistQuery->removeObjectAfterVisit = true;
|
someVistQuery->removeObjectAfterVisit = true;
|
||||||
return;
|
return;
|
||||||
@@ -4154,8 +4149,8 @@ const CGHeroInstance * CGameHandler::getVisitingHero(const CGObjectInstance *obj
|
|||||||
for(const auto & query : queries->allQueries())
|
for(const auto & query : queries->allQueries())
|
||||||
{
|
{
|
||||||
auto visit = std::dynamic_pointer_cast<const VisitQuery>(query);
|
auto visit = std::dynamic_pointer_cast<const VisitQuery>(query);
|
||||||
if (visit && visit->visitedObject == obj)
|
if (visit && visit->visitedObject == obj->id)
|
||||||
return visit->visitingHero;
|
return getHero(visit->visitingHero);
|
||||||
}
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
@@ -4167,8 +4162,8 @@ const CGObjectInstance * CGameHandler::getVisitingObject(const CGHeroInstance *h
|
|||||||
for(const auto & query : queries->allQueries())
|
for(const auto & query : queries->allQueries())
|
||||||
{
|
{
|
||||||
auto visit = std::dynamic_pointer_cast<const VisitQuery>(query);
|
auto visit = std::dynamic_pointer_cast<const VisitQuery>(query);
|
||||||
if (visit && visit->visitingHero == hero)
|
if (visit && visit->visitingHero == hero->id)
|
||||||
return visit->visitedObject;
|
return getObjInstance(visit->visitedObject);
|
||||||
}
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
@@ -4184,7 +4179,7 @@ bool CGameHandler::isVisitCoveredByAnotherQuery(const CGObjectInstance *obj, con
|
|||||||
|
|
||||||
if (auto topQuery = queries->topQuery(hero->getOwner()))
|
if (auto topQuery = queries->topQuery(hero->getOwner()))
|
||||||
if (auto visit = std::dynamic_pointer_cast<const VisitQuery>(topQuery))
|
if (auto visit = std::dynamic_pointer_cast<const VisitQuery>(topQuery))
|
||||||
return !(visit->visitedObject == obj && visit->visitingHero == hero);
|
return !(visit->visitedObject == obj->id && visit->visitingHero == hero->id);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -4247,7 +4242,7 @@ scripting::Pool * CGameHandler::getGlobalContextPool() const
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
CGObjectInstance * CGameHandler::createNewObject(const int3 & visitablePosition, MapObjectID objectID, MapObjectSubID subID)
|
std::shared_ptr<CGObjectInstance> CGameHandler::createNewObject(const int3 & visitablePosition, MapObjectID objectID, MapObjectSubID subID)
|
||||||
{
|
{
|
||||||
TerrainId terrainType = ETerrainId::NONE;
|
TerrainId terrainType = ETerrainId::NONE;
|
||||||
|
|
||||||
@@ -4259,8 +4254,8 @@ CGObjectInstance * CGameHandler::createNewObject(const int3 & visitablePosition,
|
|||||||
|
|
||||||
auto handler = LIBRARY->objtypeh->getHandlerFor(objectID, subID);
|
auto handler = LIBRARY->objtypeh->getHandlerFor(objectID, subID);
|
||||||
|
|
||||||
CGObjectInstance * o = handler->create(gs->callback, nullptr);
|
auto o = handler->create(gs->callback, nullptr);
|
||||||
handler->configureObject(o, getRandomGenerator());
|
handler->configureObject(o.get(), getRandomGenerator());
|
||||||
assert(o->ID == objectID);
|
assert(o->ID == objectID);
|
||||||
|
|
||||||
assert(!handler->getTemplates(terrainType).empty());
|
assert(!handler->getTemplates(terrainType).empty());
|
||||||
@@ -4284,7 +4279,7 @@ void CGameHandler::createWanderingMonster(const int3 & visitablePosition, Creatu
|
|||||||
{
|
{
|
||||||
auto createdObject = createNewObject(visitablePosition, Obj::MONSTER, creature);
|
auto createdObject = createNewObject(visitablePosition, Obj::MONSTER, creature);
|
||||||
|
|
||||||
auto * cre = dynamic_cast<CGCreature *>(createdObject);
|
auto cre = std::dynamic_pointer_cast<CGCreature>(createdObject);
|
||||||
assert(cre);
|
assert(cre);
|
||||||
cre->notGrowingTeam = cre->neverFlees = false;
|
cre->notGrowingTeam = cre->neverFlees = false;
|
||||||
cre->character = 2;
|
cre->character = 2;
|
||||||
@@ -4307,7 +4302,7 @@ void CGameHandler::createHole(const int3 & visitablePosition, PlayerColor initia
|
|||||||
newObject(createdObject, initiator);
|
newObject(createdObject, initiator);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CGameHandler::newObject(CGObjectInstance * object, PlayerColor initiator)
|
void CGameHandler::newObject(std::shared_ptr<CGObjectInstance> object, PlayerColor initiator)
|
||||||
{
|
{
|
||||||
object->initObj(gs->getRandomGenerator());
|
object->initObj(gs->getRandomGenerator());
|
||||||
|
|
||||||
|
|||||||
@@ -87,18 +87,17 @@ public:
|
|||||||
events::EventBus * eventBus() const override;
|
events::EventBus * eventBus() const override;
|
||||||
CVCMIServer & gameLobby() const;
|
CVCMIServer & gameLobby() const;
|
||||||
|
|
||||||
bool isValidObject(const CGObjectInstance *obj) const;
|
|
||||||
bool isBlockedByQueries(const CPackForServer *pack, PlayerColor player);
|
bool isBlockedByQueries(const CPackForServer *pack, PlayerColor player);
|
||||||
bool isAllowedExchange(ObjectInstanceID id1, ObjectInstanceID id2);
|
bool isAllowedExchange(ObjectInstanceID id1, ObjectInstanceID id2);
|
||||||
void giveSpells(const CGTownInstance *t, const CGHeroInstance *h);
|
void giveSpells(const CGTownInstance *t, const CGHeroInstance *h);
|
||||||
|
|
||||||
// Helpers to create new object of specified type
|
// Helpers to create new object of specified type
|
||||||
|
|
||||||
CGObjectInstance * createNewObject(const int3 & visitablePosition, MapObjectID objectID, MapObjectSubID subID);
|
std::shared_ptr<CGObjectInstance> createNewObject(const int3 & visitablePosition, MapObjectID objectID, MapObjectSubID subID);
|
||||||
void createWanderingMonster(const int3 & visitablePosition, CreatureID creature);
|
void createWanderingMonster(const int3 & visitablePosition, CreatureID creature);
|
||||||
void createBoat(const int3 & visitablePosition, BoatId type, PlayerColor initiator) override;
|
void createBoat(const int3 & visitablePosition, BoatId type, PlayerColor initiator) override;
|
||||||
void createHole(const int3 & visitablePosition, PlayerColor initiator);
|
void createHole(const int3 & visitablePosition, PlayerColor initiator);
|
||||||
void newObject(CGObjectInstance * object, PlayerColor initiator);
|
void newObject(std::shared_ptr<CGObjectInstance> object, PlayerColor initiator);
|
||||||
|
|
||||||
explicit CGameHandler(CVCMIServer * lobby);
|
explicit CGameHandler(CVCMIServer * lobby);
|
||||||
~CGameHandler();
|
~CGameHandler();
|
||||||
|
|||||||
@@ -507,7 +507,7 @@ RumorState NewTurnProcessor::pickNewRumor()
|
|||||||
|
|
||||||
std::tuple<EWeekType, CreatureID> NewTurnProcessor::pickWeekType(bool newMonth)
|
std::tuple<EWeekType, CreatureID> NewTurnProcessor::pickWeekType(bool newMonth)
|
||||||
{
|
{
|
||||||
for (const CGTownInstance *t : gameHandler->gameState()->getMap().towns)
|
for (const auto & t : gameHandler->gameState()->getMap().towns)
|
||||||
{
|
{
|
||||||
if (t->hasBuilt(BuildingID::GRAIL, ETownType::INFERNO))
|
if (t->hasBuilt(BuildingID::GRAIL, ETownType::INFERNO))
|
||||||
return { EWeekType::DEITYOFFIRE, CreatureID::IMP };
|
return { EWeekType::DEITYOFFIRE, CreatureID::IMP };
|
||||||
@@ -666,8 +666,8 @@ NewTurn NewTurnProcessor::generateNewTurnPack()
|
|||||||
|
|
||||||
if (newWeek)
|
if (newWeek)
|
||||||
{
|
{
|
||||||
for (CGTownInstance *t : gameHandler->gameState()->getMap().towns)
|
for (const auto & t : gameHandler->gameState()->getMap().towns)
|
||||||
n.availableCreatures.push_back(generateTownGrowth(t, n.specialWeek, n.creatureid, firstTurn));
|
n.availableCreatures.push_back(generateTownGrowth(t.get(), n.specialWeek, n.creatureid, firstTurn));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (newWeek)
|
if (newWeek)
|
||||||
@@ -695,17 +695,17 @@ void NewTurnProcessor::onNewTurn()
|
|||||||
|
|
||||||
if (newWeek)
|
if (newWeek)
|
||||||
{
|
{
|
||||||
for (CGTownInstance *t : gameHandler->gameState()->getMap().towns)
|
for (const auto & t : gameHandler->gameState()->getMap().towns)
|
||||||
if (t->hasBuilt(BuildingSubID::PORTAL_OF_SUMMONING))
|
if (t->hasBuilt(BuildingSubID::PORTAL_OF_SUMMONING))
|
||||||
gameHandler->setPortalDwelling(t, true, (n.specialWeek == EWeekType::PLAGUE ? true : false)); //set creatures for Portal of Summoning
|
gameHandler->setPortalDwelling(t.get(), true, (n.specialWeek == EWeekType::PLAGUE ? true : false)); //set creatures for Portal of Summoning
|
||||||
}
|
}
|
||||||
|
|
||||||
if (newWeek && !firstTurn)
|
if (newWeek && !firstTurn)
|
||||||
{
|
{
|
||||||
for (CGTownInstance *t : gameHandler->gameState()->getMap().towns)
|
for (const auto & t : gameHandler->gameState()->getMap().towns)
|
||||||
{
|
{
|
||||||
if (!t->getOwner().isValidPlayer())
|
if (!t->getOwner().isValidPlayer())
|
||||||
updateNeutralTownGarrison(t, 1 + gameHandler->getDate(Date::DAY) / 7);
|
updateNeutralTownGarrison(t.get(), 1 + gameHandler->getDate(Date::DAY) / 7);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -10,6 +10,7 @@
|
|||||||
#include "StdInc.h"
|
#include "StdInc.h"
|
||||||
#include "VisitQueries.h"
|
#include "VisitQueries.h"
|
||||||
|
|
||||||
|
#include "../../lib/gameState/CGameState.h"
|
||||||
#include "../../lib/mapObjects/CGHeroInstance.h"
|
#include "../../lib/mapObjects/CGHeroInstance.h"
|
||||||
#include "../../lib/mapObjects/CGTownInstance.h"
|
#include "../../lib/mapObjects/CGTownInstance.h"
|
||||||
#include "../../lib/mapObjects/TownBuildingInstance.h"
|
#include "../../lib/mapObjects/TownBuildingInstance.h"
|
||||||
@@ -18,8 +19,8 @@
|
|||||||
|
|
||||||
VisitQuery::VisitQuery(CGameHandler * owner, const CGObjectInstance * Obj, const CGHeroInstance * Hero)
|
VisitQuery::VisitQuery(CGameHandler * owner, const CGObjectInstance * Obj, const CGHeroInstance * Hero)
|
||||||
: CQuery(owner)
|
: CQuery(owner)
|
||||||
, visitedObject(Obj)
|
, visitedObject(Obj->id)
|
||||||
, visitingHero(Hero)
|
, visitingHero(Hero->id)
|
||||||
{
|
{
|
||||||
addPlayer(Hero->tempOwner);
|
addPlayer(Hero->tempOwner);
|
||||||
}
|
}
|
||||||
@@ -33,9 +34,12 @@ bool VisitQuery::blocksPack(const CPackForServer * pack) const
|
|||||||
|
|
||||||
void MapObjectVisitQuery::onExposure(QueryPtr topQuery)
|
void MapObjectVisitQuery::onExposure(QueryPtr topQuery)
|
||||||
{
|
{
|
||||||
|
auto object = gh->gameState()->getObjInstance(visitedObject);
|
||||||
|
auto hero = gh->gameState()->getHero(visitingHero);
|
||||||
|
|
||||||
//Object may have been removed and deleted.
|
//Object may have been removed and deleted.
|
||||||
if(gh->isValidObject(visitedObject))
|
if (object)
|
||||||
topQuery->notifyObjectAboutRemoval(visitedObject, visitingHero);
|
topQuery->notifyObjectAboutRemoval(object, hero);
|
||||||
|
|
||||||
owner->popIfTop(*this);
|
owner->popIfTop(*this);
|
||||||
}
|
}
|
||||||
@@ -48,11 +52,13 @@ MapObjectVisitQuery::MapObjectVisitQuery(CGameHandler * owner, const CGObjectIns
|
|||||||
|
|
||||||
void MapObjectVisitQuery::onRemoval(PlayerColor color)
|
void MapObjectVisitQuery::onRemoval(PlayerColor color)
|
||||||
{
|
{
|
||||||
gh->objectVisitEnded(visitingHero, players.front());
|
auto hero = gh->gameState()->getHero(visitingHero);
|
||||||
|
|
||||||
|
gh->objectVisitEnded(hero, players.front());
|
||||||
|
|
||||||
//Can object visit affect 2 players and what would be desired behavior?
|
//Can object visit affect 2 players and what would be desired behavior?
|
||||||
if(removeObjectAfterVisit)
|
if(removeObjectAfterVisit)
|
||||||
gh->removeObject(visitedObject, color);
|
gh->removeObject(hero, color);
|
||||||
}
|
}
|
||||||
|
|
||||||
TownBuildingVisitQuery::TownBuildingVisitQuery(CGameHandler * owner, const CGTownInstance * Obj, std::vector<const CGHeroInstance *> heroes, std::vector<BuildingID> buildingToVisit)
|
TownBuildingVisitQuery::TownBuildingVisitQuery(CGameHandler * owner, const CGTownInstance * Obj, std::vector<const CGHeroInstance *> heroes, std::vector<BuildingID> buildingToVisit)
|
||||||
@@ -67,7 +73,10 @@ TownBuildingVisitQuery::TownBuildingVisitQuery(CGameHandler * owner, const CGTow
|
|||||||
|
|
||||||
void TownBuildingVisitQuery::onExposure(QueryPtr topQuery)
|
void TownBuildingVisitQuery::onExposure(QueryPtr topQuery)
|
||||||
{
|
{
|
||||||
topQuery->notifyObjectAboutRemoval(visitedObject, visitingHero);
|
auto object = gh->gameState()->getObjInstance(visitedObject);
|
||||||
|
auto hero = gh->gameState()->getHero(visitingHero);
|
||||||
|
|
||||||
|
topQuery->notifyObjectAboutRemoval(object, hero);
|
||||||
|
|
||||||
onAdded(players.front());
|
onAdded(players.front());
|
||||||
}
|
}
|
||||||
@@ -76,9 +85,9 @@ void TownBuildingVisitQuery::onAdded(PlayerColor color)
|
|||||||
{
|
{
|
||||||
while (!visitedBuilding.empty() && owner->topQuery(color).get() == this)
|
while (!visitedBuilding.empty() && owner->topQuery(color).get() == this)
|
||||||
{
|
{
|
||||||
visitingHero = visitedBuilding.back().hero;
|
visitingHero = visitedBuilding.back().hero->id;
|
||||||
const auto * building = visitedTown->rewardableBuildings.at(visitedBuilding.back().building);
|
const auto * building = visitedTown->rewardableBuildings.at(visitedBuilding.back().building);
|
||||||
building->onHeroVisit(visitingHero);
|
building->onHeroVisit(visitedBuilding.back().hero);
|
||||||
visitedBuilding.pop_back();
|
visitedBuilding.pop_back();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -23,8 +23,8 @@ protected:
|
|||||||
VisitQuery(CGameHandler * owner, const CGObjectInstance * Obj, const CGHeroInstance * Hero);
|
VisitQuery(CGameHandler * owner, const CGObjectInstance * Obj, const CGHeroInstance * Hero);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
const CGObjectInstance * visitedObject;
|
ObjectInstanceID visitedObject;
|
||||||
const CGHeroInstance * visitingHero;
|
ObjectInstanceID visitingHero;
|
||||||
|
|
||||||
bool blocksPack(const CPackForServer * pack) const final;
|
bool blocksPack(const CPackForServer * pack) const final;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -226,8 +226,8 @@ TEST_F(CGameStateTest, DISABLED_issue2765)
|
|||||||
{
|
{
|
||||||
startTestGame();
|
startTestGame();
|
||||||
|
|
||||||
CGHeroInstance * attacker = map->heroesOnMap[0];
|
auto attacker = map->heroesOnMap[0];
|
||||||
CGHeroInstance * defender = map->heroesOnMap[1];
|
auto defender = map->heroesOnMap[1];
|
||||||
|
|
||||||
ASSERT_NE(attacker->tempOwner, defender->tempOwner);
|
ASSERT_NE(attacker->tempOwner, defender->tempOwner);
|
||||||
|
|
||||||
@@ -239,7 +239,7 @@ TEST_F(CGameStateTest, DISABLED_issue2765)
|
|||||||
gameCallback->sendAndApply(na);
|
gameCallback->sendAndApply(na);
|
||||||
}
|
}
|
||||||
|
|
||||||
startTestBattle(attacker, defender);
|
startTestBattle(attacker.get(), defender.get());
|
||||||
|
|
||||||
{
|
{
|
||||||
battle::UnitInfo info;
|
battle::UnitInfo info;
|
||||||
@@ -270,11 +270,11 @@ TEST_F(CGameStateTest, DISABLED_issue2765)
|
|||||||
ASSERT_NE(def, nullptr);
|
ASSERT_NE(def, nullptr);
|
||||||
ASSERT_NE(att, def);
|
ASSERT_NE(att, def);
|
||||||
|
|
||||||
EXPECT_NE(att->getMyHero(), defender);
|
EXPECT_NE(att->getMyHero(), defender.get());
|
||||||
EXPECT_NE(def->getMyHero(), attacker);
|
EXPECT_NE(def->getMyHero(), attacker.get());
|
||||||
|
|
||||||
EXPECT_EQ(att->getMyHero(), attacker) << att->nodeName();
|
EXPECT_EQ(att->getMyHero(), attacker.get()) << att->nodeName();
|
||||||
EXPECT_EQ(def->getMyHero(), defender) << def->nodeName();
|
EXPECT_EQ(def->getMyHero(), defender.get()) << def->nodeName();
|
||||||
|
|
||||||
{
|
{
|
||||||
using namespace ::testing;
|
using namespace ::testing;
|
||||||
@@ -308,8 +308,8 @@ TEST_F(CGameStateTest, DISABLED_battleResurrection)
|
|||||||
{
|
{
|
||||||
startTestGame();
|
startTestGame();
|
||||||
|
|
||||||
CGHeroInstance * attacker = map->heroesOnMap[0];
|
auto attacker = map->heroesOnMap[0];
|
||||||
CGHeroInstance * defender = map->heroesOnMap[1];
|
auto defender = map->heroesOnMap[1];
|
||||||
|
|
||||||
ASSERT_NE(attacker->tempOwner, defender->tempOwner);
|
ASSERT_NE(attacker->tempOwner, defender->tempOwner);
|
||||||
|
|
||||||
@@ -327,7 +327,7 @@ TEST_F(CGameStateTest, DISABLED_battleResurrection)
|
|||||||
gameCallback->sendAndApply(na);
|
gameCallback->sendAndApply(na);
|
||||||
}
|
}
|
||||||
|
|
||||||
startTestBattle(attacker, defender);
|
startTestBattle(attacker.get(), defender.get());
|
||||||
|
|
||||||
uint32_t unitId = gameState->currentBattles.front()->battleNextUnitId();
|
uint32_t unitId = gameState->currentBattles.front()->battleNextUnitId();
|
||||||
|
|
||||||
@@ -380,7 +380,7 @@ TEST_F(CGameStateTest, DISABLED_battleResurrection)
|
|||||||
const CSpell * spell = SpellID(SpellID::RESURRECTION).toSpell();
|
const CSpell * spell = SpellID(SpellID::RESURRECTION).toSpell();
|
||||||
ASSERT_NE(spell, nullptr);
|
ASSERT_NE(spell, nullptr);
|
||||||
|
|
||||||
spells::BattleCast cast(gameState->currentBattles.front().get(), attacker, spells::Mode::HERO, spell);
|
spells::BattleCast cast(gameState->currentBattles.front().get(), attacker.get(), spells::Mode::HERO, spell);
|
||||||
|
|
||||||
spells::Target target;
|
spells::Target target;
|
||||||
target.emplace_back(unit);
|
target.emplace_back(unit);
|
||||||
|
|||||||
@@ -232,7 +232,7 @@ void MapComparer::compareObjects()
|
|||||||
|
|
||||||
auto actualObject = it->second;
|
auto actualObject = it->second;
|
||||||
|
|
||||||
compareObject(actualObject, expectedObject);
|
compareObject(actualObject.get(), expectedObject.get());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user