mirror of
https://github.com/vcmi/vcmi.git
synced 2024-12-24 22:14:36 +02:00
Merge pull request #3147 from IvanSavenko/serialization_refactor
Serialization refactor - remove VLC from saved games
This commit is contained in:
commit
07472d3b05
@ -421,14 +421,14 @@ void AIGateway::requestRealized(PackageApplied * pa)
|
||||
NET_EVENT_HANDLER;
|
||||
if(status.haveTurn())
|
||||
{
|
||||
if(pa->packType == typeList.getTypeID<EndTurn>())
|
||||
if(pa->packType == CTypeList::getInstance().getTypeID<EndTurn>(nullptr))
|
||||
{
|
||||
if(pa->result)
|
||||
status.madeTurn();
|
||||
}
|
||||
}
|
||||
|
||||
if(pa->packType == typeList.getTypeID<QueryReply>())
|
||||
if(pa->packType == CTypeList::getInstance().getTypeID<QueryReply>(nullptr))
|
||||
{
|
||||
status.receivedAnswerConfirmation(pa->requestID, pa->result);
|
||||
}
|
||||
|
@ -505,14 +505,14 @@ void VCAI::requestRealized(PackageApplied * pa)
|
||||
NET_EVENT_HANDLER;
|
||||
if(status.haveTurn())
|
||||
{
|
||||
if(pa->packType == typeList.getTypeID<EndTurn>())
|
||||
if(pa->packType == CTypeList::getInstance().getTypeID<EndTurn>(nullptr))
|
||||
{
|
||||
if(pa->result)
|
||||
status.madeTurn();
|
||||
}
|
||||
}
|
||||
|
||||
if(pa->packType == typeList.getTypeID<QueryReply>())
|
||||
if(pa->packType == CTypeList::getInstance().getTypeID<QueryReply>(nullptr))
|
||||
{
|
||||
status.receivedAnswerConfirmation(pa->requestID, pa->result);
|
||||
}
|
||||
|
@ -1237,10 +1237,10 @@ void CPlayerInterface::showArtifactAssemblyDialog(const Artifact * artifact, con
|
||||
|
||||
void CPlayerInterface::requestRealized( PackageApplied *pa )
|
||||
{
|
||||
if(pa->packType == typeList.getTypeID<MoveHero>())
|
||||
if(pa->packType == CTypeList::getInstance().getTypeID<MoveHero>(nullptr))
|
||||
movementController->onMoveHeroApplied();
|
||||
|
||||
if(pa->packType == typeList.getTypeID<QueryReply>())
|
||||
if(pa->packType == CTypeList::getInstance().getTypeID<QueryReply>(nullptr))
|
||||
movementController->onQueryReplyApplied();
|
||||
}
|
||||
|
||||
|
@ -47,7 +47,7 @@
|
||||
#include "../lib/modding/ModIncompatibility.h"
|
||||
#include "../lib/rmg/CMapGenOptions.h"
|
||||
#include "../lib/filesystem/Filesystem.h"
|
||||
#include "../lib/registerTypes/RegisterTypes.h"
|
||||
#include "../lib/registerTypes/RegisterTypesLobbyPacks.h"
|
||||
#include "../lib/serializer/Connection.h"
|
||||
#include "../lib/serializer/CMemorySerializer.h"
|
||||
|
||||
@ -94,7 +94,7 @@ public:
|
||||
T * ptr = static_cast<T *>(pack);
|
||||
ApplyOnLobbyHandlerNetPackVisitor visitor(*handler);
|
||||
|
||||
logNetwork->trace("\tImmediately apply on lobby: %s", typeList.getTypeInfo(ptr)->name());
|
||||
logNetwork->trace("\tImmediately apply on lobby: %s", typeid(ptr).name());
|
||||
ptr->visit(visitor);
|
||||
|
||||
return visitor.getResult();
|
||||
@ -105,7 +105,7 @@ public:
|
||||
T * ptr = static_cast<T *>(pack);
|
||||
ApplyOnLobbyScreenNetPackVisitor visitor(*handler, lobby);
|
||||
|
||||
logNetwork->trace("\tApply on lobby from queue: %s", typeList.getTypeInfo(ptr)->name());
|
||||
logNetwork->trace("\tApply on lobby from queue: %s", typeid(ptr).name());
|
||||
ptr->visit(visitor);
|
||||
}
|
||||
};
|
||||
@ -298,7 +298,7 @@ void CServerHandler::applyPacksOnLobbyScreen()
|
||||
boost::mutex::scoped_lock interfaceLock(GH.interfaceMutex);
|
||||
CPackForLobby * pack = packsForLobbyScreen.front();
|
||||
packsForLobbyScreen.pop_front();
|
||||
CBaseForLobbyApply * apply = applier->getApplier(typeList.getTypeID(pack)); //find the applier
|
||||
CBaseForLobbyApply * apply = applier->getApplier(CTypeList::getInstance().getTypeID(pack)); //find the applier
|
||||
apply->applyOnLobbyScreen(dynamic_cast<CLobbyScreen *>(SEL), this, pack);
|
||||
GH.windows().totalRedraw();
|
||||
delete pack;
|
||||
@ -953,7 +953,7 @@ void CServerHandler::threadHandleConnection()
|
||||
|
||||
void CServerHandler::visitForLobby(CPackForLobby & lobbyPack)
|
||||
{
|
||||
if(applier->getApplier(typeList.getTypeID(&lobbyPack))->applyOnLobbyHandler(this, &lobbyPack))
|
||||
if(applier->getApplier(CTypeList::getInstance().getTypeID(&lobbyPack))->applyOnLobbyHandler(this, &lobbyPack))
|
||||
{
|
||||
if(!settings["session"]["headless"].Bool())
|
||||
{
|
||||
|
@ -24,6 +24,7 @@
|
||||
#include "../CCallback.h"
|
||||
#include "../lib/CConfigHandler.h"
|
||||
#include "../lib/gameState/CGameState.h"
|
||||
#include "../lib/CPlayerState.h"
|
||||
#include "../lib/CThreadHelper.h"
|
||||
#include "../lib/VCMIDirs.h"
|
||||
#include "../lib/UnlockGuard.h"
|
||||
@ -32,7 +33,7 @@
|
||||
#include "../lib/mapping/CMapService.h"
|
||||
#include "../lib/pathfinder/CGPathNode.h"
|
||||
#include "../lib/filesystem/Filesystem.h"
|
||||
#include "../lib/registerTypes/RegisterTypes.h"
|
||||
#include "../lib/registerTypes/RegisterTypesClientPacks.h"
|
||||
#include "../lib/serializer/Connection.h"
|
||||
|
||||
#include <memory>
|
||||
@ -137,8 +138,7 @@ CClient::CClient()
|
||||
{
|
||||
waitingRequest.clear();
|
||||
applier = std::make_shared<CApplier<CBaseForCLApply>>();
|
||||
registerTypesClientPacks1(*applier);
|
||||
registerTypesClientPacks2(*applier);
|
||||
registerTypesClientPacks(*applier);
|
||||
IObjectInterface::cb = this;
|
||||
gs = nullptr;
|
||||
}
|
||||
@ -523,20 +523,20 @@ void CClient::installNewBattleInterface(std::shared_ptr<CBattleGameInterface> ba
|
||||
|
||||
void CClient::handlePack(CPack * pack)
|
||||
{
|
||||
CBaseForCLApply * apply = applier->getApplier(typeList.getTypeID(pack)); //find the applier
|
||||
CBaseForCLApply * apply = applier->getApplier(CTypeList::getInstance().getTypeID(pack)); //find the applier
|
||||
if(apply)
|
||||
{
|
||||
boost::mutex::scoped_lock interfaceLock(GH.interfaceMutex);
|
||||
apply->applyOnClBefore(this, pack);
|
||||
logNetwork->trace("\tMade first apply on cl: %s", typeList.getTypeInfo(pack)->name());
|
||||
logNetwork->trace("\tMade first apply on cl: %s", typeid(pack).name());
|
||||
gs->apply(pack);
|
||||
logNetwork->trace("\tApplied on gs: %s", typeList.getTypeInfo(pack)->name());
|
||||
logNetwork->trace("\tApplied on gs: %s", typeid(pack).name());
|
||||
apply->applyOnClAfter(this, pack);
|
||||
logNetwork->trace("\tMade second apply on cl: %s", typeList.getTypeInfo(pack)->name());
|
||||
logNetwork->trace("\tMade second apply on cl: %s", typeid(pack).name());
|
||||
}
|
||||
else
|
||||
{
|
||||
logNetwork->error("Message %s cannot be applied, cannot find applier!", typeList.getTypeInfo(pack)->name());
|
||||
logNetwork->error("Message %s cannot be applied, cannot find applier!", typeid(pack).name());
|
||||
}
|
||||
delete pack;
|
||||
}
|
||||
|
@ -74,6 +74,10 @@ std::string CMapHandler::getTerrainDescr(const int3 & pos, bool rightClick) cons
|
||||
|
||||
bool CMapHandler::compareObjectBlitOrder(const CGObjectInstance * a, const CGObjectInstance * b)
|
||||
{
|
||||
//FIXME: Optimize
|
||||
// this method is called A LOT on game start and some parts, e.g. for loops are too slow for that
|
||||
|
||||
assert(a && b);
|
||||
if(!a)
|
||||
return true;
|
||||
if(!b)
|
||||
|
@ -39,7 +39,7 @@
|
||||
#include "../../lib/TerrainHandler.h"
|
||||
#include "../../lib/filesystem/Filesystem.h"
|
||||
|
||||
#include "../../lib/serializer/BinaryDeserializer.h"
|
||||
#include "../../lib/serializer/CLoadFile.h"
|
||||
#include "../../lib/StartInfo.h"
|
||||
#include "../../lib/rmg/CMapGenOptions.h"
|
||||
|
||||
|
@ -116,6 +116,7 @@ macro(add_main_lib TARGET_NAME LIBRARY_TYPE)
|
||||
${MAIN_LIB_DIR}/mapping/MapFormatJson.cpp
|
||||
${MAIN_LIB_DIR}/mapping/ObstacleProxy.cpp
|
||||
|
||||
${MAIN_LIB_DIR}/modding/ActiveModsInSaveList.cpp
|
||||
${MAIN_LIB_DIR}/modding/CModHandler.cpp
|
||||
${MAIN_LIB_DIR}/modding/CModInfo.cpp
|
||||
${MAIN_LIB_DIR}/modding/CModVersion.cpp
|
||||
@ -132,15 +133,6 @@ macro(add_main_lib TARGET_NAME LIBRARY_TYPE)
|
||||
${MAIN_LIB_DIR}/pathfinder/PathfindingRules.cpp
|
||||
${MAIN_LIB_DIR}/pathfinder/TurnInfo.cpp
|
||||
|
||||
${MAIN_LIB_DIR}/registerTypes/RegisterTypes.cpp
|
||||
${MAIN_LIB_DIR}/registerTypes/TypesClientPacks1.cpp
|
||||
${MAIN_LIB_DIR}/registerTypes/TypesClientPacks2.cpp
|
||||
${MAIN_LIB_DIR}/registerTypes/TypesMapObjects1.cpp
|
||||
${MAIN_LIB_DIR}/registerTypes/TypesMapObjects2.cpp
|
||||
${MAIN_LIB_DIR}/registerTypes/TypesMapObjects3.cpp
|
||||
${MAIN_LIB_DIR}/registerTypes/TypesLobbyPacks.cpp
|
||||
${MAIN_LIB_DIR}/registerTypes/TypesServerPacks.cpp
|
||||
|
||||
${MAIN_LIB_DIR}/rewardable/Configuration.cpp
|
||||
${MAIN_LIB_DIR}/rewardable/Info.cpp
|
||||
${MAIN_LIB_DIR}/rewardable/Interface.cpp
|
||||
@ -180,9 +172,10 @@ macro(add_main_lib TARGET_NAME LIBRARY_TYPE)
|
||||
|
||||
${MAIN_LIB_DIR}/serializer/BinaryDeserializer.cpp
|
||||
${MAIN_LIB_DIR}/serializer/BinarySerializer.cpp
|
||||
${MAIN_LIB_DIR}/serializer/CLoadIntegrityValidator.cpp
|
||||
${MAIN_LIB_DIR}/serializer/CLoadFile.cpp
|
||||
${MAIN_LIB_DIR}/serializer/CMemorySerializer.cpp
|
||||
${MAIN_LIB_DIR}/serializer/Connection.cpp
|
||||
${MAIN_LIB_DIR}/serializer/CSaveFile.cpp
|
||||
${MAIN_LIB_DIR}/serializer/CSerializer.cpp
|
||||
${MAIN_LIB_DIR}/serializer/CTypeList.cpp
|
||||
${MAIN_LIB_DIR}/serializer/JsonDeserializer.cpp
|
||||
@ -467,6 +460,7 @@ macro(add_main_lib TARGET_NAME LIBRARY_TYPE)
|
||||
${MAIN_LIB_DIR}/mapping/MapFormatJson.h
|
||||
${MAIN_LIB_DIR}/mapping/ObstacleProxy.h
|
||||
|
||||
${MAIN_LIB_DIR}/modding/ActiveModsInSaveList.h
|
||||
${MAIN_LIB_DIR}/modding/CModHandler.h
|
||||
${MAIN_LIB_DIR}/modding/CModInfo.h
|
||||
${MAIN_LIB_DIR}/modding/CModVersion.h
|
||||
@ -475,6 +469,7 @@ macro(add_main_lib TARGET_NAME LIBRARY_TYPE)
|
||||
${MAIN_LIB_DIR}/modding/ModIncompatibility.h
|
||||
${MAIN_LIB_DIR}/modding/ModScope.h
|
||||
${MAIN_LIB_DIR}/modding/ModUtility.h
|
||||
${MAIN_LIB_DIR}/modding/ModVerificationInfo.h
|
||||
|
||||
${MAIN_LIB_DIR}/networkPacks/ArtifactLocation.h
|
||||
${MAIN_LIB_DIR}/networkPacks/BattleChanges.h
|
||||
@ -503,6 +498,10 @@ macro(add_main_lib TARGET_NAME LIBRARY_TYPE)
|
||||
${MAIN_LIB_DIR}/pathfinder/TurnInfo.h
|
||||
|
||||
${MAIN_LIB_DIR}/registerTypes/RegisterTypes.h
|
||||
${MAIN_LIB_DIR}/registerTypes/RegisterTypesClientPacks.h
|
||||
${MAIN_LIB_DIR}/registerTypes/RegisterTypesLobbyPacks.h
|
||||
${MAIN_LIB_DIR}/registerTypes/RegisterTypesMapObjects.h
|
||||
${MAIN_LIB_DIR}/registerTypes/RegisterTypesServerPacks.h
|
||||
|
||||
${MAIN_LIB_DIR}/rewardable/Configuration.h
|
||||
${MAIN_LIB_DIR}/rewardable/Info.h
|
||||
@ -546,9 +545,10 @@ macro(add_main_lib TARGET_NAME LIBRARY_TYPE)
|
||||
|
||||
${MAIN_LIB_DIR}/serializer/BinaryDeserializer.h
|
||||
${MAIN_LIB_DIR}/serializer/BinarySerializer.h
|
||||
${MAIN_LIB_DIR}/serializer/CLoadIntegrityValidator.h
|
||||
${MAIN_LIB_DIR}/serializer/CLoadFile.h
|
||||
${MAIN_LIB_DIR}/serializer/CMemorySerializer.h
|
||||
${MAIN_LIB_DIR}/serializer/Connection.h
|
||||
${MAIN_LIB_DIR}/serializer/CSaveFile.h
|
||||
${MAIN_LIB_DIR}/serializer/CSerializer.h
|
||||
${MAIN_LIB_DIR}/serializer/CTypeList.h
|
||||
${MAIN_LIB_DIR}/serializer/JsonDeserializer.h
|
||||
|
@ -50,6 +50,8 @@ template <typename IdType>
|
||||
class DLL_LINKAGE EntityT : public Entity
|
||||
{
|
||||
public:
|
||||
using IdentifierType = IdType;
|
||||
|
||||
virtual IdType getId() const = 0;
|
||||
};
|
||||
|
||||
|
@ -53,19 +53,6 @@ public:
|
||||
std::string getNameTranslated() const override;
|
||||
void registerIcons(const IconRegistar & cb) const override;
|
||||
BattleField getId() const override;
|
||||
|
||||
template <typename Handler> void serialize(Handler & h, const int version)
|
||||
{
|
||||
h & name;
|
||||
h & identifier;
|
||||
h & isSpecial;
|
||||
h & graphics;
|
||||
h & icon;
|
||||
h & iconIndex;
|
||||
h & battlefield;
|
||||
h & impassableHexes;
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
class DLL_LINKAGE BattleFieldService : public EntityServiceT<BattleField, BattleFieldInfo>
|
||||
@ -85,11 +72,6 @@ public:
|
||||
virtual const std::vector<std::string> & getTypeNames() const override;
|
||||
virtual std::vector<JsonNode> loadLegacyData() override;
|
||||
virtual std::vector<bool> getDefaultAllowed() const override;
|
||||
|
||||
template <typename Handler> void serialize(Handler & h, const int version)
|
||||
{
|
||||
h & objects;
|
||||
}
|
||||
};
|
||||
|
||||
VCMI_LIB_NAMESPACE_END
|
||||
|
@ -607,75 +607,6 @@ void CArtHandler::loadComponents(CArtifact * art, const JsonNode & node)
|
||||
}
|
||||
}
|
||||
|
||||
ArtifactID CArtHandler::pickRandomArtifact(CRandomGenerator & rand, int flags, std::function<bool(ArtifactID)> accepts)
|
||||
{
|
||||
std::set<ArtifactID> potentialPicks;
|
||||
|
||||
// Select artifacts that satisfy provided criterias
|
||||
for (auto const * artifact : allowedArtifacts)
|
||||
{
|
||||
assert(artifact->aClass != CArtifact::ART_SPECIAL); // should be filtered out when allowedArtifacts is initialized
|
||||
|
||||
if ((flags & CArtifact::ART_TREASURE) == 0 && artifact->aClass == CArtifact::ART_TREASURE)
|
||||
continue;
|
||||
|
||||
if ((flags & CArtifact::ART_MINOR) == 0 && artifact->aClass == CArtifact::ART_MINOR)
|
||||
continue;
|
||||
|
||||
if ((flags & CArtifact::ART_MAJOR) == 0 && artifact->aClass == CArtifact::ART_MAJOR)
|
||||
continue;
|
||||
|
||||
if ((flags & CArtifact::ART_RELIC) == 0 && artifact->aClass == CArtifact::ART_RELIC)
|
||||
continue;
|
||||
|
||||
if (!accepts(artifact->id))
|
||||
continue;
|
||||
|
||||
potentialPicks.insert(artifact->id);
|
||||
}
|
||||
|
||||
return pickRandomArtifact(rand, potentialPicks);
|
||||
}
|
||||
|
||||
ArtifactID CArtHandler::pickRandomArtifact(CRandomGenerator & rand, std::set<ArtifactID> potentialPicks)
|
||||
{
|
||||
// No allowed artifacts at all - give Grail - this can't be banned (hopefully)
|
||||
// FIXME: investigate how such cases are handled by H3 - some heavily customized user-made maps likely rely on H3 behavior
|
||||
if (potentialPicks.empty())
|
||||
{
|
||||
logGlobal->warn("Failed to find artifact that matches requested parameters!");
|
||||
return ArtifactID::GRAIL;
|
||||
}
|
||||
|
||||
// Find how many times least used artifacts were picked by randomizer
|
||||
int leastUsedTimes = std::numeric_limits<int>::max();
|
||||
for (auto const & artifact : potentialPicks)
|
||||
if (allocatedArtifacts[artifact] < leastUsedTimes)
|
||||
leastUsedTimes = allocatedArtifacts[artifact];
|
||||
|
||||
// Pick all artifacts that were used least number of times
|
||||
std::set<ArtifactID> preferredPicks;
|
||||
for (auto const & artifact : potentialPicks)
|
||||
if (allocatedArtifacts[artifact] == leastUsedTimes)
|
||||
preferredPicks.insert(artifact);
|
||||
|
||||
assert(!preferredPicks.empty());
|
||||
|
||||
ArtifactID artID = *RandomGeneratorUtil::nextItem(preferredPicks, rand);
|
||||
allocatedArtifacts[artID] += 1; // record +1 more usage
|
||||
return artID;
|
||||
}
|
||||
|
||||
ArtifactID CArtHandler::pickRandomArtifact(CRandomGenerator & rand, std::function<bool(ArtifactID)> accepts)
|
||||
{
|
||||
return pickRandomArtifact(rand, 0xff, std::move(accepts));
|
||||
}
|
||||
|
||||
ArtifactID CArtHandler::pickRandomArtifact(CRandomGenerator & rand, int flags)
|
||||
{
|
||||
return pickRandomArtifact(rand, flags, [](const ArtifactID &) { return true; });
|
||||
}
|
||||
|
||||
void CArtHandler::makeItCreatureArt(CArtifact * a, bool onlyCreature)
|
||||
{
|
||||
if (onlyCreature)
|
||||
@ -723,7 +654,6 @@ bool CArtHandler::legalArtifact(const ArtifactID & id)
|
||||
void CArtHandler::initAllowedArtifactsList(const std::vector<bool> &allowed)
|
||||
{
|
||||
allowedArtifacts.clear();
|
||||
allocatedArtifacts.clear();
|
||||
|
||||
for (ArtifactID i=ArtifactID::SPELLBOOK; i < ArtifactID(static_cast<si32>(objects.size())); i.advance(1))
|
||||
{
|
||||
|
@ -53,12 +53,6 @@ public:
|
||||
bool isCombined() const;
|
||||
const std::vector<CArtifact*> & getConstituents() const;
|
||||
const std::vector<CArtifact*> & getPartOf() const;
|
||||
|
||||
template <typename Handler> void serialize(Handler & h, const int version)
|
||||
{
|
||||
h & constituents;
|
||||
h & partOf;
|
||||
}
|
||||
};
|
||||
|
||||
class DLL_LINKAGE CScrollArtifact
|
||||
@ -83,12 +77,6 @@ public:
|
||||
const std::vector <std::pair<ui16, Bonus>> & getBonusesPerLevel() const;
|
||||
std::vector <std::pair<ui16, Bonus>> & getThresholdBonuses();
|
||||
const std::vector <std::pair<ui16, Bonus>> & getThresholdBonuses() const;
|
||||
|
||||
template <typename Handler> void serialize(Handler & h, const int version)
|
||||
{
|
||||
h & bonusesPerLevel;
|
||||
h & thresholdBonuses;
|
||||
}
|
||||
};
|
||||
|
||||
// Container for artifacts. Not for instances.
|
||||
@ -144,25 +132,6 @@ public:
|
||||
// Is used for testing purposes only
|
||||
void setImage(int32_t iconIndex, std::string image, std::string large);
|
||||
|
||||
template <typename Handler> void serialize(Handler & h, const int version)
|
||||
{
|
||||
h & static_cast<CBonusSystemNode&>(*this);
|
||||
h & static_cast<CCombinedArtifact&>(*this);
|
||||
h & static_cast<CGrowingArtifact&>(*this);
|
||||
h & image;
|
||||
h & large;
|
||||
h & advMapDef;
|
||||
h & iconIndex;
|
||||
h & price;
|
||||
h & possibleSlots;
|
||||
h & aClass;
|
||||
h & id;
|
||||
h & modScope;
|
||||
h & identifier;
|
||||
h & warMachine;
|
||||
h & onlyOnWaterMap;
|
||||
}
|
||||
|
||||
CArtifact();
|
||||
~CArtifact();
|
||||
|
||||
@ -172,9 +141,6 @@ public:
|
||||
class DLL_LINKAGE CArtHandler : public CHandlerBase<ArtifactID, Artifact, CArtifact, ArtifactService>
|
||||
{
|
||||
public:
|
||||
/// Stores number of times each artifact was placed on map via randomization
|
||||
std::map<ArtifactID, int> allocatedArtifacts;
|
||||
|
||||
/// List of artifacts allowed on the map
|
||||
std::vector<CArtifact *> allowedArtifacts;
|
||||
|
||||
@ -182,12 +148,6 @@ public:
|
||||
|
||||
static CArtifact::EartClass stringToClass(const std::string & className); //TODO: rework EartClass to make this a constructor
|
||||
|
||||
/// Gets a artifact ID randomly and removes the selected artifact from this handler.
|
||||
ArtifactID pickRandomArtifact(CRandomGenerator & rand, int flags);
|
||||
ArtifactID pickRandomArtifact(CRandomGenerator & rand, std::function<bool(ArtifactID)> accepts);
|
||||
ArtifactID pickRandomArtifact(CRandomGenerator & rand, int flags, std::function<bool(ArtifactID)> accepts);
|
||||
ArtifactID pickRandomArtifact(CRandomGenerator & rand, std::set<ArtifactID> filtered);
|
||||
|
||||
bool legalArtifact(const ArtifactID & id);
|
||||
void initAllowedArtifactsList(const std::vector<bool> &allowed); //allowed[art_id] -> 0 if not allowed, 1 if allowed
|
||||
static void makeItCreatureArt(CArtifact * a, bool onlyCreature = true);
|
||||
@ -203,13 +163,6 @@ public:
|
||||
|
||||
std::vector<bool> getDefaultAllowed() const override;
|
||||
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{
|
||||
h & objects;
|
||||
h & allowedArtifacts;
|
||||
h & allocatedArtifacts;
|
||||
}
|
||||
|
||||
protected:
|
||||
const std::vector<std::string> & getTypeNames() const override;
|
||||
CArtifact * loadFromJson(const std::string & scope, const JsonNode & json, const std::string & identifier, size_t index) override;
|
||||
|
@ -83,11 +83,6 @@ public:
|
||||
struct RayColor {
|
||||
ColorRGBA start;
|
||||
ColorRGBA end;
|
||||
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{
|
||||
h & start & end;
|
||||
}
|
||||
};
|
||||
|
||||
double timeBetweenFidgets, idleAnimationTime,
|
||||
@ -100,25 +95,7 @@ public:
|
||||
|
||||
AnimationPath projectileImageName;
|
||||
std::vector<RayColor> projectileRay;
|
||||
//bool projectileSpin; //if true, appropriate projectile is spinning during flight
|
||||
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{
|
||||
h & timeBetweenFidgets;
|
||||
h & idleAnimationTime;
|
||||
h & walkAnimationTime;
|
||||
h & attackAnimationTime;
|
||||
h & upperRightMissleOffsetX;
|
||||
h & rightMissleOffsetX;
|
||||
h & lowerRightMissleOffsetX;
|
||||
h & upperRightMissleOffsetY;
|
||||
h & rightMissleOffsetY;
|
||||
h & lowerRightMissleOffsetY;
|
||||
h & missleFrameAngles;
|
||||
h & attackClimaxFrame;
|
||||
h & projectileImageName;
|
||||
h & projectileRay;
|
||||
}
|
||||
} animation;
|
||||
|
||||
//sound info
|
||||
@ -132,18 +109,6 @@ public:
|
||||
AudioPath wince; // attacked but did not die
|
||||
AudioPath startMoving;
|
||||
AudioPath endMoving;
|
||||
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{
|
||||
h & attack;
|
||||
h & defend;
|
||||
h & killed;
|
||||
h & move;
|
||||
h & shoot;
|
||||
h & wince;
|
||||
h & startMoving;
|
||||
h & endMoving;
|
||||
}
|
||||
} sounds;
|
||||
|
||||
ArtifactID warMachine;
|
||||
@ -210,35 +175,6 @@ public:
|
||||
void updateFrom(const JsonNode & data);
|
||||
void serializeJson(JsonSerializeFormat & handler);
|
||||
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{
|
||||
h & static_cast<CBonusSystemNode&>(*this);
|
||||
h & cost;
|
||||
h & upgrades;
|
||||
h & fightValue;
|
||||
h & AIValue;
|
||||
h & growth;
|
||||
h & hordeGrowth;
|
||||
h & ammMin;
|
||||
h & ammMax;
|
||||
h & level;
|
||||
h & animDefName;
|
||||
h & iconIndex;
|
||||
h & smallIconName;
|
||||
h & largeIconName;
|
||||
|
||||
h & idNumber;
|
||||
h & faction;
|
||||
h & sounds;
|
||||
h & animation;
|
||||
|
||||
h & doubleWide;
|
||||
h & special;
|
||||
h & identifier;
|
||||
h & modScope;
|
||||
h & warMachine;
|
||||
}
|
||||
|
||||
CCreature();
|
||||
|
||||
private:
|
||||
@ -303,19 +239,6 @@ public:
|
||||
std::vector<JsonNode> loadLegacyData() override;
|
||||
|
||||
std::vector<bool> getDefaultAllowed() const override;
|
||||
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{
|
||||
//TODO: should be optimized, not all these informations needs to be serialized (same for ccreature)
|
||||
h & doubledCreatures;
|
||||
h & objects;
|
||||
h & expRanks;
|
||||
h & maxExpPerBattle;
|
||||
h & expAfterUpgrade;
|
||||
h & skillLevels;
|
||||
h & skillRequirements;
|
||||
h & commanderLevelPremy;
|
||||
}
|
||||
};
|
||||
|
||||
VCMI_LIB_NAMESPACE_END
|
||||
|
@ -52,13 +52,6 @@ public:
|
||||
ui32 minAmount;
|
||||
ui32 maxAmount;
|
||||
CreatureID creature;
|
||||
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{
|
||||
h & minAmount;
|
||||
h & maxAmount;
|
||||
h & creature;
|
||||
}
|
||||
};
|
||||
si32 imageIndex = 0;
|
||||
|
||||
@ -104,29 +97,6 @@ public:
|
||||
|
||||
void updateFrom(const JsonNode & data);
|
||||
void serializeJson(JsonSerializeFormat & handler);
|
||||
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{
|
||||
h & ID;
|
||||
h & imageIndex;
|
||||
h & initialArmy;
|
||||
h & heroClass;
|
||||
h & secSkillsInit;
|
||||
h & specialty;
|
||||
h & spells;
|
||||
h & haveSpellBook;
|
||||
h & gender;
|
||||
h & special;
|
||||
h & onlyOnWaterMap;
|
||||
h & onlyOnMapWithoutWater;
|
||||
h & iconSpecSmall;
|
||||
h & iconSpecLarge;
|
||||
h & portraitSmall;
|
||||
h & portraitLarge;
|
||||
h & identifier;
|
||||
h & modScope;
|
||||
h & battleImage;
|
||||
}
|
||||
};
|
||||
|
||||
class DLL_LINKAGE CHeroClass : public HeroClass
|
||||
@ -183,25 +153,6 @@ public:
|
||||
void updateFrom(const JsonNode & data);
|
||||
void serializeJson(JsonSerializeFormat & handler);
|
||||
|
||||
template <typename Handler> void serialize(Handler & h, const int version)
|
||||
{
|
||||
h & modScope;
|
||||
h & identifier;
|
||||
h & faction;
|
||||
h & id;
|
||||
h & defaultTavernChance;
|
||||
h & primarySkillInitial;
|
||||
h & primarySkillLowLevel;
|
||||
h & primarySkillHighLevel;
|
||||
h & secSkillProbability;
|
||||
h & selectionProbability;
|
||||
h & affinity;
|
||||
h & commander;
|
||||
h & imageBattleMale;
|
||||
h & imageBattleFemale;
|
||||
h & imageMapMale;
|
||||
h & imageMapFemale;
|
||||
}
|
||||
EAlignment getAlignment() const;
|
||||
};
|
||||
|
||||
@ -218,11 +169,6 @@ public:
|
||||
|
||||
~CHeroClassHandler();
|
||||
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{
|
||||
h & objects;
|
||||
}
|
||||
|
||||
protected:
|
||||
const std::vector<std::string> & getTypeNames() const override;
|
||||
CHeroClass * loadFromJson(const std::string & scope, const JsonNode & node, const std::string & identifier, size_t index) override;
|
||||
@ -262,13 +208,6 @@ public:
|
||||
|
||||
std::vector<bool> getDefaultAllowed() const override;
|
||||
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{
|
||||
h & classes;
|
||||
h & objects;
|
||||
h & expPerLevel;
|
||||
}
|
||||
|
||||
protected:
|
||||
const std::vector<std::string> & getTypeNames() const override;
|
||||
CHero * loadFromJson(const std::string & scope, const JsonNode & node, const std::string & identifier, size_t index) override;
|
||||
|
@ -29,14 +29,6 @@ public:
|
||||
std::string iconMedium;
|
||||
std::string iconLarge;
|
||||
std::vector<std::shared_ptr<Bonus>> effects;
|
||||
|
||||
template <typename Handler> void serialize(Handler & h, const int version)
|
||||
{
|
||||
h & iconSmall;
|
||||
h & iconMedium;
|
||||
h & iconLarge;
|
||||
h & effects;
|
||||
}
|
||||
};
|
||||
|
||||
private:
|
||||
@ -82,17 +74,6 @@ public:
|
||||
|
||||
bool onlyOnWaterMap;
|
||||
|
||||
template <typename Handler> void serialize(Handler & h, const int version)
|
||||
{
|
||||
h & id;
|
||||
h & identifier;
|
||||
h & gainChance;
|
||||
h & levels;
|
||||
h & obligatoryMajor;
|
||||
h & obligatoryMinor;
|
||||
h & onlyOnWaterMap;
|
||||
}
|
||||
|
||||
friend class CSkillHandler;
|
||||
friend DLL_LINKAGE std::ostream & operator<<(std::ostream & out, const CSkill & skill);
|
||||
friend DLL_LINKAGE std::ostream & operator<<(std::ostream & out, const CSkill::LevelInfo & info);
|
||||
@ -111,11 +92,6 @@ public:
|
||||
|
||||
std::vector<bool> getDefaultAllowed() const override;
|
||||
|
||||
template <typename Handler> void serialize(Handler & h, const int version)
|
||||
{
|
||||
h & objects;
|
||||
}
|
||||
|
||||
protected:
|
||||
const std::vector<std::string> & getTypeNames() const override;
|
||||
CSkill * loadFromJson(const std::string & scope, const JsonNode & json, const std::string & identifier, size_t index) override;
|
||||
|
@ -123,25 +123,6 @@ public:
|
||||
|
||||
void addNewBonus(const std::shared_ptr<Bonus> & b, BonusList & bonusList) const;
|
||||
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{
|
||||
h & modScope;
|
||||
h & identifier;
|
||||
h & town;
|
||||
h & bid;
|
||||
h & resources;
|
||||
h & produce;
|
||||
h & requirements;
|
||||
h & upgrade;
|
||||
h & mode;
|
||||
h & subId;
|
||||
h & height;
|
||||
h & overrideBids;
|
||||
h & buildingBonuses;
|
||||
h & onVisitBonuses;
|
||||
h & rewardableObjectInfo;
|
||||
}
|
||||
|
||||
friend class CTownHandler;
|
||||
};
|
||||
|
||||
@ -160,17 +141,6 @@ struct DLL_LINKAGE CStructure
|
||||
std::string identifier;
|
||||
|
||||
bool hiddenUpgrade; // used only if "building" is upgrade, if true - structure on town screen will behave exactly like parent (mouse clicks, hover texts, etc)
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{
|
||||
h & pos;
|
||||
h & defName;
|
||||
h & borderName;
|
||||
h & areaName;
|
||||
h & identifier;
|
||||
h & building;
|
||||
h & buildable;
|
||||
h & hiddenUpgrade;
|
||||
}
|
||||
};
|
||||
|
||||
struct DLL_LINKAGE SPuzzleInfo
|
||||
@ -179,15 +149,6 @@ struct DLL_LINKAGE SPuzzleInfo
|
||||
si16 x, y; //position
|
||||
ui16 whenUncovered; //determines the sequnce of discovering (the lesser it is the sooner puzzle will be discovered)
|
||||
ImagePath filename; //file with graphic of this puzzle
|
||||
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{
|
||||
h & number;
|
||||
h & x;
|
||||
h & y;
|
||||
h & whenUncovered;
|
||||
h & filename;
|
||||
}
|
||||
};
|
||||
|
||||
class DLL_LINKAGE CFaction : public Faction
|
||||
@ -238,20 +199,6 @@ public:
|
||||
|
||||
void updateFrom(const JsonNode & data);
|
||||
void serializeJson(JsonSerializeFormat & handler);
|
||||
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{
|
||||
h & modScope;
|
||||
h & identifier;
|
||||
h & index;
|
||||
h & nativeTerrain;
|
||||
h & boatType;
|
||||
h & alignment;
|
||||
h & town;
|
||||
h & creatureBg120;
|
||||
h & creatureBg130;
|
||||
h & puzzleMap;
|
||||
}
|
||||
};
|
||||
|
||||
class DLL_LINKAGE CTown
|
||||
@ -323,44 +270,7 @@ public:
|
||||
std::string towerIconSmall;
|
||||
std::string towerIconLarge;
|
||||
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{
|
||||
h & icons;
|
||||
h & iconSmall;
|
||||
h & iconLarge;
|
||||
h & tavernVideo;
|
||||
h & musicTheme;
|
||||
h & townBackground;
|
||||
h & guildBackground;
|
||||
h & guildWindow;
|
||||
h & buildingsIcons;
|
||||
h & hallBackground;
|
||||
h & hallSlots;
|
||||
h & structures;
|
||||
h & siegePrefix;
|
||||
h & siegePositions;
|
||||
h & siegeShooter;
|
||||
h & towerIconSmall;
|
||||
h & towerIconLarge;
|
||||
}
|
||||
} clientInfo;
|
||||
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{
|
||||
h & namesCount;
|
||||
h & faction;
|
||||
h & creatures;
|
||||
h & dwellings;
|
||||
h & dwellingNames;
|
||||
h & buildings;
|
||||
h & hordeLvl;
|
||||
h & mageLevel;
|
||||
h & primaryRes;
|
||||
h & warMachine;
|
||||
h & clientInfo;
|
||||
h & moatAbility;
|
||||
h & defaultTavernChance;
|
||||
}
|
||||
|
||||
private:
|
||||
///generated bonusing buildings messages for all towns of this type.
|
||||
@ -445,12 +355,6 @@ public:
|
||||
|
||||
static void loadSpecialBuildingBonuses(const JsonNode & source, BonusList & bonusList, CBuilding * building);
|
||||
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{
|
||||
h & objects;
|
||||
h & randomTown;
|
||||
}
|
||||
|
||||
protected:
|
||||
const std::vector<std::string> & getTypeNames() const override;
|
||||
CFaction * loadFromJson(const std::string & scope, const JsonNode & data, const std::string & identifier, size_t index) override;
|
||||
|
@ -21,10 +21,8 @@
|
||||
#include "bonuses/Propagators.h"
|
||||
#include "bonuses/Updaters.h"
|
||||
|
||||
#include "serializer/CSerializer.h" // for SAVEGAME_MAGIC
|
||||
#include "serializer/BinaryDeserializer.h"
|
||||
#include "serializer/BinarySerializer.h"
|
||||
#include "serializer/CLoadIntegrityValidator.h"
|
||||
#include "serializer/CLoadFile.h"
|
||||
#include "serializer/CSaveFile.h"
|
||||
#include "rmg/CMapGenOptions.h"
|
||||
#include "mapObjectConstructors/AObjectTypeHandler.h"
|
||||
#include "mapObjectConstructors/CObjectClassesHandler.h"
|
||||
@ -41,6 +39,7 @@
|
||||
#include "modding/CModInfo.h"
|
||||
#include "modding/IdentifierStorage.h"
|
||||
#include "modding/CModVersion.h"
|
||||
#include "modding/ActiveModsInSaveList.h"
|
||||
#include "CPlayerState.h"
|
||||
#include "GameSettings.h"
|
||||
#include "ScriptHandler.h"
|
||||
@ -145,14 +144,14 @@ void CPrivilegedInfoCallback::getAllTiles(std::unordered_set<int3> & tiles, std:
|
||||
}
|
||||
}
|
||||
|
||||
void CPrivilegedInfoCallback::pickAllowedArtsSet(std::vector<const CArtifact *> & out, CRandomGenerator & rand) const
|
||||
void CPrivilegedInfoCallback::pickAllowedArtsSet(std::vector<const CArtifact *> & out, CRandomGenerator & rand)
|
||||
{
|
||||
for (int j = 0; j < 3 ; j++)
|
||||
out.push_back(VLC->arth->pickRandomArtifact(rand, CArtifact::ART_TREASURE).toArtifact());
|
||||
out.push_back(gameState()->pickRandomArtifact(rand, CArtifact::ART_TREASURE).toArtifact());
|
||||
for (int j = 0; j < 3 ; j++)
|
||||
out.push_back(VLC->arth->pickRandomArtifact(rand, CArtifact::ART_MINOR).toArtifact());
|
||||
out.push_back(gameState()->pickRandomArtifact(rand, CArtifact::ART_MINOR).toArtifact());
|
||||
|
||||
out.push_back(VLC->arth->pickRandomArtifact(rand, CArtifact::ART_MAJOR).toArtifact());
|
||||
out.push_back(gameState()->pickRandomArtifact(rand, CArtifact::ART_MAJOR).toArtifact());
|
||||
}
|
||||
|
||||
void CPrivilegedInfoCallback::getAllowedSpells(std::vector<SpellID> & out, std::optional<ui16> level)
|
||||
@ -184,6 +183,7 @@ void CPrivilegedInfoCallback::loadCommonState(Loader & in)
|
||||
|
||||
CMapHeader dum;
|
||||
StartInfo * si = nullptr;
|
||||
ActiveModsInSaveList activeMods;
|
||||
|
||||
logGlobal->info("\tReading header");
|
||||
in.serializer & dum;
|
||||
@ -191,8 +191,8 @@ void CPrivilegedInfoCallback::loadCommonState(Loader & in)
|
||||
logGlobal->info("\tReading options");
|
||||
in.serializer & si;
|
||||
|
||||
logGlobal->info("\tReading handlers");
|
||||
in.serializer & *VLC;
|
||||
logGlobal->info("\tReading mod list");
|
||||
in.serializer & activeMods;
|
||||
|
||||
logGlobal->info("\tReading gamestate");
|
||||
in.serializer & gs;
|
||||
@ -201,20 +201,21 @@ void CPrivilegedInfoCallback::loadCommonState(Loader & in)
|
||||
template<typename Saver>
|
||||
void CPrivilegedInfoCallback::saveCommonState(Saver & out) const
|
||||
{
|
||||
ActiveModsInSaveList activeMods;
|
||||
|
||||
logGlobal->info("Saving lib part of game...");
|
||||
out.putMagicBytes(SAVEGAME_MAGIC);
|
||||
logGlobal->info("\tSaving header");
|
||||
out.serializer & static_cast<CMapHeader&>(*gs->map);
|
||||
logGlobal->info("\tSaving options");
|
||||
out.serializer & gs->scenarioOps;
|
||||
logGlobal->info("\tSaving handlers");
|
||||
out.serializer & *VLC;
|
||||
logGlobal->info("\tSaving mod list");
|
||||
out.serializer & activeMods;
|
||||
logGlobal->info("\tSaving gamestate");
|
||||
out.serializer & gs;
|
||||
}
|
||||
|
||||
// hardly memory usage for `-gdwarf-4` flag
|
||||
template DLL_LINKAGE void CPrivilegedInfoCallback::loadCommonState<CLoadIntegrityValidator>(CLoadIntegrityValidator &);
|
||||
template DLL_LINKAGE void CPrivilegedInfoCallback::loadCommonState<CLoadFile>(CLoadFile &);
|
||||
template DLL_LINKAGE void CPrivilegedInfoCallback::saveCommonState<CSaveFile>(CSaveFile &) const;
|
||||
|
||||
|
@ -61,7 +61,7 @@ public:
|
||||
void getAllTiles(std::unordered_set<int3> &tiles, std::optional<PlayerColor> player, int level, std::function<bool(const TerrainTile *)> filter) const;
|
||||
|
||||
//gives 3 treasures, 3 minors, 1 major -> used by Black Market and Artifact Merchant
|
||||
void pickAllowedArtsSet(std::vector<const CArtifact *> & out, CRandomGenerator & rand) const;
|
||||
void pickAllowedArtsSet(std::vector<const CArtifact *> & out, CRandomGenerator & rand);
|
||||
void getAllowedSpells(std::vector<SpellID> &out, std::optional<ui16> level = std::nullopt);
|
||||
|
||||
template<typename Saver>
|
||||
|
@ -247,8 +247,8 @@ namespace JsonDetail
|
||||
static Type convert(const JsonNode & node)
|
||||
{
|
||||
///this should be triggered only for numeric types and enums
|
||||
static_assert(boost::mpl::or_<std::is_arithmetic<Type>, std::is_enum<Type>, boost::is_class<Type> >::value, "Unsupported type for JsonNode::convertTo()!");
|
||||
return JsonConvImpl<Type, boost::mpl::or_<std::is_enum<Type>, boost::is_class<Type> >::value >::convertImpl(node);
|
||||
static_assert(std::is_arithmetic_v<Type> || std::is_enum_v<Type> || std::is_class_v<Type>, "Unsupported type for JsonNode::convertTo()!");
|
||||
return JsonConvImpl<Type, std::is_enum_v<Type> || std::is_class_v<Type> >::convertImpl(node);
|
||||
|
||||
}
|
||||
};
|
||||
|
@ -24,6 +24,7 @@
|
||||
#include "CSkillHandler.h"
|
||||
#include "CHeroHandler.h"
|
||||
#include "IGameCallback.h"
|
||||
#include "gameState/CGameState.h"
|
||||
#include "mapObjects/IObjectInterface.h"
|
||||
#include "modding/IdentifierStorage.h"
|
||||
#include "modding/ModScope.h"
|
||||
@ -388,7 +389,7 @@ namespace JsonRandom
|
||||
|
||||
std::set<ArtifactID> potentialPicks = filterKeys(value, allowedArts, variables);
|
||||
|
||||
return VLC->arth->pickRandomArtifact(rng, potentialPicks);
|
||||
return IObjectInterface::cb->gameState()->pickRandomArtifact(rng, potentialPicks);
|
||||
}
|
||||
|
||||
std::vector<ArtifactID> loadArtifacts(const JsonNode & value, CRandomGenerator & rng, const Variables & variables)
|
||||
|
@ -54,23 +54,6 @@ public:
|
||||
std::vector<BattleHex> getBlocked(BattleHex hex) const; //returns vector of hexes blocked by obstacle when it's placed on hex 'hex'
|
||||
|
||||
bool isAppropriate(const TerrainId terrainType, const BattleField & specialBattlefield) const;
|
||||
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{
|
||||
h & obstacle;
|
||||
h & iconIndex;
|
||||
h & identifier;
|
||||
h & animation;
|
||||
h & appearAnimation;
|
||||
h & appearSound;
|
||||
h & allowedTerrains;
|
||||
h & allowedSpecialBfields;
|
||||
h & isAbsoluteObstacle;
|
||||
h & isForegroundObstacle;
|
||||
h & width;
|
||||
h & height;
|
||||
h & blockedTiles;
|
||||
}
|
||||
};
|
||||
|
||||
class DLL_LINKAGE ObstacleService : public EntityServiceT<Obstacle, ObstacleInfo>
|
||||
@ -89,11 +72,6 @@ public:
|
||||
const std::vector<std::string> & getTypeNames() const override;
|
||||
std::vector<JsonNode> loadLegacyData() override;
|
||||
std::vector<bool> getDefaultAllowed() const override;
|
||||
|
||||
template <typename Handler> void serialize(Handler & h, const int version)
|
||||
{
|
||||
h & objects;
|
||||
}
|
||||
};
|
||||
|
||||
VCMI_LIB_NAMESPACE_END
|
||||
|
@ -24,12 +24,6 @@ struct DLL_LINKAGE RiverPaletteAnimation
|
||||
int32_t start;
|
||||
/// total numbers of colors to cycle
|
||||
int32_t length;
|
||||
|
||||
template <typename Handler> void serialize(Handler& h, const int version)
|
||||
{
|
||||
h & start;
|
||||
h & length;
|
||||
}
|
||||
};
|
||||
|
||||
class DLL_LINKAGE RiverType : public EntityT<RiverId>
|
||||
@ -57,16 +51,6 @@ public:
|
||||
std::vector<RiverPaletteAnimation> paletteAnimation;
|
||||
|
||||
RiverType();
|
||||
|
||||
template <typename Handler> void serialize(Handler& h, const int version)
|
||||
{
|
||||
h & tilesFilename;
|
||||
h & identifier;
|
||||
h & modScope;
|
||||
h & deltaName;
|
||||
h & id;
|
||||
h & paletteAnimation;
|
||||
}
|
||||
};
|
||||
|
||||
class DLL_LINKAGE RiverTypeService : public EntityServiceT<RiverId, RiverType>
|
||||
@ -88,11 +72,6 @@ public:
|
||||
virtual const std::vector<std::string> & getTypeNames() const override;
|
||||
virtual std::vector<JsonNode> loadLegacyData() override;
|
||||
virtual std::vector<bool> getDefaultAllowed() const override;
|
||||
|
||||
template <typename Handler> void serialize(Handler & h, const int version)
|
||||
{
|
||||
h & objects;
|
||||
}
|
||||
};
|
||||
|
||||
VCMI_LIB_NAMESPACE_END
|
||||
|
@ -41,15 +41,6 @@ public:
|
||||
ui8 movementCost;
|
||||
|
||||
RoadType();
|
||||
|
||||
template <typename Handler> void serialize(Handler& h, const int version)
|
||||
{
|
||||
h & tilesFilename;
|
||||
h & identifier;
|
||||
h & modScope;
|
||||
h & id;
|
||||
h & movementCost;
|
||||
}
|
||||
};
|
||||
|
||||
class DLL_LINKAGE RoadTypeService : public EntityServiceT<RoadId, RoadType>
|
||||
@ -71,11 +62,6 @@ public:
|
||||
virtual const std::vector<std::string> & getTypeNames() const override;
|
||||
virtual std::vector<JsonNode> loadLegacyData() override;
|
||||
virtual std::vector<bool> getDefaultAllowed() const override;
|
||||
|
||||
template <typename Handler> void serialize(Handler & h, const int version)
|
||||
{
|
||||
h & objects;
|
||||
}
|
||||
};
|
||||
|
||||
VCMI_LIB_NAMESPACE_END
|
||||
|
@ -91,30 +91,6 @@ public:
|
||||
bool isSurface() const;
|
||||
bool isUnderground() const;
|
||||
bool isTransitionRequired() const;
|
||||
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{
|
||||
h & battleFields;
|
||||
h & prohibitTransitions;
|
||||
h & minimapBlocked;
|
||||
h & minimapUnblocked;
|
||||
h & modScope;
|
||||
h & identifier;
|
||||
h & musicFilename;
|
||||
h & tilesFilename;
|
||||
h & shortIdentifier;
|
||||
h & terrainViewPatterns;
|
||||
h & rockTerrain;
|
||||
h & river;
|
||||
h & paletteAnimation;
|
||||
|
||||
h & id;
|
||||
h & moveCost;
|
||||
h & horseSound;
|
||||
h & horseSoundPenalty;
|
||||
h & passabilityType;
|
||||
h & transitionRequired;
|
||||
}
|
||||
};
|
||||
|
||||
class DLL_LINKAGE TerrainTypeService : public EntityServiceT<TerrainId, TerrainType>
|
||||
@ -134,11 +110,6 @@ public:
|
||||
virtual const std::vector<std::string> & getTypeNames() const override;
|
||||
virtual std::vector<JsonNode> loadLegacyData() override;
|
||||
virtual std::vector<bool> getDefaultAllowed() const override;
|
||||
|
||||
template <typename Handler> void serialize(Handler & h, const int version)
|
||||
{
|
||||
h & objects;
|
||||
}
|
||||
};
|
||||
|
||||
VCMI_LIB_NAMESPACE_END
|
||||
|
@ -120,51 +120,6 @@ public:
|
||||
#if SCRIPTING_ENABLED
|
||||
void scriptsLoaded();
|
||||
#endif
|
||||
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{
|
||||
h & identifiersHandler; // must be first - identifiers registry is used for handlers loading
|
||||
#if SCRIPTING_ENABLED
|
||||
h & scriptHandler;//must be first (or second after identifiers), it can modify factories other handlers depends on
|
||||
if(!h.saving)
|
||||
{
|
||||
scriptsLoaded();
|
||||
}
|
||||
#endif
|
||||
|
||||
h & settingsHandler;
|
||||
h & heroh;
|
||||
h & arth;
|
||||
h & creh;
|
||||
h & townh;
|
||||
h & objh;
|
||||
h & objtypeh;
|
||||
h & spellh;
|
||||
h & skillh;
|
||||
h & battlefieldsHandler;
|
||||
h & obstacleHandler;
|
||||
h & roadTypeHandler;
|
||||
h & riverTypeHandler;
|
||||
h & terrainTypeHandler;
|
||||
|
||||
if(!h.saving)
|
||||
{
|
||||
//modh will be changed and modh->content will be empty after deserialization
|
||||
auto content = getContent();
|
||||
h & modh;
|
||||
setContent(content);
|
||||
}
|
||||
else
|
||||
h & modh;
|
||||
|
||||
h & IS_AI_ENABLED;
|
||||
h & bth;
|
||||
|
||||
if(!h.saving)
|
||||
{
|
||||
callWhenDeserializing();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
extern DLL_LINKAGE LibClasses * VLC;
|
||||
|
@ -22,7 +22,7 @@ public:
|
||||
template<typename T>
|
||||
CSelector(const T &t, //SFINAE trick -> include this c-tor in overload resolution only if parameter is class
|
||||
//(includes functors, lambdas) or function. Without that VC is going mad about ambiguities.
|
||||
typename std::enable_if < boost::mpl::or_ < std::is_class<T>, std::is_function<T >> ::value>::type *dummy = nullptr)
|
||||
typename std::enable_if_t < std::is_class_v<T> || std::is_function_v<T> > *dummy = nullptr)
|
||||
: TBase(t)
|
||||
{}
|
||||
|
||||
|
@ -37,6 +37,8 @@
|
||||
#include "constants/StringConstants.h"
|
||||
#include "CGeneralTextHandler.h"
|
||||
#include "TerrainHandler.h" //TODO: remove
|
||||
#include "RiverHandler.h"
|
||||
#include "RoadHandler.h"
|
||||
#include "BattleFieldHandler.h"
|
||||
#include "ObstacleHandler.h"
|
||||
#include "CTownHandler.h"
|
||||
@ -404,6 +406,11 @@ std::string FactionID::entityType()
|
||||
return "faction";
|
||||
}
|
||||
|
||||
const Faction * FactionID::toEntity(const Services * service) const
|
||||
{
|
||||
return service->factions()->getByIndex(num);
|
||||
}
|
||||
|
||||
si32 TerrainId::decode(const std::string & identifier)
|
||||
{
|
||||
auto rawId = VLC->identifiers()->getIdentifier(ModScope::scopeGame(), entityType(), identifier);
|
||||
@ -423,6 +430,21 @@ std::string TerrainId::entityType()
|
||||
return "terrain";
|
||||
}
|
||||
|
||||
const TerrainType * TerrainId::toEntity(const Services * service) const
|
||||
{
|
||||
return VLC->terrainTypeHandler->getByIndex(num);
|
||||
}
|
||||
|
||||
const RoadType * RoadId::toEntity(const Services * service) const
|
||||
{
|
||||
return VLC->roadTypeHandler->getByIndex(num);
|
||||
}
|
||||
|
||||
const RiverType * RiverId::toEntity(const Services * service) const
|
||||
{
|
||||
return VLC->riverTypeHandler->getByIndex(num);
|
||||
}
|
||||
|
||||
const BattleField BattleField::NONE;
|
||||
|
||||
const BattleFieldInfo * BattleField::getInfo() const
|
||||
|
@ -22,6 +22,10 @@ class CreatureService;
|
||||
class HeroType;
|
||||
class CHero;
|
||||
class HeroTypeService;
|
||||
class Faction;
|
||||
class RoadType;
|
||||
class RiverType;
|
||||
class TerrainType;
|
||||
|
||||
namespace spells
|
||||
{
|
||||
@ -181,20 +185,20 @@ public:
|
||||
static std::string entityType();
|
||||
};
|
||||
|
||||
class HeroTypeID : public Identifier<HeroTypeID>
|
||||
class DLL_LINKAGE HeroTypeID : public Identifier<HeroTypeID>
|
||||
{
|
||||
public:
|
||||
using Identifier<HeroTypeID>::Identifier;
|
||||
///json serialization helpers
|
||||
DLL_LINKAGE static si32 decode(const std::string & identifier);
|
||||
DLL_LINKAGE static std::string encode(const si32 index);
|
||||
static si32 decode(const std::string & identifier);
|
||||
static std::string encode(const si32 index);
|
||||
static std::string entityType();
|
||||
|
||||
const CHero * toHeroType() const;
|
||||
const HeroType * toEntity(const Services * services) const;
|
||||
|
||||
DLL_LINKAGE static const HeroTypeID NONE;
|
||||
DLL_LINKAGE static const HeroTypeID RANDOM;
|
||||
static const HeroTypeID NONE;
|
||||
static const HeroTypeID RANDOM;
|
||||
|
||||
bool isValid() const
|
||||
{
|
||||
@ -349,6 +353,7 @@ public:
|
||||
|
||||
static si32 decode(const std::string& identifier);
|
||||
static std::string encode(const si32 index);
|
||||
const Faction * toEntity(const Services * service) const;
|
||||
static std::string entityType();
|
||||
|
||||
bool isValid() const
|
||||
@ -596,6 +601,8 @@ public:
|
||||
static const RoadId DIRT_ROAD;
|
||||
static const RoadId GRAVEL_ROAD;
|
||||
static const RoadId COBBLESTONE_ROAD;
|
||||
|
||||
const RoadType * toEntity(const Services * service) const;
|
||||
};
|
||||
|
||||
class DLL_LINKAGE RiverId : public Identifier<RiverId>
|
||||
@ -608,6 +615,8 @@ public:
|
||||
static const RiverId ICY_RIVER;
|
||||
static const RiverId MUD_RIVER;
|
||||
static const RiverId LAVA_RIVER;
|
||||
|
||||
const RiverType * toEntity(const Services * service) const;
|
||||
};
|
||||
|
||||
class DLL_LINKAGE EPathfindingLayerBase : public IdentifierBase
|
||||
@ -912,6 +921,7 @@ public:
|
||||
DLL_LINKAGE static si32 decode(const std::string & identifier);
|
||||
DLL_LINKAGE static std::string encode(const si32 index);
|
||||
static std::string entityType();
|
||||
const TerrainType * toEntity(const Services * service) const;
|
||||
};
|
||||
|
||||
class ObstacleInfo;
|
||||
|
@ -42,7 +42,7 @@
|
||||
#include "../modding/IdentifierStorage.h"
|
||||
#include "../pathfinder/CPathfinder.h"
|
||||
#include "../pathfinder/PathfinderOptions.h"
|
||||
#include "../registerTypes/RegisterTypes.h"
|
||||
#include "../registerTypes/RegisterTypesClientPacks.h"
|
||||
#include "../rmg/CMapGenerator.h"
|
||||
#include "../serializer/CMemorySerializer.h"
|
||||
#include "../serializer/CTypeList.h"
|
||||
@ -157,8 +157,7 @@ CGameState::CGameState()
|
||||
gs = this;
|
||||
heroesPool = std::make_unique<TavernHeroesPool>();
|
||||
applier = std::make_shared<CApplier<CBaseForGSApply>>();
|
||||
registerTypesClientPacks1(*applier);
|
||||
registerTypesClientPacks2(*applier);
|
||||
registerTypesClientPacks(*applier);
|
||||
globalEffects.setNodeType(CBonusSystemNode::GLOBAL_EFFECTS);
|
||||
}
|
||||
|
||||
@ -760,7 +759,7 @@ void CGameState::initStartingBonus()
|
||||
logGlobal->error("Cannot give starting artifact - no heroes!");
|
||||
break;
|
||||
}
|
||||
const Artifact * toGive = VLC->arth->pickRandomArtifact(getRandomGenerator(), CArtifact::ART_TREASURE).toEntity(VLC);
|
||||
const Artifact * toGive = pickRandomArtifact(getRandomGenerator(), CArtifact::ART_TREASURE).toEntity(VLC);
|
||||
|
||||
CGHeroInstance *hero = elem.second.heroes[0];
|
||||
if(!giveHeroArtifact(hero, toGive->getId()))
|
||||
@ -921,11 +920,9 @@ void CGameState::initMapObjects()
|
||||
for(CGObjectInstance *obj : map->objects)
|
||||
{
|
||||
if(obj)
|
||||
{
|
||||
logGlobal->trace("Calling Init for object %d, %s, %s", obj->id.getNum(), obj->typeName, obj->subTypeName);
|
||||
obj->initObj(getRandomGenerator());
|
||||
}
|
||||
}
|
||||
logGlobal->debug("\tObject initialization done");
|
||||
for(CGObjectInstance *obj : map->objects)
|
||||
{
|
||||
if(!obj)
|
||||
@ -1136,7 +1133,7 @@ PlayerRelations CGameState::getPlayerRelations( PlayerColor color1, PlayerColor
|
||||
|
||||
void CGameState::apply(CPack *pack)
|
||||
{
|
||||
ui16 typ = typeList.getTypeID(pack);
|
||||
ui16 typ = CTypeList::getInstance().getTypeID(pack);
|
||||
applier->getApplier(typ)->applyOnGS(this, pack);
|
||||
}
|
||||
|
||||
@ -1971,4 +1968,73 @@ CRandomGenerator & CGameState::getRandomGenerator()
|
||||
return rand;
|
||||
}
|
||||
|
||||
ArtifactID CGameState::pickRandomArtifact(CRandomGenerator & rand, int flags, std::function<bool(ArtifactID)> accepts)
|
||||
{
|
||||
std::set<ArtifactID> potentialPicks;
|
||||
|
||||
// Select artifacts that satisfy provided criterias
|
||||
for (auto const * artifact : VLC->arth->allowedArtifacts)
|
||||
{
|
||||
assert(artifact->aClass != CArtifact::ART_SPECIAL); // should be filtered out when allowedArtifacts is initialized
|
||||
|
||||
if ((flags & CArtifact::ART_TREASURE) == 0 && artifact->aClass == CArtifact::ART_TREASURE)
|
||||
continue;
|
||||
|
||||
if ((flags & CArtifact::ART_MINOR) == 0 && artifact->aClass == CArtifact::ART_MINOR)
|
||||
continue;
|
||||
|
||||
if ((flags & CArtifact::ART_MAJOR) == 0 && artifact->aClass == CArtifact::ART_MAJOR)
|
||||
continue;
|
||||
|
||||
if ((flags & CArtifact::ART_RELIC) == 0 && artifact->aClass == CArtifact::ART_RELIC)
|
||||
continue;
|
||||
|
||||
if (!accepts(artifact->getId()))
|
||||
continue;
|
||||
|
||||
potentialPicks.insert(artifact->getId());
|
||||
}
|
||||
|
||||
return pickRandomArtifact(rand, potentialPicks);
|
||||
}
|
||||
|
||||
ArtifactID CGameState::pickRandomArtifact(CRandomGenerator & rand, std::set<ArtifactID> potentialPicks)
|
||||
{
|
||||
// No allowed artifacts at all - give Grail - this can't be banned (hopefully)
|
||||
// FIXME: investigate how such cases are handled by H3 - some heavily customized user-made maps likely rely on H3 behavior
|
||||
if (potentialPicks.empty())
|
||||
{
|
||||
logGlobal->warn("Failed to find artifact that matches requested parameters!");
|
||||
return ArtifactID::GRAIL;
|
||||
}
|
||||
|
||||
// Find how many times least used artifacts were picked by randomizer
|
||||
int leastUsedTimes = std::numeric_limits<int>::max();
|
||||
for (auto const & artifact : potentialPicks)
|
||||
if (allocatedArtifacts[artifact] < leastUsedTimes)
|
||||
leastUsedTimes = allocatedArtifacts[artifact];
|
||||
|
||||
// Pick all artifacts that were used least number of times
|
||||
std::set<ArtifactID> preferredPicks;
|
||||
for (auto const & artifact : potentialPicks)
|
||||
if (allocatedArtifacts[artifact] == leastUsedTimes)
|
||||
preferredPicks.insert(artifact);
|
||||
|
||||
assert(!preferredPicks.empty());
|
||||
|
||||
ArtifactID artID = *RandomGeneratorUtil::nextItem(preferredPicks, rand);
|
||||
allocatedArtifacts[artID] += 1; // record +1 more usage
|
||||
return artID;
|
||||
}
|
||||
|
||||
ArtifactID CGameState::pickRandomArtifact(CRandomGenerator & rand, std::function<bool(ArtifactID)> accepts)
|
||||
{
|
||||
return pickRandomArtifact(rand, 0xff, std::move(accepts));
|
||||
}
|
||||
|
||||
ArtifactID CGameState::pickRandomArtifact(CRandomGenerator & rand, int flags)
|
||||
{
|
||||
return pickRandomArtifact(rand, flags, [](const ArtifactID &) { return true; });
|
||||
}
|
||||
|
||||
VCMI_LIB_NAMESPACE_END
|
||||
|
@ -83,6 +83,9 @@ class DLL_LINKAGE CGameState : public CNonConstInfoCallback
|
||||
friend class CGameStateCampaign;
|
||||
|
||||
public:
|
||||
/// Stores number of times each artifact was placed on map via randomization
|
||||
std::map<ArtifactID, int> allocatedArtifacts;
|
||||
|
||||
/// List of currently ongoing battles
|
||||
std::vector<std::unique_ptr<BattleInfo>> currentBattles;
|
||||
/// ID that can be allocated to next battle
|
||||
@ -130,6 +133,12 @@ public:
|
||||
std::vector<CGObjectInstance*> guardingCreatures (int3 pos) const;
|
||||
void updateRumor();
|
||||
|
||||
/// Gets a artifact ID randomly and removes the selected artifact from this handler.
|
||||
ArtifactID pickRandomArtifact(CRandomGenerator & rand, int flags);
|
||||
ArtifactID pickRandomArtifact(CRandomGenerator & rand, std::function<bool(ArtifactID)> accepts);
|
||||
ArtifactID pickRandomArtifact(CRandomGenerator & rand, int flags, std::function<bool(ArtifactID)> accepts);
|
||||
ArtifactID pickRandomArtifact(CRandomGenerator & rand, std::set<ArtifactID> filtered);
|
||||
|
||||
/// Returns battle in which selected player is engaged, or nullptr if none.
|
||||
/// Can NOT be used with neutral player, use battle by ID instead
|
||||
const BattleInfo * getBattle(const PlayerColor & player) const;
|
||||
@ -176,6 +185,7 @@ public:
|
||||
h & rand;
|
||||
h & rumor;
|
||||
h & campaign;
|
||||
h & allocatedArtifacts;
|
||||
|
||||
BONUS_TREE_DESERIALIZATION_FIX
|
||||
}
|
||||
|
@ -16,7 +16,7 @@
|
||||
#include "../campaign/CampaignState.h"
|
||||
#include "../mapping/CMapEditManager.h"
|
||||
#include "../mapObjects/CGHeroInstance.h"
|
||||
#include "../registerTypes/RegisterTypes.h"
|
||||
#include "../networkPacks/ArtifactLocation.h"
|
||||
#include "../mapObjectConstructors/AObjectTypeHandler.h"
|
||||
#include "../mapObjectConstructors/CObjectClassesHandler.h"
|
||||
#include "../StartInfo.h"
|
||||
|
@ -112,20 +112,6 @@ public:
|
||||
|
||||
/// Returns object configuration, if available. Otherwise returns NULL
|
||||
virtual std::unique_ptr<IObjectInfo> getObjectInfo(std::shared_ptr<const ObjectTemplate> tmpl) const;
|
||||
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{
|
||||
h & type;
|
||||
h & subtype;
|
||||
h & templates;
|
||||
h & rmgInfo;
|
||||
h & modScope;
|
||||
h & typeName;
|
||||
h & subTypeName;
|
||||
h & sounds;
|
||||
h & aiValue;
|
||||
h & battlefield;
|
||||
}
|
||||
};
|
||||
|
||||
VCMI_LIB_NAMESPACE_END
|
||||
|
@ -92,15 +92,6 @@ public:
|
||||
bool hasNameTextID() const override;
|
||||
|
||||
std::unique_ptr<IObjectInfo> getObjectInfo(std::shared_ptr<const ObjectTemplate> tmpl) const override;
|
||||
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{
|
||||
h & levels;
|
||||
h & bankResetDuration;
|
||||
h & blockVisit;
|
||||
h & coastVisitable;
|
||||
h & static_cast<CDefaultObjectTypeHandler<CBank>&>(*this);
|
||||
}
|
||||
};
|
||||
|
||||
VCMI_LIB_NAMESPACE_END
|
||||
|
@ -62,16 +62,6 @@ public:
|
||||
std::string getJsonKey() const;
|
||||
std::string getNameTextID() const;
|
||||
std::string getNameTranslated() const;
|
||||
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{
|
||||
h & id;
|
||||
h & handlerName;
|
||||
h & base;
|
||||
h & objects;
|
||||
h & identifier;
|
||||
h & modScope;
|
||||
}
|
||||
};
|
||||
|
||||
/// Main class responsible for creation of all adventure map objects
|
||||
@ -130,11 +120,6 @@ public:
|
||||
std::string getObjectHandlerName(MapObjectID type) const;
|
||||
|
||||
std::string getJsonKey(MapObjectID type) const;
|
||||
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{
|
||||
h & objects;
|
||||
}
|
||||
};
|
||||
|
||||
VCMI_LIB_NAMESPACE_END
|
||||
|
@ -30,13 +30,6 @@ public:
|
||||
void configureObject(CGObjectInstance * object, CRandomGenerator & rng) const override;
|
||||
|
||||
std::unique_ptr<IObjectInfo> getObjectInfo(std::shared_ptr<const ObjectTemplate> tmpl) const override;
|
||||
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{
|
||||
AObjectTypeHandler::serialize(h, version);
|
||||
|
||||
h & objectInfo;
|
||||
}
|
||||
};
|
||||
|
||||
VCMI_LIB_NAMESPACE_END
|
||||
|
@ -66,14 +66,6 @@ public:
|
||||
|
||||
bool hasNameTextID() const override;
|
||||
std::string getNameTextID() const override;
|
||||
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{
|
||||
h & filtersJson;
|
||||
h & faction;
|
||||
h & filters;
|
||||
h & static_cast<CDefaultObjectTypeHandler<CGTownInstance>&>(*this);
|
||||
}
|
||||
};
|
||||
|
||||
class CHeroInstanceConstructor : public CDefaultObjectTypeHandler<CGHeroInstance>
|
||||
@ -93,14 +85,6 @@ public:
|
||||
|
||||
bool hasNameTextID() const override;
|
||||
std::string getNameTextID() const override;
|
||||
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{
|
||||
h & filtersJson;
|
||||
h & heroClass;
|
||||
h & filters;
|
||||
h & static_cast<CDefaultObjectTypeHandler<CGHeroInstance>&>(*this);
|
||||
}
|
||||
};
|
||||
|
||||
class DLL_LINKAGE BoatInstanceConstructor : public CDefaultObjectTypeHandler<CGBoat>
|
||||
@ -122,18 +106,6 @@ public:
|
||||
|
||||
/// Returns boat preview animation, for use in Shipyards
|
||||
AnimationPath getBoatAnimationName() const;
|
||||
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{
|
||||
h & static_cast<CDefaultObjectTypeHandler<CGBoat>&>(*this);
|
||||
h & layer;
|
||||
h & onboardAssaultAllowed;
|
||||
h & onboardVisitAllowed;
|
||||
h & bonuses;
|
||||
h & actualAnimation;
|
||||
h & overlayAnimation;
|
||||
h & flagAnimations;
|
||||
}
|
||||
};
|
||||
|
||||
class MarketInstanceConstructor : public CDefaultObjectTypeHandler<CGMarket>
|
||||
@ -152,12 +124,6 @@ public:
|
||||
void initializeObject(CGMarket * object) const override;
|
||||
void randomizeObject(CGMarket * object, CRandomGenerator & rng) const override;
|
||||
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{
|
||||
h & static_cast<CDefaultObjectTypeHandler<CGMarket>&>(*this);
|
||||
h & marketModes;
|
||||
h & marketEfficiency;
|
||||
}
|
||||
};
|
||||
|
||||
VCMI_LIB_NAMESPACE_END
|
||||
|
@ -33,13 +33,6 @@ public:
|
||||
|
||||
bool producesCreature(const CCreature * crea) const;
|
||||
std::vector<const CCreature *> getProducedCreatures() const;
|
||||
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{
|
||||
h & availableCreatures;
|
||||
h & guards;
|
||||
h & static_cast<CDefaultObjectTypeHandler<CGDwelling>&>(*this);
|
||||
}
|
||||
};
|
||||
|
||||
VCMI_LIB_NAMESPACE_END
|
||||
|
@ -24,11 +24,6 @@ protected:
|
||||
void initializeObject(HillFort * object) const override;
|
||||
|
||||
public:
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{
|
||||
h & static_cast<AObjectTypeHandler&>(*this);
|
||||
h & parameters;
|
||||
}
|
||||
};
|
||||
|
||||
VCMI_LIB_NAMESPACE_END
|
||||
|
@ -33,14 +33,6 @@ struct DLL_LINKAGE RandomMapInfo
|
||||
{}
|
||||
|
||||
void setMapLimit(ui32 val) { mapLimit = val; }
|
||||
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{
|
||||
h & value;
|
||||
h & mapLimit;
|
||||
h & zoneLimit;
|
||||
h & rarity;
|
||||
}
|
||||
};
|
||||
|
||||
VCMI_LIB_NAMESPACE_END
|
||||
|
@ -18,13 +18,6 @@ struct SObjectSounds
|
||||
std::vector<AudioPath> ambient;
|
||||
std::vector<AudioPath> visit;
|
||||
std::vector<AudioPath> removal;
|
||||
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{
|
||||
h & ambient;
|
||||
h & visit;
|
||||
h & removal;
|
||||
}
|
||||
};
|
||||
|
||||
VCMI_LIB_NAMESPACE_END
|
||||
|
@ -24,11 +24,6 @@ protected:
|
||||
void initializeObject(CGShipyard * object) const override;
|
||||
|
||||
public:
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{
|
||||
h & static_cast<AObjectTypeHandler&>(*this);
|
||||
h & parameters;
|
||||
}
|
||||
};
|
||||
|
||||
VCMI_LIB_NAMESPACE_END
|
||||
|
@ -117,7 +117,7 @@ std::set<int3> CGObjectInstance::getBlockedPos() const
|
||||
return ret;
|
||||
}
|
||||
|
||||
std::set<int3> CGObjectInstance::getBlockedOffsets() const
|
||||
const std::set<int3> & CGObjectInstance::getBlockedOffsets() const
|
||||
{
|
||||
return appearance->getBlockedOffsets();
|
||||
}
|
||||
|
@ -77,7 +77,7 @@ public:
|
||||
bool coveringAt (const int3 & pos) const; //returns true if object covers with picture location (x, y) (h3m pos)
|
||||
|
||||
std::set<int3> getBlockedPos() const; //returns set of positions blocked by this object
|
||||
std::set<int3> getBlockedOffsets() const; //returns set of relative positions blocked by this object
|
||||
const std::set<int3> & getBlockedOffsets() const; //returns set of relative positions blocked by this object
|
||||
|
||||
/// returns true if object is visitable
|
||||
bool isVisitable() const;
|
||||
|
@ -92,7 +92,18 @@ public:
|
||||
for(auto * bonusingBuilding : bonusingBuildings)
|
||||
bonusingBuilding->town = this;
|
||||
|
||||
h & town;
|
||||
if (h.saving)
|
||||
{
|
||||
CFaction * faction = town ? town->faction : nullptr;
|
||||
h & faction;
|
||||
}
|
||||
else
|
||||
{
|
||||
CFaction * faction = nullptr;
|
||||
h & faction;
|
||||
town = faction ? faction->town : nullptr;
|
||||
}
|
||||
|
||||
h & townAndVis;
|
||||
BONUS_TREE_DESERIALIZATION_FIX
|
||||
|
||||
|
@ -22,11 +22,6 @@ public:
|
||||
std::vector<ui32> resVals; //default values of resources in gold
|
||||
|
||||
CObjectHandler();
|
||||
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{
|
||||
h & resVals;
|
||||
}
|
||||
};
|
||||
|
||||
VCMI_LIB_NAMESPACE_END
|
||||
|
@ -724,19 +724,19 @@ void CGArtifact::pickRandomObject(CRandomGenerator & rand)
|
||||
switch(ID.toEnum())
|
||||
{
|
||||
case MapObjectID::RANDOM_ART:
|
||||
subID = VLC->arth->pickRandomArtifact(rand, CArtifact::ART_TREASURE | CArtifact::ART_MINOR | CArtifact::ART_MAJOR | CArtifact::ART_RELIC);
|
||||
subID = cb->gameState()->pickRandomArtifact(rand, CArtifact::ART_TREASURE | CArtifact::ART_MINOR | CArtifact::ART_MAJOR | CArtifact::ART_RELIC);
|
||||
break;
|
||||
case MapObjectID::RANDOM_TREASURE_ART:
|
||||
subID = VLC->arth->pickRandomArtifact(rand, CArtifact::ART_TREASURE);
|
||||
subID = cb->gameState()->pickRandomArtifact(rand, CArtifact::ART_TREASURE);
|
||||
break;
|
||||
case MapObjectID::RANDOM_MINOR_ART:
|
||||
subID = VLC->arth->pickRandomArtifact(rand, CArtifact::ART_MINOR);
|
||||
subID = cb->gameState()->pickRandomArtifact(rand, CArtifact::ART_MINOR);
|
||||
break;
|
||||
case MapObjectID::RANDOM_MAJOR_ART:
|
||||
subID = VLC->arth->pickRandomArtifact(rand, CArtifact::ART_MAJOR);
|
||||
subID = cb->gameState()->pickRandomArtifact(rand, CArtifact::ART_MAJOR);
|
||||
break;
|
||||
case MapObjectID::RANDOM_RELIC_ART:
|
||||
subID = VLC->arth->pickRandomArtifact(rand, CArtifact::ART_RELIC);
|
||||
subID = cb->gameState()->pickRandomArtifact(rand, CArtifact::ART_RELIC);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -80,7 +80,7 @@ public:
|
||||
bool isVisibleAt(si32 X, si32 Y) const;
|
||||
bool isBlockedAt(si32 X, si32 Y) const;
|
||||
|
||||
inline std::set<int3> getBlockedOffsets() const
|
||||
inline const std::set<int3> & getBlockedOffsets() const
|
||||
{
|
||||
return blockedOffsets;
|
||||
};
|
||||
|
@ -20,7 +20,7 @@ VCMI_LIB_NAMESPACE_BEGIN
|
||||
|
||||
class CGObjectInstance;
|
||||
enum class EMapFormat : uint8_t;
|
||||
using ModCompatibilityInfo = std::map<std::string, CModInfo::VerificationInfo>;
|
||||
using ModCompatibilityInfo = std::map<std::string, ModVerificationInfo>;
|
||||
|
||||
/// The hero name struct consists of the hero id and the hero name.
|
||||
struct DLL_LINKAGE SHeroName
|
||||
|
@ -21,7 +21,7 @@
|
||||
|
||||
#include "../campaign/CampaignHandler.h"
|
||||
#include "../filesystem/Filesystem.h"
|
||||
#include "../serializer/CMemorySerializer.h"
|
||||
#include "../serializer/CLoadFile.h"
|
||||
#include "../CGeneralTextHandler.h"
|
||||
#include "../rmg/CMapGenOptions.h"
|
||||
#include "../CCreatureHandler.h"
|
||||
|
@ -23,7 +23,7 @@ class CInputStream;
|
||||
class IMapLoader;
|
||||
class IMapPatcher;
|
||||
|
||||
using ModCompatibilityInfo = std::map<std::string, CModInfo::VerificationInfo>;
|
||||
using ModCompatibilityInfo = std::map<std::string, ModVerificationInfo>;
|
||||
|
||||
/**
|
||||
* The map service provides loading of VCMI/H3 map files. It can
|
||||
|
@ -966,7 +966,7 @@ void CMapLoaderJson::readHeader(const bool complete)
|
||||
{
|
||||
for(auto & mod : header["mods"].Vector())
|
||||
{
|
||||
CModInfo::VerificationInfo info;
|
||||
ModVerificationInfo info;
|
||||
info.version = CModVersion::fromString(mod["version"].String());
|
||||
info.checksum = mod["checksum"].Integer();
|
||||
info.name = mod["name"].String();
|
||||
|
112
lib/modding/ActiveModsInSaveList.cpp
Normal file
112
lib/modding/ActiveModsInSaveList.cpp
Normal file
@ -0,0 +1,112 @@
|
||||
/*
|
||||
* ActiveModsInSaveList.cpp, 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
|
||||
*
|
||||
*/
|
||||
#include "StdInc.h"
|
||||
#include "ActiveModsInSaveList.h"
|
||||
|
||||
#include "../VCMI_Lib.h"
|
||||
#include "CModInfo.h"
|
||||
#include "CModHandler.h"
|
||||
#include "ModIncompatibility.h"
|
||||
|
||||
VCMI_LIB_NAMESPACE_BEGIN
|
||||
|
||||
std::vector<TModID> ActiveModsInSaveList::getActiveMods()
|
||||
{
|
||||
return VLC->modh->getActiveMods();
|
||||
}
|
||||
|
||||
const ModVerificationInfo & ActiveModsInSaveList::getVerificationInfo(TModID mod)
|
||||
{
|
||||
return VLC->modh->getModInfo(mod).getVerificationInfo();
|
||||
}
|
||||
|
||||
void ActiveModsInSaveList::verifyActiveMods(const std::vector<std::pair<TModID, ModVerificationInfo>> & modList)
|
||||
{
|
||||
auto searchVerificationInfo = [&modList](const TModID & m) -> const ModVerificationInfo*
|
||||
{
|
||||
for(auto & i : modList)
|
||||
if(i.first == m)
|
||||
return &i.second;
|
||||
return nullptr;
|
||||
};
|
||||
|
||||
std::vector<TModID> missingMods, excessiveMods;
|
||||
ModIncompatibility::ModListWithVersion missingModsResult;
|
||||
ModIncompatibility::ModList excessiveModsResult;
|
||||
|
||||
for(const auto & m : VLC->modh->getActiveMods())
|
||||
{
|
||||
if(searchVerificationInfo(m))
|
||||
continue;
|
||||
|
||||
//TODO: support actual disabling of these mods
|
||||
if(VLC->modh->getModInfo(m).checkModGameplayAffecting())
|
||||
excessiveMods.push_back(m);
|
||||
}
|
||||
|
||||
for(const auto & infoPair : modList)
|
||||
{
|
||||
auto & remoteModId = infoPair.first;
|
||||
auto & remoteModInfo = infoPair.second;
|
||||
|
||||
bool modAffectsGameplay = remoteModInfo.impactsGameplay;
|
||||
//parent mod affects gameplay if child affects too
|
||||
for(const auto & subInfoPair : modList)
|
||||
modAffectsGameplay |= (subInfoPair.second.impactsGameplay && subInfoPair.second.parent == remoteModId);
|
||||
|
||||
if(!vstd::contains(VLC->modh->getAllMods(), remoteModId))
|
||||
{
|
||||
if(modAffectsGameplay)
|
||||
missingMods.push_back(remoteModId); //mod is not installed
|
||||
continue;
|
||||
}
|
||||
|
||||
auto & localModInfo = VLC->modh->getModInfo(remoteModId).getVerificationInfo();
|
||||
modAffectsGameplay |= VLC->modh->getModInfo(remoteModId).checkModGameplayAffecting();
|
||||
bool modVersionCompatible = localModInfo.version.isNull()
|
||||
|| remoteModInfo.version.isNull()
|
||||
|| localModInfo.version.compatible(remoteModInfo.version);
|
||||
bool modLocalyEnabled = vstd::contains(VLC->modh->getActiveMods(), remoteModId);
|
||||
|
||||
if(modVersionCompatible && modAffectsGameplay && modLocalyEnabled)
|
||||
continue;
|
||||
|
||||
if(modAffectsGameplay)
|
||||
missingMods.push_back(remoteModId); //incompatible mod impacts gameplay
|
||||
}
|
||||
|
||||
//filter mods
|
||||
for(auto & m : missingMods)
|
||||
{
|
||||
if(auto * vInfo = searchVerificationInfo(m))
|
||||
{
|
||||
assert(vInfo->parent != m);
|
||||
if(!vInfo->parent.empty() && vstd::contains(missingMods, vInfo->parent))
|
||||
continue;
|
||||
missingModsResult.push_back({vInfo->name, vInfo->version.toString()});
|
||||
}
|
||||
}
|
||||
for(auto & m : excessiveMods)
|
||||
{
|
||||
auto & vInfo = VLC->modh->getModInfo(m).getVerificationInfo();
|
||||
assert(vInfo.parent != m);
|
||||
if(!vInfo.parent.empty() && vstd::contains(excessiveMods, vInfo.parent))
|
||||
continue;
|
||||
excessiveModsResult.push_back(vInfo.name);
|
||||
}
|
||||
|
||||
if(!missingModsResult.empty() || !excessiveModsResult.empty())
|
||||
throw ModIncompatibility(missingModsResult, excessiveModsResult);
|
||||
|
||||
//TODO: support actual enabling of required mods
|
||||
}
|
||||
|
||||
|
||||
VCMI_LIB_NAMESPACE_END
|
51
lib/modding/ActiveModsInSaveList.h
Normal file
51
lib/modding/ActiveModsInSaveList.h
Normal file
@ -0,0 +1,51 @@
|
||||
/*
|
||||
* ActiveModsInSaveList.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
|
||||
|
||||
#include "ModVerificationInfo.h"
|
||||
|
||||
VCMI_LIB_NAMESPACE_BEGIN
|
||||
|
||||
class ActiveModsInSaveList
|
||||
{
|
||||
std::vector<TModID> getActiveMods();
|
||||
const ModVerificationInfo & getVerificationInfo(TModID mod);
|
||||
|
||||
/// Checks whether provided mod list is compatible with current VLC and throws on failure
|
||||
void verifyActiveMods(const std::vector<std::pair<TModID, ModVerificationInfo>> & modList);
|
||||
public:
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{
|
||||
if(h.saving)
|
||||
{
|
||||
std::vector<TModID> activeMods = getActiveMods();
|
||||
h & activeMods;
|
||||
for(const auto & m : activeMods)
|
||||
h & getVerificationInfo(m);
|
||||
}
|
||||
else
|
||||
{
|
||||
std::vector<TModID> saveActiveMods;
|
||||
h & saveActiveMods;
|
||||
|
||||
std::vector<std::pair<TModID, ModVerificationInfo>> saveModInfos(saveActiveMods.size());
|
||||
for(int i = 0; i < saveActiveMods.size(); ++i)
|
||||
{
|
||||
saveModInfos[i].first = saveActiveMods[i];
|
||||
h & saveModInfos[i].second;
|
||||
}
|
||||
|
||||
verifyActiveMods(saveModInfos);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
VCMI_LIB_NAMESPACE_END
|
@ -491,88 +491,6 @@ void CModHandler::afterLoad(bool onlyEssential)
|
||||
std::fstream file(CResourceHandler::get()->getResourceName(ResourcePath("config/modSettings.json"))->c_str(), std::ofstream::out | std::ofstream::trunc);
|
||||
file << modSettings.toJson();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void CModHandler::trySetActiveMods(const std::vector<std::pair<TModID, CModInfo::VerificationInfo>> & modList)
|
||||
{
|
||||
auto searchVerificationInfo = [&modList](const TModID & m) -> const CModInfo::VerificationInfo*
|
||||
{
|
||||
for(auto & i : modList)
|
||||
if(i.first == m)
|
||||
return &i.second;
|
||||
return nullptr;
|
||||
};
|
||||
|
||||
std::vector<TModID> missingMods, excessiveMods;
|
||||
ModIncompatibility::ModListWithVersion missingModsResult;
|
||||
ModIncompatibility::ModList excessiveModsResult;
|
||||
|
||||
for(const auto & m : activeMods)
|
||||
{
|
||||
if(searchVerificationInfo(m))
|
||||
continue;
|
||||
|
||||
//TODO: support actual disabling of these mods
|
||||
if(getModInfo(m).checkModGameplayAffecting())
|
||||
excessiveMods.push_back(m);
|
||||
}
|
||||
|
||||
for(const auto & infoPair : modList)
|
||||
{
|
||||
auto & remoteModId = infoPair.first;
|
||||
auto & remoteModInfo = infoPair.second;
|
||||
|
||||
bool modAffectsGameplay = remoteModInfo.impactsGameplay;
|
||||
//parent mod affects gameplay if child affects too
|
||||
for(const auto & subInfoPair : modList)
|
||||
modAffectsGameplay |= (subInfoPair.second.impactsGameplay && subInfoPair.second.parent == remoteModId);
|
||||
|
||||
if(!allMods.count(remoteModId))
|
||||
{
|
||||
if(modAffectsGameplay)
|
||||
missingMods.push_back(remoteModId); //mod is not installed
|
||||
continue;
|
||||
}
|
||||
|
||||
auto & localModInfo = getModInfo(remoteModId).getVerificationInfo();
|
||||
modAffectsGameplay |= getModInfo(remoteModId).checkModGameplayAffecting();
|
||||
bool modVersionCompatible = localModInfo.version.isNull()
|
||||
|| remoteModInfo.version.isNull()
|
||||
|| localModInfo.version.compatible(remoteModInfo.version);
|
||||
bool modLocalyEnabled = vstd::contains(activeMods, remoteModId);
|
||||
|
||||
if(modVersionCompatible && modAffectsGameplay && modLocalyEnabled)
|
||||
continue;
|
||||
|
||||
if(modAffectsGameplay)
|
||||
missingMods.push_back(remoteModId); //incompatible mod impacts gameplay
|
||||
}
|
||||
|
||||
//filter mods
|
||||
for(auto & m : missingMods)
|
||||
{
|
||||
if(auto * vInfo = searchVerificationInfo(m))
|
||||
{
|
||||
assert(vInfo->parent != m);
|
||||
if(!vInfo->parent.empty() && vstd::contains(missingMods, vInfo->parent))
|
||||
continue;
|
||||
missingModsResult.push_back({vInfo->name, vInfo->version.toString()});
|
||||
}
|
||||
}
|
||||
for(auto & m : excessiveMods)
|
||||
{
|
||||
auto & vInfo = getModInfo(m).getVerificationInfo();
|
||||
assert(vInfo.parent != m);
|
||||
if(!vInfo.parent.empty() && vstd::contains(excessiveMods, vInfo.parent))
|
||||
continue;
|
||||
excessiveModsResult.push_back(vInfo.name);
|
||||
}
|
||||
|
||||
if(!missingModsResult.empty() || !excessiveModsResult.empty())
|
||||
throw ModIncompatibility(missingModsResult, excessiveModsResult);
|
||||
|
||||
//TODO: support actual enabling of required mods
|
||||
}
|
||||
|
||||
VCMI_LIB_NAMESPACE_END
|
||||
|
@ -9,21 +9,22 @@
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "CModInfo.h"
|
||||
|
||||
VCMI_LIB_NAMESPACE_BEGIN
|
||||
|
||||
class CModHandler;
|
||||
class CModIndentifier;
|
||||
class CModInfo;
|
||||
struct CModVersion;
|
||||
class JsonNode;
|
||||
class IHandlerBase;
|
||||
class CIdentifierStorage;
|
||||
class CContentHandler;
|
||||
struct ModVerificationInfo;
|
||||
class ResourcePath;
|
||||
|
||||
using TModID = std::string;
|
||||
|
||||
class DLL_LINKAGE CModHandler : boost::noncopyable
|
||||
class DLL_LINKAGE CModHandler final : boost::noncopyable
|
||||
{
|
||||
std::map <TModID, CModInfo> allMods;
|
||||
std::vector <TModID> activeMods;//active mods, in order in which they were loaded
|
||||
@ -50,9 +51,6 @@ class DLL_LINKAGE CModHandler : boost::noncopyable
|
||||
|
||||
CModVersion getModVersion(TModID modName) const;
|
||||
|
||||
/// Attempt to set active mods according to provided list of mods from save, throws on failure
|
||||
void trySetActiveMods(const std::vector<std::pair<TModID, CModInfo::VerificationInfo>> & modList);
|
||||
|
||||
public:
|
||||
std::shared_ptr<CContentHandler> content; //(!)Do not serialize FIXME: make private
|
||||
|
||||
@ -79,32 +77,7 @@ public:
|
||||
void afterLoad(bool onlyEssential);
|
||||
|
||||
CModHandler();
|
||||
virtual ~CModHandler();
|
||||
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{
|
||||
if(h.saving)
|
||||
{
|
||||
h & activeMods;
|
||||
for(const auto & m : activeMods)
|
||||
h & getModInfo(m).getVerificationInfo();
|
||||
}
|
||||
else
|
||||
{
|
||||
loadMods();
|
||||
std::vector<TModID> saveActiveMods;
|
||||
h & saveActiveMods;
|
||||
|
||||
std::vector<std::pair<TModID, CModInfo::VerificationInfo>> saveModInfos(saveActiveMods.size());
|
||||
for(int i = 0; i < saveActiveMods.size(); ++i)
|
||||
{
|
||||
saveModInfos[i].first = saveActiveMods[i];
|
||||
h & saveModInfos[i].second;
|
||||
}
|
||||
|
||||
trySetActiveMods(saveModInfos);
|
||||
}
|
||||
}
|
||||
~CModHandler();
|
||||
};
|
||||
|
||||
VCMI_LIB_NAMESPACE_END
|
||||
|
@ -177,7 +177,7 @@ bool CModInfo::checkModGameplayAffecting() const
|
||||
return *modGameplayAffecting;
|
||||
}
|
||||
|
||||
const CModInfo::VerificationInfo & CModInfo::getVerificationInfo() const
|
||||
const ModVerificationInfo & CModInfo::getVerificationInfo() const
|
||||
{
|
||||
return verificationInfo;
|
||||
}
|
||||
|
@ -10,12 +10,10 @@
|
||||
#pragma once
|
||||
|
||||
#include "../JsonNode.h"
|
||||
#include "CModVersion.h"
|
||||
#include "ModVerificationInfo.h"
|
||||
|
||||
VCMI_LIB_NAMESPACE_BEGIN
|
||||
|
||||
using TModID = std::string;
|
||||
|
||||
class DLL_LINKAGE CModInfo
|
||||
{
|
||||
/// cached result of checkModGameplayAffecting() call
|
||||
@ -30,34 +28,6 @@ public:
|
||||
PASSED
|
||||
};
|
||||
|
||||
struct VerificationInfo
|
||||
{
|
||||
/// human-readable mod name
|
||||
std::string name;
|
||||
|
||||
/// version of the mod
|
||||
CModVersion version;
|
||||
|
||||
/// CRC-32 checksum of the mod
|
||||
ui32 checksum = 0;
|
||||
|
||||
/// parent mod ID, empty if root-level mod
|
||||
TModID parent;
|
||||
|
||||
/// for serialization purposes
|
||||
bool impactsGameplay = true;
|
||||
|
||||
template <typename Handler>
|
||||
void serialize(Handler & h, const int v)
|
||||
{
|
||||
h & name;
|
||||
h & version;
|
||||
h & checksum;
|
||||
h & parent;
|
||||
h & impactsGameplay;
|
||||
}
|
||||
};
|
||||
|
||||
/// identifier, identical to name of folder with mod
|
||||
std::string identifier;
|
||||
|
||||
@ -94,7 +64,7 @@ public:
|
||||
/// return true if this mod can affect gameplay, e.g. adds or modifies any game objects
|
||||
bool checkModGameplayAffecting() const;
|
||||
|
||||
const VerificationInfo & getVerificationInfo() const;
|
||||
const ModVerificationInfo & getVerificationInfo() const;
|
||||
|
||||
private:
|
||||
/// true if mod is enabled by user, e.g. in Launcher UI
|
||||
@ -103,7 +73,7 @@ private:
|
||||
/// true if mod can be loaded - compatible and has no missing deps
|
||||
bool implicitlyEnabled;
|
||||
|
||||
VerificationInfo verificationInfo;
|
||||
ModVerificationInfo verificationInfo;
|
||||
|
||||
void loadLocalData(const JsonNode & data);
|
||||
};
|
||||
|
@ -18,6 +18,8 @@
|
||||
|
||||
VCMI_LIB_NAMESPACE_BEGIN
|
||||
|
||||
using TModID = std::string;
|
||||
|
||||
struct DLL_LINKAGE CModVersion
|
||||
{
|
||||
static const int Any = -1;
|
||||
|
@ -52,12 +52,6 @@ class DLL_LINKAGE CIdentifierStorage
|
||||
{
|
||||
return id == other.id && scope == other.scope;
|
||||
}
|
||||
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{
|
||||
h & id;
|
||||
h & scope;
|
||||
}
|
||||
};
|
||||
|
||||
std::multimap<std::string, ObjectData> registeredObjects;
|
||||
@ -102,12 +96,6 @@ public:
|
||||
|
||||
/// called at the very end of loading to check for any missing ID's
|
||||
void finalize();
|
||||
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{
|
||||
h & registeredObjects;
|
||||
h & state;
|
||||
}
|
||||
};
|
||||
|
||||
VCMI_LIB_NAMESPACE_END
|
||||
|
44
lib/modding/ModVerificationInfo.h
Normal file
44
lib/modding/ModVerificationInfo.h
Normal file
@ -0,0 +1,44 @@
|
||||
/*
|
||||
* ModVerificationInfo.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
|
||||
|
||||
#include "CModVersion.h"
|
||||
|
||||
VCMI_LIB_NAMESPACE_BEGIN
|
||||
|
||||
struct ModVerificationInfo
|
||||
{
|
||||
/// human-readable mod name
|
||||
std::string name;
|
||||
|
||||
/// version of the mod
|
||||
CModVersion version;
|
||||
|
||||
/// CRC-32 checksum of the mod
|
||||
ui32 checksum = 0;
|
||||
|
||||
/// parent mod ID, empty if root-level mod
|
||||
TModID parent;
|
||||
|
||||
/// for serialization purposes
|
||||
bool impactsGameplay = true;
|
||||
|
||||
template <typename Handler>
|
||||
void serialize(Handler & h, const int v)
|
||||
{
|
||||
h & name;
|
||||
h & version;
|
||||
h & checksum;
|
||||
h & parent;
|
||||
h & impactsGameplay;
|
||||
}
|
||||
};
|
||||
|
||||
VCMI_LIB_NAMESPACE_END
|
@ -858,7 +858,7 @@ void AddQuest::applyGs(CGameState * gs) const
|
||||
|
||||
void UpdateArtHandlerLists::applyGs(CGameState * gs) const
|
||||
{
|
||||
VLC->arth->allocatedArtifacts = allocatedArtifacts;
|
||||
gs->allocatedArtifacts = allocatedArtifacts;
|
||||
}
|
||||
|
||||
void UpdateMapEvents::applyGs(CGameState * gs) const
|
||||
|
@ -1,52 +0,0 @@
|
||||
/*
|
||||
* RegisterTypes.cpp, 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
|
||||
*
|
||||
*/
|
||||
#include "StdInc.h"
|
||||
#define INSTANTIATE_REGISTER_TYPES_HERE
|
||||
#include "RegisterTypes.h"
|
||||
|
||||
#include "../mapping/CMapInfo.h"
|
||||
#include "../StartInfo.h"
|
||||
#include "../mapObjects/CObjectHandler.h"
|
||||
#include "../CCreatureHandler.h"
|
||||
#include "../spells/CSpellHandler.h"
|
||||
|
||||
#include "../serializer/BinaryDeserializer.h"
|
||||
#include "../serializer/BinarySerializer.h"
|
||||
#include "../serializer/CTypeList.h"
|
||||
|
||||
VCMI_LIB_NAMESPACE_BEGIN
|
||||
|
||||
// For reference: peak memory usage by gcc during compilation of register type templates
|
||||
// registerTypesMapObjects: 1.9 Gb
|
||||
// registerTypes2: 2.2 Gb
|
||||
// registerTypesClientPacks1 1.6 Gb
|
||||
// registerTypesClientPacks2 1.6 Gb
|
||||
// registerTypesServerPacks: 1.3 Gb
|
||||
// registerTypes4: 1.3 Gb
|
||||
|
||||
|
||||
#define DEFINE_EXTERNAL_METHOD(METHODNAME) \
|
||||
extern template DLL_LINKAGE void METHODNAME<BinaryDeserializer>(BinaryDeserializer & s); \
|
||||
extern template DLL_LINKAGE void METHODNAME<BinarySerializer>(BinarySerializer & s); \
|
||||
extern template DLL_LINKAGE void METHODNAME<CTypeList>(CTypeList & s); \
|
||||
|
||||
//DEFINE_EXTERNAL_METHOD(registerTypesMapObjects)
|
||||
DEFINE_EXTERNAL_METHOD(registerTypesMapObjects1)
|
||||
DEFINE_EXTERNAL_METHOD(registerTypesMapObjects2)
|
||||
DEFINE_EXTERNAL_METHOD(registerTypesClientPacks1)
|
||||
DEFINE_EXTERNAL_METHOD(registerTypesClientPacks2)
|
||||
DEFINE_EXTERNAL_METHOD(registerTypesServerPacks)
|
||||
DEFINE_EXTERNAL_METHOD(registerTypesLobbyPacks)
|
||||
|
||||
template void registerTypes<BinaryDeserializer>(BinaryDeserializer & s);
|
||||
template void registerTypes<BinarySerializer>(BinarySerializer & s);
|
||||
template void registerTypes<CTypeList>(CTypeList & s);
|
||||
|
||||
VCMI_LIB_NAMESPACE_END
|
@ -9,413 +9,20 @@
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "../networkPacks/PacksForClient.h"
|
||||
#include "../networkPacks/PacksForClientBattle.h"
|
||||
#include "../networkPacks/PacksForServer.h"
|
||||
#include "../networkPacks/PacksForLobby.h"
|
||||
#include "../networkPacks/SetStackEffect.h"
|
||||
#include "../VCMI_Lib.h"
|
||||
#include "../CArtHandler.h"
|
||||
#include "../CCreatureSet.h"
|
||||
#include "../CPlayerState.h"
|
||||
#include "../CHeroHandler.h"
|
||||
#include "../CTownHandler.h"
|
||||
#include "../mapObjectConstructors/CRewardableConstructor.h"
|
||||
#include "../mapObjectConstructors/CommonConstructors.h"
|
||||
#include "../mapObjectConstructors/CBankInstanceConstructor.h"
|
||||
#include "../mapObjectConstructors/DwellingInstanceConstructor.h"
|
||||
#include "../mapObjectConstructors/HillFortInstanceConstructor.h"
|
||||
#include "../mapObjectConstructors/ShipyardInstanceConstructor.h"
|
||||
#include "../mapObjects/MapObjects.h"
|
||||
#include "../mapObjects/CGCreature.h"
|
||||
#include "../mapObjects/CGTownBuilding.h"
|
||||
#include "../mapObjects/ObjectTemplate.h"
|
||||
#include "../battle/CObstacleInstance.h"
|
||||
#include "../bonuses/CBonusSystemNode.h"
|
||||
#include "../bonuses/Limiters.h"
|
||||
#include "../bonuses/Updaters.h"
|
||||
#include "../bonuses/Propagators.h"
|
||||
#include "../CStack.h"
|
||||
#include "RegisterTypesClientPacks.h"
|
||||
#include "RegisterTypesLobbyPacks.h"
|
||||
#include "RegisterTypesMapObjects.h"
|
||||
#include "RegisterTypesServerPacks.h"
|
||||
|
||||
VCMI_LIB_NAMESPACE_BEGIN
|
||||
|
||||
class BinarySerializer;
|
||||
class BinaryDeserializer;
|
||||
class CTypeList;
|
||||
|
||||
template<typename Serializer>
|
||||
void registerTypesMapObjects1(Serializer &s)
|
||||
{
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Adventure map objects
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
s.template registerType<IObjectInterface, CGObjectInstance>();
|
||||
|
||||
// Non-armed objects
|
||||
s.template registerType<CGObjectInstance, CGTeleport>();
|
||||
s.template registerType<CGTeleport, CGMonolith>();
|
||||
s.template registerType<CGMonolith, CGSubterraneanGate>();
|
||||
s.template registerType<CGMonolith, CGWhirlpool>();
|
||||
s.template registerType<CGObjectInstance, CGSignBottle>();
|
||||
s.template registerType<CGObjectInstance, CGKeys>();
|
||||
s.template registerType<CGKeys, CGKeymasterTent>();
|
||||
s.template registerType<CGKeys, CGBorderGuard>(); s.template registerType<IQuestObject, CGBorderGuard>();
|
||||
s.template registerType<CGBorderGuard, CGBorderGate>();
|
||||
s.template registerType<CGObjectInstance, CGBoat>();
|
||||
s.template registerType<CGObjectInstance, CGMagi>();
|
||||
s.template registerType<CGObjectInstance, CGSirens>();
|
||||
s.template registerType<CGObjectInstance, CGShipyard>();
|
||||
s.template registerType<CGObjectInstance, CGDenOfthieves>();
|
||||
s.template registerType<CGObjectInstance, CGLighthouse>();
|
||||
s.template registerType<CGObjectInstance, CGTerrainPatch>();
|
||||
s.template registerType<CGObjectInstance, HillFort>();
|
||||
s.template registerType<CGObjectInstance, CGMarket>();
|
||||
s.template registerType<CGMarket, CGBlackMarket>();
|
||||
s.template registerType<CGMarket, CGUniversity>();
|
||||
s.template registerType<CGObjectInstance, CGHeroPlaceholder>();
|
||||
|
||||
s.template registerType<CGObjectInstance, CArmedInstance>(); s.template registerType<CBonusSystemNode, CArmedInstance>(); s.template registerType<CCreatureSet, CArmedInstance>();
|
||||
|
||||
// Armed objects
|
||||
s.template registerType<CArmedInstance, CGHeroInstance>(); s.template registerType<CArtifactSet, CGHeroInstance>();
|
||||
s.template registerType<CArmedInstance, CGDwelling>();
|
||||
s.template registerType<CGDwelling, CGTownInstance>();
|
||||
s.template registerType<CArmedInstance, CGPandoraBox>();
|
||||
s.template registerType<CGPandoraBox, CGEvent>();
|
||||
s.template registerType<CArmedInstance, CGCreature>();
|
||||
s.template registerType<CArmedInstance, CGGarrison>();
|
||||
s.template registerType<CArmedInstance, CGArtifact>();
|
||||
s.template registerType<CArmedInstance, CGResource>();
|
||||
s.template registerType<CArmedInstance, CGMine>();
|
||||
s.template registerType<CArmedInstance, CBank>();
|
||||
s.template registerType<CArmedInstance, CGSeerHut>(); s.template registerType<IQuestObject, CGSeerHut>();
|
||||
s.template registerType<CGSeerHut, CGQuestGuard>();
|
||||
}
|
||||
|
||||
template<typename Serializer>
|
||||
void registerTypesMapObjectTypes(Serializer &s)
|
||||
{
|
||||
s.template registerType<AObjectTypeHandler, CRewardableConstructor>();
|
||||
s.template registerType<AObjectTypeHandler, CHeroInstanceConstructor>();
|
||||
s.template registerType<AObjectTypeHandler, CTownInstanceConstructor>();
|
||||
s.template registerType<AObjectTypeHandler, DwellingInstanceConstructor>();
|
||||
s.template registerType<AObjectTypeHandler, CBankInstanceConstructor>();
|
||||
s.template registerType<AObjectTypeHandler, BoatInstanceConstructor>();
|
||||
s.template registerType<AObjectTypeHandler, MarketInstanceConstructor>();
|
||||
s.template registerType<AObjectTypeHandler, CObstacleConstructor>();
|
||||
s.template registerType<AObjectTypeHandler, ShipyardInstanceConstructor>();
|
||||
s.template registerType<AObjectTypeHandler, HillFortInstanceConstructor>();
|
||||
s.template registerType<AObjectTypeHandler, CreatureInstanceConstructor>();
|
||||
s.template registerType<AObjectTypeHandler, ResourceInstanceConstructor>();
|
||||
|
||||
#define REGISTER_GENERIC_HANDLER(TYPENAME) s.template registerType<AObjectTypeHandler, CDefaultObjectTypeHandler<TYPENAME> >()
|
||||
|
||||
REGISTER_GENERIC_HANDLER(CGObjectInstance);
|
||||
REGISTER_GENERIC_HANDLER(CGArtifact);
|
||||
REGISTER_GENERIC_HANDLER(CGBlackMarket);
|
||||
REGISTER_GENERIC_HANDLER(CGBoat);
|
||||
REGISTER_GENERIC_HANDLER(CGBorderGate);
|
||||
REGISTER_GENERIC_HANDLER(CGBorderGuard);
|
||||
REGISTER_GENERIC_HANDLER(CGCreature);
|
||||
REGISTER_GENERIC_HANDLER(CGDenOfthieves);
|
||||
REGISTER_GENERIC_HANDLER(CGDwelling);
|
||||
REGISTER_GENERIC_HANDLER(CGEvent);
|
||||
REGISTER_GENERIC_HANDLER(CGGarrison);
|
||||
REGISTER_GENERIC_HANDLER(CGHeroPlaceholder);
|
||||
REGISTER_GENERIC_HANDLER(CGHeroInstance);
|
||||
REGISTER_GENERIC_HANDLER(CGKeymasterTent);
|
||||
REGISTER_GENERIC_HANDLER(CGLighthouse);
|
||||
REGISTER_GENERIC_HANDLER(CGTerrainPatch);
|
||||
REGISTER_GENERIC_HANDLER(CGMagi);
|
||||
REGISTER_GENERIC_HANDLER(CGMarket);
|
||||
REGISTER_GENERIC_HANDLER(CGMine);
|
||||
REGISTER_GENERIC_HANDLER(CGObelisk);
|
||||
REGISTER_GENERIC_HANDLER(CGPandoraBox);
|
||||
REGISTER_GENERIC_HANDLER(CGQuestGuard);
|
||||
REGISTER_GENERIC_HANDLER(CGResource);
|
||||
REGISTER_GENERIC_HANDLER(CGSeerHut);
|
||||
REGISTER_GENERIC_HANDLER(CGShipyard);
|
||||
REGISTER_GENERIC_HANDLER(CGSignBottle);
|
||||
REGISTER_GENERIC_HANDLER(CGSirens);
|
||||
REGISTER_GENERIC_HANDLER(CGMonolith);
|
||||
REGISTER_GENERIC_HANDLER(CGSubterraneanGate);
|
||||
REGISTER_GENERIC_HANDLER(CGWhirlpool);
|
||||
REGISTER_GENERIC_HANDLER(CGTownInstance);
|
||||
REGISTER_GENERIC_HANDLER(CGUniversity);
|
||||
REGISTER_GENERIC_HANDLER(HillFort);
|
||||
|
||||
#undef REGISTER_GENERIC_HANDLER
|
||||
|
||||
s.template registerType<IUpdater, GrowsWithLevelUpdater>();
|
||||
s.template registerType<IUpdater, TimesHeroLevelUpdater>();
|
||||
s.template registerType<IUpdater, TimesStackLevelUpdater>();
|
||||
s.template registerType<IUpdater, OwnerUpdater>();
|
||||
s.template registerType<IUpdater, ArmyMovementUpdater>();
|
||||
|
||||
s.template registerType<ILimiter, AnyOfLimiter>();
|
||||
s.template registerType<ILimiter, NoneOfLimiter>();
|
||||
s.template registerType<ILimiter, OppositeSideLimiter>();
|
||||
//new types (other than netpacks) must register here
|
||||
//order of type registration is critical for loading old savegames
|
||||
}
|
||||
|
||||
template<typename Serializer>
|
||||
void registerTypesMapObjects2(Serializer &s)
|
||||
{
|
||||
//Other object-related
|
||||
s.template registerType<IObjectInterface, CGTownBuilding>();
|
||||
s.template registerType<CGTownBuilding, CTownBonus>();
|
||||
s.template registerType<CGTownBuilding, COPWBonus>();
|
||||
s.template registerType<CGTownBuilding, CTownRewardableBuilding>();
|
||||
|
||||
s.template registerType<CGObjectInstance, CRewardableObject>();
|
||||
|
||||
s.template registerType<CGObjectInstance, CTeamVisited>();
|
||||
s.template registerType<CTeamVisited, CGObelisk>();
|
||||
|
||||
//s.template registerType<CQuest>();
|
||||
//s.template registerType<IQuestObject>();
|
||||
|
||||
//end of objects
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Bonus system
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
//s.template registerType<IPropagator>();
|
||||
s.template registerType<IPropagator, CPropagatorNodeType>();
|
||||
|
||||
// Limiters
|
||||
//s.template registerType<ILimiter>();
|
||||
s.template registerType<ILimiter, AllOfLimiter>();
|
||||
s.template registerType<ILimiter, CCreatureTypeLimiter>();
|
||||
s.template registerType<ILimiter, HasAnotherBonusLimiter>();
|
||||
s.template registerType<ILimiter, CreatureTerrainLimiter>();
|
||||
s.template registerType<ILimiter, FactionLimiter>();
|
||||
s.template registerType<ILimiter, CreatureLevelLimiter>();
|
||||
s.template registerType<ILimiter, CreatureAlignmentLimiter>();
|
||||
s.template registerType<ILimiter, RankRangeLimiter>();
|
||||
s.template registerType<ILimiter, UnitOnHexLimiter>();
|
||||
|
||||
// s.template registerType<CBonusSystemNode>();
|
||||
s.template registerType<CBonusSystemNode, CArtifact>();
|
||||
s.template registerType<CBonusSystemNode, CCreature>();
|
||||
s.template registerType<CBonusSystemNode, CStackInstance>();
|
||||
s.template registerType<CStackInstance, CCommanderInstance>();
|
||||
s.template registerType<CBonusSystemNode, PlayerState>();
|
||||
s.template registerType<CBonusSystemNode, TeamState>();
|
||||
//s.template registerType<CGameState>(); //TODO
|
||||
//s.template registerType<CArmedInstance>();
|
||||
s.template registerType<CBonusSystemNode, CStack>();
|
||||
s.template registerType<CBonusSystemNode, BattleInfo>();
|
||||
//s.template registerType<QuestInfo>();
|
||||
s.template registerType<CBonusSystemNode, CArtifactInstance>();
|
||||
|
||||
//s.template registerType<CObstacleInstance>();
|
||||
s.template registerType<CObstacleInstance, SpellCreatedObstacle>();
|
||||
}
|
||||
template<typename Serializer>
|
||||
void registerTypesClientPacks1(Serializer &s)
|
||||
{
|
||||
s.template registerType<CPack, CPackForClient>();
|
||||
|
||||
s.template registerType<CPackForClient, PackageApplied>();
|
||||
s.template registerType<CPackForClient, SystemMessage>();
|
||||
s.template registerType<CPackForClient, PlayerBlocked>();
|
||||
s.template registerType<CPackForClient, PlayerCheated>();
|
||||
s.template registerType<CPackForClient, PlayerStartsTurn>();
|
||||
s.template registerType<CPackForClient, DaysWithoutTown>();
|
||||
s.template registerType<CPackForClient, TurnTimeUpdate>();
|
||||
s.template registerType<CPackForClient, SetResources>();
|
||||
s.template registerType<CPackForClient, SetPrimSkill>();
|
||||
s.template registerType<CPackForClient, SetSecSkill>();
|
||||
s.template registerType<CPackForClient, HeroVisitCastle>();
|
||||
s.template registerType<CPackForClient, ChangeSpells>();
|
||||
s.template registerType<CPackForClient, SetMana>();
|
||||
s.template registerType<CPackForClient, SetMovePoints>();
|
||||
s.template registerType<CPackForClient, FoWChange>();
|
||||
s.template registerType<CPackForClient, SetAvailableHero>();
|
||||
s.template registerType<CPackForClient, GiveBonus>();
|
||||
s.template registerType<CPackForClient, ChangeObjPos>();
|
||||
s.template registerType<CPackForClient, PlayerEndsTurn>();
|
||||
s.template registerType<CPackForClient, PlayerEndsGame>();
|
||||
s.template registerType<CPackForClient, PlayerReinitInterface>();
|
||||
s.template registerType<CPackForClient, RemoveBonus>();
|
||||
s.template registerType<CPackForClient, UpdateArtHandlerLists>();
|
||||
s.template registerType<CPackForClient, UpdateMapEvents>();
|
||||
s.template registerType<CPackForClient, UpdateCastleEvents>();
|
||||
s.template registerType<CPackForClient, ChangeFormation>();
|
||||
s.template registerType<CPackForClient, RemoveObject>();
|
||||
s.template registerType<CPackForClient, TryMoveHero>();
|
||||
s.template registerType<CPackForClient, NewStructures>();
|
||||
s.template registerType<CPackForClient, RazeStructures>();
|
||||
s.template registerType<CPackForClient, SetAvailableCreatures>();
|
||||
s.template registerType<CPackForClient, SetHeroesInTown>();
|
||||
s.template registerType<CPackForClient, HeroRecruited>();
|
||||
s.template registerType<CPackForClient, GiveHero>();
|
||||
s.template registerType<CPackForClient, NewTurn>();
|
||||
s.template registerType<CPackForClient, InfoWindow>();
|
||||
s.template registerType<CPackForClient, SetObjectProperty>();
|
||||
s.template registerType<CPackForClient, AdvmapSpellCast>();
|
||||
s.template registerType<CPackForClient, OpenWindow>();
|
||||
s.template registerType<CPackForClient, NewObject>();
|
||||
s.template registerType<CPackForClient, NewArtifact>();
|
||||
s.template registerType<CPackForClient, AddQuest>();
|
||||
s.template registerType<CPackForClient, SetAvailableArtifacts>();
|
||||
s.template registerType<CPackForClient, CenterView>();
|
||||
s.template registerType<CPackForClient, HeroVisit>();
|
||||
s.template registerType<CPackForClient, SetCommanderProperty>();
|
||||
s.template registerType<CPackForClient, ChangeObjectVisitors>();
|
||||
s.template registerType<CPackForClient, ShowWorldViewEx>();
|
||||
s.template registerType<CPackForClient, PrepareHeroLevelUp>();
|
||||
s.template registerType<CPackForClient, EntitiesChanged>();
|
||||
}
|
||||
|
||||
template<typename Serializer>
|
||||
void registerTypesClientPacks2(Serializer &s)
|
||||
{
|
||||
s.template registerType<CPackForClient, BattleStart>();
|
||||
s.template registerType<CPackForClient, BattleNextRound>();
|
||||
s.template registerType<CPackForClient, BattleSetActiveStack>();
|
||||
s.template registerType<CPackForClient, BattleResult>();
|
||||
s.template registerType<CPackForClient, BattleResultAccepted>();
|
||||
s.template registerType<CPackForClient, BattleCancelled>();
|
||||
s.template registerType<CPackForClient, BattleLogMessage>();
|
||||
s.template registerType<CPackForClient, BattleStackMoved>();
|
||||
s.template registerType<CPackForClient, BattleAttack>();
|
||||
s.template registerType<CPackForClient, StartAction>();
|
||||
s.template registerType<CPackForClient, EndAction>();
|
||||
s.template registerType<CPackForClient, BattleSpellCast>();
|
||||
s.template registerType<CPackForClient, SetStackEffect>();
|
||||
s.template registerType<CPackForClient, BattleTriggerEffect>();
|
||||
s.template registerType<CPackForClient, BattleUpdateGateState>();
|
||||
s.template registerType<CPackForClient, BattleSetStackProperty>();
|
||||
s.template registerType<CPackForClient, StacksInjured>();
|
||||
s.template registerType<CPackForClient, BattleResultsApplied>();
|
||||
s.template registerType<CPackForClient, BattleUnitsChanged>();
|
||||
s.template registerType<CPackForClient, BattleObstaclesChanged>();
|
||||
s.template registerType<CPackForClient, CatapultAttack>();
|
||||
|
||||
s.template registerType<CPackForClient, Query>();
|
||||
s.template registerType<Query, HeroLevelUp>();
|
||||
s.template registerType<Query, CommanderLevelUp>();
|
||||
s.template registerType<Query, BlockingDialog>();
|
||||
s.template registerType<Query, GarrisonDialog>();
|
||||
s.template registerType<Query, ExchangeDialog>();
|
||||
s.template registerType<Query, TeleportDialog>();
|
||||
s.template registerType<Query, MapObjectSelectDialog>();
|
||||
|
||||
s.template registerType<CPackForClient, CGarrisonOperationPack>();
|
||||
s.template registerType<CGarrisonOperationPack, ChangeStackCount>();
|
||||
s.template registerType<CGarrisonOperationPack, SetStackType>();
|
||||
s.template registerType<CGarrisonOperationPack, EraseStack>();
|
||||
s.template registerType<CGarrisonOperationPack, SwapStacks>();
|
||||
s.template registerType<CGarrisonOperationPack, InsertNewStack>();
|
||||
s.template registerType<CGarrisonOperationPack, RebalanceStacks>();
|
||||
|
||||
s.template registerType<CPackForClient, CArtifactOperationPack>();
|
||||
s.template registerType<CArtifactOperationPack, PutArtifact>();
|
||||
s.template registerType<CArtifactOperationPack, EraseArtifact>();
|
||||
s.template registerType<CArtifactOperationPack, MoveArtifact>();
|
||||
s.template registerType<CArtifactOperationPack, AssembledArtifact>();
|
||||
s.template registerType<CArtifactOperationPack, DisassembledArtifact>();
|
||||
s.template registerType<CArtifactOperationPack, BulkMoveArtifacts>();
|
||||
|
||||
s.template registerType<CPackForClient, PlayerMessageClient>();
|
||||
s.template registerType<CGarrisonOperationPack, BulkRebalanceStacks>();
|
||||
s.template registerType<CGarrisonOperationPack, BulkSmartRebalanceStacks>();
|
||||
}
|
||||
|
||||
template<typename Serializer>
|
||||
void registerTypesServerPacks(Serializer &s)
|
||||
{
|
||||
s.template registerType<CPack, CPackForServer>();
|
||||
s.template registerType<CPackForServer, EndTurn>();
|
||||
s.template registerType<CPackForServer, DismissHero>();
|
||||
s.template registerType<CPackForServer, MoveHero>();
|
||||
s.template registerType<CPackForServer, ArrangeStacks>();
|
||||
s.template registerType<CPackForServer, DisbandCreature>();
|
||||
s.template registerType<CPackForServer, BuildStructure>();
|
||||
s.template registerType<CPackForServer, RecruitCreatures>();
|
||||
s.template registerType<CPackForServer, UpgradeCreature>();
|
||||
s.template registerType<CPackForServer, GarrisonHeroSwap>();
|
||||
s.template registerType<CPackForServer, ExchangeArtifacts>();
|
||||
s.template registerType<CPackForServer, AssembleArtifacts>();
|
||||
s.template registerType<CPackForServer, BuyArtifact>();
|
||||
s.template registerType<CPackForServer, TradeOnMarketplace>();
|
||||
s.template registerType<CPackForServer, SetFormation>();
|
||||
s.template registerType<CPackForServer, HireHero>();
|
||||
s.template registerType<CPackForServer, BuildBoat>();
|
||||
s.template registerType<CPackForServer, QueryReply>();
|
||||
s.template registerType<CPackForServer, MakeAction>();
|
||||
s.template registerType<CPackForServer, DigWithHero>();
|
||||
s.template registerType<CPackForServer, CastAdvSpell>();
|
||||
s.template registerType<CPackForServer, CastleTeleportHero>();
|
||||
s.template registerType<CPackForServer, SaveGame>();
|
||||
s.template registerType<CPackForServer, PlayerMessage>();
|
||||
s.template registerType<CPackForServer, BulkSplitStack>();
|
||||
s.template registerType<CPackForServer, BulkMergeStacks>();
|
||||
s.template registerType<CPackForServer, BulkSmartSplitStack>();
|
||||
s.template registerType<CPackForServer, BulkMoveArmy>();
|
||||
s.template registerType<CPackForServer, BulkExchangeArtifacts>();
|
||||
s.template registerType<CPackForServer, EraseArtifactByClient>();
|
||||
s.template registerType<CPackForServer, GamePause>();
|
||||
}
|
||||
|
||||
template<typename Serializer>
|
||||
void registerTypesLobbyPacks(Serializer &s)
|
||||
{
|
||||
s.template registerType<CPack, CPackForLobby>();
|
||||
s.template registerType<CPackForLobby, CLobbyPackToPropagate>();
|
||||
s.template registerType<CPackForLobby, CLobbyPackToServer>();
|
||||
|
||||
// Any client can sent
|
||||
s.template registerType<CLobbyPackToPropagate, LobbyClientConnected>();
|
||||
s.template registerType<CLobbyPackToPropagate, LobbyClientDisconnected>();
|
||||
s.template registerType<CLobbyPackToPropagate, LobbyChatMessage>();
|
||||
// Only host client send
|
||||
s.template registerType<CLobbyPackToPropagate, LobbyGuiAction>();
|
||||
s.template registerType<CLobbyPackToPropagate, LobbyLoadProgress>();
|
||||
s.template registerType<CLobbyPackToPropagate, LobbyEndGame>();
|
||||
s.template registerType<CLobbyPackToPropagate, LobbyStartGame>();
|
||||
s.template registerType<CLobbyPackToPropagate, LobbyChangeHost>();
|
||||
// Only server send
|
||||
s.template registerType<CLobbyPackToPropagate, LobbyUpdateState>();
|
||||
s.template registerType<CLobbyPackToPropagate, LobbyShowMessage>();
|
||||
|
||||
// For client with permissions
|
||||
s.template registerType<CLobbyPackToServer, LobbyChangePlayerOption>();
|
||||
// Only for host client
|
||||
s.template registerType<CLobbyPackToServer, LobbySetMap>();
|
||||
s.template registerType<CLobbyPackToServer, LobbySetCampaign>();
|
||||
s.template registerType<CLobbyPackToServer, LobbySetCampaignMap>();
|
||||
s.template registerType<CLobbyPackToServer, LobbySetCampaignBonus>();
|
||||
s.template registerType<CLobbyPackToServer, LobbySetPlayer>();
|
||||
s.template registerType<CLobbyPackToServer, LobbySetPlayerName>();
|
||||
s.template registerType<CLobbyPackToServer, LobbySetTurnTime>();
|
||||
s.template registerType<CLobbyPackToServer, LobbySetSimturns>();
|
||||
s.template registerType<CLobbyPackToServer, LobbySetDifficulty>();
|
||||
s.template registerType<CLobbyPackToServer, LobbyForceSetPlayer>();
|
||||
}
|
||||
|
||||
template<typename Serializer>
|
||||
void registerTypes(Serializer &s)
|
||||
{
|
||||
registerTypesMapObjects1(s);
|
||||
registerTypesMapObjects2(s);
|
||||
registerTypesMapObjectTypes(s);
|
||||
registerTypesClientPacks1(s);
|
||||
registerTypesClientPacks2(s);
|
||||
registerTypesMapObjects(s);
|
||||
registerTypesClientPacks(s);
|
||||
registerTypesServerPacks(s);
|
||||
registerTypesLobbyPacks(s);
|
||||
}
|
||||
|
||||
#ifndef INSTANTIATE_REGISTER_TYPES_HERE
|
||||
|
||||
extern template DLL_LINKAGE void registerTypes<BinaryDeserializer>(BinaryDeserializer & s);
|
||||
extern template DLL_LINKAGE void registerTypes<BinarySerializer>(BinarySerializer & s);
|
||||
extern template DLL_LINKAGE void registerTypes<CTypeList>(CTypeList & s);
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
VCMI_LIB_NAMESPACE_END
|
||||
|
125
lib/registerTypes/RegisterTypesClientPacks.h
Normal file
125
lib/registerTypes/RegisterTypesClientPacks.h
Normal file
@ -0,0 +1,125 @@
|
||||
/*
|
||||
* RegisterTypesClientPacks.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
|
||||
|
||||
#include "../networkPacks/PacksForClient.h"
|
||||
#include "../networkPacks/PacksForClientBattle.h"
|
||||
#include "../networkPacks/SetStackEffect.h"
|
||||
|
||||
VCMI_LIB_NAMESPACE_BEGIN
|
||||
|
||||
template<typename Serializer>
|
||||
void registerTypesClientPacks(Serializer &s)
|
||||
{
|
||||
s.template registerType<CPack, CPackForClient>();
|
||||
|
||||
s.template registerType<CPackForClient, PackageApplied>();
|
||||
s.template registerType<CPackForClient, SystemMessage>();
|
||||
s.template registerType<CPackForClient, PlayerBlocked>();
|
||||
s.template registerType<CPackForClient, PlayerCheated>();
|
||||
s.template registerType<CPackForClient, PlayerStartsTurn>();
|
||||
s.template registerType<CPackForClient, DaysWithoutTown>();
|
||||
s.template registerType<CPackForClient, TurnTimeUpdate>();
|
||||
s.template registerType<CPackForClient, SetResources>();
|
||||
s.template registerType<CPackForClient, SetPrimSkill>();
|
||||
s.template registerType<CPackForClient, SetSecSkill>();
|
||||
s.template registerType<CPackForClient, HeroVisitCastle>();
|
||||
s.template registerType<CPackForClient, ChangeSpells>();
|
||||
s.template registerType<CPackForClient, SetMana>();
|
||||
s.template registerType<CPackForClient, SetMovePoints>();
|
||||
s.template registerType<CPackForClient, FoWChange>();
|
||||
s.template registerType<CPackForClient, SetAvailableHero>();
|
||||
s.template registerType<CPackForClient, GiveBonus>();
|
||||
s.template registerType<CPackForClient, ChangeObjPos>();
|
||||
s.template registerType<CPackForClient, PlayerEndsTurn>();
|
||||
s.template registerType<CPackForClient, PlayerEndsGame>();
|
||||
s.template registerType<CPackForClient, PlayerReinitInterface>();
|
||||
s.template registerType<CPackForClient, RemoveBonus>();
|
||||
s.template registerType<CPackForClient, UpdateArtHandlerLists>();
|
||||
s.template registerType<CPackForClient, UpdateMapEvents>();
|
||||
s.template registerType<CPackForClient, UpdateCastleEvents>();
|
||||
s.template registerType<CPackForClient, ChangeFormation>();
|
||||
s.template registerType<CPackForClient, RemoveObject>();
|
||||
s.template registerType<CPackForClient, TryMoveHero>();
|
||||
s.template registerType<CPackForClient, NewStructures>();
|
||||
s.template registerType<CPackForClient, RazeStructures>();
|
||||
s.template registerType<CPackForClient, SetAvailableCreatures>();
|
||||
s.template registerType<CPackForClient, SetHeroesInTown>();
|
||||
s.template registerType<CPackForClient, HeroRecruited>();
|
||||
s.template registerType<CPackForClient, GiveHero>();
|
||||
s.template registerType<CPackForClient, NewTurn>();
|
||||
s.template registerType<CPackForClient, InfoWindow>();
|
||||
s.template registerType<CPackForClient, SetObjectProperty>();
|
||||
s.template registerType<CPackForClient, AdvmapSpellCast>();
|
||||
s.template registerType<CPackForClient, OpenWindow>();
|
||||
s.template registerType<CPackForClient, NewObject>();
|
||||
s.template registerType<CPackForClient, NewArtifact>();
|
||||
s.template registerType<CPackForClient, AddQuest>();
|
||||
s.template registerType<CPackForClient, SetAvailableArtifacts>();
|
||||
s.template registerType<CPackForClient, CenterView>();
|
||||
s.template registerType<CPackForClient, HeroVisit>();
|
||||
s.template registerType<CPackForClient, SetCommanderProperty>();
|
||||
s.template registerType<CPackForClient, ChangeObjectVisitors>();
|
||||
s.template registerType<CPackForClient, ShowWorldViewEx>();
|
||||
s.template registerType<CPackForClient, PrepareHeroLevelUp>();
|
||||
s.template registerType<CPackForClient, EntitiesChanged>();
|
||||
s.template registerType<CPackForClient, BattleStart>();
|
||||
s.template registerType<CPackForClient, BattleNextRound>();
|
||||
s.template registerType<CPackForClient, BattleSetActiveStack>();
|
||||
s.template registerType<CPackForClient, BattleResult>();
|
||||
s.template registerType<CPackForClient, BattleResultAccepted>();
|
||||
s.template registerType<CPackForClient, BattleCancelled>();
|
||||
s.template registerType<CPackForClient, BattleLogMessage>();
|
||||
s.template registerType<CPackForClient, BattleStackMoved>();
|
||||
s.template registerType<CPackForClient, BattleAttack>();
|
||||
s.template registerType<CPackForClient, StartAction>();
|
||||
s.template registerType<CPackForClient, EndAction>();
|
||||
s.template registerType<CPackForClient, BattleSpellCast>();
|
||||
s.template registerType<CPackForClient, SetStackEffect>();
|
||||
s.template registerType<CPackForClient, BattleTriggerEffect>();
|
||||
s.template registerType<CPackForClient, BattleUpdateGateState>();
|
||||
s.template registerType<CPackForClient, BattleSetStackProperty>();
|
||||
s.template registerType<CPackForClient, StacksInjured>();
|
||||
s.template registerType<CPackForClient, BattleResultsApplied>();
|
||||
s.template registerType<CPackForClient, BattleUnitsChanged>();
|
||||
s.template registerType<CPackForClient, BattleObstaclesChanged>();
|
||||
s.template registerType<CPackForClient, CatapultAttack>();
|
||||
|
||||
s.template registerType<CPackForClient, Query>();
|
||||
s.template registerType<Query, HeroLevelUp>();
|
||||
s.template registerType<Query, CommanderLevelUp>();
|
||||
s.template registerType<Query, BlockingDialog>();
|
||||
s.template registerType<Query, GarrisonDialog>();
|
||||
s.template registerType<Query, ExchangeDialog>();
|
||||
s.template registerType<Query, TeleportDialog>();
|
||||
s.template registerType<Query, MapObjectSelectDialog>();
|
||||
|
||||
s.template registerType<CPackForClient, CGarrisonOperationPack>();
|
||||
s.template registerType<CGarrisonOperationPack, ChangeStackCount>();
|
||||
s.template registerType<CGarrisonOperationPack, SetStackType>();
|
||||
s.template registerType<CGarrisonOperationPack, EraseStack>();
|
||||
s.template registerType<CGarrisonOperationPack, SwapStacks>();
|
||||
s.template registerType<CGarrisonOperationPack, InsertNewStack>();
|
||||
s.template registerType<CGarrisonOperationPack, RebalanceStacks>();
|
||||
|
||||
s.template registerType<CPackForClient, CArtifactOperationPack>();
|
||||
s.template registerType<CArtifactOperationPack, PutArtifact>();
|
||||
s.template registerType<CArtifactOperationPack, EraseArtifact>();
|
||||
s.template registerType<CArtifactOperationPack, MoveArtifact>();
|
||||
s.template registerType<CArtifactOperationPack, AssembledArtifact>();
|
||||
s.template registerType<CArtifactOperationPack, DisassembledArtifact>();
|
||||
s.template registerType<CArtifactOperationPack, BulkMoveArtifacts>();
|
||||
|
||||
s.template registerType<CPackForClient, PlayerMessageClient>();
|
||||
s.template registerType<CGarrisonOperationPack, BulkRebalanceStacks>();
|
||||
s.template registerType<CGarrisonOperationPack, BulkSmartRebalanceStacks>();
|
||||
}
|
||||
|
||||
VCMI_LIB_NAMESPACE_END
|
62
lib/registerTypes/RegisterTypesLobbyPacks.h
Normal file
62
lib/registerTypes/RegisterTypesLobbyPacks.h
Normal file
@ -0,0 +1,62 @@
|
||||
/*
|
||||
* RegisterTypesLobbyPacks.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
|
||||
|
||||
#include "../networkPacks/PacksForLobby.h"
|
||||
#include "../gameState/CGameState.h"
|
||||
#include "../campaign/CampaignState.h"
|
||||
#include "../mapping/CMapInfo.h"
|
||||
#include "../rmg/CMapGenOptions.h"
|
||||
#include "../gameState/TavernHeroesPool.h"
|
||||
#include "../gameState/CGameStateCampaign.h"
|
||||
#include "../mapping/CMap.h"
|
||||
#include "../TerrainHandler.h"
|
||||
#include "../RiverHandler.h"
|
||||
#include "../RoadHandler.h"
|
||||
|
||||
VCMI_LIB_NAMESPACE_BEGIN
|
||||
|
||||
template<typename Serializer>
|
||||
void registerTypesLobbyPacks(Serializer &s)
|
||||
{
|
||||
s.template registerType<CPack, CPackForLobby>();
|
||||
s.template registerType<CPackForLobby, CLobbyPackToPropagate>();
|
||||
s.template registerType<CPackForLobby, CLobbyPackToServer>();
|
||||
|
||||
// Any client can sent
|
||||
s.template registerType<CLobbyPackToPropagate, LobbyClientConnected>();
|
||||
s.template registerType<CLobbyPackToPropagate, LobbyClientDisconnected>();
|
||||
s.template registerType<CLobbyPackToPropagate, LobbyChatMessage>();
|
||||
// Only host client send
|
||||
s.template registerType<CLobbyPackToPropagate, LobbyGuiAction>();
|
||||
s.template registerType<CLobbyPackToPropagate, LobbyLoadProgress>();
|
||||
s.template registerType<CLobbyPackToPropagate, LobbyEndGame>();
|
||||
s.template registerType<CLobbyPackToPropagate, LobbyStartGame>();
|
||||
s.template registerType<CLobbyPackToPropagate, LobbyChangeHost>();
|
||||
// Only server send
|
||||
s.template registerType<CLobbyPackToPropagate, LobbyUpdateState>();
|
||||
s.template registerType<CLobbyPackToPropagate, LobbyShowMessage>();
|
||||
|
||||
// For client with permissions
|
||||
s.template registerType<CLobbyPackToServer, LobbyChangePlayerOption>();
|
||||
// Only for host client
|
||||
s.template registerType<CLobbyPackToServer, LobbySetMap>();
|
||||
s.template registerType<CLobbyPackToServer, LobbySetCampaign>();
|
||||
s.template registerType<CLobbyPackToServer, LobbySetCampaignMap>();
|
||||
s.template registerType<CLobbyPackToServer, LobbySetCampaignBonus>();
|
||||
s.template registerType<CLobbyPackToServer, LobbySetPlayer>();
|
||||
s.template registerType<CLobbyPackToServer, LobbySetPlayerName>();
|
||||
s.template registerType<CLobbyPackToServer, LobbySetTurnTime>();
|
||||
s.template registerType<CLobbyPackToServer, LobbySetSimturns>();
|
||||
s.template registerType<CLobbyPackToServer, LobbySetDifficulty>();
|
||||
s.template registerType<CLobbyPackToServer, LobbyForceSetPlayer>();
|
||||
}
|
||||
|
||||
VCMI_LIB_NAMESPACE_END
|
137
lib/registerTypes/RegisterTypesMapObjects.h
Normal file
137
lib/registerTypes/RegisterTypesMapObjects.h
Normal file
@ -0,0 +1,137 @@
|
||||
/*
|
||||
* RegisterTypesMapObjects.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
|
||||
|
||||
#include "../mapObjectConstructors/CBankInstanceConstructor.h"
|
||||
#include "../mapObjects/MapObjects.h"
|
||||
#include "../mapObjects/CGCreature.h"
|
||||
#include "../mapObjects/CGTownBuilding.h"
|
||||
#include "../mapObjects/ObjectTemplate.h"
|
||||
#include "../battle/BattleInfo.h"
|
||||
#include "../battle/CObstacleInstance.h"
|
||||
#include "../bonuses/Limiters.h"
|
||||
#include "../bonuses/Updaters.h"
|
||||
#include "../bonuses/Propagators.h"
|
||||
#include "../CPlayerState.h"
|
||||
#include "../CStack.h"
|
||||
#include "../CHeroHandler.h"
|
||||
|
||||
VCMI_LIB_NAMESPACE_BEGIN
|
||||
|
||||
template<typename Serializer>
|
||||
void registerTypesMapObjects(Serializer &s)
|
||||
{
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Adventure map objects
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
s.template registerType<IObjectInterface, CGObjectInstance>();
|
||||
|
||||
// Non-armed objects
|
||||
s.template registerType<CGObjectInstance, CGTeleport>();
|
||||
s.template registerType<CGTeleport, CGMonolith>();
|
||||
s.template registerType<CGMonolith, CGSubterraneanGate>();
|
||||
s.template registerType<CGMonolith, CGWhirlpool>();
|
||||
s.template registerType<CGObjectInstance, CGSignBottle>();
|
||||
s.template registerType<CGObjectInstance, CGKeys>();
|
||||
s.template registerType<CGKeys, CGKeymasterTent>();
|
||||
s.template registerType<CGKeys, CGBorderGuard>(); s.template registerType<IQuestObject, CGBorderGuard>();
|
||||
s.template registerType<CGBorderGuard, CGBorderGate>();
|
||||
s.template registerType<CGObjectInstance, CGBoat>();
|
||||
s.template registerType<CGObjectInstance, CGMagi>();
|
||||
s.template registerType<CGObjectInstance, CGSirens>();
|
||||
s.template registerType<CGObjectInstance, CGShipyard>();
|
||||
s.template registerType<CGObjectInstance, CGDenOfthieves>();
|
||||
s.template registerType<CGObjectInstance, CGLighthouse>();
|
||||
s.template registerType<CGObjectInstance, CGTerrainPatch>();
|
||||
s.template registerType<CGObjectInstance, HillFort>();
|
||||
s.template registerType<CGObjectInstance, CGMarket>();
|
||||
s.template registerType<CGMarket, CGBlackMarket>();
|
||||
s.template registerType<CGMarket, CGUniversity>();
|
||||
s.template registerType<CGObjectInstance, CGHeroPlaceholder>();
|
||||
|
||||
s.template registerType<CGObjectInstance, CArmedInstance>(); s.template registerType<CBonusSystemNode, CArmedInstance>(); s.template registerType<CCreatureSet, CArmedInstance>();
|
||||
|
||||
// Armed objects
|
||||
s.template registerType<CArmedInstance, CGHeroInstance>(); s.template registerType<CArtifactSet, CGHeroInstance>();
|
||||
s.template registerType<CArmedInstance, CGDwelling>();
|
||||
s.template registerType<CGDwelling, CGTownInstance>();
|
||||
s.template registerType<CArmedInstance, CGPandoraBox>();
|
||||
s.template registerType<CGPandoraBox, CGEvent>();
|
||||
s.template registerType<CArmedInstance, CGCreature>();
|
||||
s.template registerType<CArmedInstance, CGGarrison>();
|
||||
s.template registerType<CArmedInstance, CGArtifact>();
|
||||
s.template registerType<CArmedInstance, CGResource>();
|
||||
s.template registerType<CArmedInstance, CGMine>();
|
||||
s.template registerType<CArmedInstance, CBank>();
|
||||
s.template registerType<CArmedInstance, CGSeerHut>(); s.template registerType<IQuestObject, CGSeerHut>();
|
||||
s.template registerType<CGSeerHut, CGQuestGuard>();
|
||||
|
||||
s.template registerType<IUpdater, GrowsWithLevelUpdater>();
|
||||
s.template registerType<IUpdater, TimesHeroLevelUpdater>();
|
||||
s.template registerType<IUpdater, TimesStackLevelUpdater>();
|
||||
s.template registerType<IUpdater, OwnerUpdater>();
|
||||
s.template registerType<IUpdater, ArmyMovementUpdater>();
|
||||
|
||||
s.template registerType<ILimiter, AnyOfLimiter>();
|
||||
s.template registerType<ILimiter, NoneOfLimiter>();
|
||||
s.template registerType<ILimiter, OppositeSideLimiter>();
|
||||
//new types (other than netpacks) must register here
|
||||
//order of type registration is critical for loading old savegames
|
||||
|
||||
//Other object-related
|
||||
s.template registerType<IObjectInterface, CGTownBuilding>();
|
||||
s.template registerType<CGTownBuilding, CTownBonus>();
|
||||
s.template registerType<CGTownBuilding, COPWBonus>();
|
||||
s.template registerType<CGTownBuilding, CTownRewardableBuilding>();
|
||||
|
||||
s.template registerType<CGObjectInstance, CRewardableObject>();
|
||||
|
||||
s.template registerType<CGObjectInstance, CTeamVisited>();
|
||||
s.template registerType<CTeamVisited, CGObelisk>();
|
||||
|
||||
//end of objects
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Bonus system
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
//s.template registerType<IPropagator>();
|
||||
s.template registerType<IPropagator, CPropagatorNodeType>();
|
||||
|
||||
// Limiters
|
||||
//s.template registerType<ILimiter>();
|
||||
s.template registerType<ILimiter, AllOfLimiter>();
|
||||
s.template registerType<ILimiter, CCreatureTypeLimiter>();
|
||||
s.template registerType<ILimiter, HasAnotherBonusLimiter>();
|
||||
s.template registerType<ILimiter, CreatureTerrainLimiter>();
|
||||
s.template registerType<ILimiter, FactionLimiter>();
|
||||
s.template registerType<ILimiter, CreatureLevelLimiter>();
|
||||
s.template registerType<ILimiter, CreatureAlignmentLimiter>();
|
||||
s.template registerType<ILimiter, RankRangeLimiter>();
|
||||
s.template registerType<ILimiter, UnitOnHexLimiter>();
|
||||
|
||||
// s.template registerType<CBonusSystemNode>();
|
||||
s.template registerType<CBonusSystemNode, CArtifact>();
|
||||
s.template registerType<CBonusSystemNode, CCreature>();
|
||||
s.template registerType<CBonusSystemNode, CStackInstance>();
|
||||
s.template registerType<CStackInstance, CCommanderInstance>();
|
||||
s.template registerType<CBonusSystemNode, PlayerState>();
|
||||
s.template registerType<CBonusSystemNode, TeamState>();
|
||||
//s.template registerType<CGameState>(); //TODO
|
||||
//s.template registerType<CArmedInstance>();
|
||||
s.template registerType<CBonusSystemNode, CStack>();
|
||||
s.template registerType<CBonusSystemNode, BattleInfo>();
|
||||
//s.template registerType<QuestInfo>();
|
||||
s.template registerType<CBonusSystemNode, CArtifactInstance>();
|
||||
|
||||
//s.template registerType<CObstacleInstance>();
|
||||
s.template registerType<CObstacleInstance, SpellCreatedObstacle>();
|
||||
}
|
||||
|
||||
VCMI_LIB_NAMESPACE_END
|
56
lib/registerTypes/RegisterTypesServerPacks.h
Normal file
56
lib/registerTypes/RegisterTypesServerPacks.h
Normal file
@ -0,0 +1,56 @@
|
||||
/*
|
||||
* RegisterTypesServerPacks.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
|
||||
|
||||
#include "../networkPacks/PacksForServer.h"
|
||||
|
||||
VCMI_LIB_NAMESPACE_BEGIN
|
||||
|
||||
class BinarySerializer;
|
||||
class BinaryDeserializer;
|
||||
class CTypeList;
|
||||
|
||||
template<typename Serializer>
|
||||
void registerTypesServerPacks(Serializer &s)
|
||||
{
|
||||
s.template registerType<CPack, CPackForServer>();
|
||||
s.template registerType<CPackForServer, EndTurn>();
|
||||
s.template registerType<CPackForServer, DismissHero>();
|
||||
s.template registerType<CPackForServer, MoveHero>();
|
||||
s.template registerType<CPackForServer, ArrangeStacks>();
|
||||
s.template registerType<CPackForServer, DisbandCreature>();
|
||||
s.template registerType<CPackForServer, BuildStructure>();
|
||||
s.template registerType<CPackForServer, RecruitCreatures>();
|
||||
s.template registerType<CPackForServer, UpgradeCreature>();
|
||||
s.template registerType<CPackForServer, GarrisonHeroSwap>();
|
||||
s.template registerType<CPackForServer, ExchangeArtifacts>();
|
||||
s.template registerType<CPackForServer, AssembleArtifacts>();
|
||||
s.template registerType<CPackForServer, BuyArtifact>();
|
||||
s.template registerType<CPackForServer, TradeOnMarketplace>();
|
||||
s.template registerType<CPackForServer, SetFormation>();
|
||||
s.template registerType<CPackForServer, HireHero>();
|
||||
s.template registerType<CPackForServer, BuildBoat>();
|
||||
s.template registerType<CPackForServer, QueryReply>();
|
||||
s.template registerType<CPackForServer, MakeAction>();
|
||||
s.template registerType<CPackForServer, DigWithHero>();
|
||||
s.template registerType<CPackForServer, CastAdvSpell>();
|
||||
s.template registerType<CPackForServer, CastleTeleportHero>();
|
||||
s.template registerType<CPackForServer, SaveGame>();
|
||||
s.template registerType<CPackForServer, PlayerMessage>();
|
||||
s.template registerType<CPackForServer, BulkSplitStack>();
|
||||
s.template registerType<CPackForServer, BulkMergeStacks>();
|
||||
s.template registerType<CPackForServer, BulkSmartSplitStack>();
|
||||
s.template registerType<CPackForServer, BulkMoveArmy>();
|
||||
s.template registerType<CPackForServer, BulkExchangeArtifacts>();
|
||||
s.template registerType<CPackForServer, EraseArtifactByClient>();
|
||||
s.template registerType<CPackForServer, GamePause>();
|
||||
}
|
||||
|
||||
VCMI_LIB_NAMESPACE_END
|
@ -1,33 +0,0 @@
|
||||
/*
|
||||
* TypesClientPacks1.cpp, 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
|
||||
*
|
||||
*/
|
||||
#include "StdInc.h"
|
||||
#include "RegisterTypes.h"
|
||||
|
||||
#include "../StartInfo.h"
|
||||
#include "../mapObjects/CObjectHandler.h"
|
||||
#include "../CCreatureHandler.h"
|
||||
#include "../VCMI_Lib.h"
|
||||
#include "../CArtHandler.h"
|
||||
#include "../CHeroHandler.h"
|
||||
#include "../spells/CSpellHandler.h"
|
||||
#include "../CTownHandler.h"
|
||||
|
||||
#include "../serializer/BinaryDeserializer.h"
|
||||
#include "../serializer/BinarySerializer.h"
|
||||
#include "../serializer/CTypeList.h"
|
||||
|
||||
VCMI_LIB_NAMESPACE_BEGIN
|
||||
|
||||
|
||||
template void registerTypesClientPacks1<BinaryDeserializer>(BinaryDeserializer & s);
|
||||
template void registerTypesClientPacks1<BinarySerializer>(BinarySerializer & s);
|
||||
template void registerTypesClientPacks1<CTypeList>(CTypeList & s);
|
||||
|
||||
VCMI_LIB_NAMESPACE_END
|
@ -1,37 +0,0 @@
|
||||
/*
|
||||
* TypesClientPacks2.cpp, 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
|
||||
*
|
||||
*/
|
||||
#include "StdInc.h"
|
||||
#include "RegisterTypes.h"
|
||||
|
||||
#include "../StartInfo.h"
|
||||
#include "../CStack.h"
|
||||
#include "../battle/BattleInfo.h"
|
||||
#include "../mapObjects/CObjectHandler.h"
|
||||
#include "../CCreatureHandler.h"
|
||||
#include "../VCMI_Lib.h"
|
||||
#include "../CArtHandler.h"
|
||||
#include "../CHeroHandler.h"
|
||||
#include "../spells/CSpellHandler.h"
|
||||
#include "../CTownHandler.h"
|
||||
|
||||
#include "../serializer/BinaryDeserializer.h"
|
||||
#include "../serializer/BinarySerializer.h"
|
||||
#include "../serializer/CTypeList.h"
|
||||
|
||||
VCMI_LIB_NAMESPACE_BEGIN
|
||||
|
||||
|
||||
template void registerTypesClientPacks2<BinaryDeserializer>(BinaryDeserializer & s);
|
||||
template void registerTypesClientPacks2<BinarySerializer>(BinarySerializer & s);
|
||||
template void registerTypesClientPacks2<CTypeList>(CTypeList & s);
|
||||
|
||||
|
||||
|
||||
VCMI_LIB_NAMESPACE_END
|
@ -1,43 +0,0 @@
|
||||
/*
|
||||
* TypesLobbyPacks.cpp, 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
|
||||
*
|
||||
*/
|
||||
#include "StdInc.h"
|
||||
#include "RegisterTypes.h"
|
||||
|
||||
#include "../mapping/CMapInfo.h"
|
||||
#include "../StartInfo.h"
|
||||
#include "../gameState/CGameState.h"
|
||||
#include "../gameState/CGameStateCampaign.h"
|
||||
#include "../gameState/TavernHeroesPool.h"
|
||||
#include "../mapping/CMap.h"
|
||||
#include "../mapObjects/CObjectHandler.h"
|
||||
#include "../CCreatureHandler.h"
|
||||
#include "../VCMI_Lib.h"
|
||||
#include "../CArtHandler.h"
|
||||
#include "../CHeroHandler.h"
|
||||
#include "../spells/CSpellHandler.h"
|
||||
#include "../CTownHandler.h"
|
||||
#include "../RoadHandler.h"
|
||||
#include "../RiverHandler.h"
|
||||
#include "../TerrainHandler.h"
|
||||
#include "../campaign/CampaignState.h"
|
||||
#include "../rmg/CMapGenOptions.h"
|
||||
|
||||
#include "../serializer/BinaryDeserializer.h"
|
||||
#include "../serializer/BinarySerializer.h"
|
||||
#include "../serializer/CTypeList.h"
|
||||
|
||||
VCMI_LIB_NAMESPACE_BEGIN
|
||||
|
||||
template void registerTypesLobbyPacks<BinaryDeserializer>(BinaryDeserializer & s);
|
||||
template void registerTypesLobbyPacks<BinarySerializer>(BinarySerializer & s);
|
||||
template void registerTypesLobbyPacks<CTypeList>(CTypeList & s);
|
||||
|
||||
|
||||
VCMI_LIB_NAMESPACE_END
|
@ -1,34 +0,0 @@
|
||||
/*
|
||||
* TypesMapObjects1.cpp, 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
|
||||
*
|
||||
*/
|
||||
#include "StdInc.h"
|
||||
#include "RegisterTypes.h"
|
||||
|
||||
#include "../StartInfo.h"
|
||||
#include "../mapObjects/CObjectHandler.h"
|
||||
#include "../CCreatureHandler.h"
|
||||
#include "../VCMI_Lib.h"
|
||||
#include "../CArtHandler.h"
|
||||
#include "../CHeroHandler.h"
|
||||
#include "../spells/CSpellHandler.h"
|
||||
#include "../CTownHandler.h"
|
||||
|
||||
#include "../serializer/BinaryDeserializer.h"
|
||||
#include "../serializer/BinarySerializer.h"
|
||||
#include "../serializer/CTypeList.h"
|
||||
|
||||
VCMI_LIB_NAMESPACE_BEGIN
|
||||
|
||||
template void registerTypesMapObjects1<BinaryDeserializer>(BinaryDeserializer & s);
|
||||
template void registerTypesMapObjects1<BinarySerializer>(BinarySerializer & s);
|
||||
template void registerTypesMapObjects1<CTypeList>(CTypeList & s);
|
||||
|
||||
|
||||
|
||||
VCMI_LIB_NAMESPACE_END
|
@ -1,36 +0,0 @@
|
||||
/*
|
||||
* TypesMapObjects2.cpp, 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
|
||||
*
|
||||
*/
|
||||
#include "StdInc.h"
|
||||
#include "RegisterTypes.h"
|
||||
|
||||
#include "../StartInfo.h"
|
||||
#include "../CStack.h"
|
||||
#include "../battle/BattleInfo.h"
|
||||
#include "../mapObjects/CObjectHandler.h"
|
||||
#include "../CCreatureHandler.h"
|
||||
#include "../VCMI_Lib.h"
|
||||
#include "../CArtHandler.h"
|
||||
#include "../CHeroHandler.h"
|
||||
#include "../spells/CSpellHandler.h"
|
||||
#include "../CTownHandler.h"
|
||||
|
||||
#include "../serializer/BinaryDeserializer.h"
|
||||
#include "../serializer/BinarySerializer.h"
|
||||
#include "../serializer/CTypeList.h"
|
||||
|
||||
VCMI_LIB_NAMESPACE_BEGIN
|
||||
|
||||
|
||||
template void registerTypesMapObjects2<BinaryDeserializer>(BinaryDeserializer & s);
|
||||
template void registerTypesMapObjects2<BinarySerializer>(BinarySerializer & s);
|
||||
template void registerTypesMapObjects2<CTypeList>(CTypeList & s);
|
||||
|
||||
|
||||
VCMI_LIB_NAMESPACE_END
|
@ -1,32 +0,0 @@
|
||||
/*
|
||||
* TypesMapObjects3.cpp, 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
|
||||
*
|
||||
*/
|
||||
#include "StdInc.h"
|
||||
#include "RegisterTypes.h"
|
||||
|
||||
#include "../StartInfo.h"
|
||||
#include "../mapObjects/CObjectHandler.h"
|
||||
#include "../CCreatureHandler.h"
|
||||
#include "../VCMI_Lib.h"
|
||||
#include "../CArtHandler.h"
|
||||
#include "../CHeroHandler.h"
|
||||
#include "../spells/CSpellHandler.h"
|
||||
#include "../CTownHandler.h"
|
||||
|
||||
#include "../serializer/BinaryDeserializer.h"
|
||||
#include "../serializer/BinarySerializer.h"
|
||||
#include "../serializer/CTypeList.h"
|
||||
|
||||
VCMI_LIB_NAMESPACE_BEGIN
|
||||
|
||||
template void registerTypesMapObjectTypes<BinaryDeserializer>(BinaryDeserializer & s);
|
||||
template void registerTypesMapObjectTypes<BinarySerializer>(BinarySerializer & s);
|
||||
template void registerTypesMapObjectTypes<CTypeList>(CTypeList & s);
|
||||
|
||||
VCMI_LIB_NAMESPACE_END
|
@ -1,32 +0,0 @@
|
||||
/*
|
||||
* TypesServerPacks.cpp, 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
|
||||
*
|
||||
*/
|
||||
#include "StdInc.h"
|
||||
#include "RegisterTypes.h"
|
||||
|
||||
#include "../StartInfo.h"
|
||||
#include "../mapObjects/CObjectHandler.h"
|
||||
#include "../CCreatureHandler.h"
|
||||
#include "../VCMI_Lib.h"
|
||||
#include "../CArtHandler.h"
|
||||
#include "../CHeroHandler.h"
|
||||
#include "../spells/CSpellHandler.h"
|
||||
#include "../CTownHandler.h"
|
||||
|
||||
#include "../serializer/BinaryDeserializer.h"
|
||||
#include "../serializer/BinarySerializer.h"
|
||||
#include "../serializer/CTypeList.h"
|
||||
|
||||
VCMI_LIB_NAMESPACE_BEGIN
|
||||
|
||||
template void registerTypesServerPacks<BinaryDeserializer>(BinaryDeserializer & s);
|
||||
template void registerTypesServerPacks<BinarySerializer>(BinarySerializer & s);
|
||||
template void registerTypesServerPacks<CTypeList>(CTypeList & s);
|
||||
|
||||
VCMI_LIB_NAMESPACE_END
|
@ -9,97 +9,18 @@
|
||||
*/
|
||||
#include "StdInc.h"
|
||||
#include "BinaryDeserializer.h"
|
||||
|
||||
#include "../registerTypes/RegisterTypes.h"
|
||||
|
||||
VCMI_LIB_NAMESPACE_BEGIN
|
||||
|
||||
extern template void registerTypes<BinaryDeserializer>(BinaryDeserializer & s);
|
||||
|
||||
CLoadFile::CLoadFile(const boost::filesystem::path & fname, int minimalVersion)
|
||||
: serializer(this)
|
||||
BinaryDeserializer::BinaryDeserializer(IBinaryReader * r): CLoaderBase(r)
|
||||
{
|
||||
registerTypes(serializer);
|
||||
openNextFile(fname, minimalVersion);
|
||||
}
|
||||
saving = false;
|
||||
fileVersion = 0;
|
||||
smartPointerSerialization = true;
|
||||
reverseEndianess = false;
|
||||
|
||||
//must be instantiated in .cpp file for access to complete types of all member fields
|
||||
CLoadFile::~CLoadFile() = default;
|
||||
|
||||
int CLoadFile::read(void * data, unsigned size)
|
||||
{
|
||||
sfile->read(reinterpret_cast<char *>(data), size);
|
||||
return size;
|
||||
}
|
||||
|
||||
void CLoadFile::openNextFile(const boost::filesystem::path & fname, int minimalVersion)
|
||||
{
|
||||
assert(!serializer.reverseEndianess);
|
||||
assert(minimalVersion <= SERIALIZATION_VERSION);
|
||||
|
||||
try
|
||||
{
|
||||
fName = fname.string();
|
||||
sfile = std::make_unique<std::fstream>(fname.c_str(), std::ios::in | std::ios::binary);
|
||||
sfile->exceptions(std::ifstream::failbit | std::ifstream::badbit); //we throw a lot anyway
|
||||
|
||||
if(!(*sfile))
|
||||
THROW_FORMAT("Error: cannot open to read %s!", fName);
|
||||
|
||||
//we can read
|
||||
char buffer[4];
|
||||
sfile->read(buffer, 4);
|
||||
if(std::memcmp(buffer, "VCMI", 4) != 0)
|
||||
THROW_FORMAT("Error: not a VCMI file(%s)!", fName);
|
||||
|
||||
serializer & serializer.fileVersion;
|
||||
if(serializer.fileVersion < minimalVersion)
|
||||
THROW_FORMAT("Error: too old file format (%s)!", fName);
|
||||
|
||||
if(serializer.fileVersion > SERIALIZATION_VERSION)
|
||||
{
|
||||
logGlobal->warn("Warning format version mismatch: found %d when current is %d! (file %s)\n", serializer.fileVersion, SERIALIZATION_VERSION , fName);
|
||||
|
||||
auto * versionptr = reinterpret_cast<char *>(&serializer.fileVersion);
|
||||
std::reverse(versionptr, versionptr + 4);
|
||||
logGlobal->warn("Version number reversed is %x, checking...", serializer.fileVersion);
|
||||
|
||||
if(serializer.fileVersion == SERIALIZATION_VERSION)
|
||||
{
|
||||
logGlobal->warn("%s seems to have different endianness! Entering reversing mode.", fname.string());
|
||||
serializer.reverseEndianess = true;
|
||||
}
|
||||
else
|
||||
THROW_FORMAT("Error: too new file format (%s)!", fName);
|
||||
}
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
clear(); //if anything went wrong, we delete file and rethrow
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
void CLoadFile::reportState(vstd::CLoggerBase * out)
|
||||
{
|
||||
out->debug("CLoadFile");
|
||||
if(!!sfile && *sfile)
|
||||
out->debug("\tOpened %s Position: %d", fName, sfile->tellg());
|
||||
}
|
||||
|
||||
void CLoadFile::clear()
|
||||
{
|
||||
sfile = nullptr;
|
||||
fName.clear();
|
||||
serializer.fileVersion = 0;
|
||||
}
|
||||
|
||||
void CLoadFile::checkMagicBytes(const std::string &text)
|
||||
{
|
||||
std::string loaded = text;
|
||||
read((void *)loaded.data(), static_cast<unsigned int>(text.length()));
|
||||
if(loaded != text)
|
||||
throw std::runtime_error("Magic bytes doesn't match!");
|
||||
registerTypes(*this);
|
||||
}
|
||||
|
||||
VCMI_LIB_NAMESPACE_END
|
||||
|
@ -9,17 +9,12 @@
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <boost/mpl/vector.hpp>
|
||||
#include <boost/mpl/for_each.hpp>
|
||||
|
||||
#include "CSerializer.h"
|
||||
#include "CTypeList.h"
|
||||
#include "../mapObjects/CGHeroInstance.h"
|
||||
#include "../../Global.h"
|
||||
|
||||
VCMI_LIB_NAMESPACE_BEGIN
|
||||
|
||||
class CStackInstance;
|
||||
|
||||
class DLL_LINKAGE CLoaderBase
|
||||
{
|
||||
protected:
|
||||
@ -37,41 +32,6 @@ public:
|
||||
/// Effectively revesed version of BinarySerializer
|
||||
class DLL_LINKAGE BinaryDeserializer : public CLoaderBase
|
||||
{
|
||||
template<typename Variant, typename Source>
|
||||
struct VariantLoaderHelper
|
||||
{
|
||||
Source & source;
|
||||
std::vector<std::function<Variant()>> funcs;
|
||||
|
||||
template <class V>
|
||||
struct mpl_types_impl;
|
||||
|
||||
template <class... Ts>
|
||||
struct mpl_types_impl<std::variant<Ts...>> {
|
||||
using type = boost::mpl::vector<Ts...>;
|
||||
};
|
||||
|
||||
template <class V>
|
||||
using mpl_types = typename mpl_types_impl<V>::type;
|
||||
|
||||
VariantLoaderHelper(Source & source):
|
||||
source(source)
|
||||
{
|
||||
boost::mpl::for_each<mpl_types<Variant>>(std::ref(*this));
|
||||
}
|
||||
|
||||
template<typename Type>
|
||||
void operator()(Type)
|
||||
{
|
||||
funcs.push_back([&]() -> Variant
|
||||
{
|
||||
Type obj;
|
||||
source.load(obj);
|
||||
return Variant(obj);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Ser,typename T>
|
||||
struct LoadIfStackInstance
|
||||
{
|
||||
@ -138,40 +98,40 @@ class DLL_LINKAGE BinaryDeserializer : public CLoaderBase
|
||||
return length;
|
||||
}
|
||||
|
||||
template <typename T> class CPointerLoader;
|
||||
template <typename Type> class CPointerLoader;
|
||||
|
||||
class CBasicPointerLoader
|
||||
class IPointerLoader
|
||||
{
|
||||
public:
|
||||
virtual const std::type_info * loadPtr(CLoaderBase &ar, void *data, ui32 pid) const =0; //data is pointer to the ACTUAL POINTER
|
||||
virtual ~CBasicPointerLoader(){}
|
||||
virtual void * loadPtr(CLoaderBase &ar, ui32 pid) const =0; //data is pointer to the ACTUAL POINTER
|
||||
virtual ~IPointerLoader() = default;
|
||||
|
||||
template<typename T> static CBasicPointerLoader *getApplier(const T * t=nullptr)
|
||||
template<typename Type> static IPointerLoader *getApplier(const Type * t = nullptr)
|
||||
{
|
||||
return new CPointerLoader<T>();
|
||||
return new CPointerLoader<Type>();
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T> class CPointerLoader : public CBasicPointerLoader
|
||||
template <typename Type>
|
||||
class CPointerLoader : public IPointerLoader
|
||||
{
|
||||
public:
|
||||
const std::type_info * loadPtr(CLoaderBase &ar, void *data, ui32 pid) const override //data is pointer to the ACTUAL POINTER
|
||||
void * loadPtr(CLoaderBase &ar, ui32 pid) const override //data is pointer to the ACTUAL POINTER
|
||||
{
|
||||
auto & s = static_cast<BinaryDeserializer &>(ar);
|
||||
T *&ptr = *static_cast<T**>(data);
|
||||
|
||||
//create new object under pointer
|
||||
typedef typename std::remove_pointer<T>::type npT;
|
||||
ptr = ClassObjectCreator<npT>::invoke(); //does new npT or throws for abstract classes
|
||||
Type * ptr = ClassObjectCreator<Type>::invoke(); //does new npT or throws for abstract classes
|
||||
s.ptrAllocated(ptr, pid);
|
||||
//T is most derived known type, it's time to call actual serialize
|
||||
|
||||
assert(s.fileVersion != 0);
|
||||
ptr->serialize(s,s.fileVersion);
|
||||
return &typeid(T);
|
||||
|
||||
return static_cast<void*>(ptr);
|
||||
}
|
||||
};
|
||||
|
||||
CApplier<CBasicPointerLoader> applier;
|
||||
CApplier<IPointerLoader> applier;
|
||||
|
||||
int write(const void * data, unsigned size);
|
||||
|
||||
@ -181,17 +141,11 @@ public:
|
||||
|
||||
std::map<ui32, void*> loadedPointers;
|
||||
std::map<ui32, const std::type_info*> loadedPointersTypes;
|
||||
std::map<const void*, std::any> loadedSharedPointers;
|
||||
std::map<const void*, std::shared_ptr<void>> loadedSharedPointers;
|
||||
bool smartPointerSerialization;
|
||||
bool saving;
|
||||
|
||||
BinaryDeserializer(IBinaryReader * r): CLoaderBase(r)
|
||||
{
|
||||
saving = false;
|
||||
fileVersion = 0;
|
||||
smartPointerSerialization = true;
|
||||
reverseEndianess = false;
|
||||
}
|
||||
BinaryDeserializer(IBinaryReader * r);
|
||||
|
||||
template<class T>
|
||||
BinaryDeserializer & operator&(T & t)
|
||||
@ -264,14 +218,33 @@ public:
|
||||
template < typename T, typename std::enable_if < std::is_pointer<T>::value, int >::type = 0 >
|
||||
void load(T &data)
|
||||
{
|
||||
ui8 hlp;
|
||||
load( hlp );
|
||||
if(!hlp)
|
||||
bool isNull;
|
||||
load( isNull );
|
||||
if(isNull)
|
||||
{
|
||||
data = nullptr;
|
||||
return;
|
||||
}
|
||||
|
||||
loadPointerImpl(data);
|
||||
}
|
||||
|
||||
template < typename T, typename std::enable_if < std::is_base_of_v<Entity, std::remove_pointer_t<T>>, int >::type = 0 >
|
||||
void loadPointerImpl(T &data)
|
||||
{
|
||||
using DataType = std::remove_pointer_t<T>;
|
||||
|
||||
typename DataType::IdentifierType index;
|
||||
load(index);
|
||||
|
||||
auto * constEntity = index.toEntity(VLC);
|
||||
auto * constData = dynamic_cast<const DataType *>(constEntity);
|
||||
data = const_cast<DataType *>(constData);
|
||||
}
|
||||
|
||||
template < typename T, typename std::enable_if < !std::is_base_of_v<Entity, std::remove_pointer_t<T>>, int >::type = 0 >
|
||||
void loadPointerImpl(T &data)
|
||||
{
|
||||
if(reader->smartVectorMembersSerialization)
|
||||
{
|
||||
typedef typename std::remove_const<typename std::remove_pointer<T>::type>::type TObjectType; //eg: const CGHeroInstance * => CGHeroInstance
|
||||
@ -307,11 +280,10 @@ public:
|
||||
// We already got this pointer
|
||||
// Cast it in case we are loading it to a non-first base pointer
|
||||
assert(loadedPointersTypes.count(pid));
|
||||
data = reinterpret_cast<T>(typeList.castRaw(i->second, loadedPointersTypes.at(pid), &typeid(typename std::remove_const<typename std::remove_pointer<T>::type>::type)));
|
||||
data = static_cast<T>(i->second);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
//get type id
|
||||
ui16 tid;
|
||||
load( tid );
|
||||
@ -333,8 +305,7 @@ public:
|
||||
data = nullptr;
|
||||
return;
|
||||
}
|
||||
auto typeInfo = app->loadPtr(*this,&data, pid);
|
||||
data = reinterpret_cast<T>(typeList.castRaw((void*)data, typeInfo, &typeid(typename std::remove_const<typename std::remove_pointer<T>::type>::type)));
|
||||
data = static_cast<T>(app->loadPtr(*this, pid));
|
||||
}
|
||||
}
|
||||
|
||||
@ -360,7 +331,7 @@ public:
|
||||
NonConstT *internalPtr;
|
||||
load(internalPtr);
|
||||
|
||||
void *internalPtrDerived = typeList.castToMostDerived(internalPtr);
|
||||
void * internalPtrDerived = static_cast<void*>(internalPtr);
|
||||
|
||||
if(internalPtr)
|
||||
{
|
||||
@ -369,35 +340,13 @@ public:
|
||||
{
|
||||
// This pointers is already loaded. The "data" needs to be pointed to it,
|
||||
// so their shared state is actually shared.
|
||||
try
|
||||
{
|
||||
auto actualType = typeList.getTypeInfo(internalPtr);
|
||||
auto typeWeNeedToReturn = typeList.getTypeInfo<T>();
|
||||
if(*actualType == *typeWeNeedToReturn)
|
||||
{
|
||||
// No casting needed, just unpack already stored shared_ptr and return it
|
||||
data = std::any_cast<std::shared_ptr<T>>(itr->second);
|
||||
}
|
||||
else
|
||||
{
|
||||
// We need to perform series of casts
|
||||
auto ret = typeList.castShared(itr->second, actualType, typeWeNeedToReturn);
|
||||
data = std::any_cast<std::shared_ptr<T>>(ret);
|
||||
}
|
||||
}
|
||||
catch(std::exception &e)
|
||||
{
|
||||
logGlobal->error(e.what());
|
||||
logGlobal->error("Failed to cast stored shared ptr. Real type: %s. Needed type %s. FIXME FIXME FIXME", itr->second.type().name(), typeid(std::shared_ptr<T>).name());
|
||||
//TODO scenario with inheritance -> we can have stored ptr to base and load ptr to derived (or vice versa)
|
||||
throw;
|
||||
}
|
||||
data = std::static_pointer_cast<T>(itr->second);
|
||||
}
|
||||
else
|
||||
{
|
||||
auto hlp = std::shared_ptr<NonConstT>(internalPtr);
|
||||
data = hlp;
|
||||
loadedSharedPointers[internalPtrDerived] = typeList.castSharedToMostDerived(hlp);
|
||||
loadedSharedPointers[internalPtrDerived] = std::static_pointer_cast<void>(hlp);
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -510,17 +459,19 @@ public:
|
||||
this->read((void*)data.c_str(),length);
|
||||
}
|
||||
|
||||
template<typename T0, typename... TN>
|
||||
void load(std::variant<T0, TN...> & data)
|
||||
template<typename... TN>
|
||||
void load(std::variant<TN...> & data)
|
||||
{
|
||||
using TVariant = std::variant<T0, TN...>;
|
||||
|
||||
VariantLoaderHelper<TVariant, BinaryDeserializer> loader(*this);
|
||||
|
||||
si32 which;
|
||||
load( which );
|
||||
assert(which < loader.funcs.size());
|
||||
data = loader.funcs.at(which)();
|
||||
assert(which < sizeof...(TN));
|
||||
|
||||
// Create array of variants that contains all default-constructed alternatives
|
||||
const std::variant<TN...> table[] = { TN{ }... };
|
||||
// use appropriate alternative for result
|
||||
data = table[which];
|
||||
// perform actual load via std::visit dispatch
|
||||
std::visit([&](auto& o) { load(o); }, data);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
@ -579,30 +530,4 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
class DLL_LINKAGE CLoadFile : public IBinaryReader
|
||||
{
|
||||
public:
|
||||
BinaryDeserializer serializer;
|
||||
|
||||
std::string fName;
|
||||
std::unique_ptr<std::fstream> sfile;
|
||||
|
||||
CLoadFile(const boost::filesystem::path & fname, int minimalVersion = SERIALIZATION_VERSION); //throws!
|
||||
virtual ~CLoadFile();
|
||||
int read(void * data, unsigned size) override; //throws!
|
||||
|
||||
void openNextFile(const boost::filesystem::path & fname, int minimalVersion); //throws!
|
||||
void clear();
|
||||
void reportState(vstd::CLoggerBase * out) override;
|
||||
|
||||
void checkMagicBytes(const std::string & text);
|
||||
|
||||
template<class T>
|
||||
CLoadFile & operator>>(T &t)
|
||||
{
|
||||
serializer & t;
|
||||
return * this;
|
||||
}
|
||||
};
|
||||
|
||||
VCMI_LIB_NAMESPACE_END
|
||||
|
@ -9,69 +9,15 @@
|
||||
*/
|
||||
#include "StdInc.h"
|
||||
#include "BinarySerializer.h"
|
||||
|
||||
#include "../registerTypes/RegisterTypes.h"
|
||||
|
||||
VCMI_LIB_NAMESPACE_BEGIN
|
||||
|
||||
extern template void registerTypes<BinarySerializer>(BinarySerializer & s);
|
||||
|
||||
CSaveFile::CSaveFile(const boost::filesystem::path &fname)
|
||||
: serializer(this)
|
||||
BinarySerializer::BinarySerializer(IBinaryWriter * w): CSaverBase(w)
|
||||
{
|
||||
registerTypes(serializer);
|
||||
openNextFile(fname);
|
||||
}
|
||||
|
||||
//must be instantiated in .cpp file for access to complete types of all member fields
|
||||
CSaveFile::~CSaveFile() = default;
|
||||
|
||||
int CSaveFile::write(const void * data, unsigned size)
|
||||
{
|
||||
sfile->write((char *)data,size);
|
||||
return size;
|
||||
}
|
||||
|
||||
void CSaveFile::openNextFile(const boost::filesystem::path &fname)
|
||||
{
|
||||
fName = fname;
|
||||
try
|
||||
{
|
||||
sfile = std::make_unique<std::fstream>(fname.c_str(), std::ios::out | std::ios::binary);
|
||||
sfile->exceptions(std::ifstream::failbit | std::ifstream::badbit); //we throw a lot anyway
|
||||
|
||||
if(!(*sfile))
|
||||
THROW_FORMAT("Error: cannot open to write %s!", fname);
|
||||
|
||||
sfile->write("VCMI",4); //write magic identifier
|
||||
serializer & SERIALIZATION_VERSION; //write format version
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
logGlobal->error("Failed to save to %s", fname.string());
|
||||
clear();
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
void CSaveFile::reportState(vstd::CLoggerBase * out)
|
||||
{
|
||||
out->debug("CSaveFile");
|
||||
if(sfile.get() && *sfile)
|
||||
{
|
||||
out->debug("\tOpened %s \tPosition: %d", fName, sfile->tellp());
|
||||
}
|
||||
}
|
||||
|
||||
void CSaveFile::clear()
|
||||
{
|
||||
fName.clear();
|
||||
sfile = nullptr;
|
||||
}
|
||||
|
||||
void CSaveFile::putMagicBytes(const std::string &text)
|
||||
{
|
||||
write(text.c_str(), static_cast<unsigned int>(text.length()));
|
||||
saving=true;
|
||||
smartPointerSerialization = true;
|
||||
registerTypes(*this);
|
||||
}
|
||||
|
||||
VCMI_LIB_NAMESPACE_END
|
||||
|
@ -9,6 +9,7 @@
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "CSerializer.h"
|
||||
#include "CTypeList.h"
|
||||
#include "../mapObjects/CArmedInstance.h"
|
||||
|
||||
@ -114,11 +115,7 @@ public:
|
||||
bool smartPointerSerialization;
|
||||
bool saving;
|
||||
|
||||
BinarySerializer(IBinaryWriter * w): CSaverBase(w)
|
||||
{
|
||||
saving=true;
|
||||
smartPointerSerialization = true;
|
||||
}
|
||||
BinarySerializer(IBinaryWriter * w);
|
||||
|
||||
template<typename Base, typename Derived>
|
||||
void registerType(const Base * b = nullptr, const Derived * d = nullptr)
|
||||
@ -174,16 +171,30 @@ public:
|
||||
void save(const T &data)
|
||||
{
|
||||
//write if pointer is not nullptr
|
||||
ui8 hlp = (data!=nullptr);
|
||||
save(hlp);
|
||||
bool isNull = (data == nullptr);
|
||||
save(isNull);
|
||||
|
||||
//if pointer is nullptr then we don't need anything more...
|
||||
if(!hlp)
|
||||
if(data == nullptr)
|
||||
return;
|
||||
|
||||
savePointerImpl(data);
|
||||
}
|
||||
|
||||
template < typename T, typename std::enable_if < std::is_base_of_v<Entity, std::remove_pointer_t<T>>, int >::type = 0 >
|
||||
void savePointerImpl(const T &data)
|
||||
{
|
||||
auto index = data->getId();
|
||||
save(index);
|
||||
}
|
||||
|
||||
template < typename T, typename std::enable_if < !std::is_base_of_v<Entity, std::remove_pointer_t<T>>, int >::type = 0 >
|
||||
void savePointerImpl(const T &data)
|
||||
{
|
||||
typedef typename std::remove_const<typename std::remove_pointer<T>::type>::type TObjectType;
|
||||
|
||||
if(writer->smartVectorMembersSerialization)
|
||||
{
|
||||
typedef typename std::remove_const<typename std::remove_pointer<T>::type>::type TObjectType;
|
||||
typedef typename VectorizedTypeFor<TObjectType>::type VType;
|
||||
typedef typename VectorizedIDType<TObjectType>::type IDType;
|
||||
|
||||
@ -207,7 +218,7 @@ public:
|
||||
{
|
||||
// We might have an object that has multiple inheritance and store it via the non-first base pointer.
|
||||
// Therefore, all pointers need to be normalized to the actual object address.
|
||||
auto actualPointer = typeList.castToMostDerived(data);
|
||||
const void * actualPointer = static_cast<const void*>(data);
|
||||
auto i = savedPointers.find(actualPointer);
|
||||
if(i != savedPointers.end())
|
||||
{
|
||||
@ -223,13 +234,13 @@ public:
|
||||
}
|
||||
|
||||
//write type identifier
|
||||
ui16 tid = typeList.getTypeID(data);
|
||||
uint16_t tid = CTypeList::getInstance().getTypeID(data);
|
||||
save(tid);
|
||||
|
||||
if(!tid)
|
||||
save(*data); //if type is unregistered simply write all data in a standard way
|
||||
else
|
||||
applier.getApplier(tid)->savePtr(*this, typeList.castToMostDerived(data)); //call serializer specific for our real type
|
||||
applier.getApplier(tid)->savePtr(*this, static_cast<const void*>(data)); //call serializer specific for our real type
|
||||
}
|
||||
|
||||
template < typename T, typename std::enable_if < is_serializeable<BinarySerializer, T>::value, int >::type = 0 >
|
||||
@ -389,30 +400,4 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
class DLL_LINKAGE CSaveFile : public IBinaryWriter
|
||||
{
|
||||
public:
|
||||
BinarySerializer serializer;
|
||||
|
||||
boost::filesystem::path fName;
|
||||
std::unique_ptr<std::fstream> sfile;
|
||||
|
||||
CSaveFile(const boost::filesystem::path &fname); //throws!
|
||||
~CSaveFile();
|
||||
int write(const void * data, unsigned size) override;
|
||||
|
||||
void openNextFile(const boost::filesystem::path &fname); //throws!
|
||||
void clear();
|
||||
void reportState(vstd::CLoggerBase * out) override;
|
||||
|
||||
void putMagicBytes(const std::string &text);
|
||||
|
||||
template<class T>
|
||||
CSaveFile & operator<<(const T &t)
|
||||
{
|
||||
serializer & t;
|
||||
return * this;
|
||||
}
|
||||
};
|
||||
|
||||
VCMI_LIB_NAMESPACE_END
|
||||
|
100
lib/serializer/CLoadFile.cpp
Normal file
100
lib/serializer/CLoadFile.cpp
Normal file
@ -0,0 +1,100 @@
|
||||
/*
|
||||
* CLoadFile.cpp, 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
|
||||
*
|
||||
*/
|
||||
#include "StdInc.h"
|
||||
#include "CLoadFile.h"
|
||||
|
||||
VCMI_LIB_NAMESPACE_BEGIN
|
||||
|
||||
CLoadFile::CLoadFile(const boost::filesystem::path & fname, int minimalVersion)
|
||||
: serializer(this)
|
||||
{
|
||||
openNextFile(fname, minimalVersion);
|
||||
}
|
||||
|
||||
//must be instantiated in .cpp file for access to complete types of all member fields
|
||||
CLoadFile::~CLoadFile() = default;
|
||||
|
||||
int CLoadFile::read(void * data, unsigned size)
|
||||
{
|
||||
sfile->read(reinterpret_cast<char *>(data), size);
|
||||
return size;
|
||||
}
|
||||
|
||||
void CLoadFile::openNextFile(const boost::filesystem::path & fname, int minimalVersion)
|
||||
{
|
||||
assert(!serializer.reverseEndianess);
|
||||
assert(minimalVersion <= SERIALIZATION_VERSION);
|
||||
|
||||
try
|
||||
{
|
||||
fName = fname.string();
|
||||
sfile = std::make_unique<std::fstream>(fname.c_str(), std::ios::in | std::ios::binary);
|
||||
sfile->exceptions(std::ifstream::failbit | std::ifstream::badbit); //we throw a lot anyway
|
||||
|
||||
if(!(*sfile))
|
||||
THROW_FORMAT("Error: cannot open to read %s!", fName);
|
||||
|
||||
//we can read
|
||||
char buffer[4];
|
||||
sfile->read(buffer, 4);
|
||||
if(std::memcmp(buffer, "VCMI", 4) != 0)
|
||||
THROW_FORMAT("Error: not a VCMI file(%s)!", fName);
|
||||
|
||||
serializer & serializer.fileVersion;
|
||||
if(serializer.fileVersion < minimalVersion)
|
||||
THROW_FORMAT("Error: too old file format (%s)!", fName);
|
||||
|
||||
if(serializer.fileVersion > SERIALIZATION_VERSION)
|
||||
{
|
||||
logGlobal->warn("Warning format version mismatch: found %d when current is %d! (file %s)\n", serializer.fileVersion, SERIALIZATION_VERSION , fName);
|
||||
|
||||
auto * versionptr = reinterpret_cast<char *>(&serializer.fileVersion);
|
||||
std::reverse(versionptr, versionptr + 4);
|
||||
logGlobal->warn("Version number reversed is %x, checking...", serializer.fileVersion);
|
||||
|
||||
if(serializer.fileVersion == SERIALIZATION_VERSION)
|
||||
{
|
||||
logGlobal->warn("%s seems to have different endianness! Entering reversing mode.", fname.string());
|
||||
serializer.reverseEndianess = true;
|
||||
}
|
||||
else
|
||||
THROW_FORMAT("Error: too new file format (%s)!", fName);
|
||||
}
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
clear(); //if anything went wrong, we delete file and rethrow
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
void CLoadFile::reportState(vstd::CLoggerBase * out)
|
||||
{
|
||||
out->debug("CLoadFile");
|
||||
if(!!sfile && *sfile)
|
||||
out->debug("\tOpened %s Position: %d", fName, sfile->tellg());
|
||||
}
|
||||
|
||||
void CLoadFile::clear()
|
||||
{
|
||||
sfile = nullptr;
|
||||
fName.clear();
|
||||
serializer.fileVersion = 0;
|
||||
}
|
||||
|
||||
void CLoadFile::checkMagicBytes(const std::string &text)
|
||||
{
|
||||
std::string loaded = text;
|
||||
read((void *)loaded.data(), static_cast<unsigned int>(text.length()));
|
||||
if(loaded != text)
|
||||
throw std::runtime_error("Magic bytes doesn't match!");
|
||||
}
|
||||
|
||||
VCMI_LIB_NAMESPACE_END
|
42
lib/serializer/CLoadFile.h
Normal file
42
lib/serializer/CLoadFile.h
Normal file
@ -0,0 +1,42 @@
|
||||
/*
|
||||
* CLoadFile.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
|
||||
|
||||
#include "BinaryDeserializer.h"
|
||||
|
||||
VCMI_LIB_NAMESPACE_BEGIN
|
||||
|
||||
class DLL_LINKAGE CLoadFile : public IBinaryReader
|
||||
{
|
||||
public:
|
||||
BinaryDeserializer serializer;
|
||||
|
||||
std::string fName;
|
||||
std::unique_ptr<std::fstream> sfile;
|
||||
|
||||
CLoadFile(const boost::filesystem::path & fname, int minimalVersion = SERIALIZATION_VERSION); //throws!
|
||||
virtual ~CLoadFile();
|
||||
int read(void * data, unsigned size) override; //throws!
|
||||
|
||||
void openNextFile(const boost::filesystem::path & fname, int minimalVersion); //throws!
|
||||
void clear();
|
||||
void reportState(vstd::CLoggerBase * out) override;
|
||||
|
||||
void checkMagicBytes(const std::string & text);
|
||||
|
||||
template<class T>
|
||||
CLoadFile & operator>>(T &t)
|
||||
{
|
||||
serializer & t;
|
||||
return * this;
|
||||
}
|
||||
};
|
||||
|
||||
VCMI_LIB_NAMESPACE_END
|
@ -1,68 +0,0 @@
|
||||
/*
|
||||
* CLoadIntegrityValidator.cpp, 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
|
||||
*
|
||||
*/
|
||||
#include "StdInc.h"
|
||||
#include "CLoadIntegrityValidator.h"
|
||||
|
||||
#include "../registerTypes/RegisterTypes.h"
|
||||
|
||||
VCMI_LIB_NAMESPACE_BEGIN
|
||||
|
||||
CLoadIntegrityValidator::CLoadIntegrityValidator(const boost::filesystem::path &primaryFileName, const boost::filesystem::path &controlFileName, int minimalVersion)
|
||||
: serializer(this), foundDesync(false)
|
||||
{
|
||||
registerTypes(serializer);
|
||||
primaryFile = std::make_unique<CLoadFile>(primaryFileName, minimalVersion);
|
||||
controlFile = std::make_unique<CLoadFile>(controlFileName, minimalVersion);
|
||||
|
||||
assert(primaryFile->serializer.fileVersion == controlFile->serializer.fileVersion);
|
||||
serializer.fileVersion = primaryFile->serializer.fileVersion;
|
||||
}
|
||||
|
||||
int CLoadIntegrityValidator::read( void * data, unsigned size )
|
||||
{
|
||||
assert(primaryFile);
|
||||
assert(controlFile);
|
||||
|
||||
if(!size)
|
||||
return size;
|
||||
|
||||
std::vector<ui8> controlData(size);
|
||||
auto ret = primaryFile->read(data, size);
|
||||
|
||||
if(!foundDesync)
|
||||
{
|
||||
controlFile->read(controlData.data(), size);
|
||||
if(std::memcmp(data, controlData.data(), size) != 0)
|
||||
{
|
||||
logGlobal->error("Desync found! Position: %d", primaryFile->sfile->tellg());
|
||||
foundDesync = true;
|
||||
//throw std::runtime_error("Savegame dsynchronized!");
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
std::unique_ptr<CLoadFile> CLoadIntegrityValidator::decay()
|
||||
{
|
||||
primaryFile->serializer.loadedPointers = this->serializer.loadedPointers;
|
||||
primaryFile->serializer.loadedPointersTypes = this->serializer.loadedPointersTypes;
|
||||
return std::move(primaryFile);
|
||||
}
|
||||
|
||||
void CLoadIntegrityValidator::checkMagicBytes(const std::string & text) const
|
||||
{
|
||||
assert(primaryFile);
|
||||
assert(controlFile);
|
||||
|
||||
primaryFile->checkMagicBytes(text);
|
||||
controlFile->checkMagicBytes(text);
|
||||
}
|
||||
|
||||
VCMI_LIB_NAMESPACE_END
|
@ -1,33 +0,0 @@
|
||||
/*
|
||||
* CLoadIntegrityValidator.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
|
||||
|
||||
#include "BinaryDeserializer.h"
|
||||
|
||||
VCMI_LIB_NAMESPACE_BEGIN
|
||||
|
||||
/// Simple byte-to-byte saves comparator
|
||||
class DLL_LINKAGE CLoadIntegrityValidator
|
||||
: public IBinaryReader
|
||||
{
|
||||
public:
|
||||
BinaryDeserializer serializer;
|
||||
std::unique_ptr<CLoadFile> primaryFile, controlFile;
|
||||
bool foundDesync;
|
||||
|
||||
CLoadIntegrityValidator(const boost::filesystem::path &primaryFileName, const boost::filesystem::path &controlFileName, int minimalVersion = SERIALIZATION_VERSION); //throws!
|
||||
|
||||
int read( void * data, unsigned size) override; //throws!
|
||||
void checkMagicBytes(const std::string & text) const;
|
||||
|
||||
std::unique_ptr<CLoadFile> decay(); //returns primary file. CLoadIntegrityValidator stops being usable anymore
|
||||
};
|
||||
|
||||
VCMI_LIB_NAMESPACE_END
|
@ -10,8 +10,6 @@
|
||||
#include "StdInc.h"
|
||||
#include "CMemorySerializer.h"
|
||||
|
||||
#include "../registerTypes/RegisterTypes.h"
|
||||
|
||||
VCMI_LIB_NAMESPACE_BEGIN
|
||||
|
||||
int CMemorySerializer::read(void * data, unsigned size)
|
||||
@ -34,8 +32,6 @@ int CMemorySerializer::write(const void * data, unsigned size)
|
||||
|
||||
CMemorySerializer::CMemorySerializer(): iser(this), oser(this), readPos(0)
|
||||
{
|
||||
registerTypes(iser);
|
||||
registerTypes(oser);
|
||||
iser.fileVersion = SERIALIZATION_VERSION;
|
||||
}
|
||||
|
||||
|
72
lib/serializer/CSaveFile.cpp
Normal file
72
lib/serializer/CSaveFile.cpp
Normal file
@ -0,0 +1,72 @@
|
||||
/*
|
||||
* CSaveFile.cpp, 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
|
||||
*
|
||||
*/
|
||||
#include "StdInc.h"
|
||||
#include "CSaveFile.h"
|
||||
|
||||
VCMI_LIB_NAMESPACE_BEGIN
|
||||
|
||||
CSaveFile::CSaveFile(const boost::filesystem::path &fname)
|
||||
: serializer(this)
|
||||
{
|
||||
openNextFile(fname);
|
||||
}
|
||||
|
||||
//must be instantiated in .cpp file for access to complete types of all member fields
|
||||
CSaveFile::~CSaveFile() = default;
|
||||
|
||||
int CSaveFile::write(const void * data, unsigned size)
|
||||
{
|
||||
sfile->write((char *)data,size);
|
||||
return size;
|
||||
}
|
||||
|
||||
void CSaveFile::openNextFile(const boost::filesystem::path &fname)
|
||||
{
|
||||
fName = fname;
|
||||
try
|
||||
{
|
||||
sfile = std::make_unique<std::fstream>(fname.c_str(), std::ios::out | std::ios::binary);
|
||||
sfile->exceptions(std::ifstream::failbit | std::ifstream::badbit); //we throw a lot anyway
|
||||
|
||||
if(!(*sfile))
|
||||
THROW_FORMAT("Error: cannot open to write %s!", fname);
|
||||
|
||||
sfile->write("VCMI",4); //write magic identifier
|
||||
serializer & SERIALIZATION_VERSION; //write format version
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
logGlobal->error("Failed to save to %s", fname.string());
|
||||
clear();
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
void CSaveFile::reportState(vstd::CLoggerBase * out)
|
||||
{
|
||||
out->debug("CSaveFile");
|
||||
if(sfile.get() && *sfile)
|
||||
{
|
||||
out->debug("\tOpened %s \tPosition: %d", fName, sfile->tellp());
|
||||
}
|
||||
}
|
||||
|
||||
void CSaveFile::clear()
|
||||
{
|
||||
fName.clear();
|
||||
sfile = nullptr;
|
||||
}
|
||||
|
||||
void CSaveFile::putMagicBytes(const std::string &text)
|
||||
{
|
||||
write(text.c_str(), static_cast<unsigned int>(text.length()));
|
||||
}
|
||||
|
||||
VCMI_LIB_NAMESPACE_END
|
42
lib/serializer/CSaveFile.h
Normal file
42
lib/serializer/CSaveFile.h
Normal file
@ -0,0 +1,42 @@
|
||||
/*
|
||||
* CSaveFile.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
|
||||
|
||||
#include "BinarySerializer.h"
|
||||
|
||||
VCMI_LIB_NAMESPACE_BEGIN
|
||||
|
||||
class DLL_LINKAGE CSaveFile : public IBinaryWriter
|
||||
{
|
||||
public:
|
||||
BinarySerializer serializer;
|
||||
|
||||
boost::filesystem::path fName;
|
||||
std::unique_ptr<std::fstream> sfile;
|
||||
|
||||
CSaveFile(const boost::filesystem::path &fname); //throws!
|
||||
~CSaveFile();
|
||||
int write(const void * data, unsigned size) override;
|
||||
|
||||
void openNextFile(const boost::filesystem::path &fname); //throws!
|
||||
void clear();
|
||||
void reportState(vstd::CLoggerBase * out) override;
|
||||
|
||||
void putMagicBytes(const std::string &text);
|
||||
|
||||
template<class T>
|
||||
CSaveFile & operator<<(const T &t)
|
||||
{
|
||||
serializer & t;
|
||||
return * this;
|
||||
}
|
||||
};
|
||||
|
||||
VCMI_LIB_NAMESPACE_END
|
@ -14,8 +14,8 @@
|
||||
|
||||
VCMI_LIB_NAMESPACE_BEGIN
|
||||
|
||||
const ui32 SERIALIZATION_VERSION = 828;
|
||||
const ui32 MINIMAL_SERIALIZATION_VERSION = 828;
|
||||
const ui32 SERIALIZATION_VERSION = 830;
|
||||
const ui32 MINIMAL_SERIALIZATION_VERSION = 830;
|
||||
const std::string SAVEGAME_MAGIC = "VCMISVG";
|
||||
|
||||
class CHero;
|
||||
@ -149,42 +149,31 @@ struct is_serializeable
|
||||
template <typename T> //metafunction returning CGObjectInstance if T is its derivate or T elsewise
|
||||
struct VectorizedTypeFor
|
||||
{
|
||||
using type = typename
|
||||
//if
|
||||
boost::mpl::eval_if<std::is_same<CGHeroInstance, T>,
|
||||
boost::mpl::identity<CGHeroInstance>,
|
||||
//else if
|
||||
boost::mpl::eval_if<std::is_base_of<CGObjectInstance, T>,
|
||||
boost::mpl::identity<CGObjectInstance>,
|
||||
//else
|
||||
boost::mpl::identity<T>
|
||||
>>::type;
|
||||
using type = std::conditional_t<std::is_base_of_v<CGObjectInstance, T>, CGObjectInstance, T>;
|
||||
};
|
||||
template <typename U>
|
||||
|
||||
template <>
|
||||
struct VectorizedTypeFor<CGHeroInstance>
|
||||
{
|
||||
using type = CGHeroInstance;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct VectorizedIDType
|
||||
{
|
||||
using type = typename
|
||||
//if
|
||||
boost::mpl::eval_if<std::is_same<CArtifact, U>,
|
||||
boost::mpl::identity<ArtifactID>,
|
||||
//else if
|
||||
boost::mpl::eval_if<std::is_same<CCreature, U>,
|
||||
boost::mpl::identity<CreatureID>,
|
||||
//else if
|
||||
boost::mpl::eval_if<std::is_same<CHero, U>,
|
||||
boost::mpl::identity<HeroTypeID>,
|
||||
//else if
|
||||
boost::mpl::eval_if<std::is_same<CArtifactInstance, U>,
|
||||
boost::mpl::identity<ArtifactInstanceID>,
|
||||
//else if
|
||||
boost::mpl::eval_if<std::is_same<CGHeroInstance, U>,
|
||||
boost::mpl::identity<HeroTypeID>,
|
||||
//else if
|
||||
boost::mpl::eval_if<std::is_base_of<CGObjectInstance, U>,
|
||||
boost::mpl::identity<ObjectInstanceID>,
|
||||
//else
|
||||
boost::mpl::identity<si32>
|
||||
>>>>>>::type;
|
||||
using type = std::conditional_t<std::is_base_of_v<CGObjectInstance, T>, ObjectInstanceID, int32_t>;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct VectorizedIDType<CArtifactInstance>
|
||||
{
|
||||
using type = ArtifactInstanceID;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct VectorizedIDType<CGHeroInstance>
|
||||
{
|
||||
using type = HeroTypeID;
|
||||
};
|
||||
|
||||
/// Base class for deserializers
|
||||
|
@ -14,128 +14,9 @@
|
||||
|
||||
VCMI_LIB_NAMESPACE_BEGIN
|
||||
|
||||
extern template void registerTypes<CTypeList>(CTypeList & s);
|
||||
|
||||
CTypeList typeList;
|
||||
|
||||
CTypeList::CTypeList()
|
||||
{
|
||||
registerTypes(*this);
|
||||
}
|
||||
|
||||
CTypeList::TypeInfoPtr CTypeList::registerType(const std::type_info *type)
|
||||
{
|
||||
if(auto typeDescr = getTypeDescriptor(type, false))
|
||||
return typeDescr; //type found, return ptr to structure
|
||||
|
||||
//type not found - add it to the list and return given ID
|
||||
auto newType = std::make_shared<TypeDescriptor>();
|
||||
newType->typeID = static_cast<ui16>(typeInfos.size() + 1);
|
||||
newType->name = type->name();
|
||||
typeInfos[type] = newType;
|
||||
|
||||
return newType;
|
||||
}
|
||||
|
||||
ui16 CTypeList::getTypeID(const std::type_info *type, bool throws) const
|
||||
{
|
||||
auto descriptor = getTypeDescriptor(type, throws);
|
||||
if (descriptor == nullptr)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
return descriptor->typeID;
|
||||
}
|
||||
|
||||
CTypeList::TypeInfoPtr CTypeList::getTypeDescriptor(ui16 typeID) const
|
||||
{
|
||||
auto found = std::find_if(typeInfos.begin(), typeInfos.end(), [typeID](const std::pair<const std::type_info *, TypeInfoPtr> & p) -> bool
|
||||
{
|
||||
return p.second->typeID == typeID;
|
||||
});
|
||||
|
||||
if(found != typeInfos.end())
|
||||
{
|
||||
return found->second;
|
||||
}
|
||||
|
||||
return TypeInfoPtr();
|
||||
}
|
||||
|
||||
std::vector<CTypeList::TypeInfoPtr> CTypeList::castSequence(TypeInfoPtr from, TypeInfoPtr to) const
|
||||
{
|
||||
if(!strcmp(from->name, to->name))
|
||||
return std::vector<CTypeList::TypeInfoPtr>();
|
||||
|
||||
// Perform a simple BFS in the class hierarchy.
|
||||
|
||||
auto BFS = [&](bool upcast)
|
||||
{
|
||||
std::map<TypeInfoPtr, TypeInfoPtr> previous;
|
||||
std::queue<TypeInfoPtr> q;
|
||||
q.push(to);
|
||||
while(!q.empty())
|
||||
{
|
||||
auto typeNode = q.front();
|
||||
q.pop();
|
||||
for(auto & weakNode : (upcast ? typeNode->parents : typeNode->children) )
|
||||
{
|
||||
auto nodeBase = weakNode.lock();
|
||||
if(!previous.count(nodeBase))
|
||||
{
|
||||
previous[nodeBase] = typeNode;
|
||||
q.push(nodeBase);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<TypeInfoPtr> ret;
|
||||
|
||||
if(!previous.count(from))
|
||||
return ret;
|
||||
|
||||
ret.push_back(from);
|
||||
TypeInfoPtr ptr = from;
|
||||
do
|
||||
{
|
||||
ptr = previous.at(ptr);
|
||||
ret.push_back(ptr);
|
||||
} while(ptr != to);
|
||||
|
||||
return ret;
|
||||
};
|
||||
|
||||
// Try looking both up and down.
|
||||
auto ret = BFS(true);
|
||||
if(ret.empty())
|
||||
ret = BFS(false);
|
||||
|
||||
if(ret.empty())
|
||||
THROW_FORMAT("Cannot find relation between types %s and %s. Were they (and all classes between them) properly registered?", from->name % to->name);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
std::vector<CTypeList::TypeInfoPtr> CTypeList::castSequence(const std::type_info *from, const std::type_info *to) const
|
||||
{
|
||||
//This additional if is needed because getTypeDescriptor might fail if type is not registered
|
||||
// (and if casting is not needed, then registereing should no be required)
|
||||
if(!strcmp(from->name(), to->name()))
|
||||
return std::vector<CTypeList::TypeInfoPtr>();
|
||||
|
||||
return castSequence(getTypeDescriptor(from), getTypeDescriptor(to));
|
||||
}
|
||||
|
||||
CTypeList::TypeInfoPtr CTypeList::getTypeDescriptor(const std::type_info *type, bool throws) const
|
||||
{
|
||||
auto i = typeInfos.find(type);
|
||||
if(i != typeInfos.end())
|
||||
return i->second; //type found, return ptr to structure
|
||||
|
||||
if(!throws)
|
||||
return nullptr;
|
||||
|
||||
THROW_FORMAT("Cannot find type descriptor for type %s. Was it registered?", type->name());
|
||||
}
|
||||
|
||||
VCMI_LIB_NAMESPACE_END
|
||||
|
@ -9,199 +9,72 @@
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "CSerializer.h"
|
||||
|
||||
VCMI_LIB_NAMESPACE_BEGIN
|
||||
|
||||
struct IPointerCaster
|
||||
{
|
||||
virtual std::any castRawPtr(const std::any &ptr) const = 0; // takes From*, returns To*
|
||||
virtual std::any castSharedPtr(const std::any &ptr) const = 0; // takes std::shared_ptr<From>, performs dynamic cast, returns std::shared_ptr<To>
|
||||
virtual std::any castWeakPtr(const std::any &ptr) const = 0; // takes std::weak_ptr<From>, performs dynamic cast, returns std::weak_ptr<To>. The object under poitner must live.
|
||||
//virtual std::any castUniquePtr(const std::any &ptr) const = 0; // takes std::unique_ptr<From>, performs dynamic cast, returns std::unique_ptr<To>
|
||||
virtual ~IPointerCaster() = default;
|
||||
};
|
||||
|
||||
template <typename From, typename To>
|
||||
struct PointerCaster : IPointerCaster
|
||||
{
|
||||
virtual std::any castRawPtr(const std::any &ptr) const override // takes void* pointing to From object, performs dynamic cast, returns void* pointing to To object
|
||||
{
|
||||
From * from = (From*)std::any_cast<void*>(ptr);
|
||||
To * ret = static_cast<To*>(from);
|
||||
return (void*)ret;
|
||||
}
|
||||
|
||||
// Helper function performing casts between smart pointers
|
||||
template<typename SmartPt>
|
||||
std::any castSmartPtr(const std::any &ptr) const
|
||||
{
|
||||
try
|
||||
{
|
||||
auto from = std::any_cast<SmartPt>(ptr);
|
||||
auto ret = std::static_pointer_cast<To>(from);
|
||||
return ret;
|
||||
}
|
||||
catch(std::exception &e)
|
||||
{
|
||||
THROW_FORMAT("Failed cast %s -> %s. Given argument was %s. Error message: %s", typeid(From).name() % typeid(To).name() % ptr.type().name() % e.what());
|
||||
}
|
||||
}
|
||||
|
||||
virtual std::any castSharedPtr(const std::any &ptr) const override
|
||||
{
|
||||
return castSmartPtr<std::shared_ptr<From>>(ptr);
|
||||
}
|
||||
virtual std::any castWeakPtr(const std::any &ptr) const override
|
||||
{
|
||||
auto from = std::any_cast<std::weak_ptr<From>>(ptr);
|
||||
return castSmartPtr<std::shared_ptr<From>>(from.lock());
|
||||
}
|
||||
};
|
||||
|
||||
/// Class that implements basic reflection-like mechanisms
|
||||
/// For every type registered via registerType() generates inheritance tree
|
||||
/// Rarely used directly - usually used as part of CApplier
|
||||
class DLL_LINKAGE CTypeList: public boost::noncopyable
|
||||
class CTypeList
|
||||
{
|
||||
//public:
|
||||
struct TypeDescriptor;
|
||||
using TypeInfoPtr = std::shared_ptr<TypeDescriptor>;
|
||||
using WeakTypeInfoPtr = std::weak_ptr<TypeDescriptor>;
|
||||
struct TypeDescriptor
|
||||
{
|
||||
ui16 typeID;
|
||||
const char *name;
|
||||
std::vector<WeakTypeInfoPtr> children, parents;
|
||||
};
|
||||
using TMutex = boost::shared_mutex;
|
||||
using TUniqueLock = boost::unique_lock<TMutex>;
|
||||
using TSharedLock = boost::shared_lock<TMutex>;
|
||||
std::map<std::string, uint16_t> typeInfos;
|
||||
|
||||
private:
|
||||
mutable TMutex mx;
|
||||
|
||||
std::map<const std::type_info *, TypeInfoPtr, TypeComparer> typeInfos;
|
||||
std::map<std::pair<TypeInfoPtr, TypeInfoPtr>, std::unique_ptr<const IPointerCaster>> casters; //for each pair <Base, Der> we provide a caster (each registered relations creates a single entry here)
|
||||
|
||||
/// Returns sequence of types starting from "from" and ending on "to". Every next type is derived from the previous.
|
||||
/// Throws if there is no link registered.
|
||||
std::vector<TypeInfoPtr> castSequence(TypeInfoPtr from, TypeInfoPtr to) const;
|
||||
std::vector<TypeInfoPtr> castSequence(const std::type_info *from, const std::type_info *to) const;
|
||||
|
||||
template<std::any(IPointerCaster::*CastingFunction)(const std::any &) const>
|
||||
std::any castHelper(std::any inputPtr, const std::type_info *fromArg, const std::type_info *toArg) const
|
||||
{
|
||||
TSharedLock lock(mx);
|
||||
auto typesSequence = castSequence(fromArg, toArg);
|
||||
|
||||
std::any ptr = inputPtr;
|
||||
for(int i = 0; i < static_cast<int>(typesSequence.size()) - 1; i++)
|
||||
{
|
||||
auto &from = typesSequence[i];
|
||||
auto &to = typesSequence[i + 1];
|
||||
auto castingPair = std::make_pair(from, to);
|
||||
if(!casters.count(castingPair))
|
||||
THROW_FORMAT("Cannot find caster for conversion %s -> %s which is needed to cast %s -> %s", from->name % to->name % fromArg->name() % toArg->name());
|
||||
|
||||
const auto & caster = casters.at(castingPair);
|
||||
ptr = (*caster.*CastingFunction)(ptr); //Why does unique_ptr not have operator->* ..?
|
||||
}
|
||||
|
||||
return ptr;
|
||||
}
|
||||
CTypeList & operator=(CTypeList &) = delete;
|
||||
|
||||
TypeInfoPtr getTypeDescriptor(const std::type_info *type, bool throws = true) const; //if not throws, failure returns nullptr
|
||||
TypeInfoPtr registerType(const std::type_info *type);
|
||||
|
||||
public:
|
||||
|
||||
CTypeList();
|
||||
|
||||
template <typename Base, typename Derived>
|
||||
void registerType(const Base * b = nullptr, const Derived * d = nullptr)
|
||||
{
|
||||
TUniqueLock lock(mx);
|
||||
static_assert(std::is_base_of<Base, Derived>::value, "First registerType template parameter needs to ba a base class of the second one.");
|
||||
static_assert(std::has_virtual_destructor<Base>::value, "Base class needs to have a virtual destructor.");
|
||||
static_assert(!std::is_same<Base, Derived>::value, "Parameters of registerTypes should be two different types.");
|
||||
auto bt = getTypeInfo(b);
|
||||
auto dt = getTypeInfo(d); //obtain std::type_info
|
||||
auto bti = registerType(bt);
|
||||
auto dti = registerType(dt); //obtain our TypeDescriptor
|
||||
|
||||
// register the relation between classes
|
||||
bti->children.push_back(dti);
|
||||
dti->parents.push_back(bti);
|
||||
casters[std::make_pair(bti, dti)] = std::make_unique<const PointerCaster<Base, Derived>>();
|
||||
casters[std::make_pair(dti, bti)] = std::make_unique<const PointerCaster<Derived, Base>>();
|
||||
}
|
||||
|
||||
ui16 getTypeID(const std::type_info *type, bool throws = false) const;
|
||||
DLL_LINKAGE CTypeList();
|
||||
|
||||
template <typename T>
|
||||
ui16 getTypeID(const T * t = nullptr, bool throws = false) const
|
||||
{
|
||||
return getTypeID(getTypeInfo(t), throws);
|
||||
}
|
||||
|
||||
TypeInfoPtr getTypeDescriptor(ui16 typeID) const;
|
||||
|
||||
template<typename TInput>
|
||||
void * castToMostDerived(const TInput * inputPtr) const
|
||||
{
|
||||
const auto & baseType = typeid(typename std::remove_cv<TInput>::type);
|
||||
auto derivedType = getTypeInfo(inputPtr);
|
||||
|
||||
if (strcmp(baseType.name(), derivedType->name()) == 0)
|
||||
{
|
||||
return const_cast<void*>(reinterpret_cast<const void*>(inputPtr));
|
||||
}
|
||||
|
||||
return std::any_cast<void*>(castHelper<&IPointerCaster::castRawPtr>(
|
||||
const_cast<void*>(reinterpret_cast<const void*>(inputPtr)), &baseType,
|
||||
derivedType));
|
||||
}
|
||||
|
||||
template<typename TInput>
|
||||
std::any castSharedToMostDerived(const std::shared_ptr<TInput> inputPtr) const
|
||||
{
|
||||
const auto & baseType = typeid(typename std::remove_cv<TInput>::type);
|
||||
auto derivedType = getTypeInfo(inputPtr.get());
|
||||
|
||||
if (!strcmp(baseType.name(), derivedType->name()))
|
||||
return inputPtr;
|
||||
|
||||
return castHelper<&IPointerCaster::castSharedPtr>(inputPtr, &baseType, derivedType);
|
||||
}
|
||||
|
||||
void * castRaw(void *inputPtr, const std::type_info *from, const std::type_info *to) const
|
||||
{
|
||||
return std::any_cast<void*>(castHelper<&IPointerCaster::castRawPtr>(inputPtr, from, to));
|
||||
}
|
||||
std::any castShared(std::any inputPtr, const std::type_info *from, const std::type_info *to) const
|
||||
{
|
||||
return castHelper<&IPointerCaster::castSharedPtr>(inputPtr, from, to);
|
||||
}
|
||||
|
||||
template <typename T> const std::type_info * getTypeInfo(const T * t = nullptr) const
|
||||
const std::type_info & getTypeInfo(const T * t = nullptr) const
|
||||
{
|
||||
if(t)
|
||||
return &typeid(*t);
|
||||
return typeid(*t);
|
||||
else
|
||||
return &typeid(T);
|
||||
return typeid(T);
|
||||
}
|
||||
|
||||
public:
|
||||
static CTypeList & getInstance()
|
||||
{
|
||||
static CTypeList registry;
|
||||
return registry;
|
||||
}
|
||||
|
||||
template<typename T, typename U>
|
||||
void registerType()
|
||||
{
|
||||
registerType<T>();
|
||||
registerType<U>();
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void registerType()
|
||||
{
|
||||
const std::type_info & typeInfo = typeid(T);
|
||||
|
||||
if (typeInfos.count(typeInfo.name()) != 0)
|
||||
return;
|
||||
|
||||
typeInfos[typeInfo.name()] = typeInfos.size() + 1;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
uint16_t getTypeID(T * typePtr)
|
||||
{
|
||||
static_assert(!std::is_pointer_v<T>, "CTypeList does not supports pointers!");
|
||||
static_assert(!std::is_reference_v<T>, "CTypeList does not supports references!");
|
||||
|
||||
const std::type_info & typeInfo = getTypeInfo(typePtr);
|
||||
|
||||
if (typeInfos.count(typeInfo.name()) == 0)
|
||||
return 0;
|
||||
|
||||
return typeInfos.at(typeInfo.name());
|
||||
}
|
||||
};
|
||||
|
||||
extern DLL_LINKAGE CTypeList typeList;
|
||||
|
||||
/// Wrapper over CTypeList. Allows execution of templated class T for any type
|
||||
/// that was resgistered for this applier
|
||||
template<typename T>
|
||||
class CApplier : boost::noncopyable
|
||||
{
|
||||
std::map<ui16, std::unique_ptr<T>> apps;
|
||||
std::map<int32_t, std::unique_ptr<T>> apps;
|
||||
|
||||
template<typename RegisteredType>
|
||||
void addApplier(ui16 ID)
|
||||
@ -224,9 +97,8 @@ public:
|
||||
template<typename Base, typename Derived>
|
||||
void registerType(const Base * b = nullptr, const Derived * d = nullptr)
|
||||
{
|
||||
typeList.registerType(b, d);
|
||||
addApplier<Base>(typeList.getTypeID(b));
|
||||
addApplier<Derived>(typeList.getTypeID(d));
|
||||
addApplier<Base>(CTypeList::getInstance().getTypeID<Base>(nullptr));
|
||||
addApplier<Derived>(CTypeList::getInstance().getTypeID<Derived>(nullptr));
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -9,58 +9,18 @@
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <typeinfo>
|
||||
#include <string>
|
||||
#include "CTypeList.h"
|
||||
|
||||
VCMI_LIB_NAMESPACE_BEGIN
|
||||
|
||||
template<class T, class F>
|
||||
inline const T * dynamic_ptr_cast(const F * ptr)
|
||||
{
|
||||
#ifndef VCMI_APPLE
|
||||
return dynamic_cast<const T *>(ptr);
|
||||
#else
|
||||
if(!strcmp(typeid(*ptr).name(), typeid(T).name()))
|
||||
{
|
||||
return static_cast<const T *>(ptr);
|
||||
}
|
||||
try
|
||||
{
|
||||
auto * sourceTypeInfo = typeList.getTypeInfo(ptr);
|
||||
auto * targetTypeInfo = &typeid(typename std::remove_const<typename std::remove_pointer<T>::type>::type);
|
||||
typeList.castRaw((void *)ptr, sourceTypeInfo, targetTypeInfo);
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
return static_cast<const T *>(ptr);
|
||||
#endif
|
||||
}
|
||||
|
||||
template<class T, class F>
|
||||
inline T * dynamic_ptr_cast(F * ptr)
|
||||
{
|
||||
#ifndef VCMI_APPLE
|
||||
return dynamic_cast<T *>(ptr);
|
||||
#else
|
||||
if(!strcmp(typeid(*ptr).name(), typeid(T).name()))
|
||||
{
|
||||
return static_cast<T *>(ptr);
|
||||
}
|
||||
try
|
||||
{
|
||||
auto * sourceTypeInfo = typeList.getTypeInfo(ptr);
|
||||
auto * targetTypeInfo = &typeid(typename std::remove_const<typename std::remove_pointer<T>::type>::type);
|
||||
typeList.castRaw((void *)ptr, sourceTypeInfo, targetTypeInfo);
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
return static_cast<T *>(ptr);
|
||||
#endif
|
||||
}
|
||||
|
||||
VCMI_LIB_NAMESPACE_END
|
||||
|
@ -10,8 +10,7 @@
|
||||
#include "StdInc.h"
|
||||
#include "Connection.h"
|
||||
|
||||
#include "../registerTypes/RegisterTypes.h"
|
||||
#include "../mapping/CMapHeader.h"
|
||||
#include "../networkPacks/NetPacksBase.h"
|
||||
|
||||
#include <boost/asio.hpp>
|
||||
|
||||
@ -45,8 +44,6 @@ void CConnection::init()
|
||||
|
||||
enableSmartPointerSerialization();
|
||||
disableStackSendingByID();
|
||||
registerTypes(iser);
|
||||
registerTypes(oser);
|
||||
#ifndef VCMI_ENDIAN_BIG
|
||||
myEndianess = true;
|
||||
#else
|
||||
|
@ -267,39 +267,6 @@ public:
|
||||
void updateFrom(const JsonNode & data);
|
||||
void serializeJson(JsonSerializeFormat & handler);
|
||||
|
||||
template <typename Handler> void serialize(Handler & h, const int version)
|
||||
{
|
||||
h & identifier;
|
||||
if (version > 820)
|
||||
h & modScope;
|
||||
h & id;
|
||||
h & level;
|
||||
h & power;
|
||||
h & probabilities;
|
||||
h & attributes;
|
||||
h & combat;
|
||||
h & creatureAbility;
|
||||
h & positiveness;
|
||||
h & counteredSpells;
|
||||
h & rising;
|
||||
h & damage;
|
||||
h & offensive;
|
||||
h & targetType;
|
||||
h & targetCondition;
|
||||
h & iconImmune;
|
||||
h & defaultProbability;
|
||||
h & special;
|
||||
h & castSound;
|
||||
h & iconBook;
|
||||
h & iconEffect;
|
||||
h & iconScenarioBonus;
|
||||
h & iconScroll;
|
||||
h & levels;
|
||||
h & school;
|
||||
h & animationInfo;
|
||||
h & nonMagical;
|
||||
h & onlyOnWaterMap;
|
||||
}
|
||||
friend class CSpellHandler;
|
||||
friend class Graphics;
|
||||
friend class test::CSpellTest;
|
||||
@ -384,15 +351,6 @@ public:
|
||||
*/
|
||||
std::vector<bool> getDefaultAllowed() const override;
|
||||
|
||||
template <typename Handler> void serialize(Handler & h, const int version)
|
||||
{
|
||||
h & objects;
|
||||
if(!h.saving)
|
||||
{
|
||||
afterLoadFinalization();
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
const std::vector<std::string> & getTypeNames() const override;
|
||||
CSpell * loadFromJson(const std::string & scope, const JsonNode & json, const std::string & identifier, size_t index) override;
|
||||
|
@ -16,7 +16,7 @@
|
||||
#include "../lib/modding/CModInfo.h"
|
||||
|
||||
VCMI_LIB_NAMESPACE_BEGIN
|
||||
using ModCompatibilityInfo = std::map<std::string, CModInfo::VerificationInfo>;
|
||||
using ModCompatibilityInfo = std::map<std::string, ModVerificationInfo>;
|
||||
class EditorObstaclePlacer;
|
||||
VCMI_LIB_NAMESPACE_END
|
||||
|
||||
|
@ -27,6 +27,7 @@
|
||||
#include "../lib/CCreatureSet.h"
|
||||
#include "../lib/CGeneralTextHandler.h"
|
||||
#include "../lib/CHeroHandler.h"
|
||||
#include "../lib/CPlayerState.h"
|
||||
#include "../lib/CSoundBase.h"
|
||||
#include "../lib/CThreadHelper.h"
|
||||
#include "../lib/CTownHandler.h"
|
||||
@ -47,20 +48,19 @@
|
||||
|
||||
#include "../lib/mapping/CMap.h"
|
||||
#include "../lib/mapping/CMapService.h"
|
||||
#include "../lib/mapObjects/CGMarket.h"
|
||||
#include "../lib/modding/ModIncompatibility.h"
|
||||
#include "../lib/networkPacks/StackLocation.h"
|
||||
#include "../lib/pathfinder/CPathfinder.h"
|
||||
#include "../lib/pathfinder/PathfinderOptions.h"
|
||||
#include "../lib/pathfinder/TurnInfo.h"
|
||||
|
||||
#include "../lib/registerTypes/RegisterTypes.h"
|
||||
#include "../lib/registerTypes/RegisterTypesServerPacks.h"
|
||||
|
||||
#include "../lib/rmg/CMapGenOptions.h"
|
||||
|
||||
#include "../lib/serializer/CTypeList.h"
|
||||
#include "../lib/serializer/Cast.h"
|
||||
#include "../lib/serializer/Connection.h"
|
||||
#include "../lib/serializer/JsonSerializer.h"
|
||||
#include "../lib/serializer/CSaveFile.h"
|
||||
#include "../lib/serializer/CLoadFile.h"
|
||||
|
||||
#include "../lib/spells/CSpellHandler.h"
|
||||
|
||||
@ -463,12 +463,12 @@ void CGameHandler::handleReceivedPack(CPackForServer * pack)
|
||||
PackageApplied applied;
|
||||
applied.player = pack->player;
|
||||
applied.result = succesfullyApplied;
|
||||
applied.packType = typeList.getTypeID(pack);
|
||||
applied.packType = CTypeList::getInstance().getTypeID(pack);
|
||||
applied.requestID = pack->requestID;
|
||||
pack->c->sendPack(&applied);
|
||||
};
|
||||
|
||||
CBaseForGHApply * apply = applier->getApplier(typeList.getTypeID(pack)); //and appropriate applier object
|
||||
CBaseForGHApply * apply = applier->getApplier(CTypeList::getInstance().getTypeID(pack)); //and appropriate applier object
|
||||
if(isBlockedByQueries(pack, pack->player))
|
||||
{
|
||||
sendPackageResponse(false);
|
||||
@ -4057,7 +4057,7 @@ void CGameHandler::spawnWanderingMonsters(CreatureID creatureID)
|
||||
void CGameHandler::synchronizeArtifactHandlerLists()
|
||||
{
|
||||
UpdateArtHandlerLists uahl;
|
||||
uahl.allocatedArtifacts = VLC->arth->allocatedArtifacts;
|
||||
uahl.allocatedArtifacts = gs->allocatedArtifacts;
|
||||
sendAndApply(&uahl);
|
||||
}
|
||||
|
||||
|
@ -47,7 +47,7 @@
|
||||
#include "../lib/UnlockGuard.h"
|
||||
|
||||
// for applier
|
||||
#include "../lib/registerTypes/RegisterTypes.h"
|
||||
#include "../lib/registerTypes/RegisterTypesLobbyPacks.h"
|
||||
|
||||
// UUID generation
|
||||
#include <boost/uuid/uuid.hpp>
|
||||
@ -485,7 +485,7 @@ void CVCMIServer::threadHandleClient(std::shared_ptr<CConnection> c)
|
||||
|
||||
void CVCMIServer::handleReceivedPack(std::unique_ptr<CPackForLobby> pack)
|
||||
{
|
||||
CBaseForServerApply * apply = applier->getApplier(typeList.getTypeID(pack.get()));
|
||||
CBaseForServerApply * apply = applier->getApplier(CTypeList::getInstance().getTypeID(pack.get()));
|
||||
if(apply->applyOnServerBefore(this, pack.get()))
|
||||
addToAnnounceQueue(std::move(pack));
|
||||
}
|
||||
@ -502,7 +502,7 @@ void CVCMIServer::announcePack(std::unique_ptr<CPackForLobby> pack)
|
||||
c->sendPack(pack.get());
|
||||
}
|
||||
|
||||
applier->getApplier(typeList.getTypeID(pack.get()))->applyOnServerAfter(this, pack.get());
|
||||
applier->getApplier(CTypeList::getInstance().getTypeID(pack.get()))->applyOnServerAfter(this, pack.get());
|
||||
}
|
||||
|
||||
void CVCMIServer::announceMessage(const std::string & txt)
|
||||
|
Loading…
Reference in New Issue
Block a user