浏览代码

Hill fort upgrade costs are now loaded from json

Ivan Savenko 2 年之前
父节点
当前提交
a94b68e6aa

+ 2 - 0
cmake_modules/VCMI_lib.cmake

@@ -70,6 +70,7 @@ macro(add_main_lib TARGET_NAME LIBRARY_TYPE)
 		${MAIN_LIB_DIR}/mapObjectConstructors/CObjectClassesHandler.cpp
 		${MAIN_LIB_DIR}/mapObjectConstructors/CommonConstructors.cpp
 		${MAIN_LIB_DIR}/mapObjectConstructors/CRewardableConstructor.cpp
+		${MAIN_LIB_DIR}/mapObjectConstructors/HillFortInstanceConstructor.cpp
 		${MAIN_LIB_DIR}/mapObjectConstructors/ShrineInstanceConstructor.cpp
 
 		${MAIN_LIB_DIR}/mapObjects/CArmedInstance.cpp
@@ -376,6 +377,7 @@ macro(add_main_lib TARGET_NAME LIBRARY_TYPE)
 		${MAIN_LIB_DIR}/mapObjectConstructors/CObjectClassesHandler.h
 		${MAIN_LIB_DIR}/mapObjectConstructors/CommonConstructors.h
 		${MAIN_LIB_DIR}/mapObjectConstructors/CRewardableConstructor.h
+		${MAIN_LIB_DIR}/mapObjectConstructors/HillFortInstanceConstructor.h
 		${MAIN_LIB_DIR}/mapObjectConstructors/IObjectInfo.h
 		${MAIN_LIB_DIR}/mapObjectConstructors/RandomMapInfo.h
 		${MAIN_LIB_DIR}/mapObjectConstructors/ShrineInstanceConstructor.h

+ 9 - 2
config/objects/generic.json

@@ -857,7 +857,14 @@
 					"zoneLimit"	: 1,
 					"value"		: 7000,
 					"rarity"	: 20
-				}
+				},
+				"upgradeCostFactor" : [
+					0,  // level 1
+					25,
+					50,
+					75,
+					100 // level 5+
+				]
 			}
 		}
 	},
@@ -873,7 +880,7 @@
 			}
 		}
 	},
-	"marketOfTime" : { // Unused/not implemented H3 object present on some maps RoE maps
+	"marketOfTime" : { // Unused/not implemented H3 object present on some RoE maps
 		"index" :50,
 		"handler": "generic"
 	},

+ 2 - 2
lib/mapObjectConstructors/CDefaultObjectTypeHandler.h

@@ -39,11 +39,11 @@ public:
 		return createTyped(tmpl);
 	}
 
-	virtual void configureObject(CGObjectInstance * object, CRandomGenerator & rng) const override
+	void configureObject(CGObjectInstance * object, CRandomGenerator & rng) const override
 	{
 	}
 
-	virtual std::unique_ptr<IObjectInfo> getObjectInfo(std::shared_ptr<const ObjectTemplate> tmpl) const override
+	std::unique_ptr<IObjectInfo> getObjectInfo(std::shared_ptr<const ObjectTemplate> tmpl) const override
 	{
 		return nullptr;
 	}

+ 2 - 1
lib/mapObjectConstructors/CObjectClassesHandler.cpp

@@ -25,6 +25,7 @@
 #include "../mapObjectConstructors/CommonConstructors.h"
 #include "../mapObjectConstructors/CBankInstanceConstructor.h"
 #include "../mapObjectConstructors/ShrineInstanceConstructor.h"
+#include "../mapObjectConstructors/HillFortInstanceConstructor.h"
 #include "../mapObjects/CQuest.h"
 #include "../mapObjects/CGPandoraBox.h"
 #include "../mapObjects/ObjectTemplate.h"
@@ -46,6 +47,7 @@ CObjectClassesHandler::CObjectClassesHandler()
 	SET_HANDLER_CLASS("boat", BoatInstanceConstructor);
 	SET_HANDLER_CLASS("market", MarketInstanceConstructor);
 	SET_HANDLER_CLASS("shrine", ShrineInstanceConstructor);
+	SET_HANDLER_CLASS("hillFort", HillFortInstanceConstructor);
 
 	SET_HANDLER_CLASS("static", CObstacleConstructor);
 	SET_HANDLER_CLASS("", CObstacleConstructor);
@@ -87,7 +89,6 @@ CObjectClassesHandler::CObjectClassesHandler()
 	SET_HANDLER("whirlpool", CGWhirlpool);
 	SET_HANDLER("witch", CGWitchHut);
 	SET_HANDLER("terrain", CGTerrainPatch);
-	SET_HANDLER("hillFort", HillFort);
 
 #undef SET_HANDLER_CLASS
 #undef SET_HANDLER

+ 50 - 0
lib/mapObjectConstructors/HillFortInstanceConstructor.cpp

@@ -0,0 +1,50 @@
+/*
+* HillFortInstanceConstructor.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 "HillFortInstanceConstructor.h"
+
+#include "../mapObjects/MiscObjects.h"
+#include "IObjectInfo.h"
+
+VCMI_LIB_NAMESPACE_BEGIN
+
+void HillFortInstanceConstructor::initTypeData(const JsonNode & config)
+{
+	parameters = config;
+}
+
+CGObjectInstance * HillFortInstanceConstructor::create(std::shared_ptr<const ObjectTemplate> tmpl) const
+{
+	HillFort * fort = new HillFort;
+
+	preInitObject(fort);
+
+	if(tmpl)
+		fort->appearance = tmpl;
+
+	return fort;
+}
+
+void HillFortInstanceConstructor::configureObject(CGObjectInstance * object, CRandomGenerator & rng) const
+{
+	HillFort * fort = dynamic_cast<HillFort *>(object);
+
+	if(!fort)
+		throw std::runtime_error("Unexpected object instance in HillFortInstanceConstructor!");
+
+	fort->upgradeCostPercentage = parameters["upgradeCostFactor"].convertTo<std::vector<int>>();
+}
+
+std::unique_ptr<IObjectInfo> HillFortInstanceConstructor::getObjectInfo(std::shared_ptr<const ObjectTemplate> tmpl) const
+{
+	return nullptr;
+}
+
+VCMI_LIB_NAMESPACE_END

+ 34 - 0
lib/mapObjectConstructors/HillFortInstanceConstructor.h

@@ -0,0 +1,34 @@
+/*
+* HillFortInstanceConstructor.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 "AObjectTypeHandler.h"
+
+VCMI_LIB_NAMESPACE_BEGIN
+
+class HillFortInstanceConstructor final : public AObjectTypeHandler
+{
+	JsonNode parameters;
+
+protected:
+	void initTypeData(const JsonNode & config) override;
+	CGObjectInstance * create(std::shared_ptr<const ObjectTemplate> tmpl = nullptr) const override;
+	void configureObject(CGObjectInstance * object, CRandomGenerator & rng) const override;
+	std::unique_ptr<IObjectInfo> getObjectInfo(std::shared_ptr<const ObjectTemplate> tmpl) const override;
+
+public:
+	template <typename Handler> void serialize(Handler &h, const int version)
+	{
+		h & static_cast<AObjectTypeHandler&>(*this);
+		h & parameters;
+	}
+};
+
+VCMI_LIB_NAMESPACE_END

+ 12 - 2
lib/mapObjects/MiscObjects.cpp

@@ -2169,10 +2169,20 @@ void HillFort::onHeroVisit(const CGHeroInstance * h) const
 	openWindow(EOpenWindowMode::HILL_FORT_WINDOW,id.getNum(),h->id.getNum());
 }
 
+void HillFort::initObj(CRandomGenerator & rand)
+{
+	VLC->objtypeh->getHandlerFor(ID, subID)->configureObject(this, rand);
+}
+
 void HillFort::fillUpgradeInfo(UpgradeInfo & info, const CStackInstance &stack) const
 {
-	static const int costModifiers[] = {0, 25, 50, 75, 100}; //we get cheaper upgrades depending on level
-	const int costModifier = costModifiers[std::min<int>(std::max((int)stack.type->getLevel() - 1, 0), std::size(costModifiers) - 1)];
+	int32_t level = stack.type->getLevel();
+	int32_t index = std::clamp<int32_t>(level - 1, 0, upgradeCostPercentage.size() - 1);
+
+	int costModifier = upgradeCostPercentage[index];
+
+	if (costModifier < 0)
+		return; // upgrade not allowed
 
 	for(const auto & nid : stack.type->upgrades)
 	{

+ 13 - 0
lib/mapObjects/MiscObjects.h

@@ -15,6 +15,7 @@
 VCMI_LIB_NAMESPACE_BEGIN
 
 class CMap;
+class HillFortInstanceConstructor;
 
 // 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
@@ -555,9 +556,21 @@ public:
 
 class DLL_LINKAGE HillFort : public CGObjectInstance, public ICreatureUpgrader
 {
+	friend class HillFortInstanceConstructor;
+
+	std::vector<int> upgradeCostPercentage;
+
 protected:
+	void initObj(CRandomGenerator & rand) override;
 	void onHeroVisit(const CGHeroInstance * h) const override;
 	void fillUpgradeInfo(UpgradeInfo & info, const CStackInstance &stack) const override;
+
+public:
+	template <typename Handler> void serialize(Handler &h, const int version)
+	{
+		h & static_cast<CGObjectInstance&>(*this);
+		h & upgradeCostPercentage;
+	}
 };
 
 VCMI_LIB_NAMESPACE_END

+ 4 - 0
lib/registerTypes/RegisterTypes.h

@@ -21,6 +21,8 @@
 #include "../mapObjectConstructors/CRewardableConstructor.h"
 #include "../mapObjectConstructors/CommonConstructors.h"
 #include "../mapObjectConstructors/CBankInstanceConstructor.h"
+#include "../mapObjectConstructors/HillFortInstanceConstructor.h"
+#include "../mapObjectConstructors/ShrineInstanceConstructor.h"
 #include "../mapObjects/MapObjects.h"
 #include "../mapObjects/CGTownBuilding.h"
 #include "../mapObjects/ObjectTemplate.h"
@@ -99,6 +101,8 @@ void registerTypesMapObjectTypes(Serializer &s)
 	s.template registerType<AObjectTypeHandler, BoatInstanceConstructor>();
 	s.template registerType<AObjectTypeHandler, MarketInstanceConstructor>();
 	s.template registerType<AObjectTypeHandler, CObstacleConstructor>();
+	s.template registerType<AObjectTypeHandler, ShrineInstanceConstructor>();
+	s.template registerType<AObjectTypeHandler, HillFortInstanceConstructor>();
 
 #define REGISTER_GENERIC_HANDLER(TYPENAME) s.template registerType<AObjectTypeHandler, CDefaultObjectTypeHandler<TYPENAME> >()