2
0
Laserlicht 1 жил өмнө
parent
commit
53b7c5da6f

+ 3 - 1
Mods/vcmi/config/vcmi/english.json

@@ -687,5 +687,7 @@
 	"core.bonus.DISINTEGRATE.name": "Disintegrate",
 	"core.bonus.DISINTEGRATE.name": "Disintegrate",
 	"core.bonus.DISINTEGRATE.description": "No corpse remains after death",
 	"core.bonus.DISINTEGRATE.description": "No corpse remains after death",
 	"core.bonus.INVINCIBLE.name": "Invincible",
 	"core.bonus.INVINCIBLE.name": "Invincible",
-	"core.bonus.INVINCIBLE.description": "Cannot be affected by anything"
+	"core.bonus.INVINCIBLE.description": "Cannot be affected by anything",
+	"core.bonus.MECHANICAL.name": "Mechanical",
+	"core.bonus.MECHANICAL.description": "Immunity to many effects, repairable"
 }
 }

+ 2 - 1
client/widgets/MiscWidgets.cpp

@@ -573,7 +573,8 @@ void MoraleLuckBox::set(const AFactionMember * node)
 	boost::algorithm::replace_first(text,"%s",CGI->generaltexth->arraytxt[neutralDescr[morale]-mrlt]);
 	boost::algorithm::replace_first(text,"%s",CGI->generaltexth->arraytxt[neutralDescr[morale]-mrlt]);
 
 
 	if (morale && node && (node->getBonusBearer()->hasBonusOfType(BonusType::UNDEAD)
 	if (morale && node && (node->getBonusBearer()->hasBonusOfType(BonusType::UNDEAD)
-			|| node->getBonusBearer()->hasBonusOfType(BonusType::NON_LIVING)))
+			|| node->getBonusBearer()->hasBonusOfType(BonusType::NON_LIVING)
+			|| node->getBonusBearer()->hasBonusOfType(BonusType::MECHANICAL)))
 	{
 	{
 		text += CGI->generaltexth->arraytxt[113]; //unaffected by morale
 		text += CGI->generaltexth->arraytxt[113]; //unaffected by morale
 		component.value = 0;
 		component.value = 0;

+ 8 - 0
config/artifacts.json

@@ -1995,6 +1995,10 @@
 						"type" : "HAS_ANOTHER_BONUS_LIMITER",
 						"type" : "HAS_ANOTHER_BONUS_LIMITER",
 						"parameters" : [ "NON_LIVING" ]
 						"parameters" : [ "NON_LIVING" ]
 					},
 					},
+					{
+						"type" : "HAS_ANOTHER_BONUS_LIMITER",
+						"parameters" : [ "MECHANICAL" ]
+					},
 					{
 					{
 						"type" : "HAS_ANOTHER_BONUS_LIMITER",
 						"type" : "HAS_ANOTHER_BONUS_LIMITER",
 						"parameters" : [ "GARGOYLE" ]
 						"parameters" : [ "GARGOYLE" ]
@@ -2012,6 +2016,10 @@
 						"type" : "HAS_ANOTHER_BONUS_LIMITER",
 						"type" : "HAS_ANOTHER_BONUS_LIMITER",
 						"parameters" : [ "NON_LIVING" ]
 						"parameters" : [ "NON_LIVING" ]
 					},
 					},
+					{
+						"type" : "HAS_ANOTHER_BONUS_LIMITER",
+						"parameters" : [ "MECHANICAL" ]
+					},
 					{
 					{
 						"type" : "HAS_ANOTHER_BONUS_LIMITER",
 						"type" : "HAS_ANOTHER_BONUS_LIMITER",
 						"parameters" : [ "GARGOYLE" ]
 						"parameters" : [ "GARGOYLE" ]

+ 8 - 0
config/bonuses.json

@@ -399,6 +399,14 @@
 		}
 		}
 	},
 	},
 
 
+	"MECHANICAL":
+	{
+		"graphics":
+		{
+			"icon":  "zvs/Lib1.res/Mechanical"
+		}
+	},
+
 	"RANDOM_SPELLCASTER":
 	"RANDOM_SPELLCASTER":
 	{
 	{
 		"graphics":
 		"graphics":

+ 5 - 0
config/spells/ability.json

@@ -88,6 +88,7 @@
 		"targetCondition" : {
 		"targetCondition" : {
 			"noneOf" : {
 			"noneOf" : {
 				"bonus.NON_LIVING" : "absolute",
 				"bonus.NON_LIVING" : "absolute",
+				"bonus.MECHANICAL" : "absolute",
 				"bonus.SIEGE_WEAPON" : "absolute",
 				"bonus.SIEGE_WEAPON" : "absolute",
 				"bonus.UNDEAD" : "absolute",
 				"bonus.UNDEAD" : "absolute",
 				"bonus.GARGOYLE" : "absolute"
 				"bonus.GARGOYLE" : "absolute"
@@ -159,6 +160,7 @@
 		"targetCondition" : {
 		"targetCondition" : {
 			"noneOf" : {
 			"noneOf" : {
 				"bonus.NON_LIVING" : "normal",
 				"bonus.NON_LIVING" : "normal",
+				"bonus.MECHANICAL" : "normal",
 				"bonus.SIEGE_WEAPON" : "absolute",
 				"bonus.SIEGE_WEAPON" : "absolute",
 				"bonus.UNDEAD" : "normal"
 				"bonus.UNDEAD" : "normal"
 			}
 			}
@@ -238,6 +240,7 @@
 		"targetCondition" : {
 		"targetCondition" : {
 			"noneOf" : {
 			"noneOf" : {
 				"bonus.NON_LIVING" : "absolute",
 				"bonus.NON_LIVING" : "absolute",
+				"bonus.MECHANICAL" : "absolute",
 				"bonus.SIEGE_WEAPON" : "absolute",
 				"bonus.SIEGE_WEAPON" : "absolute",
 				"bonus.UNDEAD" : "absolute",
 				"bonus.UNDEAD" : "absolute",
 				"bonus.GARGOYLE" : "absolute"
 				"bonus.GARGOYLE" : "absolute"
@@ -270,6 +273,7 @@
 		"targetCondition" : {
 		"targetCondition" : {
 			"noneOf" : {
 			"noneOf" : {
 				"bonus.NON_LIVING" : "absolute",
 				"bonus.NON_LIVING" : "absolute",
+				"bonus.MECHANICAL" : "absolute",
 				"bonus.SIEGE_WEAPON" : "absolute",
 				"bonus.SIEGE_WEAPON" : "absolute",
 				"bonus.UNDEAD" : "absolute",
 				"bonus.UNDEAD" : "absolute",
 				"bonus.GARGOYLE" : "absolute"
 				"bonus.GARGOYLE" : "absolute"
@@ -357,6 +361,7 @@
 		"targetCondition" : {
 		"targetCondition" : {
 			"noneOf" : {
 			"noneOf" : {
 				"bonus.NON_LIVING" : "absolute",
 				"bonus.NON_LIVING" : "absolute",
+				"bonus.MECHANICAL" : "absolute",
 				"bonus.SIEGE_WEAPON" : "absolute",
 				"bonus.SIEGE_WEAPON" : "absolute",
 				"bonus.UNDEAD" : "absolute",
 				"bonus.UNDEAD" : "absolute",
 				"bonus.GARGOYLE" : "absolute"
 				"bonus.GARGOYLE" : "absolute"

+ 2 - 0
config/spells/other.json

@@ -531,6 +531,7 @@
 		"targetCondition" : {
 		"targetCondition" : {
 			"noneOf" : {
 			"noneOf" : {
 				"bonus.NON_LIVING" : "absolute",
 				"bonus.NON_LIVING" : "absolute",
+				"bonus.MECHANICAL" : "absolute",
 				"bonus.SIEGE_WEAPON" : "absolute",
 				"bonus.SIEGE_WEAPON" : "absolute",
 				"bonus.UNDEAD" : "absolute",
 				"bonus.UNDEAD" : "absolute",
 				"bonus.GARGOYLE" : "absolute"
 				"bonus.GARGOYLE" : "absolute"
@@ -602,6 +603,7 @@
 		"targetCondition" : {
 		"targetCondition" : {
 			"noneOf" : {
 			"noneOf" : {
 				"bonus.NON_LIVING" : "absolute",
 				"bonus.NON_LIVING" : "absolute",
+				"bonus.MECHANICAL" : "absolute",
 				"bonus.SIEGE_WEAPON" : "absolute",
 				"bonus.SIEGE_WEAPON" : "absolute",
 				"bonus.UNDEAD" : "absolute",
 				"bonus.UNDEAD" : "absolute",
 				"bonus.GARGOYLE" : "absolute"
 				"bonus.GARGOYLE" : "absolute"

+ 8 - 1
config/spells/timed.json

@@ -806,6 +806,7 @@
 			"noneOf" : {
 			"noneOf" : {
 				"bonus.MIND_IMMUNITY" : "normal",
 				"bonus.MIND_IMMUNITY" : "normal",
 				"bonus.NON_LIVING" : "normal",
 				"bonus.NON_LIVING" : "normal",
+				"bonus.MECHANICAL" : "normal",
 				"bonus.SIEGE_WEAPON" : "absolute",
 				"bonus.SIEGE_WEAPON" : "absolute",
 				"bonus.UNDEAD" : "absolute"
 				"bonus.UNDEAD" : "absolute"
 			}
 			}
@@ -859,6 +860,7 @@
 			"noneOf" : {
 			"noneOf" : {
 				"bonus.MIND_IMMUNITY" : "normal",
 				"bonus.MIND_IMMUNITY" : "normal",
 				"bonus.NON_LIVING" : "normal",
 				"bonus.NON_LIVING" : "normal",
+				"bonus.MECHANICAL" : "normal",
 				"bonus.SIEGE_WEAPON" : "absolute",
 				"bonus.SIEGE_WEAPON" : "absolute",
 				"bonus.UNDEAD" : "absolute"
 				"bonus.UNDEAD" : "absolute"
 			}
 			}
@@ -1155,6 +1157,7 @@
 			"noneOf" : {
 			"noneOf" : {
 				"bonus.MIND_IMMUNITY" : "absolute",
 				"bonus.MIND_IMMUNITY" : "absolute",
 				"bonus.NON_LIVING" : "absolute",
 				"bonus.NON_LIVING" : "absolute",
+				"bonus.MECHANICAL" : "absolute",
 				"bonus.SIEGE_WEAPON" : "absolute",
 				"bonus.SIEGE_WEAPON" : "absolute",
 				"bonus.UNDEAD" : "absolute"
 				"bonus.UNDEAD" : "absolute"
 			}
 			}
@@ -1245,6 +1248,7 @@
 			"noneOf" : {
 			"noneOf" : {
 				"bonus.MIND_IMMUNITY" : "normal",
 				"bonus.MIND_IMMUNITY" : "normal",
 				"bonus.NON_LIVING" : "normal",
 				"bonus.NON_LIVING" : "normal",
+				"bonus.MECHANICAL" : "normal",
 				"bonus.SIEGE_WEAPON" : "absolute",
 				"bonus.SIEGE_WEAPON" : "absolute",
 				"bonus.UNDEAD" : "normal"
 				"bonus.UNDEAD" : "normal"
 			}
 			}
@@ -1311,7 +1315,8 @@
 				"bonus.SIEGE_WEAPON":"absolute",
 				"bonus.SIEGE_WEAPON":"absolute",
 				"bonus.MIND_IMMUNITY":"normal",
 				"bonus.MIND_IMMUNITY":"normal",
 				"bonus.UNDEAD":"normal",
 				"bonus.UNDEAD":"normal",
-				"bonus.NON_LIVING":"normal"
+				"bonus.NON_LIVING":"normal",
+				"bonus.MECHANICAL":"normal"
 			}
 			}
 		},
 		},
 		"flags" : {
 		"flags" : {
@@ -1379,6 +1384,7 @@
 			"noneOf" : {
 			"noneOf" : {
 				"bonus.MIND_IMMUNITY" : "normal",
 				"bonus.MIND_IMMUNITY" : "normal",
 				"bonus.NON_LIVING" : "normal",
 				"bonus.NON_LIVING" : "normal",
+				"bonus.MECHANICAL" : "normal",
 				"bonus.SIEGE_WEAPON" : "absolute",
 				"bonus.SIEGE_WEAPON" : "absolute",
 				"bonus.UNDEAD" : "normal"
 				"bonus.UNDEAD" : "normal"
 			}
 			}
@@ -1437,6 +1443,7 @@
 			"noneOf" : {
 			"noneOf" : {
 				"bonus.MIND_IMMUNITY" : "normal",
 				"bonus.MIND_IMMUNITY" : "normal",
 				"bonus.NON_LIVING" : "normal",
 				"bonus.NON_LIVING" : "normal",
+				"bonus.MECHANICAL" : "normal",
 				"bonus.SIEGE_WEAPON" : "absolute",
 				"bonus.SIEGE_WEAPON" : "absolute",
 				"bonus.UNDEAD" : "absolute"
 				"bonus.UNDEAD" : "absolute"
 			}
 			}

+ 1 - 0
config/spells/vcmiAbility.json

@@ -41,6 +41,7 @@
 		"targetCondition" : {
 		"targetCondition" : {
 			"noneOf" : {
 			"noneOf" : {
 				"bonus.NON_LIVING" : "absolute",
 				"bonus.NON_LIVING" : "absolute",
+				"bonus.MECHANICAL" : "absolute",
 				"bonus.SIEGE_WEAPON" : "absolute",
 				"bonus.SIEGE_WEAPON" : "absolute",
 				"bonus.UNDEAD" : "absolute",
 				"bonus.UNDEAD" : "absolute",
 				"bonus.GARGOYLE" : "absolute"
 				"bonus.GARGOYLE" : "absolute"

+ 4 - 0
docs/modders/Bonus/Bonus_Types.md

@@ -402,6 +402,10 @@ Increases starting amount of shots that unit has in battle
 
 
 Affected unit is considered to not be alive and not affected by morale and certain spells
 Affected unit is considered to not be alive and not affected by morale and certain spells
 
 
+### MECHANICAL
+
+Affected unit is considered to not be alive and not affected by morale and certain spells but should be repairable from engineers (factory).
+
 ### GARGOYLE
 ### GARGOYLE
 
 
 Affected unit is considered to be a gargoyle and not affected by certain spells
 Affected unit is considered to be a gargoyle and not affected by certain spells

+ 2 - 1
lib/BasicTypes.cpp

@@ -102,7 +102,7 @@ int AFactionMember::moraleValAndBonusList(TConstBonusListPtr & bonusList) const
 		return maxGoodMorale;
 		return maxGoodMorale;
 	}
 	}
 
 
-	static const auto unaffectedByMoraleSelector = Selector::type()(BonusType::NON_LIVING).Or(Selector::type()(BonusType::UNDEAD))
+	static const auto unaffectedByMoraleSelector = Selector::type()(BonusType::NON_LIVING).Or(Selector::type()(BonusType::MECHANICAL)).Or(Selector::type()(BonusType::UNDEAD))
 													.Or(Selector::type()(BonusType::SIEGE_WEAPON)).Or(Selector::type()(BonusType::NO_MORALE));
 													.Or(Selector::type()(BonusType::SIEGE_WEAPON)).Or(Selector::type()(BonusType::NO_MORALE));
 
 
 	static const std::string cachingStrUn = "AFactionMember::unaffectedByMoraleSelector";
 	static const std::string cachingStrUn = "AFactionMember::unaffectedByMoraleSelector";
@@ -187,6 +187,7 @@ bool ACreature::isLiving() const //TODO: theoreticaly there exists "LIVING" bonu
 	static const std::string cachingStr = "ACreature::isLiving";
 	static const std::string cachingStr = "ACreature::isLiving";
 	static const CSelector selector = Selector::type()(BonusType::UNDEAD)
 	static const CSelector selector = Selector::type()(BonusType::UNDEAD)
 		.Or(Selector::type()(BonusType::NON_LIVING))
 		.Or(Selector::type()(BonusType::NON_LIVING))
+		.Or(Selector::type()(BonusType::MECHANICAL))
 		.Or(Selector::type()(BonusType::GARGOYLE))
 		.Or(Selector::type()(BonusType::GARGOYLE))
 		.Or(Selector::type()(BonusType::SIEGE_WEAPON));
 		.Or(Selector::type()(BonusType::SIEGE_WEAPON));
 
 

+ 1 - 0
lib/bonuses/BonusEnum.h

@@ -180,6 +180,7 @@ class JsonNode;
 	BONUS_NAME(RESOURCES_TOWN_MULTIPLYING_BOOST) /*Bonus that does not account for propagation and gives extra resources per day with amount multiplied by number of owned towns. val - base resource amount to be multiplied times number of owned towns, subtype - resource type*/ \
 	BONUS_NAME(RESOURCES_TOWN_MULTIPLYING_BOOST) /*Bonus that does not account for propagation and gives extra resources per day with amount multiplied by number of owned towns. val - base resource amount to be multiplied times number of owned towns, subtype - resource type*/ \
 	BONUS_NAME(DISINTEGRATE) /* after death no corpse remains */ \
 	BONUS_NAME(DISINTEGRATE) /* after death no corpse remains */ \
 	BONUS_NAME(INVINCIBLE) /* cannot be target of attacks or spells */ \
 	BONUS_NAME(INVINCIBLE) /* cannot be target of attacks or spells */ \
+	BONUS_NAME(MECHANICAL) /*eg. factory creatures, cannot be rised or healed, only neutral morale, repairable by engineer */ \
 	/* end of list */
 	/* end of list */