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

Merge pull request #2202 from IvanSavenko/map_objects_reorganization

Map objects code reorganization
This commit is contained in:
Ivan Savenko 2023-06-05 18:35:05 +03:00 committed by GitHub
commit 8d278e653f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
118 changed files with 1881 additions and 1594 deletions

View File

@ -11,6 +11,7 @@
#include "../../lib/UnlockGuard.h"
#include "../../lib/mapObjects/MapObjects.h"
#include "../../lib/mapObjects/ObjectTemplate.h"
#include "../../lib/CConfigHandler.h"
#include "../../lib/CHeroHandler.h"
#include "../../lib/GameSettings.h"

View File

@ -45,7 +45,6 @@
#include "../../lib/CTownHandler.h"
#include "../../lib/spells/CSpellHandler.h"
#include "../../lib/CStopWatch.h"
#include "../../lib/mapObjects/CObjectHandler.h"
#include "../../lib/mapObjects/CGHeroInstance.h"
#include "../../lib/CPathfinder.h"
#include "../../CCallback.h"

View File

@ -10,10 +10,13 @@
#include "../StdInc.h"
#include "FuzzyHelper.h"
#include "../../../lib/mapObjects/CommonConstructors.h"
#include "../Goals/Goals.h"
#include "Nullkiller.h"
#include "../../../lib/mapObjectConstructors/AObjectTypeHandler.h"
#include "../../../lib/mapObjectConstructors/CObjectClassesHandler.h"
#include "../../../lib/mapObjectConstructors/CommonConstructors.h"
namespace NKAI
{

View File

@ -11,8 +11,10 @@
#include <limits>
#include "Nullkiller.h"
#include "../../../lib/mapObjectConstructors/AObjectTypeHandler.h"
#include "../../../lib/mapObjectConstructors/CObjectClassesHandler.h"
#include "../../../lib/mapObjectConstructors/CommonConstructors.h"
#include "../../../lib/mapObjects/MapObjects.h"
#include "../../../lib/mapObjects/CommonConstructors.h"
#include "../../../lib/CCreatureHandler.h"
#include "../../../lib/CPathfinder.h"
#include "../../../lib/CGameStateFwd.h"

View File

@ -15,7 +15,6 @@
#include "../../lib/CTownHandler.h"
#include "../../lib/spells/CSpellHandler.h"
#include "../../lib/CStopWatch.h"
#include "../../lib/mapObjects/CObjectHandler.h"
#include "../../lib/mapObjects/CGHeroInstance.h"
#include "../../lib/CPathfinder.h"
#include "../../CCallback.h"

View File

@ -10,10 +10,15 @@
#include "StdInc.h"
#include "FuzzyHelper.h"
#include "../../lib/mapObjects/CommonConstructors.h"
#include "Goals/Goals.h"
#include "VCAI.h"
#include "../../lib/mapObjectConstructors/AObjectTypeHandler.h"
#include "../../lib/mapObjectConstructors/CObjectClassesHandler.h"
#include "../../lib/mapObjectConstructors/CommonConstructors.h"
#include "../../lib/mapObjects/CBank.h"
#include "../../lib/mapObjects/CGDwelling.h"
FuzzyHelper * fh;
extern boost::thread_specific_ptr<VCAI> ai;
@ -332,4 +337,4 @@ ui64 FuzzyHelper::evaluateDanger(const CGObjectInstance * obj, const VCAI * ai)
default:
return 0;
}
}
}

View File

@ -4,6 +4,7 @@
#include "../../lib/VCMI_Lib.h"
#include "../../lib/CCreatureHandler.h"
#include "../../lib/CHeroHandler.h"
#include "../../lib/mapObjectConstructors/AObjectTypeHandler.h"
#include "../../lib/mapObjects/CGHeroInstance.h"
#include "../../lib/mapObjects/CGTownInstance.h"
#include "../../lib/mapObjects/MiscObjects.h"

View File

@ -8,7 +8,8 @@
*
*/
#pragma once
#include "../../lib/mapObjects/CObjectClassesHandler.h"
#include "../../lib/mapObjectConstructors/CObjectClassesHandler.h"
class MapObjectsEvaluator
{

View File

@ -16,6 +16,7 @@
#include "../../lib/UnlockGuard.h"
#include "../../lib/mapObjects/MapObjects.h"
#include "../../lib/mapObjects/ObjectTemplate.h"
#include "../../lib/CConfigHandler.h"
#include "../../lib/CHeroHandler.h"
#include "../../lib/GameSettings.h"

View File

@ -16,7 +16,6 @@
#include "client/Client.h"
#include "lib/mapping/CMap.h"
#include "lib/CBuildingHandler.h"
#include "lib/mapObjects/CObjectClassesHandler.h"
#include "lib/CGeneralTextHandler.h"
#include "lib/CHeroHandler.h"
#include "lib/NetPacks.h"

View File

@ -52,9 +52,9 @@
#include "../lib/serializer/BinarySerializer.h"
#include "../lib/spells/CSpellHandler.h"
#include "../lib/CTownHandler.h"
#include "../lib/mapObjects/CObjectClassesHandler.h" // For displaying correct UI when interacting with objects
#include "../lib/mapObjects/CGTownInstance.h"
#include "../lib/mapObjects/MiscObjects.h"
#include "../lib/mapObjects/ObjectTemplate.h"
#include "../lib/CStack.h"
#include "../lib/JsonNode.h"
#include "CMusicHandler.h"

View File

@ -36,6 +36,7 @@
#include "../lib/CSoundBase.h"
#include "../lib/StartInfo.h"
#include "../lib/CConfigHandler.h"
#include "../lib/mapObjects/CGMarket.h"
#include "../lib/mapping/CCampaignHandler.h"
#include "../lib/CGameState.h"
#include "../lib/CStack.h"

View File

@ -27,6 +27,7 @@
#include "../../lib/TerrainHandler.h"
#include "../../lib/mapObjects/CGHeroInstance.h"
#include "../../lib/mapObjects/MiscObjects.h"
#include "../../lib/mapObjects/ObjectTemplate.h"
#include "../../lib/mapping/CMapDefines.h"
struct NeighborTilesInfo

View File

@ -20,6 +20,7 @@
#include "../render/IImage.h"
#include "../../lib/mapObjects/CObjectHandler.h"
#include "../../lib/int3.h"
MapViewCache::~MapViewCache() = default;

View File

@ -19,8 +19,9 @@
#include "../../lib/CGeneralTextHandler.h"
#include "../../lib/TerrainHandler.h"
#include "../../lib/UnlockGuard.h"
#include "../../lib/mapObjectConstructors/CObjectClassesHandler.h"
#include "../../lib/mapObjects/CGHeroInstance.h"
#include "../../lib/mapObjects/CObjectClassesHandler.h"
#include "../../lib/mapObjects/ObjectTemplate.h"
#include "../../lib/mapping/CMap.h"
bool CMapHandler::hasOngoingAnimations()

View File

@ -36,8 +36,6 @@
#include "../lib/JsonNode.h"
#include "../lib/vcmi_endian.h"
#include "../lib/CStopWatch.h"
#include "../lib/mapObjects/CObjectClassesHandler.h"
#include "../lib/mapObjects/CObjectHandler.h"
#include "../lib/CHeroHandler.h"
#include <SDL_surface.h>

View File

@ -46,7 +46,9 @@
#include "../../CCallback.h"
#include "../lib/mapObjects/CGHeroInstance.h"
#include "../lib/mapObjects/CGMarket.h"
#include "../lib/mapObjects/CGTownInstance.h"
#include "../lib/mapObjects/ObjectTemplate.h"
#include "../lib/CArtHandler.h"
#include "../lib/CBuildingHandler.h"
#include "../lib/CConfigHandler.h"

View File

@ -65,20 +65,25 @@ macro(add_main_lib TARGET_NAME LIBRARY_TYPE)
${MAIN_LIB_DIR}/logging/CBasicLogConfigurator.cpp
${MAIN_LIB_DIR}/logging/CLogger.cpp
${MAIN_LIB_DIR}/mapObjectConstructors/AObjectTypeHandler.cpp
${MAIN_LIB_DIR}/mapObjectConstructors/CObjectClassesHandler.cpp
${MAIN_LIB_DIR}/mapObjectConstructors/CommonConstructors.cpp
${MAIN_LIB_DIR}/mapObjectConstructors/CRewardableConstructor.cpp
${MAIN_LIB_DIR}/mapObjects/CArmedInstance.cpp
${MAIN_LIB_DIR}/mapObjects/CBank.cpp
${MAIN_LIB_DIR}/mapObjects/CGDwelling.cpp
${MAIN_LIB_DIR}/mapObjects/CGHeroInstance.cpp
${MAIN_LIB_DIR}/mapObjects/CGMarket.cpp
${MAIN_LIB_DIR}/mapObjects/CGObjectInstance.cpp
${MAIN_LIB_DIR}/mapObjects/CGPandoraBox.cpp
${MAIN_LIB_DIR}/mapObjects/CGTownBuilding.cpp
${MAIN_LIB_DIR}/mapObjects/CGTownInstance.cpp
${MAIN_LIB_DIR}/mapObjects/CObjectClassesHandler.cpp
${MAIN_LIB_DIR}/mapObjects/CObjectHandler.cpp
${MAIN_LIB_DIR}/mapObjects/CommonConstructors.cpp
${MAIN_LIB_DIR}/mapObjects/CQuest.cpp
${MAIN_LIB_DIR}/mapObjects/CRewardableConstructor.cpp
${MAIN_LIB_DIR}/mapObjects/CRewardableObject.cpp
${MAIN_LIB_DIR}/mapObjects/IMarket.cpp
${MAIN_LIB_DIR}/mapObjects/IObjectInterface.cpp
${MAIN_LIB_DIR}/mapObjects/MiscObjects.cpp
${MAIN_LIB_DIR}/mapObjects/ObjectTemplate.cpp
@ -362,20 +367,28 @@ macro(add_main_lib TARGET_NAME LIBRARY_TYPE)
${MAIN_LIB_DIR}/logging/CBasicLogConfigurator.h
${MAIN_LIB_DIR}/logging/CLogger.h
${MAIN_LIB_DIR}/mapObjectConstructors/AObjectTypeHandler.h
${MAIN_LIB_DIR}/mapObjectConstructors/CObjectClassesHandler.h
${MAIN_LIB_DIR}/mapObjectConstructors/CommonConstructors.h
${MAIN_LIB_DIR}/mapObjectConstructors/CRewardableConstructor.h
${MAIN_LIB_DIR}/mapObjectConstructors/IObjectInfo.h
${MAIN_LIB_DIR}/mapObjectConstructors/RandomMapInfo.h
${MAIN_LIB_DIR}/mapObjectConstructors/SObjectSounds.h
${MAIN_LIB_DIR}/mapObjects/CArmedInstance.h
${MAIN_LIB_DIR}/mapObjects/CBank.h
${MAIN_LIB_DIR}/mapObjects/CGDwelling.h
${MAIN_LIB_DIR}/mapObjects/CGHeroInstance.h
${MAIN_LIB_DIR}/mapObjects/CGMarket.h
${MAIN_LIB_DIR}/mapObjects/CGObjectInstance.h
${MAIN_LIB_DIR}/mapObjects/CGPandoraBox.h
${MAIN_LIB_DIR}/mapObjects/CGTownBuilding.h
${MAIN_LIB_DIR}/mapObjects/CGTownInstance.h
${MAIN_LIB_DIR}/mapObjects/CObjectClassesHandler.h
${MAIN_LIB_DIR}/mapObjects/CObjectHandler.h
${MAIN_LIB_DIR}/mapObjects/CommonConstructors.h
${MAIN_LIB_DIR}/mapObjects/CQuest.h
${MAIN_LIB_DIR}/mapObjects/CRewardableConstructor.h
${MAIN_LIB_DIR}/mapObjects/CRewardableObject.h
${MAIN_LIB_DIR}/mapObjects/IMarket.h
${MAIN_LIB_DIR}/mapObjects/IObjectInterface.h
${MAIN_LIB_DIR}/mapObjects/MapObjects.h
${MAIN_LIB_DIR}/mapObjects/MiscObjects.h
${MAIN_LIB_DIR}/mapObjects/ObjectTemplate.h

View File

@ -23,7 +23,8 @@
#include "StringConstants.h"
#include "CRandomGenerator.h"
#include "mapObjects/CObjectClassesHandler.h"
#include "mapObjectConstructors/AObjectTypeHandler.h"
#include "mapObjectConstructors/CObjectClassesHandler.h"
#include "mapping/CMap.h"
#include "serializer/JsonSerializeFormat.h"

View File

@ -23,7 +23,8 @@
#include "bonuses/Updaters.h"
#include "serializer/JsonDeserializer.h"
#include "serializer/JsonUpdater.h"
#include "mapObjects/CObjectClassesHandler.h"
#include "mapObjectConstructors/AObjectTypeHandler.h"
#include "mapObjectConstructors/CObjectClassesHandler.h"
VCMI_LIB_NAMESPACE_BEGIN

View File

@ -12,7 +12,6 @@
#include "CGameState.h" // PlayerState
#include "CGeneralTextHandler.h"
#include "mapObjects/CObjectHandler.h" // for CGObjectInstance
#include "StartInfo.h" // for StartInfo
#include "battle/BattleInfo.h" // for BattleInfo
#include "NetPacks.h" // for InfoWindow

View File

@ -15,8 +15,6 @@
#include "spells/ViewSpellInt.h"
#include "mapObjects/CObjectHandler.h"
class CBattleCallback;
class CCallback;
@ -68,6 +66,7 @@ namespace scripting
}
#endif
using TTeleportExitsList = std::vector<std::pair<ObjectInstanceID, int3>>;
class DLL_LINKAGE CBattleGameInterface : public IBattleEventsReceiver
{

View File

@ -11,20 +11,19 @@
#include "CGameState.h"
#include "mapping/CCampaignHandler.h"
#include "mapObjects/CObjectClassesHandler.h"
#include "CArtHandler.h"
#include "CBuildingHandler.h"
#include "CGeneralTextHandler.h"
#include "CTownHandler.h"
#include "spells/CSpellHandler.h"
#include "CHeroHandler.h"
#include "mapObjects/CObjectHandler.h"
#include "CModHandler.h"
#include "GameSettings.h"
#include "TerrainHandler.h"
#include "CSkillHandler.h"
#include "mapping/CMap.h"
#include "mapping/CMapService.h"
#include "mapObjectConstructors/CObjectClassesHandler.h"
#include "StartInfo.h"
#include "NetPacks.h"
#include "registerTypes/RegisterTypes.h"

View File

@ -20,12 +20,12 @@
#include "GameSettings.h"
#include "CModHandler.h"
#include "CTownHandler.h"
#include "mapObjects/CObjectHandler.h" //for hero specialty
#include "CSkillHandler.h"
#include "mapObjects/CObjectClassesHandler.h"
#include "BattleFieldHandler.h"
#include "bonuses/Limiters.h"
#include "bonuses/Updaters.h"
#include "mapObjectConstructors/AObjectTypeHandler.h"
#include "mapObjectConstructors/CObjectClassesHandler.h"
VCMI_LIB_NAMESPACE_BEGIN

View File

@ -9,7 +9,6 @@
*/
#include "StdInc.h"
#include "CModHandler.h"
#include "mapObjects/CObjectClassesHandler.h"
#include "rmg/CRmgTemplateStorage.h"
#include "filesystem/FileStream.h"
#include "filesystem/AdapterLoaders.h"
@ -20,7 +19,6 @@
#include "CArtHandler.h"
#include "CTownHandler.h"
#include "CHeroHandler.h"
#include "mapObjects/CObjectHandler.h"
#include "StringConstants.h"
#include "CStopWatch.h"
#include "IHandlerBase.h"
@ -35,6 +33,7 @@
#include "TerrainHandler.h"
#include "BattleFieldHandler.h"
#include "ObstacleHandler.h"
#include "mapObjectConstructors/CObjectClassesHandler.h"
#include <vstd/StringUtils.h>

View File

@ -22,11 +22,11 @@
#include "TerrainHandler.h"
#include "spells/CSpellHandler.h"
#include "filesystem/Filesystem.h"
#include "mapObjects/CObjectClassesHandler.h"
#include "mapObjects/CObjectHandler.h"
#include "bonuses/Bonus.h"
#include "bonuses/Propagators.h"
#include "ResourceSet.h"
#include "mapObjectConstructors/AObjectTypeHandler.h"
#include "mapObjectConstructors/CObjectClassesHandler.h"
VCMI_LIB_NAMESPACE_BEGIN

View File

@ -22,7 +22,7 @@
#include "bonuses/Bonus.h"
#include "bonuses/BonusList.h"
#include "Point.h"
#include "mapObjects/CRewardableConstructor.h"
#include "rewardable/Info.h"
VCMI_LIB_NAMESPACE_BEGIN

View File

@ -26,7 +26,6 @@
#include <vcmi/spells/Service.h>
#include "VCMI_Lib.h"
#include "mapObjects/CObjectClassesHandler.h"//todo: remove
#include "CArtHandler.h"//todo: remove
#include "CCreatureHandler.h"//todo: remove
#include "spells/CSpellHandler.h" //todo: remove

View File

@ -28,8 +28,11 @@
#include "serializer/BinarySerializer.h"
#include "serializer/CLoadIntegrityValidator.h"
#include "rmg/CMapGenOptions.h"
#include "mapObjectConstructors/AObjectTypeHandler.h"
#include "mapObjectConstructors/CObjectClassesHandler.h"
#include "mapObjects/CObjectHandler.h"
#include "mapObjects/ObjectTemplate.h"
#include "mapping/CCampaignHandler.h"
#include "mapObjects/CObjectClassesHandler.h"
#include "StartInfo.h"
#include "CGameState.h"
#include "mapping/CMap.h"

View File

@ -23,8 +23,8 @@
#include "CCreatureSet.h"
#include "spells/CSpellHandler.h"
#include "CSkillHandler.h"
#include "mapObjects/CObjectHandler.h"
#include "IGameCallback.h"
#include "mapObjects/IObjectInterface.h"
VCMI_LIB_NAMESPACE_BEGIN

View File

@ -36,6 +36,10 @@ struct ArtSlotInfo;
struct QuestInfo;
class IBattleState;
// This one teleport-specific, but has to be available everywhere in callbacks and netpacks
// For now it's will be there till teleports code refactored and moved into own file
using TTeleportExitsList = std::vector<std::pair<ObjectInstanceID, int3>>;
struct DLL_LINKAGE Query : public CPackForClient
{
QueryID queryID; // equals to -1 if it is not an actual query (and should not be answered)

View File

@ -11,10 +11,8 @@
#include "NetPacks.h"
#include "NetPackVisitor.h"
#include "CGeneralTextHandler.h"
#include "mapObjects/CObjectClassesHandler.h"
#include "CArtHandler.h"
#include "CHeroHandler.h"
#include "mapObjects/CObjectHandler.h"
#include "CModHandler.h"
#include "VCMI_Lib.h"
#include "mapping/CMap.h"
@ -28,6 +26,9 @@
#include "StartInfo.h"
#include "CPlayerState.h"
#include "TerrainHandler.h"
#include "mapObjects/CGMarket.h"
#include "mapObjectConstructors/AObjectTypeHandler.h"
#include "mapObjectConstructors/CObjectClassesHandler.h"
#include "mapping/CCampaignHandler.h"
#include "GameSettings.h"

View File

@ -10,7 +10,8 @@
#pragma once
#include "TerrainHandler.h"
#include "mapObjects/CObjectHandler.h"
#include "mapObjects/CGObjectInstance.h"
#include "mapping/CMapDefines.h"
#include "CGameState.h"
VCMI_LIB_NAMESPACE_BEGIN

View File

@ -14,8 +14,8 @@
#include "StringConstants.h"
#include "JsonNode.h"
#include "serializer/JsonSerializeFormat.h"
#include "VCMI_Lib.h"
#include "mapObjects/CObjectHandler.h"
#include "VCMI_Lib.h"
VCMI_LIB_NAMESPACE_BEGIN

View File

@ -14,9 +14,7 @@
#include "CArtHandler.h"
#include "CBonusTypeHandler.h"
#include "CCreatureHandler.h"
#include "mapObjects/CObjectClassesHandler.h"
#include "CHeroHandler.h"
#include "mapObjects/CObjectHandler.h"
#include "CTownHandler.h"
#include "CConfigHandler.h"
#include "RoadHandler.h"
@ -34,6 +32,8 @@
#include "filesystem/Filesystem.h"
#include "CConsoleHandler.h"
#include "rmg/CRmgTemplateStorage.h"
#include "mapObjectConstructors/CObjectClassesHandler.h"
#include "mapObjects/CObjectHandler.h"
#include "mapping/CMapEditManager.h"
#include "ScriptHandler.h"
#include "BattleFieldHandler.h"

View File

@ -0,0 +1,225 @@
/*
* AObjectTypeHandler.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 "AObjectTypeHandler.h"
#include "../CGeneralTextHandler.h"
#include "../VCMI_Lib.h"
#include "../mapObjects/CGObjectInstance.h"
#include "../mapObjects/ObjectTemplate.h"
VCMI_LIB_NAMESPACE_BEGIN
std::string AObjectTypeHandler::getJsonKey() const
{
return modScope + ':' + subTypeName;
}
si32 AObjectTypeHandler::getIndex() const
{
return type;
}
si32 AObjectTypeHandler::getSubIndex() const
{
return subtype;
}
std::string AObjectTypeHandler::getTypeName() const
{
return typeName;
}
std::string AObjectTypeHandler::getSubTypeName() const
{
return subTypeName;
}
static ui32 loadJsonOrMax(const JsonNode & input)
{
if (input.isNull())
return std::numeric_limits<ui32>::max();
else
return static_cast<ui32>(input.Float());
}
void AObjectTypeHandler::init(const JsonNode & input)
{
base = input["base"];
if (!input["rmg"].isNull())
{
rmgInfo.value = static_cast<ui32>(input["rmg"]["value"].Float());
const JsonNode & mapLimit = input["rmg"]["mapLimit"];
if (!mapLimit.isNull())
rmgInfo.mapLimit = static_cast<ui32>(mapLimit.Float());
rmgInfo.zoneLimit = loadJsonOrMax(input["rmg"]["zoneLimit"]);
rmgInfo.rarity = static_cast<ui32>(input["rmg"]["rarity"].Float());
} // else block is not needed - set in constructor
for (auto entry : input["templates"].Struct())
{
entry.second.setType(JsonNode::JsonType::DATA_STRUCT);
JsonUtils::inherit(entry.second, base);
auto * tmpl = new ObjectTemplate;
tmpl->id = Obj(type);
tmpl->subid = subtype;
tmpl->stringID = entry.first; // FIXME: create "fullID" - type.object.template?
try
{
tmpl->readJson(entry.second);
templates.push_back(std::shared_ptr<const ObjectTemplate>(tmpl));
}
catch (const std::exception & e)
{
logGlobal->warn("Failed to load terrains for object %s: %s", entry.first, e.what());
}
}
for(const JsonNode & node : input["sounds"]["ambient"].Vector())
sounds.ambient.push_back(node.String());
for(const JsonNode & node : input["sounds"]["visit"].Vector())
sounds.visit.push_back(node.String());
for(const JsonNode & node : input["sounds"]["removal"].Vector())
sounds.removal.push_back(node.String());
if(input["aiValue"].isNull())
aiValue = std::nullopt;
else
aiValue = static_cast<std::optional<si32>>(input["aiValue"].Integer());
if(input["battleground"].getType() == JsonNode::JsonType::DATA_STRING)
battlefield = input["battleground"].String();
else
battlefield = std::nullopt;
initTypeData(input);
}
bool AObjectTypeHandler::objectFilter(const CGObjectInstance * obj, std::shared_ptr<const ObjectTemplate> tmpl) const
{
return false; // by default there are no overrides
}
void AObjectTypeHandler::preInitObject(CGObjectInstance * obj) const
{
obj->ID = Obj(type);
obj->subID = subtype;
obj->typeName = typeName;
obj->subTypeName = subTypeName;
}
void AObjectTypeHandler::initTypeData(const JsonNode & input)
{
// empty implementation for overrides
}
bool AObjectTypeHandler::hasNameTextID() const
{
return false;
}
std::string AObjectTypeHandler::getNameTextID() const
{
return TextIdentifier("mapObject", modScope, typeName, subTypeName, "name").get();
}
std::string AObjectTypeHandler::getNameTranslated() const
{
return VLC->generaltexth->translate(getNameTextID());
}
SObjectSounds AObjectTypeHandler::getSounds() const
{
return sounds;
}
void AObjectTypeHandler::addTemplate(const std::shared_ptr<const ObjectTemplate> & templ)
{
templates.push_back(templ);
}
void AObjectTypeHandler::addTemplate(JsonNode config)
{
config.setType(JsonNode::JsonType::DATA_STRUCT); // ensure that input is not null
JsonUtils::inherit(config, base);
auto * tmpl = new ObjectTemplate;
tmpl->id = Obj(type);
tmpl->subid = subtype;
tmpl->stringID.clear(); // TODO?
tmpl->readJson(config);
templates.emplace_back(tmpl);
}
std::vector<std::shared_ptr<const ObjectTemplate>> AObjectTypeHandler::getTemplates() const
{
return templates;
}
BattleField AObjectTypeHandler::getBattlefield() const
{
return battlefield ? BattleField::fromString(battlefield.value()) : BattleField::NONE;
}
std::vector<std::shared_ptr<const ObjectTemplate>>AObjectTypeHandler::getTemplates(TerrainId terrainType) const
{
std::vector<std::shared_ptr<const ObjectTemplate>> templates = getTemplates();
std::vector<std::shared_ptr<const ObjectTemplate>> filtered;
const auto cfun = [&](const std::shared_ptr<const ObjectTemplate> & obj)
{
return obj->canBePlacedAt(terrainType);
};
std::copy_if(templates.begin(), templates.end(), std::back_inserter(filtered), cfun);
// H3 defines allowed terrains in a weird way - artifacts, monsters and resources have faulty masks here
// Perhaps we should re-define faulty templates and remove this workaround (already done for resources)
if (type == Obj::ARTIFACT || type == Obj::MONSTER)
return templates;
else
return filtered;
}
std::shared_ptr<const ObjectTemplate> AObjectTypeHandler::getOverride(TerrainId terrainType, const CGObjectInstance * object) const
{
std::vector<std::shared_ptr<const ObjectTemplate>> ret = getTemplates(terrainType);
for (const auto & tmpl: ret)
{
if (objectFilter(object, tmpl))
return tmpl;
}
return std::shared_ptr<const ObjectTemplate>(); //empty
}
const RandomMapInfo & AObjectTypeHandler::getRMGInfo()
{
return rmgInfo;
}
std::optional<si32> AObjectTypeHandler::getAiValue() const
{
return aiValue;
}
bool AObjectTypeHandler::isStaticObject()
{
return false; // most of classes are not static
}
void AObjectTypeHandler::afterLoadFinalization()
{
}
VCMI_LIB_NAMESPACE_END

View File

@ -0,0 +1,127 @@
/*
* AObjectTypeHandler.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 "RandomMapInfo.h"
#include "SObjectSounds.h"
#include "../JsonNode.h"
VCMI_LIB_NAMESPACE_BEGIN
class ObjectTemplate;
class CGObjectInstance;
class CRandomGenerator;
class IObjectInfo;
/// Class responsible for creation of objects of specific type & subtype
class DLL_LINKAGE AObjectTypeHandler : public boost::noncopyable
{
friend class CObjectClassesHandler;
RandomMapInfo rmgInfo;
JsonNode base; /// describes base template
std::vector<std::shared_ptr<const ObjectTemplate>> templates;
SObjectSounds sounds;
std::optional<si32> aiValue;
std::optional<std::string> battlefield;
std::string modScope;
std::string typeName;
std::string subTypeName;
si32 type;
si32 subtype;
protected:
void preInitObject(CGObjectInstance * obj) const;
virtual bool objectFilter(const CGObjectInstance * obj, std::shared_ptr<const ObjectTemplate> tmpl) const;
/// initialization for classes that inherit this one
virtual void initTypeData(const JsonNode & input);
public:
virtual ~AObjectTypeHandler() = default;
si32 getIndex() const;
si32 getSubIndex() const;
std::string getTypeName() const;
std::string getSubTypeName() const;
/// loads generic data from Json structure and passes it towards type-specific constructors
void init(const JsonNode & input);
/// returns full form of identifier of this object in form of modName:objectName
std::string getJsonKey() const;
/// Returns object-specific name, if set
SObjectSounds getSounds() const;
void addTemplate(const std::shared_ptr<const ObjectTemplate> & templ);
void addTemplate(JsonNode config);
/// returns all templates matching parameters
std::vector<std::shared_ptr<const ObjectTemplate>> getTemplates() const;
std::vector<std::shared_ptr<const ObjectTemplate>> getTemplates(const TerrainId terrainType) const;
/// returns preferred template for this object, if present (e.g. one of 3 possible templates for town - village, fort and castle)
/// note that appearance will not be changed - this must be done separately (either by assignment or via pack from server)
std::shared_ptr<const ObjectTemplate> getOverride(TerrainId terrainType, const CGObjectInstance * object) const;
BattleField getBattlefield() const;
const RandomMapInfo & getRMGInfo();
std::optional<si32> getAiValue() const;
/// returns true if this class provides custom text ID's instead of generic per-object name
virtual bool hasNameTextID() const;
/// returns object's name in form of translatable text ID
virtual std::string getNameTextID() const;
/// returns object's name in form of human-readable text
std::string getNameTranslated() const;
virtual bool isStaticObject();
virtual void afterLoadFinalization();
/// Creates object and set up core properties (like ID/subID). Object is NOT initialized
/// to allow creating objects before game start (e.g. map loading)
virtual CGObjectInstance * create(std::shared_ptr<const ObjectTemplate> tmpl = nullptr) const = 0;
/// Configures object properties. Should be re-entrable, resetting state of the object if necessarily
/// This should set remaining properties, including randomized or depending on map
virtual void configureObject(CGObjectInstance * object, CRandomGenerator & rng) const = 0;
/// Returns object configuration, if available. Otherwise returns NULL
virtual std::unique_ptr<IObjectInfo> getObjectInfo(std::shared_ptr<const ObjectTemplate> tmpl) const = 0;
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

View File

@ -21,9 +21,11 @@
#include "../JsonNode.h"
#include "../CSoundBase.h"
#include "CRewardableConstructor.h"
#include "CommonConstructors.h"
#include "MapObjects.h"
#include "../mapObjectConstructors/CRewardableConstructor.h"
#include "../mapObjectConstructors/CommonConstructors.h"
#include "../mapObjects/CQuest.h"
#include "../mapObjects/CGPandoraBox.h"
#include "../mapObjects/ObjectTemplate.h"
VCMI_LIB_NAMESPACE_BEGIN
@ -470,207 +472,4 @@ std::string CObjectClassesHandler::getObjectHandlerName(si32 type) const
return objects.at(type)->handlerName;
}
std::string AObjectTypeHandler::getJsonKey() const
{
return modScope + ':' + subTypeName;
}
si32 AObjectTypeHandler::getIndex() const
{
return type;
}
si32 AObjectTypeHandler::getSubIndex() const
{
return subtype;
}
std::string AObjectTypeHandler::getTypeName() const
{
return typeName;
}
std::string AObjectTypeHandler::getSubTypeName() const
{
return subTypeName;
}
static ui32 loadJsonOrMax(const JsonNode & input)
{
if (input.isNull())
return std::numeric_limits<ui32>::max();
else
return static_cast<ui32>(input.Float());
}
void AObjectTypeHandler::init(const JsonNode & input)
{
base = input["base"];
if (!input["rmg"].isNull())
{
rmgInfo.value = static_cast<ui32>(input["rmg"]["value"].Float());
const JsonNode & mapLimit = input["rmg"]["mapLimit"];
if (!mapLimit.isNull())
rmgInfo.mapLimit = static_cast<ui32>(mapLimit.Float());
rmgInfo.zoneLimit = loadJsonOrMax(input["rmg"]["zoneLimit"]);
rmgInfo.rarity = static_cast<ui32>(input["rmg"]["rarity"].Float());
} // else block is not needed - set in constructor
for (auto entry : input["templates"].Struct())
{
entry.second.setType(JsonNode::JsonType::DATA_STRUCT);
JsonUtils::inherit(entry.second, base);
auto * tmpl = new ObjectTemplate;
tmpl->id = Obj(type);
tmpl->subid = subtype;
tmpl->stringID = entry.first; // FIXME: create "fullID" - type.object.template?
try
{
tmpl->readJson(entry.second);
templates.push_back(std::shared_ptr<const ObjectTemplate>(tmpl));
}
catch (const std::exception & e)
{
logGlobal->warn("Failed to load terrains for object %s: %s", entry.first, e.what());
}
}
for(const JsonNode & node : input["sounds"]["ambient"].Vector())
sounds.ambient.push_back(node.String());
for(const JsonNode & node : input["sounds"]["visit"].Vector())
sounds.visit.push_back(node.String());
for(const JsonNode & node : input["sounds"]["removal"].Vector())
sounds.removal.push_back(node.String());
if(input["aiValue"].isNull())
aiValue = std::nullopt;
else
aiValue = static_cast<std::optional<si32>>(input["aiValue"].Integer());
if(input["battleground"].getType() == JsonNode::JsonType::DATA_STRING)
battlefield = input["battleground"].String();
else
battlefield = std::nullopt;
initTypeData(input);
}
bool AObjectTypeHandler::objectFilter(const CGObjectInstance * obj, std::shared_ptr<const ObjectTemplate> tmpl) const
{
return false; // by default there are no overrides
}
void AObjectTypeHandler::preInitObject(CGObjectInstance * obj) const
{
obj->ID = Obj(type);
obj->subID = subtype;
obj->typeName = typeName;
obj->subTypeName = subTypeName;
}
void AObjectTypeHandler::initTypeData(const JsonNode & input)
{
// empty implementation for overrides
}
bool AObjectTypeHandler::hasNameTextID() const
{
return false;
}
std::string AObjectTypeHandler::getNameTextID() const
{
return TextIdentifier("mapObject", modScope, typeName, subTypeName, "name").get();
}
std::string AObjectTypeHandler::getNameTranslated() const
{
return VLC->generaltexth->translate(getNameTextID());
}
SObjectSounds AObjectTypeHandler::getSounds() const
{
return sounds;
}
void AObjectTypeHandler::addTemplate(const std::shared_ptr<const ObjectTemplate> & templ)
{
templates.push_back(templ);
}
void AObjectTypeHandler::addTemplate(JsonNode config)
{
config.setType(JsonNode::JsonType::DATA_STRUCT); // ensure that input is not null
JsonUtils::inherit(config, base);
auto * tmpl = new ObjectTemplate;
tmpl->id = Obj(type);
tmpl->subid = subtype;
tmpl->stringID.clear(); // TODO?
tmpl->readJson(config);
templates.emplace_back(tmpl);
}
std::vector<std::shared_ptr<const ObjectTemplate>> AObjectTypeHandler::getTemplates() const
{
return templates;
}
BattleField AObjectTypeHandler::getBattlefield() const
{
return battlefield ? BattleField::fromString(battlefield.value()) : BattleField::NONE;
}
std::vector<std::shared_ptr<const ObjectTemplate>>AObjectTypeHandler::getTemplates(TerrainId terrainType) const
{
std::vector<std::shared_ptr<const ObjectTemplate>> templates = getTemplates();
std::vector<std::shared_ptr<const ObjectTemplate>> filtered;
const auto cfun = [&](const std::shared_ptr<const ObjectTemplate> & obj)
{
return obj->canBePlacedAt(terrainType);
};
std::copy_if(templates.begin(), templates.end(), std::back_inserter(filtered), cfun);
// H3 defines allowed terrains in a weird way - artifacts, monsters and resources have faulty masks here
// Perhaps we should re-define faulty templates and remove this workaround (already done for resources)
if (type == Obj::ARTIFACT || type == Obj::MONSTER)
return templates;
else
return filtered;
}
std::shared_ptr<const ObjectTemplate> AObjectTypeHandler::getOverride(TerrainId terrainType, const CGObjectInstance * object) const
{
std::vector<std::shared_ptr<const ObjectTemplate>> ret = getTemplates(terrainType);
for (const auto & tmpl: ret)
{
if (objectFilter(object, tmpl))
return tmpl;
}
return std::shared_ptr<const ObjectTemplate>(); //empty
}
const RandomMapInfo & AObjectTypeHandler::getRMGInfo()
{
return rmgInfo;
}
std::optional<si32> AObjectTypeHandler::getAiValue() const
{
return aiValue;
}
bool AObjectTypeHandler::isStaticObject()
{
return false; // most of classes are not static
}
void AObjectTypeHandler::afterLoadFinalization()
{
}
VCMI_LIB_NAMESPACE_END

View File

@ -0,0 +1,138 @@
/*
* CObjectClassesHandler.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 "../IHandlerBase.h"
#include "../JsonNode.h"
VCMI_LIB_NAMESPACE_BEGIN
class CRandomGenerator;
class AObjectTypeHandler;
class ObjectTemplate;
struct SObjectSounds;
struct DLL_LINKAGE CompoundMapObjectID
{
si32 primaryID;
si32 secondaryID;
CompoundMapObjectID(si32 primID, si32 secID) : primaryID(primID), secondaryID(secID) {};
bool operator<(const CompoundMapObjectID& other) const
{
if(this->primaryID != other.primaryID)
return this->primaryID < other.primaryID;
else
return this->secondaryID < other.secondaryID;
}
bool operator==(const CompoundMapObjectID& other) const
{
return (this->primaryID == other.primaryID) && (this->secondaryID == other.secondaryID);
}
};
class CGObjectInstance;
using TObjectTypeHandler = std::shared_ptr<AObjectTypeHandler>;
/// Class responsible for creation of adventure map objects of specific type
class DLL_LINKAGE ObjectClass
{
public:
std::string modScope;
std::string identifier;
si32 id;
std::string handlerName; // ID of handler that controls this object, should be determined using handlerConstructor map
JsonNode base;
std::vector<TObjectTypeHandler> objects;
ObjectClass() = default;
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
class DLL_LINKAGE CObjectClassesHandler : public IHandlerBase
{
/// list of object handlers, each of them handles only one type
std::vector<ObjectClass * > objects;
/// map that is filled during contruction with all known handlers. Not serializeable due to usage of std::function
std::map<std::string, std::function<TObjectTypeHandler()> > handlerConstructors;
/// container with H3 templates, used only during loading, no need to serialize it
using TTemplatesContainer = std::multimap<std::pair<si32, si32>, std::shared_ptr<const ObjectTemplate>>;
TTemplatesContainer legacyTemplates;
TObjectTypeHandler loadSubObjectFromJson(const std::string & scope, const std::string & identifier, const JsonNode & entry, ObjectClass * obj, size_t index);
void loadSubObject(const std::string & scope, const std::string & identifier, const JsonNode & entry, ObjectClass * obj);
void loadSubObject(const std::string & scope, const std::string & identifier, const JsonNode & entry, ObjectClass * obj, size_t index);
ObjectClass * loadFromJson(const std::string & scope, const JsonNode & json, const std::string & name, size_t index);
void generateExtraMonolithsForRMG();
public:
CObjectClassesHandler();
~CObjectClassesHandler();
std::vector<JsonNode> loadLegacyData() override;
void loadObject(std::string scope, std::string name, const JsonNode & data) override;
void loadObject(std::string scope, std::string name, const JsonNode & data, size_t index) override;
void loadSubObject(const std::string & identifier, JsonNode config, si32 ID, si32 subID);
void removeSubObject(si32 ID, si32 subID);
void beforeValidate(JsonNode & object) override;
void afterLoadFinalization() override;
std::vector<bool> getDefaultAllowed() const override;
/// Queries to detect loaded objects
std::set<si32> knownObjects() const;
std::set<si32> knownSubObjects(si32 primaryID) const;
/// returns handler for specified object (ID-based). ObjectHandler keeps ownership
TObjectTypeHandler getHandlerFor(si32 type, si32 subtype) const;
TObjectTypeHandler getHandlerFor(const std::string & scope, const std::string & type, const std::string & subtype) const;
TObjectTypeHandler getHandlerFor(CompoundMapObjectID compoundIdentifier) const;
std::string getObjectName(si32 type, si32 subtype) const;
SObjectSounds getObjectSounds(si32 type, si32 subtype) const;
/// Returns handler string describing the handler (for use in client)
std::string getObjectHandlerName(si32 type) const;
template <typename Handler> void serialize(Handler &h, const int version)
{
h & objects;
}
};
VCMI_LIB_NAMESPACE_END

View File

@ -9,7 +9,8 @@
*/
#include "StdInc.h"
#include "CRewardableConstructor.h"
#include "CRewardableObject.h"
#include "../mapObjects/CRewardableObject.h"
#include "../CGeneralTextHandler.h"
#include "../IGameCallback.h"

View File

@ -9,7 +9,7 @@
*/
#pragma once
#include "../mapObjects/CObjectClassesHandler.h"
#include "AObjectTypeHandler.h"
#include "../rewardable/Info.h"
VCMI_LIB_NAMESPACE_BEGIN

View File

@ -10,18 +10,19 @@
#include "StdInc.h"
#include "CommonConstructors.h"
#include "CGTownInstance.h"
#include "CGHeroInstance.h"
#include "CBank.h"
#include "../TerrainHandler.h"
#include "../mapping/CMapDefines.h"
#include "../CHeroHandler.h"
#include "../CGeneralTextHandler.h"
#include "../CCreatureHandler.h"
#include "JsonRandom.h"
#include "../CGeneralTextHandler.h"
#include "../CHeroHandler.h"
#include "../CModHandler.h"
#include "../IGameCallback.h"
#include "../StringConstants.h"
#include "../TerrainHandler.h"
#include "../mapObjects/CBank.h"
#include "../mapObjects/CGHeroInstance.h"
#include "../mapObjects/CGTownInstance.h"
#include "../mapObjects/ObjectTemplate.h"
#include "../mapping/CMapDefines.h"
#include "JsonRandom.h"
VCMI_LIB_NAMESPACE_BEGIN

View File

@ -9,9 +9,15 @@
*/
#pragma once
#include "CObjectClassesHandler.h"
#include "../CTownHandler.h" // for building ID-based filters
#include "MapObjects.h"
#include "AObjectTypeHandler.h"
#include "../mapObjects/CGMarket.h"
#include "../mapObjects/MiscObjects.h"
#include "../mapObjects/CGHeroInstance.h"
#include "../mapObjects/CGTownInstance.h"
#include "../mapObjects/CBank.h"
#include "../LogicalExpression.h"
#include "IObjectInfo.h"
VCMI_LIB_NAMESPACE_BEGIN
@ -21,6 +27,7 @@ class CGHeroInstance;
class CGDwelling;
class CHeroClass;
class CBank;
class CFaction;
class CStackBasicDescriptor;
/// Class that is used for objects that do not have dedicated handler

View File

@ -0,0 +1,60 @@
/*
* IObjectInfo.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
VCMI_LIB_NAMESPACE_BEGIN
class DLL_LINKAGE IObjectInfo
{
public:
struct CArmyStructure
{
ui32 totalStrength;
ui32 shootersStrength;
ui32 flyersStrength;
ui32 walkersStrength;
CArmyStructure() :
totalStrength(0),
shootersStrength(0),
flyersStrength(0),
walkersStrength(0)
{}
bool operator <(const CArmyStructure & other) const
{
return this->totalStrength < other.totalStrength;
}
};
/// Returns possible composition of guards. Actual guards would be
/// somewhere between these two values
virtual CArmyStructure minGuards() const { return CArmyStructure(); }
virtual CArmyStructure maxGuards() const { return CArmyStructure(); }
virtual bool givesResources() const { return false; }
virtual bool givesExperience() const { return false; }
virtual bool givesMana() const { return false; }
virtual bool givesMovement() const { return false; }
virtual bool givesPrimarySkills() const { return false; }
virtual bool givesSecondarySkills() const { return false; }
virtual bool givesArtifacts() const { return false; }
virtual bool givesCreatures() const { return false; }
virtual bool givesSpells() const { return false; }
virtual bool givesBonuses() const { return false; }
virtual ~IObjectInfo() = default;
};
VCMI_LIB_NAMESPACE_END

View File

@ -0,0 +1,46 @@
/*
* RandomMapInfo.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
VCMI_LIB_NAMESPACE_BEGIN
/// Structure that describes placement rules for this object in random map
struct DLL_LINKAGE RandomMapInfo
{
/// How valuable this object is, 1k = worthless, 10k = Utopia-level
ui32 value;
/// How many of such objects can be placed on map, 0 = object can not be placed by RMG
std::optional<ui32> mapLimit;
/// How many of such objects can be placed in one zone, 0 = unplaceable
ui32 zoneLimit;
/// Rarity of object, 5 = extremely rare, 100 = common
ui32 rarity;
RandomMapInfo():
value(0),
zoneLimit(0),
rarity(0)
{}
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

View File

@ -0,0 +1,28 @@
/*
* SObjectSounds.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
VCMI_LIB_NAMESPACE_BEGIN
struct SObjectSounds
{
std::vector<std::string> ambient;
std::vector<std::string> visit;
std::vector<std::string> removal;
template <typename Handler> void serialize(Handler &h, const int version)
{
h & ambient;
h & visit;
h & removal;
}
};
VCMI_LIB_NAMESPACE_END

View File

@ -9,7 +9,7 @@
*/
#pragma once
#include "CObjectHandler.h"
#include "CGObjectInstance.h"
#include "../CCreatureSet.h"
#include "../bonuses/CBonusProxy.h"
#include "../bonuses/CBonusSystemNode.h"

View File

@ -17,7 +17,8 @@
#include "../NetPacks.h"
#include "../CGeneralTextHandler.h"
#include "../CSoundBase.h"
#include "CommonConstructors.h"
#include "../mapObjectConstructors/CObjectClassesHandler.h"
#include "../mapObjectConstructors/CommonConstructors.h"
#include "../IGameCallback.h"
#include "../CGameState.h"

View File

@ -9,7 +9,6 @@
*/
#pragma once
#include "CObjectHandler.h"
#include "CArmedInstance.h"
VCMI_LIB_NAMESPACE_BEGIN

View File

@ -10,8 +10,9 @@
#include "StdInc.h"
#include "CGDwelling.h"
#include "CObjectClassesHandler.h"
#include "../serializer/JsonSerializeFormat.h"
#include "../mapObjectConstructors/AObjectTypeHandler.h"
#include "../mapObjectConstructors/CObjectClassesHandler.h"
#include "../CTownHandler.h"
#include "../IGameCallback.h"
#include "../CGameState.h"

View File

@ -24,7 +24,6 @@
#include "../CSoundBase.h"
#include "../spells/CSpellHandler.h"
#include "../CSkillHandler.h"
#include "CObjectClassesHandler.h"
#include "../IGameCallback.h"
#include "../CGameState.h"
#include "../CCreatureHandler.h"
@ -32,6 +31,8 @@
#include "../mapping/CMap.h"
#include "CGTownInstance.h"
#include "../serializer/JsonSerializeFormat.h"
#include "../mapObjectConstructors/AObjectTypeHandler.h"
#include "../mapObjectConstructors/CObjectClassesHandler.h"
#include "../StringConstants.h"
#include "../battle/Unit.h"

View File

@ -11,11 +11,9 @@
#include <vcmi/spells/Caster.h>
#include "CObjectHandler.h"
#include "CArmedInstance.h"
#include "../CArtHandler.h" // For CArtifactSet
#include "../CRandomGenerator.h"
VCMI_LIB_NAMESPACE_BEGIN

View File

@ -19,166 +19,11 @@
#include "CGTownInstance.h"
#include "../GameSettings.h"
#include "../CSkillHandler.h"
#include "CObjectClassesHandler.h"
#include "../mapObjectConstructors/AObjectTypeHandler.h"
#include "../mapObjectConstructors/CObjectClassesHandler.h"
VCMI_LIB_NAMESPACE_BEGIN
bool IMarket::getOffer(int id1, int id2, int &val1, int &val2, EMarketMode::EMarketMode mode) const
{
switch(mode)
{
case EMarketMode::RESOURCE_RESOURCE:
{
double effectiveness = std::min((getMarketEfficiency() + 1.0) / 20.0, 0.5);
double r = VLC->objh->resVals[id1]; //value of given resource
double g = VLC->objh->resVals[id2] / effectiveness; //value of wanted resource
if(r>g) //if given resource is more expensive than wanted
{
val2 = static_cast<int>(ceil(r / g));
val1 = 1;
}
else //if wanted resource is more expensive
{
val1 = static_cast<int>((g / r) + 0.5);
val2 = 1;
}
}
break;
case EMarketMode::CREATURE_RESOURCE:
{
const double effectivenessArray[] = {0.0, 0.3, 0.45, 0.50, 0.65, 0.7, 0.85, 0.9, 1.0};
double effectiveness = effectivenessArray[std::min(getMarketEfficiency(), 8)];
double r = VLC->creatures()->getByIndex(id1)->getRecruitCost(EGameResID::GOLD); //value of given creature in gold
double g = VLC->objh->resVals[id2] / effectiveness; //value of wanted resource
if(r>g) //if given resource is more expensive than wanted
{
val2 = static_cast<int>(ceil(r / g));
val1 = 1;
}
else //if wanted resource is more expensive
{
val1 = static_cast<int>((g / r) + 0.5);
val2 = 1;
}
}
break;
case EMarketMode::RESOURCE_PLAYER:
val1 = 1;
val2 = 1;
break;
case EMarketMode::RESOURCE_ARTIFACT:
{
double effectiveness = std::min((getMarketEfficiency() + 3.0) / 20.0, 0.6);
double r = VLC->objh->resVals[id1]; //value of offered resource
double g = VLC->artifacts()->getByIndex(id2)->getPrice() / effectiveness; //value of bought artifact in gold
if(id1 != 6) //non-gold prices are doubled
r /= 2;
val1 = std::max(1, static_cast<int>((g / r) + 0.5)); //don't sell arts for less than 1 resource
val2 = 1;
}
break;
case EMarketMode::ARTIFACT_RESOURCE:
{
double effectiveness = std::min((getMarketEfficiency() + 3.0) / 20.0, 0.6);
double r = VLC->artifacts()->getByIndex(id1)->getPrice() * effectiveness;
double g = VLC->objh->resVals[id2];
// if(id2 != 6) //non-gold prices are doubled
// r /= 2;
val1 = 1;
val2 = std::max(1, static_cast<int>((r / g) + 0.5)); //at least one resource is given in return
}
break;
case EMarketMode::CREATURE_EXP:
{
val1 = 1;
val2 = (VLC->creh->objects[id1]->getAIValue() / 40) * 5;
}
break;
case EMarketMode::ARTIFACT_EXP:
{
val1 = 1;
int givenClass = VLC->arth->objects[id1]->getArtClassSerial();
if(givenClass < 0 || givenClass > 3)
{
val2 = 0;
return false;
}
static constexpr int expPerClass[] = {1000, 1500, 3000, 6000};
val2 = expPerClass[givenClass];
}
break;
default:
assert(0);
return false;
}
return true;
}
bool IMarket::allowsTrade(EMarketMode::EMarketMode mode) const
{
return false;
}
int IMarket::availableUnits(EMarketMode::EMarketMode mode, int marketItemSerial) const
{
switch(mode)
{
case EMarketMode::RESOURCE_RESOURCE:
case EMarketMode::ARTIFACT_RESOURCE:
case EMarketMode::CREATURE_RESOURCE:
return -1;
default:
return 1;
}
}
std::vector<int> IMarket::availableItemsIds(EMarketMode::EMarketMode mode) const
{
std::vector<int> ret;
switch(mode)
{
case EMarketMode::RESOURCE_RESOURCE:
case EMarketMode::ARTIFACT_RESOURCE:
case EMarketMode::CREATURE_RESOURCE:
for (int i = 0; i < 7; i++)
ret.push_back(i);
}
return ret;
}
const IMarket * IMarket::castFrom(const CGObjectInstance *obj, bool verbose)
{
auto * imarket = dynamic_cast<const IMarket *>(obj);
if(verbose && !imarket)
logGlobal->error("Cannot cast to IMarket object type %s", obj->typeName);
return imarket;
}
IMarket::IMarket()
{
}
std::vector<EMarketMode::EMarketMode> IMarket::availableModes() const
{
std::vector<EMarketMode::EMarketMode> ret;
for (int i = 0; i < EMarketMode::MARTKET_AFTER_LAST_PLACEHOLDER; i++)
if(allowsTrade(static_cast<EMarketMode::EMarketMode>(i)))
ret.push_back(static_cast<EMarketMode::EMarketMode>(i));
return ret;
}
void CGMarket::initObj(CRandomGenerator & rand)
{
VLC->objtypeh->getHandlerFor(ID, subID)->configureObject(this, rand);

View File

@ -9,27 +9,11 @@
*/
#pragma once
#include "CObjectHandler.h"
#include "CGObjectInstance.h"
#include "IMarket.h"
VCMI_LIB_NAMESPACE_BEGIN
class DLL_LINKAGE IMarket
{
public:
IMarket();
virtual ~IMarket() {}
virtual int getMarketEfficiency() const = 0;
virtual bool allowsTrade(EMarketMode::EMarketMode mode) const;
virtual int availableUnits(EMarketMode::EMarketMode mode, int marketItemSerial) const; //-1 if unlimited
virtual std::vector<int> availableItemsIds(EMarketMode::EMarketMode mode) const;
bool getOffer(int id1, int id2, int &val1, int &val2, EMarketMode::EMarketMode mode) const; //val1 - how many units of id1 player has to give to receive val2 units
std::vector<EMarketMode::EMarketMode> availableModes() const;
static const IMarket *castFrom(const CGObjectInstance *obj, bool verbose = true);
};
class DLL_LINKAGE CGMarket : public CGObjectInstance, public IMarket
{
public:

View File

@ -0,0 +1,348 @@
/*
* CObjectHandler.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 "CGObjectInstance.h"
#include "CGHeroInstance.h"
#include "ObjectTemplate.h"
#include "../CGameState.h"
#include "../CGeneralTextHandler.h"
#include "../IGameCallback.h"
#include "../NetPacks.h"
#include "../StringConstants.h"
#include "../TerrainHandler.h"
#include "../mapObjectConstructors/AObjectTypeHandler.h"
#include "../mapObjectConstructors/CObjectClassesHandler.h"
#include "../mapping/CMap.h"
#include "../serializer/JsonSerializeFormat.h"
VCMI_LIB_NAMESPACE_BEGIN
//TODO: remove constructor
CGObjectInstance::CGObjectInstance():
pos(-1,-1,-1),
ID(Obj::NO_OBJ),
subID(-1),
tempOwner(PlayerColor::UNFLAGGABLE),
blockVisit(false)
{
}
//must be instantiated in .cpp file for access to complete types of all member fields
CGObjectInstance::~CGObjectInstance() = default;
int32_t CGObjectInstance::getObjGroupIndex() const
{
return ID.num;
}
int32_t CGObjectInstance::getObjTypeIndex() const
{
return subID;
}
int3 CGObjectInstance::getPosition() const
{
return pos;
}
int3 CGObjectInstance::getTopVisiblePos() const
{
return pos - appearance->getTopVisibleOffset();
}
void CGObjectInstance::setOwner(const PlayerColor & ow)
{
tempOwner = ow;
}
int CGObjectInstance::getWidth() const//returns width of object graphic in tiles
{
return appearance->getWidth();
}
int CGObjectInstance::getHeight() const //returns height of object graphic in tiles
{
return appearance->getHeight();
}
bool CGObjectInstance::visitableAt(int x, int y) const //returns true if object is visitable at location (x, y) form left top tile of image (x, y in tiles)
{
return appearance->isVisitableAt(pos.x - x, pos.y - y);
}
bool CGObjectInstance::blockingAt(int x, int y) const
{
return appearance->isBlockedAt(pos.x - x, pos.y - y);
}
bool CGObjectInstance::coveringAt(int x, int y) const
{
return appearance->isVisibleAt(pos.x - x, pos.y - y);
}
std::set<int3> CGObjectInstance::getBlockedPos() const
{
std::set<int3> ret;
for(int w=0; w<getWidth(); ++w)
{
for(int h=0; h<getHeight(); ++h)
{
if(appearance->isBlockedAt(w, h))
ret.insert(int3(pos.x - w, pos.y - h, pos.z));
}
}
return ret;
}
std::set<int3> CGObjectInstance::getBlockedOffsets() const
{
return appearance->getBlockedOffsets();
}
void CGObjectInstance::setType(si32 ID, si32 subID)
{
auto position = visitablePos();
auto oldOffset = getVisitableOffset();
auto &tile = cb->gameState()->map->getTile(position);
//recalculate blockvis tiles - new appearance might have different blockmap than before
cb->gameState()->map->removeBlockVisTiles(this, true);
auto handler = VLC->objtypeh->getHandlerFor(ID, subID);
if(!handler)
{
logGlobal->error("Unknown object type %d:%d at %s", ID, subID, visitablePos().toString());
return;
}
if(!handler->getTemplates(tile.terType->getId()).empty())
{
appearance = handler->getTemplates(tile.terType->getId())[0];
}
else
{
logGlobal->warn("Object %d:%d at %s has no templates suitable for terrain %s", ID, subID, visitablePos().toString(), tile.terType->getNameTranslated());
appearance = handler->getTemplates()[0]; // get at least some appearance since alternative is crash
}
if(this->ID == Obj::PRISON && ID == Obj::HERO)
{
auto newOffset = getVisitableOffset();
// FIXME: potentially unused code - setType is NOT called when releasing hero from prison
// instead, appearance update & pos adjustment occurs in GiveHero::applyGs
// adjust position since hero and prison may have different visitable offset
pos = pos - oldOffset + newOffset;
}
this->ID = Obj(ID);
this->subID = subID;
cb->gameState()->map->addBlockVisTiles(this);
}
void CGObjectInstance::initObj(CRandomGenerator & rand)
{
switch(ID)
{
case Obj::TAVERN:
blockVisit = true;
break;
}
}
void CGObjectInstance::setProperty( ui8 what, ui32 val )
{
setPropertyDer(what, val); // call this before any actual changes (needed at least for dwellings)
switch(what)
{
case ObjProperty::OWNER:
tempOwner = PlayerColor(val);
break;
case ObjProperty::BLOCKVIS:
blockVisit = val;
break;
case ObjProperty::ID:
ID = Obj(val);
break;
case ObjProperty::SUBID:
subID = val;
break;
}
}
void CGObjectInstance::setPropertyDer( ui8 what, ui32 val )
{}
int3 CGObjectInstance::getSightCenter() const
{
return visitablePos();
}
int CGObjectInstance::getSightRadius() const
{
return 3;
}
int3 CGObjectInstance::getVisitableOffset() const
{
return appearance->getVisitableOffset();
}
void CGObjectInstance::giveDummyBonus(const ObjectInstanceID & heroID, BonusDuration::Type duration) const
{
GiveBonus gbonus;
gbonus.bonus.type = BonusType::NONE;
gbonus.id = heroID.getNum();
gbonus.bonus.duration = duration;
gbonus.bonus.source = BonusSource::OBJECT;
gbonus.bonus.sid = ID;
cb->giveHeroBonus(&gbonus);
}
std::string CGObjectInstance::getObjectName() const
{
return VLC->objtypeh->getObjectName(ID, subID);
}
std::optional<std::string> CGObjectInstance::getAmbientSound() const
{
const auto & sounds = VLC->objtypeh->getObjectSounds(ID, subID).ambient;
if(!sounds.empty())
return sounds.front(); // TODO: Support randomization of ambient sounds
return std::nullopt;
}
std::optional<std::string> CGObjectInstance::getVisitSound() const
{
const auto & sounds = VLC->objtypeh->getObjectSounds(ID, subID).visit;
if(!sounds.empty())
return *RandomGeneratorUtil::nextItem(sounds, CRandomGenerator::getDefault());
return std::nullopt;
}
std::optional<std::string> CGObjectInstance::getRemovalSound() const
{
const auto & sounds = VLC->objtypeh->getObjectSounds(ID, subID).removal;
if(!sounds.empty())
return *RandomGeneratorUtil::nextItem(sounds, CRandomGenerator::getDefault());
return std::nullopt;
}
std::string CGObjectInstance::getHoverText(PlayerColor player) const
{
auto text = getObjectName();
if (tempOwner.isValidPlayer())
text += "\n" + VLC->generaltexth->arraytxt[23 + tempOwner.getNum()];
return text;
}
std::string CGObjectInstance::getHoverText(const CGHeroInstance * hero) const
{
return getHoverText(hero->tempOwner);
}
void CGObjectInstance::onHeroVisit( const CGHeroInstance * h ) const
{
switch(ID)
{
case Obj::HILL_FORT:
{
openWindow(EOpenWindowMode::HILL_FORT_WINDOW,id.getNum(),h->id.getNum());
}
break;
case Obj::SANCTUARY:
{
//You enter the sanctuary and immediately feel as if a great weight has been lifted off your shoulders. You feel safe here.
h->showInfoDialog(114);
}
break;
case Obj::TAVERN:
{
openWindow(EOpenWindowMode::TAVERN_WINDOW,h->id.getNum(),id.getNum());
}
break;
}
}
int3 CGObjectInstance::visitablePos() const
{
return pos - getVisitableOffset();
}
bool CGObjectInstance::isVisitable() const
{
return appearance->isVisitable();
}
bool CGObjectInstance::passableFor(PlayerColor color) const
{
return false;
}
void CGObjectInstance::updateFrom(const JsonNode & data)
{
}
void CGObjectInstance::serializeJson(JsonSerializeFormat & handler)
{
//only save here, loading is handled by map loader
if(handler.saving)
{
handler.serializeString("type", typeName);
handler.serializeString("subtype", subTypeName);
handler.serializeInt("x", pos.x);
handler.serializeInt("y", pos.y);
handler.serializeInt("l", pos.z);
JsonNode app;
appearance->writeJson(app, false);
handler.serializeRaw("template", app, std::nullopt);
}
{
auto options = handler.enterStruct("options");
serializeJsonOptions(handler);
}
}
void CGObjectInstance::afterAddToMap(CMap * map)
{
//nothing here
}
void CGObjectInstance::afterRemoveFromMap(CMap * map)
{
//nothing here
}
void CGObjectInstance::serializeJsonOptions(JsonSerializeFormat & handler)
{
//nothing here
}
void CGObjectInstance::serializeJsonOwner(JsonSerializeFormat & handler)
{
ui8 temp = tempOwner.getNum();
handler.serializeEnum("owner", temp, PlayerColor::NEUTRAL.getNum(), GameConstants::PLAYER_COLOR_NAMES);
if(!handler.saving)
tempOwner = PlayerColor(temp);
}
BattleField CGObjectInstance::getBattlefield() const
{
return VLC->objtypeh->getHandlerFor(ID, subID)->getBattlefield();
}
VCMI_LIB_NAMESPACE_END

View File

@ -0,0 +1,145 @@
/*
* CGObjectInstance.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 "IObjectInterface.h"
#include "../int3.h"
#include "../bonuses/BonusEnum.h"
VCMI_LIB_NAMESPACE_BEGIN
class JsonSerializeFormat;
class ObjectTemplate;
class CMap;
class DLL_LINKAGE CGObjectInstance : public IObjectInterface
{
public:
/// Position of bottom-right corner of object on map
int3 pos;
/// Type of object, e.g. town, hero, creature.
Obj ID;
/// Subtype of object, depends on type
si32 subID;
/// Current owner of an object (when below PLAYER_LIMIT)
PlayerColor tempOwner;
/// Index of object in map's list of objects
ObjectInstanceID id;
/// Defines appearance of object on map (animation, blocked tiles, blit order, etc)
std::shared_ptr<const ObjectTemplate> appearance;
/// If true hero can visit this object only from neighbouring tiles and can't stand on this object
bool blockVisit;
std::string instanceName;
std::string typeName;
std::string subTypeName;
CGObjectInstance(); //TODO: remove constructor
~CGObjectInstance() override;
int32_t getObjGroupIndex() const override;
int32_t getObjTypeIndex() const override;
/// "center" tile from which the sight distance is calculated
int3 getSightCenter() const;
PlayerColor getOwner() const override
{
return this->tempOwner;
}
void setOwner(const PlayerColor & ow);
/** APPEARANCE ACCESSORS **/
int getWidth() const; //returns width of object graphic in tiles
int getHeight() const; //returns height of object graphic in tiles
bool visitableAt(int x, int y) const; //returns true if object is visitable at location (x, y) (h3m pos)
int3 visitablePos() const override;
int3 getPosition() const override;
int3 getTopVisiblePos() const;
bool blockingAt(int x, int y) const; //returns true if object is blocking location (x, y) (h3m pos)
bool coveringAt(int x, int y) 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
bool isVisitable() const; //returns true if object is visitable
virtual BattleField getBattlefield() const;
virtual bool isTile2Terrain() const { return false; }
std::optional<std::string> getAmbientSound() const;
std::optional<std::string> getVisitSound() const;
std::optional<std::string> getRemovalSound() const;
/** VIRTUAL METHODS **/
/// Returns true if player can pass through visitable tiles of this object
virtual bool passableFor(PlayerColor color) const;
/// Range of revealed map around this object, counting from getSightCenter()
virtual int getSightRadius() const;
/// returns (x,y,0) offset to a visitable tile of object
virtual int3 getVisitableOffset() const;
/// Called mostly during map randomization to turn random object into a regular one (e.g. "Random Monster" into "Pikeman")
virtual void setType(si32 ID, si32 subID);
/// returns text visible in status bar with specific hero/player active.
/// Returns generic name of object, without any player-specific info
virtual std::string getObjectName() const;
/// Returns hover name for situation when there are no selected heroes. Default = object name
virtual std::string getHoverText(PlayerColor player) const;
/// Returns hero-specific hover name, including visited/not visited info. Default = player-specific name
virtual std::string getHoverText(const CGHeroInstance * hero) const;
/** OVERRIDES OF IObjectInterface **/
void initObj(CRandomGenerator & rand) override;
void onHeroVisit(const CGHeroInstance * h) const override;
/// method for synchronous update. Note: For new properties classes should override setPropertyDer instead
void setProperty(ui8 what, ui32 val) final;
virtual void afterAddToMap(CMap * map);
virtual void afterRemoveFromMap(CMap * map);
///Entry point of binary (de-)serialization
template <typename Handler> void serialize(Handler &h, const int version)
{
h & instanceName;
h & typeName;
h & subTypeName;
h & pos;
h & ID;
h & subID;
h & id;
h & tempOwner;
h & blockVisit;
h & appearance;
//definfo is handled by map serializer
}
///Entry point of Json (de-)serialization
void serializeJson(JsonSerializeFormat & handler);
virtual void updateFrom(const JsonNode & data);
protected:
/// virtual method that allows synchronously update object state on server and all clients
virtual void setPropertyDer(ui8 what, ui32 val);
/// Gives dummy bonus from this object to hero. Can be used to track visited state
void giveDummyBonus(const ObjectInstanceID & heroID, BonusDuration::Type duration = BonusDuration::ONE_DAY) const;
///Serialize object-type specific options
virtual void serializeJsonOptions(JsonSerializeFormat & handler);
void serializeJsonOwner(JsonSerializeFormat & handler);
};
VCMI_LIB_NAMESPACE_END

View File

@ -9,7 +9,6 @@
*/
#pragma once
#include "CObjectHandler.h"
#include "CArmedInstance.h"
#include "../ResourceSet.h"

View File

@ -10,7 +10,7 @@
#pragma once
#include "CObjectHandler.h"
#include "IObjectInterface.h"
#include "../rewardable/Interface.h"
VCMI_LIB_NAMESPACE_BEGIN

View File

@ -11,7 +11,6 @@
#include "StdInc.h"
#include "CGTownInstance.h"
#include "CGTownBuilding.h"
#include "CObjectClassesHandler.h"
#include "../spells/CSpellHandler.h"
#include "../bonuses/Bonus.h"
#include "../battle/IBattleInfoCallback.h"
@ -24,6 +23,8 @@
#include "../mapping/CMap.h"
#include "../CPlayerState.h"
#include "../TerrainHandler.h"
#include "../mapObjectConstructors/AObjectTypeHandler.h"
#include "../mapObjectConstructors/CObjectClassesHandler.h"
#include "../serializer/JsonSerializeFormat.h"
VCMI_LIB_NAMESPACE_BEGIN

View File

@ -9,9 +9,7 @@
*/
#pragma once
#include "CObjectHandler.h"
#include "CGMarket.h" // For IMarket interface
#include "CArmedInstance.h"
#include "IMarket.h"
#include "CGDwelling.h"
#include "CGTownBuilding.h"

View File

@ -1,337 +0,0 @@
/*
* CObjectClassesHandler.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 "ObjectTemplate.h"
#include "../GameConstants.h"
#include "../ConstTransitivePtr.h"
#include "../IHandlerBase.h"
#include "../JsonNode.h"
VCMI_LIB_NAMESPACE_BEGIN
class JsonNode;
class CRandomGenerator;
struct SObjectSounds
{
std::vector<std::string> ambient;
std::vector<std::string> visit;
std::vector<std::string> removal;
template <typename Handler> void serialize(Handler &h, const int version)
{
h & ambient;
h & visit;
h & removal;
}
};
/// Structure that describes placement rules for this object in random map
struct DLL_LINKAGE RandomMapInfo
{
/// How valuable this object is, 1k = worthless, 10k = Utopia-level
ui32 value;
/// How many of such objects can be placed on map, 0 = object can not be placed by RMG
std::optional<ui32> mapLimit;
/// How many of such objects can be placed in one zone, 0 = unplaceable
ui32 zoneLimit;
/// Rarity of object, 5 = extremely rare, 100 = common
ui32 rarity;
RandomMapInfo():
value(0),
zoneLimit(0),
rarity(0)
{}
void setMapLimit(ui32 val) { mapLimit = val; }
template <typename Handler> void serialize(Handler &h, const int version)
{
h & value;
h & mapLimit;
h & zoneLimit;
h & rarity;
}
};
struct DLL_LINKAGE CompoundMapObjectID
{
si32 primaryID;
si32 secondaryID;
CompoundMapObjectID(si32 primID, si32 secID) : primaryID(primID), secondaryID(secID) {};
bool operator<(const CompoundMapObjectID& other) const
{
if(this->primaryID != other.primaryID)
return this->primaryID < other.primaryID;
else
return this->secondaryID < other.secondaryID;
}
bool operator==(const CompoundMapObjectID& other) const
{
return (this->primaryID == other.primaryID) && (this->secondaryID == other.secondaryID);
}
};
class DLL_LINKAGE IObjectInfo
{
public:
struct CArmyStructure
{
ui32 totalStrength;
ui32 shootersStrength;
ui32 flyersStrength;
ui32 walkersStrength;
CArmyStructure() :
totalStrength(0),
shootersStrength(0),
flyersStrength(0),
walkersStrength(0)
{}
bool operator <(const CArmyStructure & other) const
{
return this->totalStrength < other.totalStrength;
}
};
/// Returns possible composition of guards. Actual guards would be
/// somewhere between these two values
virtual CArmyStructure minGuards() const { return CArmyStructure(); }
virtual CArmyStructure maxGuards() const { return CArmyStructure(); }
virtual bool givesResources() const { return false; }
virtual bool givesExperience() const { return false; }
virtual bool givesMana() const { return false; }
virtual bool givesMovement() const { return false; }
virtual bool givesPrimarySkills() const { return false; }
virtual bool givesSecondarySkills() const { return false; }
virtual bool givesArtifacts() const { return false; }
virtual bool givesCreatures() const { return false; }
virtual bool givesSpells() const { return false; }
virtual bool givesBonuses() const { return false; }
virtual ~IObjectInfo() = default;
};
class CGObjectInstance;
/// Class responsible for creation of objects of specific type & subtype
class DLL_LINKAGE AObjectTypeHandler : public boost::noncopyable
{
friend class CObjectClassesHandler;
RandomMapInfo rmgInfo;
JsonNode base; /// describes base template
std::vector<std::shared_ptr<const ObjectTemplate>> templates;
SObjectSounds sounds;
std::optional<si32> aiValue;
std::optional<std::string> battlefield;
std::string modScope;
std::string typeName;
std::string subTypeName;
si32 type;
si32 subtype;
protected:
void preInitObject(CGObjectInstance * obj) const;
virtual bool objectFilter(const CGObjectInstance * obj, std::shared_ptr<const ObjectTemplate> tmpl) const;
/// initialization for classes that inherit this one
virtual void initTypeData(const JsonNode & input);
public:
virtual ~AObjectTypeHandler() = default;
si32 getIndex() const;
si32 getSubIndex() const;
std::string getTypeName() const;
std::string getSubTypeName() const;
/// loads generic data from Json structure and passes it towards type-specific constructors
void init(const JsonNode & input);
/// returns full form of identifier of this object in form of modName:objectName
std::string getJsonKey() const;
/// Returns object-specific name, if set
SObjectSounds getSounds() const;
void addTemplate(const std::shared_ptr<const ObjectTemplate> & templ);
void addTemplate(JsonNode config);
/// returns all templates matching parameters
std::vector<std::shared_ptr<const ObjectTemplate>> getTemplates() const;
std::vector<std::shared_ptr<const ObjectTemplate>> getTemplates(const TerrainId terrainType) const;
/// returns preferred template for this object, if present (e.g. one of 3 possible templates for town - village, fort and castle)
/// note that appearance will not be changed - this must be done separately (either by assignment or via pack from server)
std::shared_ptr<const ObjectTemplate> getOverride(TerrainId terrainType, const CGObjectInstance * object) const;
BattleField getBattlefield() const;
const RandomMapInfo & getRMGInfo();
std::optional<si32> getAiValue() const;
/// returns true if this class provides custom text ID's instead of generic per-object name
virtual bool hasNameTextID() const;
/// returns object's name in form of translatable text ID
virtual std::string getNameTextID() const;
/// returns object's name in form of human-readable text
std::string getNameTranslated() const;
virtual bool isStaticObject();
virtual void afterLoadFinalization();
/// Creates object and set up core properties (like ID/subID). Object is NOT initialized
/// to allow creating objects before game start (e.g. map loading)
virtual CGObjectInstance * create(std::shared_ptr<const ObjectTemplate> tmpl = nullptr) const = 0;
/// Configures object properties. Should be re-entrable, resetting state of the object if necessarily
/// This should set remaining properties, including randomized or depending on map
virtual void configureObject(CGObjectInstance * object, CRandomGenerator & rng) const = 0;
/// Returns object configuration, if available. Otherwise returns NULL
virtual std::unique_ptr<IObjectInfo> getObjectInfo(std::shared_ptr<const ObjectTemplate> tmpl) const = 0;
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;
}
};
using TObjectTypeHandler = std::shared_ptr<AObjectTypeHandler>;
/// Class responsible for creation of adventure map objects of specific type
class DLL_LINKAGE ObjectClass
{
public:
std::string modScope;
std::string identifier;
si32 id;
std::string handlerName; // ID of handler that controls this object, should be determined using handlerConstructor map
JsonNode base;
std::vector<TObjectTypeHandler> objects;
ObjectClass() = default;
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
class DLL_LINKAGE CObjectClassesHandler : public IHandlerBase
{
/// list of object handlers, each of them handles only one type
std::vector<ObjectClass * > objects;
/// map that is filled during contruction with all known handlers. Not serializeable due to usage of std::function
std::map<std::string, std::function<TObjectTypeHandler()> > handlerConstructors;
/// container with H3 templates, used only during loading, no need to serialize it
using TTemplatesContainer = std::multimap<std::pair<si32, si32>, std::shared_ptr<const ObjectTemplate>>;
TTemplatesContainer legacyTemplates;
TObjectTypeHandler loadSubObjectFromJson(const std::string & scope, const std::string & identifier, const JsonNode & entry, ObjectClass * obj, size_t index);
void loadSubObject(const std::string & scope, const std::string & identifier, const JsonNode & entry, ObjectClass * obj);
void loadSubObject(const std::string & scope, const std::string & identifier, const JsonNode & entry, ObjectClass * obj, size_t index);
ObjectClass * loadFromJson(const std::string & scope, const JsonNode & json, const std::string & name, size_t index);
void generateExtraMonolithsForRMG();
public:
CObjectClassesHandler();
~CObjectClassesHandler();
std::vector<JsonNode> loadLegacyData() override;
void loadObject(std::string scope, std::string name, const JsonNode & data) override;
void loadObject(std::string scope, std::string name, const JsonNode & data, size_t index) override;
void loadSubObject(const std::string & identifier, JsonNode config, si32 ID, si32 subID);
void removeSubObject(si32 ID, si32 subID);
void beforeValidate(JsonNode & object) override;
void afterLoadFinalization() override;
std::vector<bool> getDefaultAllowed() const override;
/// Queries to detect loaded objects
std::set<si32> knownObjects() const;
std::set<si32> knownSubObjects(si32 primaryID) const;
/// returns handler for specified object (ID-based). ObjectHandler keeps ownership
TObjectTypeHandler getHandlerFor(si32 type, si32 subtype) const;
TObjectTypeHandler getHandlerFor(const std::string & scope, const std::string & type, const std::string & subtype) const;
TObjectTypeHandler getHandlerFor(CompoundMapObjectID compoundIdentifier) const;
std::string getObjectName(si32 type, si32 subtype) const;
SObjectSounds getObjectSounds(si32 type, si32 subtype) const;
/// Returns handler string describing the handler (for use in client)
std::string getObjectHandlerName(si32 type) const;
template <typename Handler> void serialize(Handler &h, const int version)
{
h & objects;
}
};
VCMI_LIB_NAMESPACE_END

View File

@ -11,89 +11,11 @@
#include "StdInc.h"
#include "CObjectHandler.h"
#include "../NetPacks.h"
#include "../CGeneralTextHandler.h"
#include "../CHeroHandler.h"
#include "../CSoundBase.h"
#include "CGObjectInstance.h"
#include "../filesystem/ResourceID.h"
#include "../IGameCallback.h"
#include "../CGameState.h"
#include "../StringConstants.h"
#include "../mapping/CMap.h"
#include "../TerrainHandler.h"
#include "CObjectClassesHandler.h"
#include "CGTownInstance.h"
#include "../serializer/JsonSerializeFormat.h"
VCMI_LIB_NAMESPACE_BEGIN
IGameCallback * IObjectInterface::cb = nullptr;
///helpers
void IObjectInterface::openWindow(const EOpenWindowMode type, const int id1, const int id2)
{
OpenWindow ow;
ow.window = type;
ow.id1 = id1;
ow.id2 = id2;
IObjectInterface::cb->sendAndApply(&ow);
}
void IObjectInterface::showInfoDialog(const ui32 txtID, const ui16 soundID, EInfoWindowMode mode) const
{
InfoWindow iw;
iw.soundID = soundID;
iw.player = getOwner();
iw.type = mode;
iw.text.addTxt(MetaString::ADVOB_TXT,txtID);
IObjectInterface::cb->sendAndApply(&iw);
}
///IObjectInterface
void IObjectInterface::onHeroVisit(const CGHeroInstance * h) const
{}
void IObjectInterface::onHeroLeave(const CGHeroInstance * h) const
{}
void IObjectInterface::newTurn(CRandomGenerator & rand) const
{}
void IObjectInterface::initObj(CRandomGenerator & rand)
{}
void IObjectInterface::setProperty( ui8 what, ui32 val )
{}
bool IObjectInterface::wasVisited (PlayerColor player) const
{
return false;
}
bool IObjectInterface::wasVisited (const CGHeroInstance * h) const
{
return false;
}
void IObjectInterface::postInit()
{}
void IObjectInterface::preInit()
{}
void IObjectInterface::battleFinished(const CGHeroInstance *hero, const BattleResult &result) const
{}
void IObjectInterface::blockingDialogAnswered(const CGHeroInstance *hero, ui32 answer) const
{}
void IObjectInterface::garrisonDialogClosed(const CGHeroInstance *hero) const
{}
void IObjectInterface::heroLevelUpDone(const CGHeroInstance *hero) const
{}
CObjectHandler::CObjectHandler()
{
logGlobal->trace("\t\tReading resources prices ");
@ -105,324 +27,6 @@ CObjectHandler::CObjectHandler()
logGlobal->trace("\t\tDone loading resource prices!");
}
//TODO: remove constructor
CGObjectInstance::CGObjectInstance():
pos(-1,-1,-1),
ID(Obj::NO_OBJ),
subID(-1),
tempOwner(PlayerColor::UNFLAGGABLE),
blockVisit(false)
{
}
//must be instantiated in .cpp file for access to complete types of all member fields
CGObjectInstance::~CGObjectInstance() = default;
int32_t CGObjectInstance::getObjGroupIndex() const
{
return ID.num;
}
int32_t CGObjectInstance::getObjTypeIndex() const
{
return subID;
}
int3 CGObjectInstance::getPosition() const
{
return pos;
}
int3 CGObjectInstance::getTopVisiblePos() const
{
return pos - appearance->getTopVisibleOffset();
}
void CGObjectInstance::setOwner(const PlayerColor & ow)
{
tempOwner = ow;
}
int CGObjectInstance::getWidth() const//returns width of object graphic in tiles
{
return appearance->getWidth();
}
int CGObjectInstance::getHeight() const //returns height of object graphic in tiles
{
return appearance->getHeight();
}
bool CGObjectInstance::visitableAt(int x, int y) const //returns true if object is visitable at location (x, y) form left top tile of image (x, y in tiles)
{
return appearance->isVisitableAt(pos.x - x, pos.y - y);
}
bool CGObjectInstance::blockingAt(int x, int y) const
{
return appearance->isBlockedAt(pos.x - x, pos.y - y);
}
bool CGObjectInstance::coveringAt(int x, int y) const
{
return appearance->isVisibleAt(pos.x - x, pos.y - y);
}
std::set<int3> CGObjectInstance::getBlockedPos() const
{
std::set<int3> ret;
for(int w=0; w<getWidth(); ++w)
{
for(int h=0; h<getHeight(); ++h)
{
if(appearance->isBlockedAt(w, h))
ret.insert(int3(pos.x - w, pos.y - h, pos.z));
}
}
return ret;
}
std::set<int3> CGObjectInstance::getBlockedOffsets() const
{
return appearance->getBlockedOffsets();
}
void CGObjectInstance::setType(si32 ID, si32 subID)
{
auto position = visitablePos();
auto oldOffset = getVisitableOffset();
auto &tile = cb->gameState()->map->getTile(position);
//recalculate blockvis tiles - new appearance might have different blockmap than before
cb->gameState()->map->removeBlockVisTiles(this, true);
auto handler = VLC->objtypeh->getHandlerFor(ID, subID);
if(!handler)
{
logGlobal->error("Unknown object type %d:%d at %s", ID, subID, visitablePos().toString());
return;
}
if(!handler->getTemplates(tile.terType->getId()).empty())
{
appearance = handler->getTemplates(tile.terType->getId())[0];
}
else
{
logGlobal->warn("Object %d:%d at %s has no templates suitable for terrain %s", ID, subID, visitablePos().toString(), tile.terType->getNameTranslated());
appearance = handler->getTemplates()[0]; // get at least some appearance since alternative is crash
}
if(this->ID == Obj::PRISON && ID == Obj::HERO)
{
auto newOffset = getVisitableOffset();
// FIXME: potentially unused code - setType is NOT called when releasing hero from prison
// instead, appearance update & pos adjustment occurs in GiveHero::applyGs
// adjust position since hero and prison may have different visitable offset
pos = pos - oldOffset + newOffset;
}
this->ID = Obj(ID);
this->subID = subID;
cb->gameState()->map->addBlockVisTiles(this);
}
void CGObjectInstance::initObj(CRandomGenerator & rand)
{
switch(ID)
{
case Obj::TAVERN:
blockVisit = true;
break;
}
}
void CGObjectInstance::setProperty( ui8 what, ui32 val )
{
setPropertyDer(what, val); // call this before any actual changes (needed at least for dwellings)
switch(what)
{
case ObjProperty::OWNER:
tempOwner = PlayerColor(val);
break;
case ObjProperty::BLOCKVIS:
blockVisit = val;
break;
case ObjProperty::ID:
ID = Obj(val);
break;
case ObjProperty::SUBID:
subID = val;
break;
}
}
void CGObjectInstance::setPropertyDer( ui8 what, ui32 val )
{}
int3 CGObjectInstance::getSightCenter() const
{
return visitablePos();
}
int CGObjectInstance::getSightRadius() const
{
return 3;
}
int3 CGObjectInstance::getVisitableOffset() const
{
return appearance->getVisitableOffset();
}
void CGObjectInstance::giveDummyBonus(const ObjectInstanceID & heroID, BonusDuration::Type duration) const
{
GiveBonus gbonus;
gbonus.bonus.type = BonusType::NONE;
gbonus.id = heroID.getNum();
gbonus.bonus.duration = duration;
gbonus.bonus.source = BonusSource::OBJECT;
gbonus.bonus.sid = ID;
cb->giveHeroBonus(&gbonus);
}
std::string CGObjectInstance::getObjectName() const
{
return VLC->objtypeh->getObjectName(ID, subID);
}
std::optional<std::string> CGObjectInstance::getAmbientSound() const
{
const auto & sounds = VLC->objtypeh->getObjectSounds(ID, subID).ambient;
if(!sounds.empty())
return sounds.front(); // TODO: Support randomization of ambient sounds
return std::nullopt;
}
std::optional<std::string> CGObjectInstance::getVisitSound() const
{
const auto & sounds = VLC->objtypeh->getObjectSounds(ID, subID).visit;
if(!sounds.empty())
return *RandomGeneratorUtil::nextItem(sounds, CRandomGenerator::getDefault());
return std::nullopt;
}
std::optional<std::string> CGObjectInstance::getRemovalSound() const
{
const auto & sounds = VLC->objtypeh->getObjectSounds(ID, subID).removal;
if(!sounds.empty())
return *RandomGeneratorUtil::nextItem(sounds, CRandomGenerator::getDefault());
return std::nullopt;
}
std::string CGObjectInstance::getHoverText(PlayerColor player) const
{
auto text = getObjectName();
if (tempOwner.isValidPlayer())
text += "\n" + VLC->generaltexth->arraytxt[23 + tempOwner.getNum()];
return text;
}
std::string CGObjectInstance::getHoverText(const CGHeroInstance * hero) const
{
return getHoverText(hero->tempOwner);
}
void CGObjectInstance::onHeroVisit( const CGHeroInstance * h ) const
{
switch(ID)
{
case Obj::HILL_FORT:
{
openWindow(EOpenWindowMode::HILL_FORT_WINDOW,id.getNum(),h->id.getNum());
}
break;
case Obj::SANCTUARY:
{
//You enter the sanctuary and immediately feel as if a great weight has been lifted off your shoulders. You feel safe here.
h->showInfoDialog(114);
}
break;
case Obj::TAVERN:
{
openWindow(EOpenWindowMode::TAVERN_WINDOW,h->id.getNum(),id.getNum());
}
break;
}
}
int3 CGObjectInstance::visitablePos() const
{
return pos - getVisitableOffset();
}
bool CGObjectInstance::isVisitable() const
{
return appearance->isVisitable();
}
bool CGObjectInstance::passableFor(PlayerColor color) const
{
return false;
}
void CGObjectInstance::updateFrom(const JsonNode & data)
{
}
void CGObjectInstance::serializeJson(JsonSerializeFormat & handler)
{
//only save here, loading is handled by map loader
if(handler.saving)
{
handler.serializeString("type", typeName);
handler.serializeString("subtype", subTypeName);
handler.serializeInt("x", pos.x);
handler.serializeInt("y", pos.y);
handler.serializeInt("l", pos.z);
JsonNode app;
appearance->writeJson(app, false);
handler.serializeRaw("template", app, std::nullopt);
}
{
auto options = handler.enterStruct("options");
serializeJsonOptions(handler);
}
}
void CGObjectInstance::afterAddToMap(CMap * map)
{
//nothing here
}
void CGObjectInstance::afterRemoveFromMap(CMap * map)
{
//nothing here
}
void CGObjectInstance::serializeJsonOptions(JsonSerializeFormat & handler)
{
//nothing here
}
void CGObjectInstance::serializeJsonOwner(JsonSerializeFormat & handler)
{
ui8 temp = tempOwner.getNum();
handler.serializeEnum("owner", temp, PlayerColor::NEUTRAL.getNum(), GameConstants::PLAYER_COLOR_NAMES);
if(!handler.saving)
tempOwner = PlayerColor(temp);
}
BattleField CGObjectInstance::getBattlefield() const
{
return VLC->objtypeh->getHandlerFor(ID, subID)->getBattlefield();
}
CGObjectInstanceBySubIdFinder::CGObjectInstanceBySubIdFinder(CGObjectInstance * obj) : obj(obj)
{
@ -433,103 +37,4 @@ bool CGObjectInstanceBySubIdFinder::operator()(CGObjectInstance * obj) const
return this->obj->subID == obj->subID;
}
int3 IBoatGenerator::bestLocation() const
{
std::vector<int3> offsets;
getOutOffsets(offsets);
for (auto & offset : offsets)
{
if(const TerrainTile *tile = IObjectInterface::cb->getTile(o->pos + offset, false)) //tile is in the map
{
if(tile->terType->isWater() && (!tile->blocked || tile->blockingObjects.front()->ID == Obj::BOAT)) //and is water and is not blocked or is blocked by boat
return o->pos + offset;
}
}
return int3 (-1,-1,-1);
}
IBoatGenerator::EGeneratorState IBoatGenerator::shipyardStatus() const
{
int3 tile = bestLocation();
const TerrainTile *t = IObjectInterface::cb->getTile(tile);
if(!t)
return TILE_BLOCKED; //no available water
else if(t->blockingObjects.empty())
return GOOD; //OK
else if(t->blockingObjects.front()->ID == Obj::BOAT)
return BOAT_ALREADY_BUILT; //blocked with boat
else
return TILE_BLOCKED; //blocked
}
BoatId IBoatGenerator::getBoatType() const
{
//We make good ships by default
return EBoatId::BOAT_GOOD;
}
IBoatGenerator::IBoatGenerator(const CGObjectInstance *O)
: o(O)
{
}
void IBoatGenerator::getProblemText(MetaString &out, const CGHeroInstance *visitor) const
{
switch(shipyardStatus())
{
case BOAT_ALREADY_BUILT:
out.addTxt(MetaString::GENERAL_TXT, 51);
break;
case TILE_BLOCKED:
if(visitor)
{
out.addTxt(MetaString::GENERAL_TXT, 134);
out.addReplacement(visitor->getNameTranslated());
}
else
out.addTxt(MetaString::ADVOB_TXT, 189);
break;
case NO_WATER:
logGlobal->error("Shipyard without water! %s \t %d", o->pos.toString(), o->id.getNum());
return;
}
}
void IShipyard::getBoatCost(TResources & cost) const
{
cost[EGameResID::WOOD] = 10;
cost[EGameResID::GOLD] = 1000;
}
IShipyard::IShipyard(const CGObjectInstance *O)
: IBoatGenerator(O)
{
}
IShipyard * IShipyard::castFrom( CGObjectInstance *obj )
{
if(!obj)
return nullptr;
if(obj->ID == Obj::TOWN)
{
return dynamic_cast<CGTownInstance *>(obj);
}
else if(obj->ID == Obj::SHIPYARD)
{
return dynamic_cast<CGShipyard *>(obj);
}
else
{
return nullptr;
}
}
const IShipyard * IShipyard::castFrom( const CGObjectInstance *obj )
{
return castFrom(const_cast<CGObjectInstance*>(obj));
}
VCMI_LIB_NAMESPACE_END

View File

@ -9,236 +9,12 @@
*/
#pragma once
#include "ObjectTemplate.h"
#include "../int3.h"
#include "../NetPacksBase.h"
#include "../ResourceSet.h"
#include "../bonuses/Bonus.h"
#include "../GameConstants.h"
VCMI_LIB_NAMESPACE_BEGIN
class CGHeroInstance;
class IGameCallback;
class CGObjectInstance;
struct MetaString;
struct BattleResult;
class JsonSerializeFormat;
class CRandomGenerator;
class CMap;
class JsonNode;
// This one teleport-specific, but has to be available everywhere in callbacks and netpacks
// For now it's will be there till teleports code refactored and moved into own file
using TTeleportExitsList = std::vector<std::pair<ObjectInstanceID, int3>>;
class DLL_LINKAGE IObjectInterface
{
public:
static IGameCallback *cb;
virtual ~IObjectInterface() = default;
virtual int32_t getObjGroupIndex() const = 0;
virtual int32_t getObjTypeIndex() const = 0;
virtual PlayerColor getOwner() const = 0;
virtual int3 visitablePos() const = 0;
virtual int3 getPosition() const = 0;
virtual void onHeroVisit(const CGHeroInstance * h) const;
virtual void onHeroLeave(const CGHeroInstance * h) const;
virtual void newTurn(CRandomGenerator & rand) const;
virtual void initObj(CRandomGenerator & rand); //synchr
virtual void setProperty(ui8 what, ui32 val);//synchr
//Called when queries created DURING HERO VISIT are resolved
//First parameter is always hero that visited object and triggered the query
virtual void battleFinished(const CGHeroInstance *hero, const BattleResult &result) const;
virtual void blockingDialogAnswered(const CGHeroInstance *hero, ui32 answer) const;
virtual void garrisonDialogClosed(const CGHeroInstance *hero) const;
virtual void heroLevelUpDone(const CGHeroInstance *hero) const;
//unified helper to show info dialog for object owner
virtual void showInfoDialog(const ui32 txtID, const ui16 soundID = 0, EInfoWindowMode mode = EInfoWindowMode::AUTO) const;
//unified helper to show a specific window
static void openWindow(const EOpenWindowMode type, const int id1, const int id2 = -1);
//unified interface, AI helpers
virtual bool wasVisited (PlayerColor player) const;
virtual bool wasVisited (const CGHeroInstance * h) const;
static void preInit(); //called before objs receive their initObj
static void postInit();//called after objs receive their initObj
template <typename Handler> void serialize(Handler &h, const int version)
{
logGlobal->error("IObjectInterface serialized, unexpected, should not happen!");
}
};
class DLL_LINKAGE IBoatGenerator
{
public:
const CGObjectInstance *o;
IBoatGenerator(const CGObjectInstance *O);
virtual ~IBoatGenerator() = default;
virtual BoatId getBoatType() const; //0 - evil (if a ship can be evil...?), 1 - good, 2 - neutral
virtual void getOutOffsets(std::vector<int3> &offsets) const =0; //offsets to obj pos when we boat can be placed
int3 bestLocation() const; //returns location when the boat should be placed
enum EGeneratorState {GOOD, BOAT_ALREADY_BUILT, TILE_BLOCKED, NO_WATER};
EGeneratorState shipyardStatus() const; //0 - can buid, 1 - there is already a boat at dest tile, 2 - dest tile is blocked, 3 - no water
void getProblemText(MetaString &out, const CGHeroInstance *visitor = nullptr) const;
template <typename Handler> void serialize(Handler &h, const int version)
{
h & o;
}
};
class DLL_LINKAGE IShipyard : public IBoatGenerator
{
public:
IShipyard(const CGObjectInstance *O);
virtual void getBoatCost(TResources & cost) const;
static const IShipyard *castFrom(const CGObjectInstance *obj);
static IShipyard *castFrom(CGObjectInstance *obj);
template <typename Handler> void serialize(Handler &h, const int version)
{
h & static_cast<IBoatGenerator&>(*this);
}
};
class DLL_LINKAGE CGObjectInstance : public IObjectInterface
{
public:
/// Position of bottom-right corner of object on map
int3 pos;
/// Type of object, e.g. town, hero, creature.
Obj ID;
/// Subtype of object, depends on type
si32 subID;
/// Current owner of an object (when below PLAYER_LIMIT)
PlayerColor tempOwner;
/// Index of object in map's list of objects
ObjectInstanceID id;
/// Defines appearance of object on map (animation, blocked tiles, blit order, etc)
std::shared_ptr<const ObjectTemplate> appearance;
/// If true hero can visit this object only from neighbouring tiles and can't stand on this object
bool blockVisit;
std::string instanceName;
std::string typeName;
std::string subTypeName;
CGObjectInstance(); //TODO: remove constructor
~CGObjectInstance() override;
int32_t getObjGroupIndex() const override;
int32_t getObjTypeIndex() const override;
/// "center" tile from which the sight distance is calculated
int3 getSightCenter() const;
PlayerColor getOwner() const override
{
return this->tempOwner;
}
void setOwner(const PlayerColor & ow);
/** APPEARANCE ACCESSORS **/
int getWidth() const; //returns width of object graphic in tiles
int getHeight() const; //returns height of object graphic in tiles
bool visitableAt(int x, int y) const; //returns true if object is visitable at location (x, y) (h3m pos)
int3 visitablePos() const override;
int3 getPosition() const override;
int3 getTopVisiblePos() const;
bool blockingAt(int x, int y) const; //returns true if object is blocking location (x, y) (h3m pos)
bool coveringAt(int x, int y) 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
bool isVisitable() const; //returns true if object is visitable
virtual BattleField getBattlefield() const;
virtual bool isTile2Terrain() const { return false; }
std::optional<std::string> getAmbientSound() const;
std::optional<std::string> getVisitSound() const;
std::optional<std::string> getRemovalSound() const;
/** VIRTUAL METHODS **/
/// Returns true if player can pass through visitable tiles of this object
virtual bool passableFor(PlayerColor color) const;
/// Range of revealed map around this object, counting from getSightCenter()
virtual int getSightRadius() const;
/// returns (x,y,0) offset to a visitable tile of object
virtual int3 getVisitableOffset() const;
/// Called mostly during map randomization to turn random object into a regular one (e.g. "Random Monster" into "Pikeman")
virtual void setType(si32 ID, si32 subID);
/// returns text visible in status bar with specific hero/player active.
/// Returns generic name of object, without any player-specific info
virtual std::string getObjectName() const;
/// Returns hover name for situation when there are no selected heroes. Default = object name
virtual std::string getHoverText(PlayerColor player) const;
/// Returns hero-specific hover name, including visited/not visited info. Default = player-specific name
virtual std::string getHoverText(const CGHeroInstance * hero) const;
/** OVERRIDES OF IObjectInterface **/
void initObj(CRandomGenerator & rand) override;
void onHeroVisit(const CGHeroInstance * h) const override;
/// method for synchronous update. Note: For new properties classes should override setPropertyDer instead
void setProperty(ui8 what, ui32 val) final;
virtual void afterAddToMap(CMap * map);
virtual void afterRemoveFromMap(CMap * map);
///Entry point of binary (de-)serialization
template <typename Handler> void serialize(Handler &h, const int version)
{
h & instanceName;
h & typeName;
h & subTypeName;
h & pos;
h & ID;
h & subID;
h & id;
h & tempOwner;
h & blockVisit;
h & appearance;
//definfo is handled by map serializer
}
///Entry point of Json (de-)serialization
void serializeJson(JsonSerializeFormat & handler);
virtual void updateFrom(const JsonNode & data);
protected:
/// virtual method that allows synchronously update object state on server and all clients
virtual void setPropertyDer(ui8 what, ui32 val);
/// Gives dummy bonus from this object to hero. Can be used to track visited state
void giveDummyBonus(const ObjectInstanceID & heroID, BonusDuration::Type duration = BonusDuration::ONE_DAY) const;
///Serialize object-type specific options
virtual void serializeJsonOptions(JsonSerializeFormat & handler);
void serializeJsonOwner(JsonSerializeFormat & handler);
};
class int3;
/// function object which can be used to find an object with an specific sub ID
class CGObjectInstanceBySubIdFinder

View File

@ -17,10 +17,10 @@
#include "../CSoundBase.h"
#include "../CGeneralTextHandler.h"
#include "../CHeroHandler.h"
#include "CObjectClassesHandler.h"
#include "MiscObjects.h"
#include "../IGameCallback.h"
#include "../CGameState.h"
#include "../mapObjectConstructors/CObjectClassesHandler.h"
#include "../serializer/JsonSerializeFormat.h"
#include "../CModHandler.h"
#include "../GameConstants.h"

View File

@ -9,18 +9,13 @@
*/
#pragma once
#include "CObjectHandler.h"
#include "CArmedInstance.h"
#include "../ResourceSet.h"
#include "../CCreatureSet.h"
#include "../NetPacksBase.h"
VCMI_LIB_NAMESPACE_BEGIN
class CGCreature;
class DLL_LINKAGE CQuest final
{
mutable std::unordered_map<ArtifactID, unsigned, ArtifactID::hash> artifactsRequirements; // artifact ID -> required count

View File

@ -10,12 +10,13 @@
#include "StdInc.h"
#include "CRewardableObject.h"
#include "../mapObjects/CObjectClassesHandler.h"
#include "../CGameState.h"
#include "../CGeneralTextHandler.h"
#include "../CPlayerState.h"
#include "../IGameCallback.h"
#include "../NetPacks.h"
#include "../mapObjectConstructors/AObjectTypeHandler.h"
#include "../mapObjectConstructors/CObjectClassesHandler.h"
VCMI_LIB_NAMESPACE_BEGIN

179
lib/mapObjects/IMarket.cpp Normal file
View File

@ -0,0 +1,179 @@
/*
* IMarket.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 "IMarket.h"
#include "CArtHandler.h"
#include "CCreatureHandler.h"
#include "CGObjectInstance.h"
#include "CObjectHandler.h"
#include "../VCMI_Lib.h"
VCMI_LIB_NAMESPACE_BEGIN
bool IMarket::getOffer(int id1, int id2, int &val1, int &val2, EMarketMode::EMarketMode mode) const
{
switch(mode)
{
case EMarketMode::RESOURCE_RESOURCE:
{
double effectiveness = std::min((getMarketEfficiency() + 1.0) / 20.0, 0.5);
double r = VLC->objh->resVals[id1]; //value of given resource
double g = VLC->objh->resVals[id2] / effectiveness; //value of wanted resource
if(r>g) //if given resource is more expensive than wanted
{
val2 = static_cast<int>(ceil(r / g));
val1 = 1;
}
else //if wanted resource is more expensive
{
val1 = static_cast<int>((g / r) + 0.5);
val2 = 1;
}
}
break;
case EMarketMode::CREATURE_RESOURCE:
{
const double effectivenessArray[] = {0.0, 0.3, 0.45, 0.50, 0.65, 0.7, 0.85, 0.9, 1.0};
double effectiveness = effectivenessArray[std::min(getMarketEfficiency(), 8)];
double r = VLC->creatures()->getByIndex(id1)->getRecruitCost(EGameResID::GOLD); //value of given creature in gold
double g = VLC->objh->resVals[id2] / effectiveness; //value of wanted resource
if(r>g) //if given resource is more expensive than wanted
{
val2 = static_cast<int>(ceil(r / g));
val1 = 1;
}
else //if wanted resource is more expensive
{
val1 = static_cast<int>((g / r) + 0.5);
val2 = 1;
}
}
break;
case EMarketMode::RESOURCE_PLAYER:
val1 = 1;
val2 = 1;
break;
case EMarketMode::RESOURCE_ARTIFACT:
{
double effectiveness = std::min((getMarketEfficiency() + 3.0) / 20.0, 0.6);
double r = VLC->objh->resVals[id1]; //value of offered resource
double g = VLC->artifacts()->getByIndex(id2)->getPrice() / effectiveness; //value of bought artifact in gold
if(id1 != 6) //non-gold prices are doubled
r /= 2;
val1 = std::max(1, static_cast<int>((g / r) + 0.5)); //don't sell arts for less than 1 resource
val2 = 1;
}
break;
case EMarketMode::ARTIFACT_RESOURCE:
{
double effectiveness = std::min((getMarketEfficiency() + 3.0) / 20.0, 0.6);
double r = VLC->artifacts()->getByIndex(id1)->getPrice() * effectiveness;
double g = VLC->objh->resVals[id2];
// if(id2 != 6) //non-gold prices are doubled
// r /= 2;
val1 = 1;
val2 = std::max(1, static_cast<int>((r / g) + 0.5)); //at least one resource is given in return
}
break;
case EMarketMode::CREATURE_EXP:
{
val1 = 1;
val2 = (VLC->creh->objects[id1]->getAIValue() / 40) * 5;
}
break;
case EMarketMode::ARTIFACT_EXP:
{
val1 = 1;
int givenClass = VLC->arth->objects[id1]->getArtClassSerial();
if(givenClass < 0 || givenClass > 3)
{
val2 = 0;
return false;
}
static constexpr int expPerClass[] = {1000, 1500, 3000, 6000};
val2 = expPerClass[givenClass];
}
break;
default:
assert(0);
return false;
}
return true;
}
bool IMarket::allowsTrade(EMarketMode::EMarketMode mode) const
{
return false;
}
int IMarket::availableUnits(EMarketMode::EMarketMode mode, int marketItemSerial) const
{
switch(mode)
{
case EMarketMode::RESOURCE_RESOURCE:
case EMarketMode::ARTIFACT_RESOURCE:
case EMarketMode::CREATURE_RESOURCE:
return -1;
default:
return 1;
}
}
std::vector<int> IMarket::availableItemsIds(EMarketMode::EMarketMode mode) const
{
std::vector<int> ret;
switch(mode)
{
case EMarketMode::RESOURCE_RESOURCE:
case EMarketMode::ARTIFACT_RESOURCE:
case EMarketMode::CREATURE_RESOURCE:
for (int i = 0; i < 7; i++)
ret.push_back(i);
}
return ret;
}
const IMarket * IMarket::castFrom(const CGObjectInstance *obj, bool verbose)
{
auto * imarket = dynamic_cast<const IMarket *>(obj);
if(verbose && !imarket)
logGlobal->error("Cannot cast to IMarket object type %s", obj->typeName);
return imarket;
}
IMarket::IMarket()
{
}
std::vector<EMarketMode::EMarketMode> IMarket::availableModes() const
{
std::vector<EMarketMode::EMarketMode> ret;
for (int i = 0; i < EMarketMode::MARTKET_AFTER_LAST_PLACEHOLDER; i++)
if(allowsTrade(static_cast<EMarketMode::EMarketMode>(i)))
ret.push_back(static_cast<EMarketMode::EMarketMode>(i));
return ret;
}
VCMI_LIB_NAMESPACE_END

35
lib/mapObjects/IMarket.h Normal file
View File

@ -0,0 +1,35 @@
/*
* IMarket.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 "../GameConstants.h"
VCMI_LIB_NAMESPACE_BEGIN
class CGObjectInstance;
class DLL_LINKAGE IMarket
{
public:
IMarket();
virtual ~IMarket() {}
virtual int getMarketEfficiency() const = 0;
virtual bool allowsTrade(EMarketMode::EMarketMode mode) const;
virtual int availableUnits(EMarketMode::EMarketMode mode, int marketItemSerial) const; //-1 if unlimited
virtual std::vector<int> availableItemsIds(EMarketMode::EMarketMode mode) const;
bool getOffer(int id1, int id2, int &val1, int &val2, EMarketMode::EMarketMode mode) const; //val1 - how many units of id1 player has to give to receive val2 units
std::vector<EMarketMode::EMarketMode> availableModes() const;
static const IMarket *castFrom(const CGObjectInstance *obj, bool verbose = true);
};
VCMI_LIB_NAMESPACE_END

View File

@ -0,0 +1,188 @@
/*
* IObjectInterface.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 "IObjectInterface.h"
#include "CGTownInstance.h"
#include "MiscObjects.h"
#include "../NetPacks.h"
#include "../IGameCallback.h"
#include "../TerrainHandler.h"
VCMI_LIB_NAMESPACE_BEGIN
IGameCallback * IObjectInterface::cb = nullptr;
///helpers
void IObjectInterface::openWindow(const EOpenWindowMode type, const int id1, const int id2)
{
OpenWindow ow;
ow.window = type;
ow.id1 = id1;
ow.id2 = id2;
IObjectInterface::cb->sendAndApply(&ow);
}
void IObjectInterface::showInfoDialog(const ui32 txtID, const ui16 soundID, EInfoWindowMode mode) const
{
InfoWindow iw;
iw.soundID = soundID;
iw.player = getOwner();
iw.type = mode;
iw.text.addTxt(MetaString::ADVOB_TXT,txtID);
IObjectInterface::cb->sendAndApply(&iw);
}
///IObjectInterface
void IObjectInterface::onHeroVisit(const CGHeroInstance * h) const
{}
void IObjectInterface::onHeroLeave(const CGHeroInstance * h) const
{}
void IObjectInterface::newTurn(CRandomGenerator & rand) const
{}
void IObjectInterface::initObj(CRandomGenerator & rand)
{}
void IObjectInterface::setProperty( ui8 what, ui32 val )
{}
bool IObjectInterface::wasVisited (PlayerColor player) const
{
return false;
}
bool IObjectInterface::wasVisited (const CGHeroInstance * h) const
{
return false;
}
void IObjectInterface::postInit()
{}
void IObjectInterface::preInit()
{}
void IObjectInterface::battleFinished(const CGHeroInstance *hero, const BattleResult &result) const
{}
void IObjectInterface::blockingDialogAnswered(const CGHeroInstance *hero, ui32 answer) const
{}
void IObjectInterface::garrisonDialogClosed(const CGHeroInstance *hero) const
{}
void IObjectInterface::heroLevelUpDone(const CGHeroInstance *hero) const
{}
int3 IBoatGenerator::bestLocation() const
{
std::vector<int3> offsets;
getOutOffsets(offsets);
for (auto & offset : offsets)
{
if(const TerrainTile *tile = IObjectInterface::cb->getTile(o->pos + offset, false)) //tile is in the map
{
if(tile->terType->isWater() && (!tile->blocked || tile->blockingObjects.front()->ID == Obj::BOAT)) //and is water and is not blocked or is blocked by boat
return o->pos + offset;
}
}
return int3 (-1,-1,-1);
}
IBoatGenerator::EGeneratorState IBoatGenerator::shipyardStatus() const
{
int3 tile = bestLocation();
const TerrainTile *t = IObjectInterface::cb->getTile(tile);
if(!t)
return TILE_BLOCKED; //no available water
else if(t->blockingObjects.empty())
return GOOD; //OK
else if(t->blockingObjects.front()->ID == Obj::BOAT)
return BOAT_ALREADY_BUILT; //blocked with boat
else
return TILE_BLOCKED; //blocked
}
BoatId IBoatGenerator::getBoatType() const
{
//We make good ships by default
return EBoatId::BOAT_GOOD;
}
IBoatGenerator::IBoatGenerator(const CGObjectInstance *O)
: o(O)
{
}
void IBoatGenerator::getProblemText(MetaString &out, const CGHeroInstance *visitor) const
{
switch(shipyardStatus())
{
case BOAT_ALREADY_BUILT:
out.addTxt(MetaString::GENERAL_TXT, 51);
break;
case TILE_BLOCKED:
if(visitor)
{
out.addTxt(MetaString::GENERAL_TXT, 134);
out.addReplacement(visitor->getNameTranslated());
}
else
out.addTxt(MetaString::ADVOB_TXT, 189);
break;
case NO_WATER:
logGlobal->error("Shipyard without water! %s \t %d", o->pos.toString(), o->id.getNum());
return;
}
}
void IShipyard::getBoatCost(TResources & cost) const
{
cost[EGameResID::WOOD] = 10;
cost[EGameResID::GOLD] = 1000;
}
IShipyard::IShipyard(const CGObjectInstance *O)
: IBoatGenerator(O)
{
}
IShipyard * IShipyard::castFrom( CGObjectInstance *obj )
{
if(!obj)
return nullptr;
if(obj->ID == Obj::TOWN)
{
return dynamic_cast<CGTownInstance *>(obj);
}
else if(obj->ID == Obj::SHIPYARD)
{
return dynamic_cast<CGShipyard *>(obj);
}
else
{
return nullptr;
}
}
const IShipyard * IShipyard::castFrom( const CGObjectInstance *obj )
{
return castFrom(const_cast<CGObjectInstance*>(obj));
}
VCMI_LIB_NAMESPACE_END

View File

@ -0,0 +1,107 @@
/*
* IObjectInterface.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 "../NetPacksBase.h"
VCMI_LIB_NAMESPACE_BEGIN
struct BattleResult;
class CGObjectInstance;
class CRandomGenerator;
class IGameCallback;
class ResourceSet;
class int3;
class DLL_LINKAGE IObjectInterface
{
public:
static IGameCallback *cb;
virtual ~IObjectInterface() = default;
virtual int32_t getObjGroupIndex() const = 0;
virtual int32_t getObjTypeIndex() const = 0;
virtual PlayerColor getOwner() const = 0;
virtual int3 visitablePos() const = 0;
virtual int3 getPosition() const = 0;
virtual void onHeroVisit(const CGHeroInstance * h) const;
virtual void onHeroLeave(const CGHeroInstance * h) const;
virtual void newTurn(CRandomGenerator & rand) const;
virtual void initObj(CRandomGenerator & rand); //synchr
virtual void setProperty(ui8 what, ui32 val);//synchr
//Called when queries created DURING HERO VISIT are resolved
//First parameter is always hero that visited object and triggered the query
virtual void battleFinished(const CGHeroInstance *hero, const BattleResult &result) const;
virtual void blockingDialogAnswered(const CGHeroInstance *hero, ui32 answer) const;
virtual void garrisonDialogClosed(const CGHeroInstance *hero) const;
virtual void heroLevelUpDone(const CGHeroInstance *hero) const;
//unified helper to show info dialog for object owner
virtual void showInfoDialog(const ui32 txtID, const ui16 soundID = 0, EInfoWindowMode mode = EInfoWindowMode::AUTO) const;
//unified helper to show a specific window
static void openWindow(const EOpenWindowMode type, const int id1, const int id2 = -1);
//unified interface, AI helpers
virtual bool wasVisited (PlayerColor player) const;
virtual bool wasVisited (const CGHeroInstance * h) const;
static void preInit(); //called before objs receive their initObj
static void postInit();//called after objs receive their initObj
template <typename Handler> void serialize(Handler &h, const int version)
{
logGlobal->error("IObjectInterface serialized, unexpected, should not happen!");
}
};
class DLL_LINKAGE IBoatGenerator
{
public:
const CGObjectInstance *o;
IBoatGenerator(const CGObjectInstance *O);
virtual ~IBoatGenerator() = default;
virtual BoatId getBoatType() const; //0 - evil (if a ship can be evil...?), 1 - good, 2 - neutral
virtual void getOutOffsets(std::vector<int3> &offsets) const =0; //offsets to obj pos when we boat can be placed
int3 bestLocation() const; //returns location when the boat should be placed
enum EGeneratorState {GOOD, BOAT_ALREADY_BUILT, TILE_BLOCKED, NO_WATER};
EGeneratorState shipyardStatus() const; //0 - can buid, 1 - there is already a boat at dest tile, 2 - dest tile is blocked, 3 - no water
void getProblemText(MetaString &out, const CGHeroInstance *visitor = nullptr) const;
template <typename Handler> void serialize(Handler &h, const int version)
{
h & o;
}
};
class DLL_LINKAGE IShipyard : public IBoatGenerator
{
public:
IShipyard(const CGObjectInstance *O);
virtual void getBoatCost(ResourceSet & cost) const;
static const IShipyard *castFrom(const CGObjectInstance *obj);
static IShipyard *castFrom(CGObjectInstance *obj);
template <typename Handler> void serialize(Handler &h, const int version)
{
h & static_cast<IBoatGenerator&>(*this);
}
};
VCMI_LIB_NAMESPACE_END

View File

@ -19,7 +19,6 @@
#include "../CModHandler.h"
#include "../CHeroHandler.h"
#include "../CSkillHandler.h"
#include "CObjectClassesHandler.h"
#include "../spells/CSpellHandler.h"
#include "../IGameCallback.h"
#include "../CGameState.h"

View File

@ -9,7 +9,6 @@
*/
#pragma once
#include "CObjectHandler.h"
#include "CArmedInstance.h"
#include "../ResourceSet.h"
@ -17,6 +16,10 @@ VCMI_LIB_NAMESPACE_BEGIN
class CMap;
// This one teleport-specific, but has to be available everywhere in callbacks and netpacks
// For now it's will be there till teleports code refactored and moved into own file
using TTeleportExitsList = std::vector<std::pair<ObjectInstanceID, int3>>;
/// Legacy class, use CRewardableObject instead
class DLL_LINKAGE CTeamVisited: public CGObjectInstance
{

View File

@ -8,7 +8,7 @@
*
*/
#include "StdInc.h"
#include "CObjectClassesHandler.h"
#include "ObjectTemplate.h"
#include "../filesystem/Filesystem.h"
#include "../filesystem/CBinaryReader.h"
@ -16,12 +16,11 @@
#include "../GameConstants.h"
#include "../StringConstants.h"
#include "../CGeneralTextHandler.h"
#include "CObjectHandler.h"
#include "../CModHandler.h"
#include "../JsonNode.h"
#include "../TerrainHandler.h"
#include "CRewardableConstructor.h"
#include "../mapObjectConstructors/CRewardableConstructor.h"
VCMI_LIB_NAMESPACE_BEGIN

View File

@ -18,8 +18,8 @@
#include "../RiverHandler.h"
#include "../RoadHandler.h"
#include "../TerrainHandler.h"
#include "../mapObjects/CObjectClassesHandler.h"
#include "../mapObjects/CGHeroInstance.h"
#include "../mapObjects/ObjectTemplate.h"
#include "../CGeneralTextHandler.h"
#include "../spells/CSpellHandler.h"
#include "../CSkillHandler.h"

View File

@ -10,8 +10,6 @@
#include "StdInc.h"
#include "CMapEditManager.h"
#include "../mapObjects/CObjectClassesHandler.h"
#include "../mapObjects/CGHeroInstance.h"
#include "../VCMI_Lib.h"
#include "CDrawRoadsOperation.h"

View File

@ -29,8 +29,10 @@
#include "../VCMI_Lib.h"
#include "../filesystem/CBinaryReader.h"
#include "../filesystem/Filesystem.h"
#include "../mapObjects/CObjectClassesHandler.h"
#include "../mapObjectConstructors/AObjectTypeHandler.h"
#include "../mapObjectConstructors/CObjectClassesHandler.h"
#include "../mapObjects/MapObjects.h"
#include "../mapObjects/ObjectTemplate.h"
#include "../spells/CSpellHandler.h"
#include <boost/crc.hpp>

View File

@ -23,9 +23,9 @@
#include "../RiverHandler.h"
#include "../RoadHandler.h"
#include "../TerrainHandler.h"
#include "../mapObjectConstructors/AObjectTypeHandler.h"
#include "../mapObjectConstructors/CObjectClassesHandler.h"
#include "../mapObjects/ObjectTemplate.h"
#include "../mapObjects/CObjectHandler.h"
#include "../mapObjects/CObjectClassesHandler.h"
#include "../mapObjects/CGHeroInstance.h"
#include "../mapObjects/CGTownInstance.h"
#include "../spells/CSpellHandler.h"

View File

@ -15,8 +15,10 @@
#include "../VCMI_Lib.h"
#include "../CModHandler.h"
#include "../CTownHandler.h"
#include "../mapObjects/CObjectClassesHandler.h"
#include "../filesystem/Filesystem.h"
#include "../mapObjectConstructors/AObjectTypeHandler.h"
#include "../mapObjectConstructors/CObjectClassesHandler.h"
#include "../mapObjects/ObjectTemplate.h"
VCMI_LIB_NAMESPACE_BEGIN

View File

@ -10,9 +10,10 @@
#include "StdInc.h"
#include "ObstacleProxy.h"
#include "../mapObjects/CObjectClassesHandler.h"
#include "../mapObjects/CObjectHandler.h"
#include "../mapping/CMap.h"
#include "../mapObjectConstructors/AObjectTypeHandler.h"
#include "../mapObjectConstructors/CObjectClassesHandler.h"
#include "../mapObjects/ObjectTemplate.h"
VCMI_LIB_NAMESPACE_BEGIN
@ -213,4 +214,4 @@ void EditorObstaclePlacer::placeObstacles(CRandomGenerator & rand)
finalInsertion(map->getEditManager(), obstacles);
}
VCMI_LIB_NAMESPACE_END
VCMI_LIB_NAMESPACE_END

View File

@ -13,15 +13,16 @@
#include "../NetPacksLobby.h"
#include "../VCMI_Lib.h"
#include "../CArtHandler.h"
#include "../CCreatureSet.h"
#include "../CPlayerState.h"
#include "../CHeroHandler.h"
#include "../CTownHandler.h"
#include "../CModHandler.h" //needed?
#include "../mapObjects/CObjectClassesHandler.h"
#include "../mapObjects/CRewardableConstructor.h"
#include "../mapObjects/CommonConstructors.h"
#include "../mapObjectConstructors/CRewardableConstructor.h"
#include "../mapObjectConstructors/CommonConstructors.h"
#include "../mapObjects/MapObjects.h"
#include "../mapObjects/CGTownBuilding.h"
#include "../mapObjects/ObjectTemplate.h"
#include "../battle/CObstacleInstance.h"
#include "../bonuses/CBonusSystemNode.h"
#include "../bonuses/Limiters.h"

View File

@ -22,7 +22,6 @@
#include "../CTownHandler.h"
#include "../mapping/CCampaignHandler.h"
#include "../NetPacks.h"
#include "../mapObjects/CObjectClassesHandler.h"
#include "../serializer/BinaryDeserializer.h"
#include "../serializer/BinarySerializer.h"

View File

@ -24,7 +24,6 @@
#include "../CTownHandler.h"
#include "../mapping/CCampaignHandler.h"
#include "../NetPacks.h"
#include "../mapObjects/CObjectClassesHandler.h"
#include "../serializer/BinaryDeserializer.h"
#include "../serializer/BinarySerializer.h"

View File

@ -27,7 +27,6 @@
#include "../TerrainHandler.h"
#include "../mapping/CCampaignHandler.h"
#include "../NetPacks.h"
#include "../mapObjects/CObjectClassesHandler.h"
#include "../rmg/CMapGenOptions.h"
#include "../serializer/BinaryDeserializer.h"

View File

@ -22,7 +22,6 @@
#include "../CTownHandler.h"
#include "../mapping/CCampaignHandler.h"
#include "../NetPacks.h"
#include "../mapObjects/CObjectClassesHandler.h"
#include "../serializer/BinaryDeserializer.h"
#include "../serializer/BinarySerializer.h"

View File

@ -24,7 +24,6 @@
#include "../CTownHandler.h"
#include "../mapping/CCampaignHandler.h"
#include "../NetPacks.h"
#include "../mapObjects/CObjectClassesHandler.h"
#include "../serializer/BinaryDeserializer.h"
#include "../serializer/BinarySerializer.h"

View File

@ -22,7 +22,6 @@
#include "../CTownHandler.h"
#include "../mapping/CCampaignHandler.h"
#include "../NetPacks.h"
#include "../mapObjects/CObjectClassesHandler.h"
#include "../serializer/BinaryDeserializer.h"
#include "../serializer/BinarySerializer.h"

View File

@ -22,7 +22,6 @@
#include "../CTownHandler.h"
#include "../mapping/CCampaignHandler.h"
#include "../NetPacks.h"
#include "../mapObjects/CObjectClassesHandler.h"
#include "../serializer/BinaryDeserializer.h"
#include "../serializer/BinarySerializer.h"

View File

@ -12,6 +12,7 @@
#include "Limiter.h"
#include "Reward.h"
#include "NetPacksBase.h"
VCMI_LIB_NAMESPACE_BEGIN

View File

@ -14,15 +14,18 @@
#include "Reward.h"
#include "Configuration.h"
#include "../CCreatureSet.h"
#include "../CRandomGenerator.h"
#include "../StringConstants.h"
#include "../CCreatureHandler.h"
#include "../CModHandler.h"
#include "../NetPacksBase.h"
#include "../JsonRandom.h"
#include "../IGameCallback.h"
#include "../CGeneralTextHandler.h"
#include "../JsonNode.h"
#include "../IGameCallback.h"
#include "../mapObjects/IObjectInterface.h"
VCMI_LIB_NAMESPACE_BEGIN

View File

@ -11,7 +11,7 @@
#pragma once
#include "../JsonNode.h"
#include "../mapObjects/CObjectClassesHandler.h"
#include "../mapObjectConstructors/IObjectInfo.h"
VCMI_LIB_NAMESPACE_BEGIN

View File

@ -10,7 +10,6 @@
#pragma once
#include "../mapObjects/CObjectHandler.h"
#include "../CCreatureSet.h"
#include "../ResourceSet.h"
#include "../spells/ExternalCaster.h"
@ -18,6 +17,8 @@
VCMI_LIB_NAMESPACE_BEGIN
class IGameCallback;
namespace Rewardable
{

View File

@ -10,12 +10,27 @@
#include "StdInc.h"
#include "Limiter.h"
#include "../IGameCallback.h"
#include "../CGameStateFwd.h"
#include "../CPlayerState.h"
#include "../mapObjects/CGHeroInstance.h"
VCMI_LIB_NAMESPACE_BEGIN
Rewardable::Limiter::Limiter()
: dayOfWeek(0)
, daysPassed(0)
, heroExperience(0)
, heroLevel(0)
, manaPercentage(0)
, manaPoints(0)
, primary(GameConstants::PRIMARY_SKILLS, 0)
{
}
Rewardable::Limiter::~Limiter() = default;
bool Rewardable::Limiter::heroAllowed(const CGHeroInstance * hero) const
{
if(dayOfWeek != 0)

View File

@ -10,10 +10,14 @@
#pragma once
#include "../mapObjects/CGHeroInstance.h"
#include "../GameConstants.h"
#include "../ResourceSet.h"
VCMI_LIB_NAMESPACE_BEGIN
class CGHeroInstance;
class CStackBasicDescriptor;
namespace Rewardable {
struct Limiter;
@ -66,15 +70,8 @@ struct DLL_LINKAGE Limiter
/// sub-limiters, none should pass for this limiter to pass
LimitersList noneOf;
Limiter():
dayOfWeek(0),
daysPassed(0),
heroExperience(0),
heroLevel(0),
manaPercentage(0),
manaPoints(0),
primary(GameConstants::PRIMARY_SKILLS, 0)
{}
Limiter();
~Limiter();
bool heroAllowed(const CGHeroInstance * hero) const;

View File

@ -11,8 +11,25 @@
#include "StdInc.h"
#include "Reward.h"
#include "../mapObjects/CGHeroInstance.h"
VCMI_LIB_NAMESPACE_BEGIN
Rewardable::Reward::Reward()
: heroExperience(0)
, heroLevel(0)
, manaDiff(0)
, manaPercentage(-1)
, movePoints(0)
, movePercentage(-1)
, primary(4, 0)
, removeObject(false)
, spellCast(SpellID::NONE, SecSkillLevel::NONE)
{
}
Rewardable::Reward::~Reward() = default;
si32 Rewardable::Reward::calculateManaPoints(const CGHeroInstance * hero) const
{
si32 manaScaled = hero->mana;

View File

@ -10,10 +10,17 @@
#pragma once
#include "../mapObjects/CGHeroInstance.h"
#include "../ResourceSet.h"
#include "../bonuses/Bonus.h"
#include "../CCreatureSet.h"
VCMI_LIB_NAMESPACE_BEGIN
struct Bonus;
struct Component;
class CStackBasicDescriptor;
class CGHeroInstance;
namespace Rewardable
{
@ -78,17 +85,8 @@ struct DLL_LINKAGE Reward
si32 calculateManaPoints(const CGHeroInstance * h) const;
Reward() :
heroExperience(0),
heroLevel(0),
manaDiff(0),
manaPercentage(-1),
movePoints(0),
movePercentage(-1),
primary(4, 0),
removeObject(false),
spellCast(SpellID::NONE, SecSkillLevel::NONE)
{}
Reward();
~Reward();
template <typename Handler> void serialize(Handler &h, const int version)
{

View File

@ -14,12 +14,13 @@
#include "../mapping/MapFormat.h"
#include "../VCMI_Lib.h"
#include "../CGeneralTextHandler.h"
#include "../mapObjectConstructors/AObjectTypeHandler.h"
#include "../mapObjectConstructors/CObjectClassesHandler.h"
#include "../mapping/CMapEditManager.h"
#include "../CTownHandler.h"
#include "../StringConstants.h"
#include "../filesystem/Filesystem.h"
#include "CZonePlacer.h"
#include "../mapObjects/CObjectClassesHandler.h"
#include "TileInfo.h"
#include "Zone.h"
#include "Functions.h"

View File

@ -17,8 +17,8 @@
#include "../TerrainHandler.h"
#include "../CTownHandler.h"
#include "../mapping/CMap.h"
#include "../mapObjects/CommonConstructors.h"
#include "../mapObjects/MapObjects.h" //needed to resolve templates for CommonConstructors.h
#include "../mapObjectConstructors/AObjectTypeHandler.h"
#include "../mapObjectConstructors/CObjectClassesHandler.h"
#include "../VCMI_Lib.h"
VCMI_LIB_NAMESPACE_BEGIN

View File

@ -11,12 +11,12 @@
#include "StdInc.h"
#include "RmgObject.h"
#include "RmgMap.h"
#include "../mapObjects/CObjectHandler.h"
#include "../mapping/CMapEditManager.h"
#include "../mapping/CMap.h"
#include "../VCMI_Lib.h"
#include "../mapObjects/CommonConstructors.h"
#include "../mapObjects/MapObjects.h" //needed to resolve templates for CommonConstructors.h
#include "../mapObjectConstructors/AObjectTypeHandler.h"
#include "../mapObjectConstructors/CObjectClassesHandler.h"
#include "../mapObjects/ObjectTemplate.h"
#include "Functions.h"
#include "../TerrainHandler.h"

View File

@ -13,8 +13,9 @@
#include "../CMapGenerator.h"
#include "../RmgMap.h"
#include "../../TerrainHandler.h"
#include "../../mapObjectConstructors/AObjectTypeHandler.h"
#include "../../mapObjectConstructors/CObjectClassesHandler.h"
#include "../../mapping/CMapEditManager.h"
#include "../../mapObjects/CObjectClassesHandler.h"
#include "../RmgObject.h"
#include "ObjectManager.h"
#include "../Functions.h"

View File

@ -10,8 +10,9 @@
#include "ConnectionsPlacer.h"
#include "../CMapGenerator.h"
#include "../RmgMap.h"
#include "../../mapObjectConstructors/AObjectTypeHandler.h"
#include "../../mapObjectConstructors/CObjectClassesHandler.h"
#include "../../mapping/CMapEditManager.h"
#include "../../mapObjects/CObjectClassesHandler.h"
#include "../RmgPath.h"
#include "../RmgObject.h"
#include "ObjectManager.h"

Some files were not shown because too many files have changed in this diff Show More