瀏覽代碼

Basic creature joining default behavior configuration

Dydzio 9 月之前
父節點
當前提交
1c1af5c04a

+ 5 - 1
config/gameConfig.json

@@ -440,7 +440,11 @@
 			// NOTE: on HotA maps, this setting has no effect. Value provided in map will be used instead.
 			"allowRandomSpecialWeeks" : true,
 			// if enabled, every creature can get double growth month, ignoring predefined list
-			"allowAllForDoubleMonth" : false
+			"allowAllForDoubleMonth" : false,
+			// if enabled creatures may join player for free, disabling it removes free joining globally unless creature is set to join in map editor
+			"allowJoiningForFree" : true,
+			// percent of stack amount that joins player per each successful join (does not decrease cost when joining for gold), if 0 or lower creatures never join for free or gold
+			"joiningPercentage" : 100
 		},
 		
 		"dwellings" :

+ 3 - 1
config/schemas/gameSettings.json

@@ -87,7 +87,9 @@
 				"weeklyGrowthCap" :         { "type" : "number" },
 				"dailyStackExperience" :    { "type" : "number" },
 				"allowRandomSpecialWeeks" : { "type" : "boolean" },
-				"allowAllForDoubleMonth" :  { "type" : "boolean" }
+				"allowAllForDoubleMonth" :  { "type" : "boolean" },
+				"allowJoiningForFree" :     { "type" : "boolean" },
+				"joiningPercentage" :       { "type" : "number" }
 			}
 		},
 		"dwellings": {

+ 2 - 0
lib/GameSettings.cpp

@@ -57,8 +57,10 @@ const std::vector<GameSettings::SettingOption> GameSettings::settingProperties =
 		{EGameSettings::COMBAT_LAYOUTS,                                   "combat",    "layouts"                              },
 		{EGameSettings::COMBAT_ONE_HEX_TRIGGERS_OBSTACLES,                "combat",    "oneHexTriggersObstacles"              },
 		{EGameSettings::CREATURES_ALLOW_ALL_FOR_DOUBLE_MONTH,             "creatures", "allowAllForDoubleMonth"               },
+		{EGameSettings::CREATURES_ALLOW_JOINING_FOR_FREE,                 "creatures", "allowJoiningForFree"                  },
 		{EGameSettings::CREATURES_ALLOW_RANDOM_SPECIAL_WEEKS,             "creatures", "allowRandomSpecialWeeks"              },
 		{EGameSettings::CREATURES_DAILY_STACK_EXPERIENCE,                 "creatures", "dailyStackExperience"                 },
+		{EGameSettings::CREATURES_JOINING_PERCENTAGE,                     "creatures", "joiningPercentage"                    },
 		{EGameSettings::CREATURES_WEEKLY_GROWTH_CAP,                      "creatures", "weeklyGrowthCap"                      },
 		{EGameSettings::CREATURES_WEEKLY_GROWTH_PERCENT,                  "creatures", "weeklyGrowthPercent"                  },
 		{EGameSettings::DIMENSION_DOOR_EXPOSES_TERRAIN_TYPE,              "spells",    "dimensionDoorExposesTerrainType"      },

+ 2 - 0
lib/IGameSettings.h

@@ -32,6 +32,8 @@ enum class EGameSettings
 	CREATURES_ALLOW_ALL_FOR_DOUBLE_MONTH,
 	CREATURES_ALLOW_RANDOM_SPECIAL_WEEKS,
 	CREATURES_DAILY_STACK_EXPERIENCE,
+	CREATURES_ALLOW_JOINING_FOR_FREE,
+	CREATURES_JOINING_PERCENTAGE,
 	CREATURES_WEEKLY_GROWTH_CAP,
 	CREATURES_WEEKLY_GROWTH_PERCENT,
 	DIMENSION_DOOR_EXPOSES_TERRAIN_TYPE,

+ 13 - 4
lib/mapObjects/CGCreature.cpp

@@ -182,7 +182,7 @@ void CGCreature::onHeroVisit( const CGHeroInstance * h ) const
 			BlockingDialog ynd(true,false);
 			ynd.player = h->tempOwner;
 			ynd.text.appendLocalString(EMetaText::ADVOB_TXT, 86);
-			ynd.text.replaceName(getCreatureID(), getStackCount(SlotID(0)));
+			ynd.text.replaceName(getCreatureID(), getJoiningAmount());
 			cb->showBlockingDialog(this, &ynd);
 			break;
 		}
@@ -195,7 +195,7 @@ void CGCreature::onHeroVisit( const CGHeroInstance * h ) const
 			ynd.player = h->tempOwner;
 			ynd.components.emplace_back(ComponentType::RESOURCE, GameResID(GameResID::GOLD), action);
 			std::string tmp = VLC->generaltexth->advobtxt[90];
-			boost::algorithm::replace_first(tmp, "%d", std::to_string(getStackCount(SlotID(0))));
+			boost::algorithm::replace_first(tmp, "%d", std::to_string(getJoiningAmount()));
 			boost::algorithm::replace_first(tmp, "%d", std::to_string(action));
 			boost::algorithm::replace_first(tmp,"%s",getCreature()->getNamePluralTranslated());
 			ynd.text.appendRawString(tmp);
@@ -215,6 +215,11 @@ const CCreature * CGCreature::getCreature() const
 	return getCreatureID().toCreature();
 }
 
+TQuantity CGCreature::getJoiningAmount() const
+{
+	return std::max(1L, getStackCount(SlotID(0)) * cb->getSettings().getInteger(EGameSettings::CREATURES_JOINING_PERCENTAGE) / 100);
+}
+
 void CGCreature::pickRandomObject(vstd::RNG & rand)
 {
 	switch(ID.toEnum())
@@ -378,9 +383,9 @@ int CGCreature::takenAction(const CGHeroInstance *h, bool allowJoin) const
 	if(charisma < character)
 		return FIGHT;
 
-	if (allowJoin)
+	if (allowJoin && cb->getSettings().getInteger(EGameSettings::CREATURES_JOINING_PERCENTAGE) > 0)
 	{
-		if(diplomacy + sympathy + 1 >= character)
+		if((cb->getSettings().getBoolean(EGameSettings::CREATURES_ALLOW_JOINING_FOR_FREE) || character == Character::COMPLIANT) && diplomacy + sympathy + 1 >= character)
 			return JOIN_FOR_FREE;
 
 		if(diplomacy * 2 + sympathy + 1 >= character)
@@ -448,6 +453,10 @@ void CGCreature::joinDecision(const CGHeroInstance *h, int cost, ui32 accept) co
 			cb->giveResource(h->tempOwner,EGameResID::GOLD,-cost);
 
 		giveReward(h);
+
+		for(std::pair<const SlotID, CStackInstance*> stack : this->stacks)
+			stack.second->count = getJoiningAmount();
+
 		cb->tryJoiningArmy(this, h, true, true);
 	}
 }

+ 1 - 0
lib/mapObjects/CGCreature.h

@@ -51,6 +51,7 @@ public:
 	void blockingDialogAnswered(const CGHeroInstance *hero, int32_t answer) const override;
 	CreatureID getCreatureID() const;
 	const CCreature * getCreature() const;
+	TQuantity getJoiningAmount() const;
 
 	//stack formation depends on position,
 	bool containsUpgradedStack() const;