Browse Source

Support for hota victory conditions

Ivan Savenko 2 years ago
parent
commit
d4728f78ce
3 changed files with 525 additions and 139 deletions
  1. 9 0
      Mods/vcmi/config/vcmi/english.json
  2. 484 134
      config/mapOverrides.json
  3. 32 5
      lib/mapping/MapFormatH3M.cpp

+ 9 - 0
Mods/vcmi/config/vcmi/english.json

@@ -169,6 +169,15 @@
 	"vcmi.randomMapTab.widgets.teamAlignmentsLabel"  : "Team Alignments",
 	"vcmi.randomMapTab.widgets.roadTypesLabel"       : "Road Types",
 	
+	// Custom victory conditions for H3 campaigns and HotA maps
+	"vcmi.map.victoryCondition.daysPassed.toOthers" : "The enemy has managed to survive till this day. Victory is theirs!",
+	"vcmi.map.victoryCondition.daysPassed.toSelf" : "Congratulations! You have managed to survive. Victory is yours!",
+	"vcmi.map.victoryCondition.eliminateMonsters.toOthers" : "The enemy has defeated all of the monsters plaguing this land and claims victory!",
+	"vcmi.map.victoryCondition.eliminateMonsters.toSelf" : "Congratulations! You have defeated all of the monsters plaguing this land and can claim victory!",
+	"vcmi.map.victoryCondition.collectArtifacts.message" : "Acquire Three Artifacts"
+	"vcmi.map.victoryCondition.angelicAlliance.toSelf" : "Congratulations! All your enemies have been defeated and you have Angelic Alliance! Victory is yours!"
+	"vcmi.map.victoryCondition.angelicAlliance.message" : "Defeat All Enemies and create Angelic Alliance"
+	
 	// few strings from WoG used by vcmi
 	"vcmi.stackExperience.description" : "» S t a c k   E x p e r i e n c e   D e t a i l s «\n\nCreature Type ................... : %s\nExperience Rank ................. : %s (%i)\nExperience Points ............... : %i\nExperience Points to Next Rank .. : %i\nMaximum Experience per Battle ... : %i%% (%i)\nNumber of Creatures in stack .... : %i\nMaximum New Recruits\n without losing current Rank .... : %i\nExperience Multiplier ........... : %.2f\nUpgrade Multiplier .............. : %.2f\nExperience after Rank 10 ........ : %i\nMaximum New Recruits to remain at\n Rank 10 if at Maximum Experience : %i",
 	"vcmi.stackExperience.rank.0" : "Basic",

+ 484 - 134
config/mapOverrides.json

@@ -31,22 +31,29 @@
 		"defeatIconIndex" : 1,
 		"defeatString" : "core.lcdesc.2",
 		"triggeredEvents" : {
-			"heroesMustSurvive" : {
+			"heroMustSurvive1" : {
 				"condition" : [
 					"allOf",
 					[ "isHuman", { "value" : 1 } ],
-					[ "noneOf",
-						[ "allOf",
-							[ "control", { "position" : [  9, 64, 0 ], "type" : 34 } ],
-							[ "control", { "position" : [ 13, 63, 0 ], "type" : 34 } ]
-						]
-					]
+					[ "noneOf", [ "control", { "position" : [  9, 64, 0 ], "type" : 34 } ] ]
+				],
+				"effect" : {
+					"messageToSend" : "core.genrltxt.5",
+					"type" : "defeat"
+				},
+				"message" : "core.genrltxt.253"
+			},
+			"heroMustSurvive2" : {
+				"condition" : [
+					"allOf",
+					[ "isHuman", { "value" : 1 } ],
+					[ "noneOf", [ "control", { "position" : [ 13, 63, 0 ], "type" : 34 } ] ]
 				],
 				"effect" : {
 					"messageToSend" : "core.genrltxt.5",
 					"type" : "defeat"
 				},
-				"message" : "One of your heroes has suffered defeat - your quest is over!"
+				"message" : "core.genrltxt.253"
 			},
 			"standardDefeat" : {
 				"condition" : [ "daysWithoutTown", { "value" : 7 } ],
@@ -148,7 +155,7 @@
 			}
 		},
 		"victoryIconIndex" : 0,
-		"victoryString" : "Acquire sword, breastplate and shield"
+		"victoryString" : "vcmi.map.victoryCondition.collectArtifacts.message"
 	},
 	"data/ab:3" : { // Maker of Sorrows
 		"defeatIconIndex" : 1,
@@ -194,23 +201,47 @@
 		"defeatIconIndex" : 1,
 		"defeatString" : "core.lcdesc.2",
 		"triggeredEvents" : {
-			"heroesMustSurvive" : {
+			"heroesMustSurvive1" : {
+				"condition" : [
+					"allOf",
+					[ "isHuman", { "value" : 1 } ],
+					[ "noneOf",
+						[ "control", { "position" : [  7, 66, 0 ], "type" : 34 } ] // Catherine
+					]
+				],
+				"effect" : {
+					"messageToSend" : "core.genrltxt.5",
+					"type" : "defeat"
+				},
+				"message" : "core.genrltxt.253"
+			},
+			"heroesMustSurvive2" : {
+				"condition" : [
+					"allOf",
+					[ "isHuman", { "value" : 1 } ],
+					[ "noneOf",
+						[ "control", { "position" : [ 18, 68, 0 ], "type" : 34 } ] // Roland
+					]
+				],
+				"effect" : {
+					"messageToSend" : "core.genrltxt.5",
+					"type" : "defeat"
+				},
+				"message" : "core.genrltxt.253"
+			},
+			"heroesMustSurvive3" : {
 				"condition" : [
 					"allOf",
 					[ "isHuman", { "value" : 1 } ],
 					[ "noneOf",
-						[ "allOf",
-							[ "control", { "position" : [  7, 66, 0 ], "type" : 34 } ], // Catherine
-							[ "control", { "position" : [ 18, 68, 0 ], "type" : 34 } ], // Roland
-							[ "control", { "position" : [ 58, 12, 0 ], "type" : 34 } ]  //Gelu
-						]
+						[ "control", { "position" : [ 58, 12, 0 ], "type" : 34 } ]  //Gelu
 					]
 				],
 				"effect" : {
 					"messageToSend" : "core.genrltxt.5",
 					"type" : "defeat"
 				},
-				"message" : "One of your heroes has suffered defeat - your quest is over!"
+				"message" : "core.genrltxt.253"
 			},
 			"specialVictory" : {
 				"condition" : [
@@ -240,23 +271,47 @@
 		"defeatIconIndex" : 2,
 		"defeatString" : "core.lcdesc.3",
 		"triggeredEvents" : {
-			"heroesMustSurvive" : {
+			"heroesMustSurvive1" : {
+				"condition" : [
+					"allOf",
+					[ "isHuman", { "value" : 1 } ],
+					[ "noneOf",
+						[ "control", { "position" : [  4,  3, 0 ], "type" : 34 } ] // Gelu
+					]
+				],
+				"effect" : {
+					"messageToSend" : "core.genrltxt.5",
+					"type" : "defeat"
+				},
+				"message" : "core.genrltxt.253"
+			},
+			"heroesMustSurvive2" : {
+				"condition" : [
+					"allOf",
+					[ "isHuman", { "value" : 1 } ],
+					[ "noneOf",
+						[ "control", { "position" : [ 12, 63, 0 ], "type" : 34 } ] // Catherine
+					]
+				],
+				"effect" : {
+					"messageToSend" : "core.genrltxt.5",
+					"type" : "defeat"
+				},
+				"message" : "core.genrltxt.253"
+			},
+			"heroesMustSurvive3" : {
 				"condition" : [
 					"allOf",
 					[ "isHuman", { "value" : 1 } ],
 					[ "noneOf",
-						[ "allOf",
-							[ "control", { "position" : [  4,  3, 0 ], "type" : 34 } ], // Gelu
-							[ "control", { "position" : [ 12, 63, 0 ], "type" : 34 } ], // Catherine
-							[ "control", { "position" : [ 63, 51, 0 ], "type" : 34 } ]  // Roland
-						]
+						[ "control", { "position" : [ 63, 51, 0 ], "type" : 34 } ]  // Roland
 					]
 				],
 				"effect" : {
 					"messageToSend" : "core.genrltxt.5",
 					"type" : "defeat"
 				},
-				"message" : "One of your heroes has suffered defeat - your quest is over!"
+				"message" : "core.genrltxt.253"
 			},
 			"specialDefeat" : {
 				"condition" : [
@@ -494,24 +549,61 @@
 		"defeatIconIndex" : 2,
 		"defeatString" : "core.lcdesc.3",
 		"triggeredEvents" : {
-			"heroesMustSurvive" : {
+			"heroesMustSurvive1" : {
+				"condition" : [
+					"allOf",
+					[ "isHuman", { "value" : 1 } ],
+					[ "noneOf",
+						[ "control", { "position" : [ 10, 59, 0 ], "type" : 34 } ]
+					]
+				],
+				"effect" : {
+					"messageToSend" : "core.genrltxt.5",
+					"type" : "defeat"
+				},
+				"message" : "core.genrltxt.253"
+			},
+			"heroesMustSurvive2" : {
+				"condition" : [
+					"allOf",
+					[ "isHuman", { "value" : 1 } ],
+					[ "noneOf",
+						[ "control", { "position" : [  4, 63, 0 ], "type" : 34 } ]
+					]
+				],
+				"effect" : {
+					"messageToSend" : "core.genrltxt.5",
+					"type" : "defeat"
+				},
+				"message" : "core.genrltxt.253"
+			},
+			"heroesMustSurvive3" : {
 				"condition" : [
 					"allOf",
 					[ "isHuman", { "value" : 1 } ],
 					[ "noneOf",
-						[ "allOf",
-							[ "control", { "position" : [ 10, 59, 0 ], "type" : 34 } ],
-							[ "control", { "position" : [  4, 63, 0 ], "type" : 34 } ],
-							[ "control", { "position" : [ 15, 63, 0 ], "type" : 34 } ],
-							[ "control", { "position" : [ 10, 66, 0 ], "type" : 34 } ]
-						]
+						[ "control", { "position" : [ 15, 63, 0 ], "type" : 34 } ]
 					]
 				],
 				"effect" : {
 					"messageToSend" : "core.genrltxt.5",
 					"type" : "defeat"
 				},
-				"message" : "One of your heroes has suffered defeat - your quest is over!"
+				"message" : "core.genrltxt.253"
+			},
+			"heroesMustSurvive4" : {
+				"condition" : [
+					"allOf",
+					[ "isHuman", { "value" : 1 } ],
+					[ "noneOf",
+						[ "control", { "position" : [ 10, 66, 0 ], "type" : 34 } ]
+					]
+				],
+				"effect" : {
+					"messageToSend" : "core.genrltxt.5",
+					"type" : "defeat"
+				},
+				"message" : "core.genrltxt.253"
 			},
 			"specialDefeat" : {
 				"condition" : [
@@ -549,24 +641,61 @@
 		"defeatIconIndex" : 1,
 		"defeatString" : "core.lcdesc.2",
 		"triggeredEvents" : {
-			"heroesMustSurvive" : {
+			"heroesMustSurvive1" : {
+				"condition" : [
+					"allOf",
+					[ "isHuman", { "value" : 1 } ],
+					[ "noneOf",
+						[ "control", { "position" : [ 94, 60, 0 ], "type" : 34 } ]
+					]
+				],
+				"effect" : {
+					"messageToSend" : "core.genrltxt.5",
+					"type" : "defeat"
+				},
+				"message" : "core.genrltxt.253"
+			},
+			"heroesMustSurvive2" : {
+				"condition" : [
+					"allOf",
+					[ "isHuman", { "value" : 1 } ],
+					[ "noneOf",
+						[ "control", { "position" : [ 93, 51, 0 ], "type" : 34 } ]
+					]
+				],
+				"effect" : {
+					"messageToSend" : "core.genrltxt.5",
+					"type" : "defeat"
+				},
+				"message" : "core.genrltxt.253"
+			},
+			"heroesMustSurvive3" : {
+				"condition" : [
+					"allOf",
+					[ "isHuman", { "value" : 1 } ],
+					[ "noneOf",
+						[ "control", { "position" : [ 85, 64, 0 ], "type" : 34 } ]
+					]
+				],
+				"effect" : {
+					"messageToSend" : "core.genrltxt.5",
+					"type" : "defeat"
+				},
+				"message" : "core.genrltxt.253"
+			},
+			"heroesMustSurvive4" : {
 				"condition" : [
 					"allOf",
 					[ "isHuman", { "value" : 1 } ],
 					[ "noneOf",
-						[ "allOf",
-							[ "control", { "position" : [ 94, 60, 0 ], "type" : 34 } ],
-							[ "control", { "position" : [ 93, 51, 0 ], "type" : 34 } ],
-							[ "control", { "position" : [ 85, 64, 0 ], "type" : 34 } ],
-							[ "control", { "position" : [100, 63, 0 ], "type" : 34 } ]
-						]
+						[ "control", { "position" : [100, 63, 0 ], "type" : 34 } ]
 					]
 				],
 				"effect" : {
 					"messageToSend" : "core.genrltxt.5",
 					"type" : "defeat"
 				},
-				"message" : "One of your heroes has suffered defeat - your quest is over!"
+				"message" : "core.genrltxt.253"
 			},
 			"standardDefeat" : {
 				"condition" : [ "daysWithoutTown", { "value" : 7 } ],
@@ -592,24 +721,61 @@
 		"defeatIconIndex" : 2,
 		"defeatString" : "core.lcdesc.3",
 		"triggeredEvents" : {
-			"heroesMustSurvive" : {
+			"heroesMustSurvive1" : {
 				"condition" : [
 					"allOf",
 					[ "isHuman", { "value" : 1 } ],
 					[ "noneOf",
-						[ "allOf",
-							[ "control", { "position" : [ 34, 38, 0 ], "type" : 34 } ],
-							[ "control", { "position" : [ 32,  7, 0 ], "type" : 34 } ],
-							[ "control", { "position" : [  8, 63, 0 ], "type" : 34 } ],
-							[ "control", { "position" : [ 65, 63, 0 ], "type" : 34 } ]
-						]
+						[ "control", { "position" : [ 34, 38, 0 ], "type" : 34 } ]
 					]
 				],
 				"effect" : {
 					"messageToSend" : "core.genrltxt.5",
 					"type" : "defeat"
 				},
-				"message" : "One of your heroes has suffered defeat - your quest is over!"
+				"message" : "core.genrltxt.253"
+			},
+			"heroesMustSurvive2" : {
+				"condition" : [
+					"allOf",
+					[ "isHuman", { "value" : 1 } ],
+					[ "noneOf",
+						[ "control", { "position" : [ 32,  7, 0 ], "type" : 34 } ]
+					]
+				],
+				"effect" : {
+					"messageToSend" : "core.genrltxt.5",
+					"type" : "defeat"
+				},
+				"message" : "core.genrltxt.253"
+			},
+			"heroesMustSurvive3" : {
+				"condition" : [
+					"allOf",
+					[ "isHuman", { "value" : 1 } ],
+					[ "noneOf",
+						[ "control", { "position" : [  8, 63, 0 ], "type" : 34 } ]
+					]
+				],
+				"effect" : {
+					"messageToSend" : "core.genrltxt.5",
+					"type" : "defeat"
+				},
+				"message" : "core.genrltxt.253"
+			},
+			"heroesMustSurvive4" : {
+				"condition" : [
+					"allOf",
+					[ "isHuman", { "value" : 1 } ],
+					[ "noneOf",
+						[ "control", { "position" : [ 65, 63, 0 ], "type" : 34 } ]
+					]
+				],
+				"effect" : {
+					"messageToSend" : "core.genrltxt.5",
+					"type" : "defeat"
+				},
+				"message" : "core.genrltxt.253"
 			},
 			"specialDefeat" : {
 				"condition" : [
@@ -634,10 +800,10 @@
 			"specialVictory" : {
 				"condition" : [  "destroy", { "type" : 54} ],
 				"effect" : {
-					"messageToSend" : "core.genrltxt.5",
+					"messageToSend" : "vcmi.map.victoryCondition.eliminateMonsters.toOthers",
 					"type" : "victory"
 				},
-				"message" : "Congratulations! Area around your town is now secure!"
+				"message" : "vcmi.map.victoryCondition.eliminateMonsters.toSelf"
 			}
 		},
 		"victoryIconIndex" : 7,
@@ -730,10 +896,10 @@
 					[  "destroy", { "type" : 54} ]
 				],
 				"effect" : {
-					"messageToSend" : "You has been vanquished!",
+					"messageToSend" : "vcmi.map.victoryCondition.eliminateMonsters.toOthers",
 					"type" : "victory"
 				},
-				"message" : "Congratulations! You have defeated all of the monsters plaguing this land!"
+				"message" : "vcmi.map.victoryCondition.eliminateMonsters.toSelf"
 			}
 
 		},
@@ -819,10 +985,10 @@
 					[ "daysPassed", { "value" : 112 } ]
 				],
 				"effect" : {
-					"messageToSend" : "core.genrltxt.5",
+					"messageToSend" : "vcmi.map.victoryCondition.daysPassed.toOthers",
 					"type" : "victory"
 				},
-				"message" : "Congratulations! You have survived long enough for help to arrive. Victory is yours!"
+				"message" : "vcmi.map.victoryCondition.daysPassed.toSelf"
 			},
 
 		},
@@ -833,22 +999,33 @@
 		"defeatIconIndex" : 1,
 		"defeatString" : "core.lcdesc.2",
 		"triggeredEvents" : {
-			"heroesMustSurvive" : {
+			"heroesMustSurvive1" : {
 				"condition" : [
 					"allOf",
 					[ "isHuman", { "value" : 1 } ],
 					[ "noneOf",
-						[ "allOf",
-							[ "control", { "position" : [ 19, 60, 0 ], "type" : 34 } ],
-							[ "control", { "position" : [ 17, 60, 0 ], "type" : 34 } ]
-						]
+						[ "control", { "position" : [ 19, 60, 0 ], "type" : 34 } ]
 					]
 				],
 				"effect" : {
 					"messageToSend" : "core.genrltxt.5",
 					"type" : "defeat"
 				},
-				"message" : "One of your heroes has suffered defeat - your quest is over!"
+				"message" : "core.genrltxt.253"
+			},
+			"heroesMustSurvive2" : {
+				"condition" : [
+					"allOf",
+					[ "isHuman", { "value" : 1 } ],
+					[ "noneOf",
+						[ "control", { "position" : [ 17, 60, 0 ], "type" : 34 } ]
+					]
+				],
+				"effect" : {
+					"messageToSend" : "core.genrltxt.5",
+					"type" : "defeat"
+				},
+				"message" : "core.genrltxt.253"
 			},
 			"specialVictory" : {
 				"condition" : [ "haveArtifact", { "type" : 54 } ],
@@ -874,22 +1051,33 @@
 		"defeatIconIndex" : 1,
 		"defeatString" : "core.lcdesc.2",
 		"triggeredEvents" : {
-			"heroesMustSurvive" : {
+			"heroesMustSurvive1" : {
 				"condition" : [
 					"allOf",
 					[ "isHuman", { "value" : 1 } ],
 					[ "noneOf",
-						[ "allOf",
-							[ "control", { "position" : [ 25, 30, 0 ], "type" : 34 } ],
-							[ "control", { "position" : [ 25, 30, 0 ], "type" : 34 } ]
-						]
+						[ "control", { "position" : [ 25, 30, 0 ], "type" : 34 } ]
 					]
 				],
 				"effect" : {
 					"messageToSend" : "core.genrltxt.5",
 					"type" : "defeat"
 				},
-				"message" : "One of your heroes has suffered defeat - your quest is over!"
+				"message" : "core.genrltxt.253"
+			},
+			"heroesMustSurvive2" : {
+				"condition" : [
+					"allOf",
+					[ "isHuman", { "value" : 1 } ],
+					[ "noneOf",
+						[ "control", { "position" : [ 25, 30, 0 ], "type" : 34 } ]
+					]
+				],
+				"effect" : {
+					"messageToSend" : "core.genrltxt.5",
+					"type" : "defeat"
+				},
+				"message" : "core.genrltxt.253"
 			},
 			"specialVictory" : {
 				"condition" : [
@@ -919,22 +1107,33 @@
 		"defeatIconIndex" : 1,
 		"defeatString" : "core.lcdesc.2",
 		"triggeredEvents" : {
-			"heroesMustSurvive" : {
+			"heroesMustSurvive1" : {
+				"condition" : [
+					"allOf",
+					[ "isHuman", { "value" : 1 } ],
+					[ "noneOf",
+						[ "control", { "position" : [ 55, 17, 0 ], "type" : 34 } ]
+					]
+				],
+				"effect" : {
+					"messageToSend" : "core.genrltxt.5",
+					"type" : "defeat"
+				},
+				"message" : "core.genrltxt.253"
+			},
+			"heroesMustSurvive2" : {
 				"condition" : [
 					"allOf",
 					[ "isHuman", { "value" : 1 } ],
 					[ "noneOf",
-						[ "allOf",
-							[ "control", { "position" : [ 55, 17, 0 ], "type" : 34 } ],
-							[ "control", { "position" : [ 53, 17, 0 ], "type" : 34 } ]
-						]
+						[ "control", { "position" : [ 53, 17, 0 ], "type" : 34 } ]
 					]
 				],
 				"effect" : {
 					"messageToSend" : "core.genrltxt.5",
 					"type" : "defeat"
 				},
-				"message" : "One of your heroes has suffered defeat - your quest is over!"
+				"message" : "core.genrltxt.253"
 			},
 			"specialVictory" : {
 				"condition" : [
@@ -1124,22 +1323,33 @@
 		"defeatIconIndex" : 1,
 		"defeatString" : "core.lcdesc.2",
 		"triggeredEvents" : {
-			"heroesMustSurvive" : {
+			"heroesMustSurvive1" : {
 				"condition" : [
 					"allOf",
 					[ "isHuman", { "value" : 1 } ],
 					[ "noneOf",
-						[ "allOf",
-							[ "control", { "position" : [ 56, 54, 0 ], "type" : 34 } ],
-							[ "control", { "position" : [ 65, 53, 0 ], "type" : 34 } ]
-						]
+						[ "control", { "position" : [ 56, 54, 0 ], "type" : 34 } ]
 					]
 				],
 				"effect" : {
 					"messageToSend" : "core.genrltxt.5",
 					"type" : "defeat"
 				},
-				"message" : "One of your heroes has suffered defeat - your quest is over!"
+				"message" : "core.genrltxt.253"
+			},
+			"heroesMustSurvive2" : {
+				"condition" : [
+					"allOf",
+					[ "isHuman", { "value" : 1 } ],
+					[ "noneOf",
+						[ "control", { "position" : [ 65, 53, 0 ], "type" : 34 } ]
+					]
+				],
+				"effect" : {
+					"messageToSend" : "core.genrltxt.5",
+					"type" : "defeat"
+				},
+				"message" : "core.genrltxt.253"
 			},
 			"standardDefeat" : {
 				"condition" : [ "daysWithoutTown", { "value" : 7 } ],
@@ -1165,22 +1375,33 @@
 		"defeatIconIndex" : 1,
 		"defeatString" : "core.lcdesc.2",
 		"triggeredEvents" : {
-			"heroesMustSurvive" : {
+			"heroesMustSurvive1" : {
 				"condition" : [
 					"allOf",
 					[ "isHuman", { "value" : 1 } ],
 					[ "noneOf",
-						[ "allOf",
-							[ "control", { "position" : [ 65, 25, 0 ], "type" : 34 } ],
-							[ "control", { "position" : [ 67, 25, 0 ], "type" : 34 } ]
-						]
+						[ "control", { "position" : [ 65, 25, 0 ], "type" : 34 } ]
 					]
 				],
 				"effect" : {
 					"messageToSend" : "core.genrltxt.5",
 					"type" : "defeat"
 				},
-				"message" : "One of your heroes has suffered defeat - your quest is over!"
+				"message" : "core.genrltxt.253"
+			},
+			"heroesMustSurvive2" : {
+				"condition" : [
+					"allOf",
+					[ "isHuman", { "value" : 1 } ],
+					[ "noneOf",
+						[ "control", { "position" : [ 67, 25, 0 ], "type" : 34 } ]
+					]
+				],
+				"effect" : {
+					"messageToSend" : "core.genrltxt.5",
+					"type" : "defeat"
+				},
+				"message" : "core.genrltxt.253"
 			},
 			"standardDefeat" : {
 				"condition" : [ "daysWithoutTown", { "value" : 7 } ],
@@ -1258,22 +1479,33 @@
 		"defeatIconIndex" : 1,
 		"defeatString" : "core.lcdesc.2",
 		"triggeredEvents" : {
-			"heroesMustSurvive" : {
+			"heroesMustSurvive1" : {
+				"condition" : [
+					"allOf",
+					[ "isHuman", { "value" : 1 } ],
+					[ "noneOf",
+						[ "control", { "position" : [ 57, 12, 0 ], "type" : 34 } ]
+					]
+				],
+				"effect" : {
+					"messageToSend" : "core.genrltxt.5",
+					"type" : "defeat"
+				},
+				"message" : "core.genrltxt.253"
+			},
+			"heroesMustSurvive2" : {
 				"condition" : [
 					"allOf",
 					[ "isHuman", { "value" : 1 } ],
 					[ "noneOf",
-						[ "allOf",
-							[ "control", { "position" : [ 57, 12, 0 ], "type" : 34 } ],
-							[ "control", { "position" : [ 25, 11, 0 ], "type" : 34 } ]
-						]
+						[ "control", { "position" : [ 25, 11, 0 ], "type" : 34 } ]
 					]
 				],
 				"effect" : {
 					"messageToSend" : "core.genrltxt.5",
 					"type" : "defeat"
 				},
-				"message" : "One of your heroes has suffered defeat - your quest is over!"
+				"message" : "core.genrltxt.253"
 			},
 			"specialVictory" : {
 				"condition" : [
@@ -1303,22 +1535,33 @@
 		"defeatIconIndex" : 1,
 		"defeatString" : "core.lcdesc.2",
 		"triggeredEvents" : {
-			"heroesMustSurvive" : {
+			"heroesMustSurvive1" : {
 				"condition" : [
 					"allOf",
 					[ "isHuman", { "value" : 1 } ],
 					[ "noneOf",
-						[ "allOf",
-							[ "control", { "position" : [ 54,  6, 0 ], "type" : 34 } ],
-							[ "control", { "position" : [ 13,  6, 0 ], "type" : 34 } ]
-						]
+						[ "control", { "position" : [ 54,  6, 0 ], "type" : 34 } ]
 					]
 				],
 				"effect" : {
 					"messageToSend" : "core.genrltxt.5",
 					"type" : "defeat"
 				},
-				"message" : "One of your heroes has suffered defeat - your quest is over!"
+				"message" : "core.genrltxt.253"
+			},
+			"heroesMustSurvive2" : {
+				"condition" : [
+					"allOf",
+					[ "isHuman", { "value" : 1 } ],
+					[ "noneOf",
+						[ "control", { "position" : [ 13,  6, 0 ], "type" : 34 } ]
+					]
+				],
+				"effect" : {
+					"messageToSend" : "core.genrltxt.5",
+					"type" : "defeat"
+				},
+				"message" : "core.genrltxt.253"
 			},
 			"standardDefeat" : {
 				"condition" : [ "daysWithoutTown", { "value" : 7 } ],
@@ -1344,22 +1587,33 @@
 		"defeatIconIndex" : 1,
 		"defeatString" : "core.lcdesc.2",
 		"triggeredEvents" : {
-			"heroesMustSurvive" : {
+			"heroesMustSurvive1" : {
 				"condition" : [
 					"allOf",
 					[ "isHuman", { "value" : 1 } ],
 					[ "noneOf",
-						[ "allOf",
-							[ "control", { "position" : [ 34, 10, 0 ], "type" : 34 } ],
-							[ "control", { "position" : [ 36, 10, 0 ], "type" : 34 } ]
-						]
+						[ "control", { "position" : [ 34, 10, 0 ], "type" : 34 } ]
 					]
 				],
 				"effect" : {
 					"messageToSend" : "core.genrltxt.5",
 					"type" : "defeat"
 				},
-				"message" : "One of your heroes has suffered defeat - your quest is over!"
+				"message" : "core.genrltxt.253"
+			},
+			"heroesMustSurvive2" : {
+				"condition" : [
+					"allOf",
+					[ "isHuman", { "value" : 1 } ],
+					[ "noneOf",
+						[ "control", { "position" : [ 36, 10, 0 ], "type" : 34 } ]
+					]
+				],
+				"effect" : {
+					"messageToSend" : "core.genrltxt.5",
+					"type" : "defeat"
+				},
+				"message" : "core.genrltxt.253"
 			},
 			"specialVictory" : {
 				"condition" : [
@@ -1389,22 +1643,33 @@
 		"defeatIconIndex" : 3,
 		"defeatString" : "core.lcdesc.0",
 		"triggeredEvents" : {
-			"heroesMustSurvive" : {
+			"heroesMustSurvive1" : {
+				"condition" : [
+					"allOf",
+					[ "isHuman", { "value" : 1 } ],
+					[ "noneOf",
+						[ "control", { "position" : [ 21, 10, 0 ], "type" : 34 } ]
+					]
+				],
+				"effect" : {
+					"messageToSend" : "core.genrltxt.5",
+					"type" : "defeat"
+				},
+				"message" : "core.genrltxt.253"
+			},
+			"heroesMustSurvive2" : {
 				"condition" : [
 					"allOf",
 					[ "isHuman", { "value" : 1 } ],
 					[ "noneOf",
-						[ "allOf",
-							[ "control", { "position" : [ 21, 10, 0 ], "type" : 34 } ],
-							[ "control", { "position" : [ 44,  9, 0 ], "type" : 34 } ]
-						]
+						[ "control", { "position" : [ 44,  9, 0 ], "type" : 34 } ]
 					]
 				],
 				"effect" : {
 					"messageToSend" : "core.genrltxt.5",
 					"type" : "defeat"
 				},
-				"message" : "One of your heroes has suffered defeat - your quest is over!"
+				"message" : "core.genrltxt.253"
 			},
 			"specialVictory" : {
 				"condition" : [
@@ -1430,28 +1695,39 @@
 			}
 		},
 		"victoryIconIndex" : 0,
-		"victoryString" : "Acquire Three Artifacts"
+		"victoryString" : "vcmi.map.victoryCondition.collectArtifacts.message"
 	},
 	"data/final:9" : { // Barbarian Brothers
 		"defeatIconIndex" : 3,
 		"defeatString" : "core.lcdesc.0",
 		"triggeredEvents" : {
-			"heroesMustSurvive" : {
+			"heroesMustSurvive1" : {
+				"condition" : [
+					"allOf",
+					[ "isHuman", { "value" : 1 } ],
+					[ "noneOf",
+						[ "control", { "position" : [ 66, 70, 0 ], "type" : 34 } ]
+					]
+				],
+				"effect" : {
+					"messageToSend" : "core.genrltxt.5",
+					"type" : "defeat"
+				},
+				"message" : "core.genrltxt.253"
+			},
+			"heroesMustSurvive2" : {
 				"condition" : [
 					"allOf",
 					[ "isHuman", { "value" : 1 } ],
 					[ "noneOf",
-						[ "allOf",
-							[ "control", { "position" : [ 66, 70, 0 ], "type" : 34 } ],
-							[ "control", { "position" : [ 70, 66, 0 ], "type" : 34 } ]
-						]
+						[ "control", { "position" : [ 70, 66, 0 ], "type" : 34 } ]
 					]
 				],
 				"effect" : {
 					"messageToSend" : "core.genrltxt.5",
 					"type" : "defeat"
 				},
-				"message" : "One of your heroes has suffered defeat - your quest is over!"
+				"message" : "core.genrltxt.253"
 			},
 			"specialVictory" : {
 				"condition" : [
@@ -1477,30 +1753,67 @@
 			}
 		},
 		"victoryIconIndex" : 0,
-		"victoryString" : "Acquire Three Artifacts"
+		"victoryString" : "vcmi.map.victoryCondition.collectArtifacts.message"
 	},
 	"data/final:10" : { // Union
 		"defeatIconIndex" : 3,
 		"defeatString" : "core.lcdesc.0",
 		"triggeredEvents" : {
-			"heroesMustSurvive" : {
+			"heroesMustSurvive1" : {
+				"condition" : [
+					"allOf",
+					[ "isHuman", { "value" : 1 } ],
+					[ "noneOf",
+						[ "control", { "position" : [  7, 13, 0 ], "type" : 34 } ]
+					]
+				],
+				"effect" : {
+					"messageToSend" : "core.genrltxt.5",
+					"type" : "defeat"
+				},
+				"message" : "core.genrltxt.253"
+			},
+			"heroesMustSurvive2" : {
+				"condition" : [
+					"allOf",
+					[ "isHuman", { "value" : 1 } ],
+					[ "noneOf",
+						[ "control", { "position" : [  9, 15, 0 ], "type" : 34 } ]
+					]
+				],
+				"effect" : {
+					"messageToSend" : "core.genrltxt.5",
+					"type" : "defeat"
+				},
+				"message" : "core.genrltxt.253"
+			},
+			"heroesMustSurvive3" : {
 				"condition" : [
 					"allOf",
 					[ "isHuman", { "value" : 1 } ],
 					[ "noneOf",
-						[ "allOf",
-							[ "control", { "position" : [  7, 13, 0 ], "type" : 34 } ],
-							[ "control", { "position" : [  9, 15, 0 ], "type" : 34 } ],
-							[ "control", { "position" : [ 6, 103, 0 ], "type" : 34 } ],
-							[ "control", { "position" : [ 9, 105, 0 ], "type" : 34 } ]
-						]
+						[ "control", { "position" : [ 6, 103, 0 ], "type" : 34 } ]
 					]
 				],
 				"effect" : {
 					"messageToSend" : "core.genrltxt.5",
 					"type" : "defeat"
 				},
-				"message" : "One of your heroes has suffered defeat - your quest is over!"
+				"message" : "core.genrltxt.253"
+			},
+			"heroesMustSurvive4" : {
+				"condition" : [
+					"allOf",
+					[ "isHuman", { "value" : 1 } ],
+					[ "noneOf",
+						[ "control", { "position" : [ 9, 105, 0 ], "type" : 34 } ]
+					]
+				],
+				"effect" : {
+					"messageToSend" : "core.genrltxt.5",
+					"type" : "defeat"
+				},
+				"message" : "core.genrltxt.253"
 			},
 			"standardDefeat" : {
 				"condition" : [ "daysWithoutTown", { "value" : 7 } ],
@@ -1521,34 +1834,71 @@
 					"messageToSend" : "core.genrltxt.5",
 					"type" : "victory"
 				},
-				"message" : "Congratulations! All your enemies have been defeated and you have Angelic Alliance! Victory is yours!"
+				"message" : "vcmi.map.victoryCondition.angelicAlliance.toSelf"
 			}
 		},
 		"victoryIconIndex" : 11,
-		"victoryString" : "Defeat All Enemies and create Angelic Alliance"
+		"victoryString" : "vcmi.map.victoryCondition.angelicAlliance.message"
 	},
 	"data/final:11" : { // Fall of Sandro
 		"defeatIconIndex" : 2,
 		"defeatString" : "core.lcdesc.3",
 		"triggeredEvents" : {
-			"heroesMustSurvive" : {
+			"heroesMustSurvive1" : {
+				"condition" : [
+					"allOf",
+					[ "isHuman", { "value" : 1 } ],
+					[ "noneOf",
+						[ "control", { "position" : [ 14, 53, 0 ], "type" : 34 } ]
+					]
+				],
+				"effect" : {
+					"messageToSend" : "core.genrltxt.5",
+					"type" : "defeat"
+				},
+				"message" : "core.genrltxt.253"
+			},
+			"heroesMustSurvive2" : {
 				"condition" : [
 					"allOf",
 					[ "isHuman", { "value" : 1 } ],
 					[ "noneOf",
-						[ "allOf",
-							[ "control", { "position" : [ 14, 53, 0 ], "type" : 34 } ],
-							[ "control", { "position" : [ 21, 69, 0 ], "type" : 34 } ],
-							[ "control", { "position" : [ 38, 59, 0 ], "type" : 34 } ],
-							[ "control", { "position" : [ 66, 60, 0 ], "type" : 34 } ]
-						]
+						[ "control", { "position" : [ 21, 69, 0 ], "type" : 34 } ]
 					]
 				],
 				"effect" : {
 					"messageToSend" : "core.genrltxt.5",
 					"type" : "defeat"
 				},
-				"message" : "One of your heroes has suffered defeat - your quest is over!"
+				"message" : "core.genrltxt.253"
+			},
+			"heroesMustSurvive3" : {
+				"condition" : [
+					"allOf",
+					[ "isHuman", { "value" : 1 } ],
+					[ "noneOf",
+						[ "control", { "position" : [ 38, 59, 0 ], "type" : 34 } ]
+					]
+				],
+				"effect" : {
+					"messageToSend" : "core.genrltxt.5",
+					"type" : "defeat"
+				},
+				"message" : "core.genrltxt.253"
+			},
+			"heroesMustSurvive4" : {
+				"condition" : [
+					"allOf",
+					[ "isHuman", { "value" : 1 } ],
+					[ "noneOf",
+						[ "control", { "position" : [ 66, 60, 0 ], "type" : 34 } ]
+					]
+				],
+				"effect" : {
+					"messageToSend" : "core.genrltxt.5",
+					"type" : "defeat"
+				},
+				"message" : "core.genrltxt.253"
 			},
 			"specialDefeat" : {
 				"condition" : [
@@ -1586,7 +1936,7 @@
 		"defeatIconIndex" : 2,
 		"defeatString" : "core.lcdesc.3",
 		"triggeredEvents" : {
-			"heroesMustSurvive" : {
+			"heroMustSurvive" : {
 				"condition" : [
 					"allOf",
 					[ "isHuman", { "value" : 1 } ],

+ 32 - 5
lib/mapping/MapFormatH3M.cpp

@@ -341,7 +341,6 @@ void CMapLoaderH3M::readVictoryLossConditions()
 		specialVictory.description.clear(); // TODO: display in quest window
 
 		mapHeader->victoryIconIndex = static_cast<ui16>(vicCondition);
-		mapHeader->victoryMessage.appendTextID(TextIdentifier("core.vcdesc", static_cast<size_t>(vicCondition) + 1).get());
 
 		bool allowNormalVictory = reader->readBool();
 		bool appliesToAI = reader->readBool();
@@ -373,6 +372,8 @@ void CMapLoaderH3M::readVictoryLossConditions()
 				specialVictory.effect.toOtherMessage.appendTextID("core.genrltxt.281");
 				specialVictory.onFulfill.appendTextID("core.genrltxt.280");
 				specialVictory.trigger = EventExpression(cond);
+
+				mapHeader->victoryMessage.appendTextID("core.vcdesc.1");
 				break;
 			}
 			case EVictoryConditionType::GATHERTROOP:
@@ -384,6 +385,8 @@ void CMapLoaderH3M::readVictoryLossConditions()
 				specialVictory.effect.toOtherMessage.appendTextID("core.genrltxt.277");
 				specialVictory.onFulfill.appendTextID("core.genrltxt.6");
 				specialVictory.trigger = EventExpression(cond);
+
+				mapHeader->victoryMessage.appendTextID("core.vcdesc.2");
 				break;
 			}
 			case EVictoryConditionType::GATHERRESOURCE:
@@ -395,6 +398,8 @@ void CMapLoaderH3M::readVictoryLossConditions()
 				specialVictory.effect.toOtherMessage.appendTextID("core.genrltxt.279");
 				specialVictory.onFulfill.appendTextID("core.genrltxt.278");
 				specialVictory.trigger = EventExpression(cond);
+
+				mapHeader->victoryMessage.appendTextID("core.vcdesc.3");
 				break;
 			}
 			case EVictoryConditionType::BUILDCITY:
@@ -410,6 +415,8 @@ void CMapLoaderH3M::readVictoryLossConditions()
 				specialVictory.effect.toOtherMessage.appendTextID("core.genrltxt.283");
 				specialVictory.onFulfill.appendTextID("core.genrltxt.282");
 				specialVictory.trigger = EventExpression(oper);
+
+				mapHeader->victoryMessage.appendTextID("core.vcdesc.4");
 				break;
 			}
 			case EVictoryConditionType::BUILDGRAIL:
@@ -423,6 +430,8 @@ void CMapLoaderH3M::readVictoryLossConditions()
 				specialVictory.effect.toOtherMessage.appendTextID("core.genrltxt.285");
 				specialVictory.onFulfill.appendTextID("core.genrltxt.284");
 				specialVictory.trigger = EventExpression(cond);
+
+				mapHeader->victoryMessage.appendTextID("core.vcdesc.5");
 				break;
 			}
 			case EVictoryConditionType::BEATHERO:
@@ -434,6 +443,8 @@ void CMapLoaderH3M::readVictoryLossConditions()
 				specialVictory.effect.toOtherMessage.appendTextID("core.genrltxt.253");
 				specialVictory.onFulfill.appendTextID("core.genrltxt.252");
 				specialVictory.trigger = EventExpression(cond);
+
+				mapHeader->victoryMessage.appendTextID("core.vcdesc.6");
 				break;
 			}
 			case EVictoryConditionType::CAPTURECITY:
@@ -445,6 +456,8 @@ void CMapLoaderH3M::readVictoryLossConditions()
 				specialVictory.effect.toOtherMessage.appendTextID("core.genrltxt.250");
 				specialVictory.onFulfill.appendTextID("core.genrltxt.249");
 				specialVictory.trigger = EventExpression(cond);
+
+				mapHeader->victoryMessage.appendTextID("core.vcdesc.7");
 				break;
 			}
 			case EVictoryConditionType::BEATMONSTER:
@@ -456,6 +469,8 @@ void CMapLoaderH3M::readVictoryLossConditions()
 				specialVictory.effect.toOtherMessage.appendTextID("core.genrltxt.287");
 				specialVictory.onFulfill.appendTextID("core.genrltxt.286");
 				specialVictory.trigger = EventExpression(cond);
+
+				mapHeader->victoryMessage.appendTextID("core.vcdesc.8");
 				break;
 			}
 			case EVictoryConditionType::TAKEDWELLINGS:
@@ -467,6 +482,8 @@ void CMapLoaderH3M::readVictoryLossConditions()
 				specialVictory.effect.toOtherMessage.appendTextID("core.genrltxt.289");
 				specialVictory.onFulfill.appendTextID("core.genrltxt.288");
 				specialVictory.trigger = EventExpression(oper);
+
+				mapHeader->victoryMessage.appendTextID("core.vcdesc.9");
 				break;
 			}
 			case EVictoryConditionType::TAKEMINES:
@@ -477,6 +494,8 @@ void CMapLoaderH3M::readVictoryLossConditions()
 				specialVictory.effect.toOtherMessage.appendTextID("core.genrltxt.291");
 				specialVictory.onFulfill.appendTextID("core.genrltxt.290");
 				specialVictory.trigger = EventExpression(cond);
+
+				mapHeader->victoryMessage.appendTextID("core.vcdesc.10");
 				break;
 			}
 			case EVictoryConditionType::TRANSPORTITEM:
@@ -488,6 +507,8 @@ void CMapLoaderH3M::readVictoryLossConditions()
 				specialVictory.effect.toOtherMessage.appendTextID("core.genrltxt.293");
 				specialVictory.onFulfill.appendTextID("core.genrltxt.292");
 				specialVictory.trigger = EventExpression(cond);
+
+				mapHeader->victoryMessage.appendTextID("core.vcdesc.11");
 				break;
 			}
 			case EVictoryConditionType::HOTA_ELIMINATE_ALL_MONSTERS:
@@ -495,9 +516,12 @@ void CMapLoaderH3M::readVictoryLossConditions()
 				EventCondition cond(EventCondition::DESTROY);
 				cond.objectType = Obj::MONSTER;
 
-				specialVictory.effect.toOtherMessage.appendRawString("Defeat all monsters"); // Eliminate all monsters on the map
-				specialVictory.onFulfill.appendRawString("You have defeated all of the monsters plaguing this land!");
+				specialVictory.effect.toOtherMessage.appendTextID("vcmi.map.victoryCondition.eliminateMonsters.toOthers");
+				specialVictory.onFulfill.appendTextID("vcmi.map.victoryCondition.eliminateMonsters.toSelf");
 				specialVictory.trigger = EventExpression(cond);
+
+				mapHeader->victoryMessage.appendTextID("core.vcdesc.12");
+				mapHeader->victoryIconIndex = 12;
 				break;
 			}
 			case EVictoryConditionType::HOTA_SURVIVE_FOR_DAYS:
@@ -505,9 +529,12 @@ void CMapLoaderH3M::readVictoryLossConditions()
 				EventCondition cond(EventCondition::DAYS_PASSED);
 				cond.value = reader->readUInt32();
 
-				specialVictory.effect.toOtherMessage.appendRawString("Survive beyond a time limit"); // Survive by month %d, week %d, day %d.
-				specialVictory.onFulfill.appendRawString("You have managed to survive!");
+				specialVictory.effect.toOtherMessage.appendTextID("vcmi.map.victoryCondition.daysPassed.toOthers");
+				specialVictory.onFulfill.appendTextID("vcmi.map.victoryCondition.daysPassed.toSelf");
 				specialVictory.trigger = EventExpression(cond);
+
+				mapHeader->victoryMessage.appendTextID("core.vcdesc.13");
+				mapHeader->victoryIconIndex = 13;
 				break;
 			}
 			default: