Browse Source

Moved banks randomization to server-side with client netpack

Ivan Savenko 1 year ago
parent
commit
1c63fefe02

+ 2 - 0
client/Client.h

@@ -25,6 +25,7 @@ class BinaryDeserializer;
 class BinarySerializer;
 class BattleAction;
 class BattleInfo;
+struct BankConfig;
 
 template<typename T> class CApplier;
 
@@ -214,6 +215,7 @@ public:
 
 	void setObjPropertyValue(ObjectInstanceID objid, ObjProperty prop, int32_t value) override {};
 	void setObjPropertyID(ObjectInstanceID objid, ObjProperty prop, ObjPropertyID identifier) override {};
+	void setBankObjectConfiguration(ObjectInstanceID objid, const BankConfig & configuration) override {};
 	void setRewardableObjectConfiguration(ObjectInstanceID objid, const Rewardable::Configuration & configuration) override {};
 	void setRewardableObjectConfiguration(ObjectInstanceID townInstanceID, BuildingID buildingID, const Rewardable::Configuration & configuration) override{};
 

+ 2 - 0
lib/IGameCallback.h

@@ -27,6 +27,7 @@ struct BlockingDialog;
 struct TeleportDialog;
 struct StackLocation;
 struct ArtifactLocation;
+struct BankConfig;
 class CCreatureSet;
 class CStackBasicDescriptor;
 class CGCreature;
@@ -84,6 +85,7 @@ class DLL_LINKAGE IGameEventCallback
 {
 public:
 	virtual void setObjPropertyValue(ObjectInstanceID objid, ObjProperty prop, int32_t value = 0) = 0;
+	virtual void setBankObjectConfiguration(ObjectInstanceID objid, const BankConfig & configuration) = 0;
 	virtual void setRewardableObjectConfiguration(ObjectInstanceID mapObjectID, const Rewardable::Configuration & configuration) = 0;
 	virtual void setRewardableObjectConfiguration(ObjectInstanceID townInstanceID, BuildingID buildingID, const Rewardable::Configuration & configuration) = 0;
 	virtual void setObjPropertyID(ObjectInstanceID objid, ObjProperty prop, ObjPropertyID identifier) = 0;

+ 8 - 5
lib/mapObjectConstructors/CBankInstanceConstructor.cpp

@@ -37,7 +37,7 @@ void CBankInstanceConstructor::initTypeData(const JsonNode & input)
 	regularUnitPlacement = input["regularUnitPlacement"].Bool();
 }
 
-BankConfig CBankInstanceConstructor::generateConfig(IGameCallback * cb, const JsonNode & level, vstd::RNG & rng) const
+BankConfig CBankInstanceConstructor::generateLevelConfiguration(IGameCallback * cb, const JsonNode & level, vstd::RNG & rng) const
 {
 	BankConfig bc;
 	JsonRandom randomizer(cb);
@@ -60,7 +60,11 @@ void CBankInstanceConstructor::randomizeObject(CBank * bank, vstd::RNG & rng) co
 	bank->blockVisit = blockVisit;
 	bank->coastVisitable = coastVisitable;
 	bank->regularUnitPlacement = regularUnitPlacement;
+	bank->setConfig(generateConfiguration(bank->cb, rng, bank->ID));
+}
 
+BankConfig CBankInstanceConstructor::generateConfiguration(IGameCallback * cb, vstd::RNG & rng, MapObjectID objectID) const
+{
 	si32 totalChance = 0;
 	for(const auto & node : levels)
 		totalChance += static_cast<si32>(node["chance"].Float());
@@ -74,11 +78,10 @@ void CBankInstanceConstructor::randomizeObject(CBank * bank, vstd::RNG & rng) co
 	{
 		cumulativeChance += static_cast<int>(node["chance"].Float());
 		if(selectedChance < cumulativeChance)
-		{
-			bank->setConfig(generateConfig(bank->cb, node, rng));
-			break;
-		}
+			return generateLevelConfiguration(cb, node, rng);
 	}
+
+	throw std::runtime_error("Failed to select bank configuration");
 }
 
 CBankInfo::CBankInfo(const JsonVector & Config) :

+ 3 - 1
lib/mapObjectConstructors/CBankInstanceConstructor.h

@@ -69,7 +69,7 @@ public:
 
 class CBankInstanceConstructor : public CDefaultObjectTypeHandler<CBank>
 {
-	BankConfig generateConfig(IGameCallback * cb, const JsonNode & conf, vstd::RNG & rng) const;
+	BankConfig generateLevelConfiguration(IGameCallback * cb, const JsonNode & conf, vstd::RNG & rng) const;
 
 	JsonVector levels;
 
@@ -92,6 +92,8 @@ public:
 	bool hasNameTextID() const override;
 
 	std::unique_ptr<IObjectInfo> getObjectInfo(std::shared_ptr<const ObjectTemplate> tmpl) const override;
+
+	BankConfig generateConfiguration(IGameCallback * cb, vstd::RNG & rand, MapObjectID objectID) const;
 };
 
 VCMI_LIB_NAMESPACE_END

+ 7 - 6
lib/mapObjects/CBank.cpp

@@ -97,6 +97,8 @@ void CBank::setConfig(const BankConfig & config)
 
 	for(const auto & stack : config.guards)
 		setCreature (SlotID(stacksCount()), stack.type->getId(), stack.count);
+
+	daycounter = 1; //yes, 1 since "today" daycounter won't be incremented
 }
 
 void CBank::setPropertyDer (ObjProperty what, ObjPropertyID identifier)
@@ -106,11 +108,6 @@ void CBank::setPropertyDer (ObjProperty what, ObjPropertyID identifier)
 		case ObjProperty::BANK_DAYCOUNTER: //daycounter
 				daycounter+= identifier.getNum();
 			break;
-		case ObjProperty::BANK_RESET:
-			// FIXME: Object reset must be done by separate netpack from server
-			initObj(cb->gameState()->getRandomGenerator());
-			daycounter = 1; //yes, 1 since "today" daycounter won't be incremented
-			break;
 		case ObjProperty::BANK_CLEAR:
 			bankConfig.reset();
 			break;
@@ -124,7 +121,11 @@ void CBank::newTurn(vstd::RNG & rand) const
 		if (resetDuration != 0)
 		{
 			if (daycounter >= resetDuration)
-				cb->setObjPropertyValue(id, ObjProperty::BANK_RESET); //daycounter 0
+			{
+				auto handler = std::dynamic_pointer_cast<CBankInstanceConstructor>(getObjectHandler());
+				auto config = handler->generateConfiguration(cb, rand, ID);
+				cb->setBankObjectConfiguration(id, config);
+			}
 			else
 				cb->setObjPropertyValue(id, ObjProperty::BANK_DAYCOUNTER, 1); //daycounter++
 		}

+ 2 - 1
lib/mapping/CMapEditManager.cpp

@@ -115,9 +115,10 @@ void CMapUndoManager::setUndoCallback(std::function<void(bool, bool)> functor)
 CMapEditManager::CMapEditManager(CMap * map)
 	: map(map), terrainSel(map), objectSel(map)
 {
-
 }
 
+CMapEditManager::~CMapEditManager() = default;
+
 CMap * CMapEditManager::getMap()
 {
 	return map;

+ 1 - 0
lib/mapping/CMapEditManager.h

@@ -68,6 +68,7 @@ class DLL_LINKAGE CMapEditManager : boost::noncopyable
 {
 public:
 	CMapEditManager(CMap * map);
+	~CMapEditManager();
 	CMap * getMap();
 
 	/// Clears the terrain. The free level is filled with water and the underground level with rock.

+ 1 - 0
lib/networkPacks/NetPackVisitor.h

@@ -36,6 +36,7 @@ public:
 	virtual void visitGamePause(GamePause & pack) {}
 	virtual void visitEntitiesChanged(EntitiesChanged & pack) {}
 	virtual void visitSetRewardableConfiguration(SetRewardableConfiguration & pack) {}
+	virtual void visitSetBankConfiguration(SetBankConfiguration & pack) {}
 	virtual void visitSetResources(SetResources & pack) {}
 	virtual void visitSetPrimSkill(SetPrimSkill & pack) {}
 	virtual void visitSetSecSkill(SetSecSkill & pack) {}

+ 16 - 0
lib/networkPacks/NetPacksLib.cpp

@@ -33,6 +33,7 @@
 #include "StartInfo.h"
 #include "CPlayerState.h"
 #include "TerrainHandler.h"
+#include "mapObjects/CBank.h"
 #include "mapObjects/CGCreature.h"
 #include "mapObjects/CGMarket.h"
 #include "mapObjects/CGTownInstance.h"
@@ -129,6 +130,11 @@ void SetRewardableConfiguration::visitTyped(ICPackVisitor & visitor)
 	visitor.visitSetRewardableConfiguration(*this);
 }
 
+void SetBankConfiguration::visitTyped(ICPackVisitor & visitor)
+{
+	visitor.visitSetBankConfiguration(*this);
+}
+
 void SetResources::visitTyped(ICPackVisitor & visitor)
 {
 	visitor.visitSetResources(*this);
@@ -2448,6 +2454,16 @@ void SetRewardableConfiguration::applyGs(CGameState * gs)
 	rewardablePtr->configuration = configuration;
 }
 
+void SetBankConfiguration::applyGs(CGameState * gs)
+{
+	auto * objectPtr = gs->getObjInstance(objectID);
+	auto * bankPtr = dynamic_cast<CBank *>(objectPtr);
+
+	assert(bankPtr);
+
+	bankPtr->setConfig(configuration);
+}
+
 const CArtifactInstance * ArtSlotInfo::getArt() const
 {
 	if(locked)

+ 0 - 1
lib/networkPacks/ObjProperty.h

@@ -43,7 +43,6 @@ enum class ObjProperty : int8_t
 
 	//creature-bank specific
 	BANK_DAYCOUNTER,
-	BANK_RESET,
 	BANK_CLEAR,
 
 	//object with reward

+ 16 - 0
lib/networkPacks/SetRewardableConfiguration.h

@@ -12,6 +12,7 @@
 #include "NetPacksBase.h"
 
 #include "../rewardable/Configuration.h"
+#include "../mapObjectConstructors/CBankInstanceConstructor.h"
 
 VCMI_LIB_NAMESPACE_BEGIN
 
@@ -32,4 +33,19 @@ struct DLL_LINKAGE SetRewardableConfiguration : public CPackForClient
 	}
 };
 
+struct DLL_LINKAGE SetBankConfiguration : public CPackForClient
+{
+	void applyGs(CGameState * gs);
+	void visitTyped(ICPackVisitor & visitor) override;
+
+	ObjectInstanceID objectID;
+	BankConfig configuration;
+
+	template <typename Handler> void serialize(Handler & h)
+	{
+		h & objectID;
+		h & configuration;
+	}
+};
+
 VCMI_LIB_NAMESPACE_END

+ 1 - 0
lib/registerTypes/RegisterTypesClientPacks.h

@@ -122,6 +122,7 @@ void registerTypesClientPacks(Serializer &s)
 	s.template registerType<CGarrisonOperationPack, BulkSmartRebalanceStacks>();
 
 	s.template registerType<SetRewardableConfiguration, CPackForClient>();
+	s.template registerType<SetBankConfiguration, CPackForClient>();
 }
 
 VCMI_LIB_NAMESPACE_END

+ 8 - 0
server/CGameHandler.cpp

@@ -4377,6 +4377,14 @@ void CGameHandler::setObjPropertyID(ObjectInstanceID objid, ObjProperty prop, Ob
 	sendAndApply(&sob);
 }
 
+void CGameHandler::setBankObjectConfiguration(ObjectInstanceID objid, const BankConfig & configuration)
+{
+	SetBankConfiguration srb;
+	srb.objectID = objid;
+	srb.configuration = configuration;
+	sendAndApply(&srb);
+}
+
 void CGameHandler::setRewardableObjectConfiguration(ObjectInstanceID objid, const Rewardable::Configuration & configuration)
 {
 	SetRewardableConfiguration srb;

+ 1 - 0
server/CGameHandler.h

@@ -169,6 +169,7 @@ public:
 	bool isVisitCoveredByAnotherQuery(const CGObjectInstance *obj, const CGHeroInstance *hero) override;
 	void setObjPropertyValue(ObjectInstanceID objid, ObjProperty prop, int32_t value) override;
 	void setObjPropertyID(ObjectInstanceID objid, ObjProperty prop, ObjPropertyID identifier) override;
+	void setBankObjectConfiguration(ObjectInstanceID objid, const BankConfig & configuration) override;
 	void setRewardableObjectConfiguration(ObjectInstanceID objid, const Rewardable::Configuration & configuration) override;
 	void setRewardableObjectConfiguration(ObjectInstanceID townInstanceID, BuildingID buildingID, const Rewardable::Configuration & configuration) override;
 	void showInfoDialog(InfoWindow * iw) override;