浏览代码

HasChargesLimiter now works in "bonuses" json section

SoundSSGood 3 月之前
父节点
当前提交
76debab846

+ 1 - 9
lib/bonuses/Bonus.h

@@ -11,29 +11,21 @@
 
 
 #include "BonusEnum.h"
 #include "BonusEnum.h"
 #include "BonusCustomTypes.h"
 #include "BonusCustomTypes.h"
-#include "../constants/VariantIdentifier.h"
-#include "../constants/EntityIdentifiers.h"
+#include "Limiters.h"
 #include "../serializer/Serializeable.h"
 #include "../serializer/Serializeable.h"
 #include "../texts/MetaString.h"
 #include "../texts/MetaString.h"
 #include "../filesystem/ResourcePath.h"
 #include "../filesystem/ResourcePath.h"
 
 
 VCMI_LIB_NAMESPACE_BEGIN
 VCMI_LIB_NAMESPACE_BEGIN
 
 
-struct Bonus;
 class IBonusBearer;
 class IBonusBearer;
-class CBonusSystemNode;
-class ILimiter;
 class IPropagator;
 class IPropagator;
 class IUpdater;
 class IUpdater;
-class BonusList;
 class CSelector;
 class CSelector;
 class IGameInfoCallback;
 class IGameInfoCallback;
 
 
-using BonusSubtypeID = VariantIdentifier<BonusCustomSubtype, SpellID, CreatureID, PrimarySkill, TerrainId, GameResID, SpellSchool>;
-using BonusSourceID = VariantIdentifier<BonusCustomSource, SpellID, CreatureID, ArtifactID, ArtifactInstanceID, CampaignScenarioID, SecondarySkill, HeroTypeID, Obj, ObjectInstanceID, BuildingTypeUniqueID, BattleField>;
 using TBonusListPtr = std::shared_ptr<BonusList>;
 using TBonusListPtr = std::shared_ptr<BonusList>;
 using TConstBonusListPtr = std::shared_ptr<const BonusList>;
 using TConstBonusListPtr = std::shared_ptr<const BonusList>;
-using TLimiterPtr = std::shared_ptr<const ILimiter>;
 using TPropagatorPtr = std::shared_ptr<const IPropagator>;
 using TPropagatorPtr = std::shared_ptr<const IPropagator>;
 using TUpdaterPtr = std::shared_ptr<const IUpdater>;
 using TUpdaterPtr = std::shared_ptr<const IUpdater>;
 
 

+ 4 - 0
lib/bonuses/BonusCustomTypes.h

@@ -10,6 +10,7 @@
 #pragma once
 #pragma once
 
 
 #include "../constants/EntityIdentifiers.h"
 #include "../constants/EntityIdentifiers.h"
+#include "../constants/VariantIdentifier.h"
 
 
 VCMI_LIB_NAMESPACE_BEGIN
 VCMI_LIB_NAMESPACE_BEGIN
 
 
@@ -76,4 +77,7 @@ public:
 	static BonusCustomSubtype creatureLevel(int level);
 	static BonusCustomSubtype creatureLevel(int level);
 };
 };
 
 
+using BonusSubtypeID = VariantIdentifier<BonusCustomSubtype, SpellID, CreatureID, PrimarySkill, TerrainId, GameResID, SpellSchool>;
+using BonusSourceID = VariantIdentifier<BonusCustomSource, SpellID, CreatureID, ArtifactID, ArtifactInstanceID, CampaignScenarioID, SecondarySkill, HeroTypeID, Obj, ObjectInstanceID, BuildingTypeUniqueID, BattleField>;
+
 VCMI_LIB_NAMESPACE_END
 VCMI_LIB_NAMESPACE_END

+ 3 - 13
lib/bonuses/Limiters.cpp

@@ -14,13 +14,9 @@
 
 
 #include "../CBonusTypeHandler.h"
 #include "../CBonusTypeHandler.h"
 #include "../GameLibrary.h"
 #include "../GameLibrary.h"
-#include "../entities/faction/CFaction.h"
 #include "../entities/faction/CTownHandler.h"
 #include "../entities/faction/CTownHandler.h"
-#include "../spells/CSpellHandler.h"
 #include "../CCreatureHandler.h"
 #include "../CCreatureHandler.h"
 #include "../CCreatureSet.h"
 #include "../CCreatureSet.h"
-#include "../texts/CGeneralTextHandler.h"
-#include "../CSkillHandler.h"
 #include "../CStack.h"
 #include "../CStack.h"
 #include "../TerrainHandler.h"
 #include "../TerrainHandler.h"
 #include "../constants/StringConstants.h"
 #include "../constants/StringConstants.h"
@@ -81,7 +77,7 @@ static const CCreature * retrieveCreature(const CBonusSystemNode *node)
 	}
 	}
 }
 }
 
 
-ILimiter::EDecision ILimiter::limit(const BonusLimitationContext &context) const /*return true to drop the bonus */
+ILimiter::EDecision ILimiter::limit(const BonusLimitationContext &context) const
 {
 {
 	return ILimiter::EDecision::ACCEPT;
 	return ILimiter::EDecision::ACCEPT;
 }
 }
@@ -596,23 +592,17 @@ HasChargesLimiter::HasChargesLimiter(const uint16_t cost)
 {
 {
 }
 }
 
 
-HasChargesLimiter::HasChargesLimiter(const HasChargesLimiter & inst, const BonusSourceID & id)
-	: HasChargesLimiter(inst)
-{
-	chargesSourceId = id;
-}
-
 ILimiter::EDecision HasChargesLimiter::limit(const BonusLimitationContext & context) const
 ILimiter::EDecision HasChargesLimiter::limit(const BonusLimitationContext & context) const
 {
 {
 	for(const auto & bonus : context.stillUndecided)
 	for(const auto & bonus : context.stillUndecided)
 	{
 	{
-		if(bonus->type == BonusType::ARTIFACT_CHARGE && bonus->sid == chargesSourceId)
+		if(bonus->type == BonusType::ARTIFACT_CHARGE && bonus->sid == context.b.sid)
 			return ILimiter::EDecision::NOT_SURE;
 			return ILimiter::EDecision::NOT_SURE;
 	}
 	}
 
 
 	for(const auto & bonus : context.alreadyAccepted)
 	for(const auto & bonus : context.alreadyAccepted)
 	{
 	{
-		if(bonus->type == BonusType::ARTIFACT_CHARGE && bonus->sid == chargesSourceId)
+		if(bonus->type == BonusType::ARTIFACT_CHARGE && bonus->sid == context.b.sid)
 			return bonus->val >= chargeCost ? ILimiter::EDecision::ACCEPT : ILimiter::EDecision::DISCARD;
 			return bonus->val >= chargeCost ? ILimiter::EDecision::ACCEPT : ILimiter::EDecision::DISCARD;
 	}
 	}
 	return ILimiter::EDecision::DISCARD;
 	return ILimiter::EDecision::DISCARD;

+ 11 - 8
lib/bonuses/Limiters.h

@@ -7,18 +7,21 @@
  * Full text of license available in license.txt file, in main folder
  * Full text of license available in license.txt file, in main folder
  *
  *
  */
  */
+#pragma once
 
 
-#include "Bonus.h"
-
+#include "BonusCustomTypes.h"
+#include "BonusEnum.h"
 #include "../battle/BattleHexArray.h"
 #include "../battle/BattleHexArray.h"
 #include "../serializer/Serializeable.h"
 #include "../serializer/Serializeable.h"
 #include "../constants/Enumerations.h"
 #include "../constants/Enumerations.h"
 
 
 VCMI_LIB_NAMESPACE_BEGIN
 VCMI_LIB_NAMESPACE_BEGIN
 
 
+struct Bonus;
+class BonusList;
+class CBonusSystemNode;
 class CCreature;
 class CCreature;
-
-extern DLL_LINKAGE const std::map<std::string, TLimiterPtr> bonusLimiterMap;
+class JsonNode;
 
 
 struct BonusLimitationContext
 struct BonusLimitationContext
 {
 {
@@ -41,7 +44,7 @@ public:
 
 
 	virtual ~ILimiter() = default;
 	virtual ~ILimiter() = default;
 
 
-	virtual EDecision limit(const BonusLimitationContext &context) const; //0 - accept bonus; 1 - drop bonus; 2 - delay (drops eventually)
+	virtual EDecision limit(const BonusLimitationContext &context) const;
 	virtual std::string toString() const;
 	virtual std::string toString() const;
 	virtual JsonNode toJsonNode() const;
 	virtual JsonNode toJsonNode() const;
 
 
@@ -50,6 +53,9 @@ public:
 	}
 	}
 };
 };
 
 
+using TLimiterPtr = std::shared_ptr<const ILimiter>;
+extern DLL_LINKAGE const std::map<std::string, TLimiterPtr> bonusLimiterMap;
+
 class DLL_LINKAGE AggregateLimiter : public ILimiter
 class DLL_LINKAGE AggregateLimiter : public ILimiter
 {
 {
 protected:
 protected:
@@ -280,17 +286,14 @@ class DLL_LINKAGE HasChargesLimiter : public ILimiter // works with bonuses that
 {
 {
 public:
 public:
 	uint16_t chargeCost;
 	uint16_t chargeCost;
-	BonusSourceID chargesSourceId;
 
 
 	HasChargesLimiter(const uint16_t cost = 1);
 	HasChargesLimiter(const uint16_t cost = 1);
-	HasChargesLimiter(const HasChargesLimiter & inst, const BonusSourceID & id);
 	EDecision limit(const BonusLimitationContext & context) const override;
 	EDecision limit(const BonusLimitationContext & context) const override;
 
 
 	template <typename Handler> void serialize(Handler &h)
 	template <typename Handler> void serialize(Handler &h)
 	{
 	{
 		h & static_cast<ILimiter&>(*this);
 		h & static_cast<ILimiter&>(*this);
 		h & chargeCost;
 		h & chargeCost;
-		h & chargesSourceId;
 	}
 	}
 };
 };
 
 

+ 14 - 0
lib/entities/artifact/CArtHandler.cpp

@@ -259,6 +259,20 @@ std::shared_ptr<CArtifact> CArtHandler::loadFromJson(const std::string & scope,
 		}
 		}
 	}
 	}
 
 
+	// Some bonuses must be located in the instance.
+	for(const auto & b : art->getExportedBonusList())
+	{
+		if(std::dynamic_pointer_cast<const HasChargesLimiter>(b->limiter))
+		{
+			b->source = BonusSource::ARTIFACT;
+			b->duration = BonusDuration::PERMANENT;
+			b->description.appendTextID(art->getNameTextID());
+			b->description.appendRawString(" %+d");
+			art->instanceBonuses.push_back(b);
+			art->removeBonus(b);
+		}
+	}
+
 	return art;
 	return art;
 }
 }
 
 

+ 1 - 6
lib/mapping/CMap.cpp

@@ -871,12 +871,7 @@ CArtifactInstance * CMap::createArtifact(const ArtifactID & artID, const SpellID
 	}
 	}
 
 
 	for (const auto & bonus : art->instanceBonuses)
 	for (const auto & bonus : art->instanceBonuses)
-	{
-		auto instBonus = std::make_shared<Bonus>(*bonus, artInst->getId());
-		if(const auto srcLimiter = std::static_pointer_cast<const HasChargesLimiter>(bonus->limiter))
-			instBonus->limiter = std::make_shared<HasChargesLimiter>(*srcLimiter, artInst->getId());
-		artInst->addNewBonus(instBonus);
-	}
+		artInst->addNewBonus(std::make_shared<Bonus>(*bonus, artInst->getId()));
 
 
 	return artInst;
 	return artInst;
 }
 }

+ 1 - 1
server/CGameHandler.cpp

@@ -4346,7 +4346,7 @@ void CGameHandler::useChargeBasedSpell(const ObjectInstanceID & heroObjectID, co
 		{
 		{
 			const auto * artType = artInst->getType();
 			const auto * artType = artInst->getType();
 			const auto spellCost = artType->getChargeCost(spellID);
 			const auto spellCost = artType->getChargeCost(spellID);
-			if(spellCost.has_value() && artType->getDischargeCondition()== DischargeArtifactCondition::SPELLCAST)
+			if(spellCost.has_value() && spellCost.value() <= artInst->getCharges() && artType->getDischargeCondition() == DischargeArtifactCondition::SPELLCAST)
 			{
 			{
 				chargedArt.emplace(hero->getArtPos(artInst), artInst->getId(), spellCost.value());
 				chargedArt.emplace(hero->getArtPos(artInst), artInst->getId(), spellCost.value());
 			}
 			}