mirror of
https://github.com/vcmi/vcmi.git
synced 2025-09-16 09:26:28 +02:00
Support for defining new campaign regions in mods, for hota h3c
This commit is contained in:
238
config/campaignRegions.json
Normal file
238
config/campaignRegions.json
Normal file
@@ -0,0 +1,238 @@
|
||||
{
|
||||
// RoE
|
||||
|
||||
"good1" : {
|
||||
"prefix": "G1",
|
||||
"colorSuffixLength": 1,
|
||||
"desc": [
|
||||
{ "infix": "A", "x": 57, "y": 314 },
|
||||
{ "infix": "B", "x": 137, "y": 309 },
|
||||
{ "infix": "C", "x": 44, "y": 163 }
|
||||
]
|
||||
},
|
||||
|
||||
"good2" : {
|
||||
"prefix": "G2",
|
||||
"colorSuffixLength": 1,
|
||||
"desc": [
|
||||
{ "infix": "A", "x": 56, "y": 90 },
|
||||
{ "infix": "B", "x": 316, "y": 49 },
|
||||
{ "infix": "C", "x": 54, "y": 378 },
|
||||
{ "infix": "D", "x": 151, "y": 126 }
|
||||
]
|
||||
},
|
||||
|
||||
"good3" : {
|
||||
"prefix": "G3",
|
||||
"colorSuffixLength": 1,
|
||||
"desc": [
|
||||
{ "infix": "A", "x": 289, "y": 376 },
|
||||
{ "infix": "B", "x": 60, "y": 147 },
|
||||
{ "infix": "C", "x": 131, "y": 202 }
|
||||
]
|
||||
},
|
||||
|
||||
"evil1" : {
|
||||
"prefix": "E1",
|
||||
"colorSuffixLength": 1,
|
||||
"desc": [
|
||||
{ "infix": "A", "x": 270, "y": 332 },
|
||||
{ "infix": "B", "x": 138, "y": 113 },
|
||||
{ "infix": "C", "x": 26, "y": 70 },
|
||||
{ "infix": "P1", "x": 256, "y": 127 },
|
||||
{ "infix": "P2", "x": 57, "y": 314 },
|
||||
{ "infix": "P3", "x": 137, "y": 310 },
|
||||
{ "infix": "P4", "x": 44, "y": 163 }
|
||||
]
|
||||
},
|
||||
|
||||
"evil2" : {
|
||||
"prefix": "E2",
|
||||
"colorSuffixLength": 1,
|
||||
"desc": [
|
||||
{ "infix": "A", "x": 131, "y": 202 },
|
||||
{ "infix": "B", "x": 60, "y": 145 },
|
||||
{ "infix": "C", "x": 92, "y": 261 },
|
||||
{ "infix": "D", "x": 218, "y": 307 }
|
||||
]
|
||||
},
|
||||
|
||||
"neutral1" : {
|
||||
"prefix": "N1",
|
||||
"colorSuffixLength": 1,
|
||||
"desc": [
|
||||
{ "infix": "A", "x": 42, "y": 94 },
|
||||
{ "infix": "B", "x": 309, "y": 290 },
|
||||
{ "infix": "CD", "x": 188, "y": 202 }
|
||||
]
|
||||
},
|
||||
|
||||
"secret1" : {
|
||||
"prefix": "S1",
|
||||
"colorSuffixLength": 1,
|
||||
"desc": [
|
||||
{ "infix": "A", "x": 263, "y": 199 },
|
||||
{ "infix": "B", "x": 182, "y": 210 },
|
||||
{ "infix": "C", "x": 82, "y": 152 }
|
||||
]
|
||||
},
|
||||
|
||||
// AB
|
||||
|
||||
"dragonSlayer" : {
|
||||
"prefix": "BR",
|
||||
"colorSuffixLength": 2,
|
||||
"desc": [
|
||||
{ "infix": "A", "x": 18, "y": 233 },
|
||||
{ "infix": "B", "x": 125, "y": 381 },
|
||||
{ "infix": "C", "x": 224, "y": 357 },
|
||||
{ "infix": "D", "x": 192, "y": 320 }
|
||||
]
|
||||
},
|
||||
|
||||
"foolhardyWaywardness" : {
|
||||
"prefix": "IS",
|
||||
"colorSuffixLength": 2,
|
||||
"desc": [
|
||||
{ "infix": "A", "x": 294, "y": 399 },
|
||||
{ "infix": "B", "x": 183, "y": 293 },
|
||||
{ "infix": "C", "x": 40, "y": 92 },
|
||||
{ "infix": "D", "x": 294, "y": 398 }
|
||||
]
|
||||
},
|
||||
|
||||
"festivalOfLife" : {
|
||||
"prefix": "KR",
|
||||
"colorSuffixLength": 2,
|
||||
"desc": [
|
||||
{ "infix": "A", "x": 148, "y": 323 },
|
||||
{ "infix": "B", "x": 192, "y": 235 },
|
||||
{ "infix": "C", "x": 136, "y": 158 },
|
||||
{ "infix": "D", "x": 87, "y": 107 }
|
||||
]
|
||||
},
|
||||
|
||||
"dragonsBlood" : {
|
||||
"prefix": "NI",
|
||||
"colorSuffixLength": 2,
|
||||
"desc": [
|
||||
{ "infix": "A", "x": 118, "y": 111 },
|
||||
{ "infix": "B", "x": 223, "y": 145 },
|
||||
{ "infix": "C", "x": 320, "y": 213 },
|
||||
{ "infix": "D", "x": 233, "y": 250 }
|
||||
]
|
||||
},
|
||||
|
||||
"playingWithFire" : {
|
||||
"prefix": "TA",
|
||||
"colorSuffixLength": 2,
|
||||
"desc": [
|
||||
{ "infix": "A", "x": 228, "y": 233 },
|
||||
{ "infix": "B", "x": 147, "y": 194 },
|
||||
{ "infix": "C", "x": 112, "y": 97 }
|
||||
]
|
||||
},
|
||||
|
||||
"armageddonsBlade" : {
|
||||
"prefix": "AR",
|
||||
"colorSuffixLength": 2,
|
||||
"desc": [
|
||||
{ "infix": "A", "x": 135, "y": 238 },
|
||||
{ "infix": "B", "x": 135, "y": 121 },
|
||||
{ "infix": "C", "x": 206, "y": 155 },
|
||||
{ "infix": "D", "x": 105, "y": 397 },
|
||||
{ "infix": "E", "x": 109, "y": 275 },
|
||||
{ "infix": "F", "x": 158, "y": 188 },
|
||||
{ "infix": "G", "x": 200, "y": 261 },
|
||||
{ "infix": "H", "x": 232, "y": 197 }
|
||||
]
|
||||
},
|
||||
|
||||
// SoD
|
||||
|
||||
"hackAndSlash" : {
|
||||
"prefix": "HS",
|
||||
"colorSuffixLength": 2,
|
||||
"desc": [
|
||||
{ "infix": "A", "x": 141, "y": 326 },
|
||||
{ "infix": "B", "x": 238, "y": 275 },
|
||||
{ "infix": "C", "x": 22, "y": 161 },
|
||||
{ "infix": "D", "x": 5, "y": 9 }
|
||||
]
|
||||
},
|
||||
|
||||
"birthOfBarbarian" : {
|
||||
"prefix": "BB",
|
||||
"colorSuffixLength": 2,
|
||||
"desc": [
|
||||
{ "infix": "A", "x": 167, "y": 342 },
|
||||
{ "infix": "B", "x": 217, "y": 263 },
|
||||
{ "infix": "C", "x": 0, "y": 71 },
|
||||
{ "infix": "D", "x": 291, "y": 79 },
|
||||
{ "infix": "E", "x": 316, "y": 199 }
|
||||
]
|
||||
},
|
||||
|
||||
"newBeginning" : {
|
||||
"prefix": "NB",
|
||||
"colorSuffixLength": 2,
|
||||
"desc": [
|
||||
{ "infix": "A", "x": 6, "y": 292 },
|
||||
{ "infix": "B", "x": 161, "y": 334 },
|
||||
{ "infix": "C", "x": 63, "y": 195 },
|
||||
{ "infix": "D", "x": 56, "y": 46 }
|
||||
]
|
||||
},
|
||||
|
||||
"elixirOfLife" : {
|
||||
"prefix": "EL",
|
||||
"colorSuffixLength": 2,
|
||||
"desc": [
|
||||
{ "infix": "A", "x": 11, "y": 73 },
|
||||
{ "infix": "B", "x": 0, "y": 241 },
|
||||
{ "infix": "C", "x": 254, "y": 34 },
|
||||
{ "infix": "D", "x": 91, "y": 144 }
|
||||
]
|
||||
},
|
||||
|
||||
"riseOfTheNecromancer" : {
|
||||
"prefix": "RN",
|
||||
"colorSuffixLength": 2,
|
||||
"desc": [
|
||||
{ "infix": "A", "x": 84, "y": 319 },
|
||||
{ "infix": "B", "x": 194, "y": 275 },
|
||||
{ "infix": "C", "x": 67, "y": 185 },
|
||||
{ "infix": "D", "x": 77, "y": 30 }
|
||||
]
|
||||
},
|
||||
|
||||
"unholyAlliance" : {
|
||||
"prefix": "UA",
|
||||
"colorSuffixLength": 2,
|
||||
"desc": [
|
||||
{ "infix": "A", "x": 157, "y": 409 },
|
||||
{ "infix": "B", "x": 62, "y": 346 },
|
||||
{ "infix": "C", "x": 8, "y": 8 },
|
||||
{ "infix": "D", "x": 206, "y": 1 },
|
||||
{ "infix": "E", "x": 132, "y": 357 },
|
||||
{ "infix": "F", "x": 184, "y": 83 },
|
||||
{ "infix": "G", "x": 159, "y": 263 },
|
||||
{ "infix": "H", "x": 108, "y": 173 },
|
||||
{ "infix": "I", "x": 55, "y": 127 },
|
||||
{ "infix": "J", "x": 9, "y": 252 },
|
||||
{ "infix": "K", "x": 210, "y": 176 },
|
||||
{ "infix": "L", "x": 260, "y": 210 }
|
||||
]
|
||||
},
|
||||
|
||||
"spectreOfPower" : {
|
||||
"prefix": "SP",
|
||||
"colorSuffixLength": 2,
|
||||
"desc": [
|
||||
{ "infix": "A", "x": 7, "y": 295 },
|
||||
{ "infix": "B", "x": 44, "y": 141 },
|
||||
{ "infix": "C", "x": 141, "y": 21 },
|
||||
{ "infix": "D", "x": 243, "y": 156 }
|
||||
]
|
||||
}
|
||||
}
|
@@ -1,234 +0,0 @@
|
||||
{
|
||||
"campaign_regions": [
|
||||
{
|
||||
"prefix": "G1",
|
||||
"colorSuffixLength": 1,
|
||||
"desc": [
|
||||
{ "infix": "A", "x": 57, "y": 314 },
|
||||
{ "infix": "B", "x": 137, "y": 309 },
|
||||
{ "infix": "C", "x": 44, "y": 163 }
|
||||
]
|
||||
},
|
||||
|
||||
{
|
||||
"prefix": "G2",
|
||||
"colorSuffixLength": 1,
|
||||
"desc": [
|
||||
{ "infix": "A", "x": 56, "y": 90 },
|
||||
{ "infix": "B", "x": 316, "y": 49 },
|
||||
{ "infix": "C", "x": 54, "y": 378 },
|
||||
{ "infix": "D", "x": 151, "y": 126 }
|
||||
]
|
||||
},
|
||||
|
||||
{
|
||||
"prefix": "G3",
|
||||
"colorSuffixLength": 1,
|
||||
"desc": [
|
||||
{ "infix": "A", "x": 289, "y": 376 },
|
||||
{ "infix": "B", "x": 60, "y": 147 },
|
||||
{ "infix": "C", "x": 131, "y": 202 }
|
||||
]
|
||||
},
|
||||
|
||||
{
|
||||
"prefix": "E1",
|
||||
"colorSuffixLength": 1,
|
||||
"desc": [
|
||||
{ "infix": "A", "x": 270, "y": 332 },
|
||||
{ "infix": "B", "x": 138, "y": 113 },
|
||||
{ "infix": "C", "x": 26, "y": 70 },
|
||||
{ "infix": "P1", "x": 256, "y": 127 },
|
||||
{ "infix": "P2", "x": 57, "y": 314 },
|
||||
{ "infix": "P3", "x": 137, "y": 310 },
|
||||
{ "infix": "P4", "x": 44, "y": 163 }
|
||||
]
|
||||
},
|
||||
|
||||
{
|
||||
"prefix": "E2",
|
||||
"colorSuffixLength": 1,
|
||||
"desc": [
|
||||
{ "infix": "A", "x": 131, "y": 202 },
|
||||
{ "infix": "B", "x": 60, "y": 145 },
|
||||
{ "infix": "C", "x": 92, "y": 261 },
|
||||
{ "infix": "D", "x": 218, "y": 307 }
|
||||
]
|
||||
},
|
||||
|
||||
{
|
||||
"prefix": "N1",
|
||||
"colorSuffixLength": 1,
|
||||
"desc": [
|
||||
{ "infix": "A", "x": 42, "y": 94 },
|
||||
{ "infix": "B", "x": 309, "y": 290 },
|
||||
{ "infix": "CD", "x": 188, "y": 202 }
|
||||
]
|
||||
},
|
||||
|
||||
{
|
||||
"prefix": "S1",
|
||||
"colorSuffixLength": 1,
|
||||
"desc": [
|
||||
{ "infix": "A", "x": 263, "y": 199 },
|
||||
{ "infix": "B", "x": 182, "y": 210 },
|
||||
{ "infix": "C", "x": 82, "y": 152 }
|
||||
]
|
||||
},
|
||||
|
||||
{
|
||||
"prefix": "BR",
|
||||
"colorSuffixLength": 2,
|
||||
"desc": [
|
||||
{ "infix": "A", "x": 18, "y": 233 },
|
||||
{ "infix": "B", "x": 125, "y": 381 },
|
||||
{ "infix": "C", "x": 224, "y": 357 },
|
||||
{ "infix": "D", "x": 192, "y": 320 }
|
||||
]
|
||||
},
|
||||
|
||||
{
|
||||
"prefix": "IS",
|
||||
"colorSuffixLength": 2,
|
||||
"desc": [
|
||||
{ "infix": "A", "x": 294, "y": 399 },
|
||||
{ "infix": "B", "x": 183, "y": 293 },
|
||||
{ "infix": "C", "x": 40, "y": 92 },
|
||||
{ "infix": "D", "x": 294, "y": 398 }
|
||||
]
|
||||
},
|
||||
|
||||
{
|
||||
"prefix": "KR",
|
||||
"colorSuffixLength": 2,
|
||||
"desc": [
|
||||
{ "infix": "A", "x": 148, "y": 323 },
|
||||
{ "infix": "B", "x": 192, "y": 235 },
|
||||
{ "infix": "C", "x": 136, "y": 158 },
|
||||
{ "infix": "D", "x": 87, "y": 107 }
|
||||
]
|
||||
},
|
||||
|
||||
{
|
||||
"prefix": "NI",
|
||||
"colorSuffixLength": 2,
|
||||
"desc": [
|
||||
{ "infix": "A", "x": 118, "y": 111 },
|
||||
{ "infix": "B", "x": 223, "y": 145 },
|
||||
{ "infix": "C", "x": 320, "y": 213 },
|
||||
{ "infix": "D", "x": 233, "y": 250 }
|
||||
]
|
||||
},
|
||||
|
||||
{
|
||||
"prefix": "TA",
|
||||
"colorSuffixLength": 2,
|
||||
"desc": [
|
||||
{ "infix": "A", "x": 228, "y": 233 },
|
||||
{ "infix": "B", "x": 147, "y": 194 },
|
||||
{ "infix": "C", "x": 112, "y": 97 }
|
||||
]
|
||||
},
|
||||
|
||||
{
|
||||
"prefix": "AR",
|
||||
"colorSuffixLength": 2,
|
||||
"desc": [
|
||||
{ "infix": "A", "x": 135, "y": 238 },
|
||||
{ "infix": "B", "x": 135, "y": 121 },
|
||||
{ "infix": "C", "x": 206, "y": 155 },
|
||||
{ "infix": "D", "x": 105, "y": 397 },
|
||||
{ "infix": "E", "x": 109, "y": 275 },
|
||||
{ "infix": "F", "x": 158, "y": 188 },
|
||||
{ "infix": "G", "x": 200, "y": 261 },
|
||||
{ "infix": "H", "x": 232, "y": 197 }
|
||||
]
|
||||
},
|
||||
|
||||
{
|
||||
"prefix": "HS",
|
||||
"colorSuffixLength": 2,
|
||||
"desc": [
|
||||
{ "infix": "A", "x": 141, "y": 326 },
|
||||
{ "infix": "B", "x": 238, "y": 275 },
|
||||
{ "infix": "C", "x": 22, "y": 161 },
|
||||
{ "infix": "D", "x": 5, "y": 9 }
|
||||
]
|
||||
},
|
||||
|
||||
{
|
||||
"prefix": "BB",
|
||||
"colorSuffixLength": 2,
|
||||
"desc": [
|
||||
{ "infix": "A", "x": 167, "y": 342 },
|
||||
{ "infix": "B", "x": 217, "y": 263 },
|
||||
{ "infix": "C", "x": 0, "y": 71 },
|
||||
{ "infix": "D", "x": 291, "y": 79 },
|
||||
{ "infix": "E", "x": 316, "y": 199 }
|
||||
]
|
||||
},
|
||||
|
||||
{
|
||||
"prefix": "NB",
|
||||
"colorSuffixLength": 2,
|
||||
"desc": [
|
||||
{ "infix": "A", "x": 6, "y": 292 },
|
||||
{ "infix": "B", "x": 161, "y": 334 },
|
||||
{ "infix": "C", "x": 63, "y": 195 },
|
||||
{ "infix": "D", "x": 56, "y": 46 }
|
||||
]
|
||||
},
|
||||
|
||||
{
|
||||
"prefix": "EL",
|
||||
"colorSuffixLength": 2,
|
||||
"desc": [
|
||||
{ "infix": "A", "x": 11, "y": 73 },
|
||||
{ "infix": "B", "x": 0, "y": 241 },
|
||||
{ "infix": "C", "x": 254, "y": 34 },
|
||||
{ "infix": "D", "x": 91, "y": 144 }
|
||||
]
|
||||
},
|
||||
|
||||
{
|
||||
"prefix": "RN",
|
||||
"colorSuffixLength": 2,
|
||||
"desc": [
|
||||
{ "infix": "A", "x": 84, "y": 319 },
|
||||
{ "infix": "B", "x": 194, "y": 275 },
|
||||
{ "infix": "C", "x": 67, "y": 185 },
|
||||
{ "infix": "D", "x": 77, "y": 30 }
|
||||
]
|
||||
},
|
||||
|
||||
{
|
||||
"prefix": "UA",
|
||||
"colorSuffixLength": 2,
|
||||
"desc": [
|
||||
{ "infix": "A", "x": 157, "y": 409 },
|
||||
{ "infix": "B", "x": 62, "y": 346 },
|
||||
{ "infix": "C", "x": 8, "y": 8 },
|
||||
{ "infix": "D", "x": 206, "y": 1 },
|
||||
{ "infix": "E", "x": 132, "y": 357 },
|
||||
{ "infix": "F", "x": 184, "y": 83 },
|
||||
{ "infix": "G", "x": 159, "y": 263 },
|
||||
{ "infix": "H", "x": 108, "y": 173 },
|
||||
{ "infix": "I", "x": 55, "y": 127 },
|
||||
{ "infix": "J", "x": 9, "y": 252 },
|
||||
{ "infix": "K", "x": 210, "y": 176 },
|
||||
{ "infix": "L", "x": 260, "y": 210 }
|
||||
]
|
||||
},
|
||||
|
||||
{
|
||||
"prefix": "SP",
|
||||
"colorSuffixLength": 2,
|
||||
"desc": [
|
||||
{ "infix": "A", "x": 7, "y": 295 },
|
||||
{ "infix": "B", "x": 44, "y": 141 },
|
||||
{ "infix": "C", "x": 141, "y": 21 },
|
||||
{ "infix": "D", "x": 243, "y": 156 }
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
@@ -127,6 +127,11 @@
|
||||
[
|
||||
"config/obstacles.json"
|
||||
],
|
||||
"campaignRegions" :
|
||||
[
|
||||
"config/campaignRegions.json"
|
||||
],
|
||||
|
||||
|
||||
"settings":
|
||||
{
|
||||
@@ -244,6 +249,16 @@
|
||||
"portraits" : {
|
||||
"catherine" : 128, // In "RoE" Catherine only has portrait
|
||||
"portraitGeneralKendal" : 129
|
||||
},
|
||||
"campaignRegions" : {
|
||||
|
||||
"good1" : 1, // Long Live the Queen
|
||||
"good2" : 2, // Liberation
|
||||
"good3" : 3, // Song for the Father
|
||||
"evil1" : 4, // Dungeons and devils
|
||||
"evil2" : 5, // Long Live the King
|
||||
"neutral1" : 6, // Spoils of War
|
||||
"secret1" : 7 // Seeds Of Discontent
|
||||
}
|
||||
},
|
||||
"armageddonsBlade" : {
|
||||
@@ -262,6 +277,14 @@
|
||||
"portraitGeneralKendal" : 156,
|
||||
"portraitYoungCristian" : 157,
|
||||
"portraitOrdwald" : 158
|
||||
},
|
||||
"campaignRegions" : {
|
||||
"dragonSlayer" : 8,
|
||||
"foolhardyWaywardness" : 9,
|
||||
"festivalOfLife" : 10,
|
||||
"dragonsBlood" : 11,
|
||||
"playingWithFire" : 12,
|
||||
"armageddonsBlade" : 13
|
||||
}
|
||||
},
|
||||
"shadowOfDeath" : {
|
||||
@@ -276,6 +299,16 @@
|
||||
"portraitYoungGem" : 160,
|
||||
"portraitYoungSandro" : 161,
|
||||
"portraitYoungYog" : 162
|
||||
},
|
||||
|
||||
"campaignRegions" : {
|
||||
"hackAndSlash" : 14,
|
||||
"birthOfBarbarian" : 15,
|
||||
"newBeginning" : 16,
|
||||
"elixirOfLife" : 17,
|
||||
"riseOfTheNecromancer" : 18,
|
||||
"unholyAlliance" : 19,
|
||||
"spectreOfPower" : 20
|
||||
}
|
||||
},
|
||||
"chronicles" : {
|
||||
|
40
config/schemas/campaignRegion.json
Normal file
40
config/schemas/campaignRegion.json
Normal file
@@ -0,0 +1,40 @@
|
||||
{
|
||||
"type" : "object",
|
||||
"$schema" : "http://json-schema.org/draft-04/schema",
|
||||
"title" : "VCMI campaign region format",
|
||||
"description" : "Format used to define campaign regions for h3c maps in VCMI",
|
||||
"required" : [ "prefix", "colorSuffixLength", "desc" ],
|
||||
"additionalProperties" : false,
|
||||
"properties" : {
|
||||
"prefix" :
|
||||
{
|
||||
"type" : "string",
|
||||
"description" : "Prefix for all images from this region"
|
||||
},
|
||||
"colorSuffixLength" :
|
||||
{
|
||||
"type" : "number",
|
||||
"description" : "Number of symbols used to encode color, 1 or 2"
|
||||
},
|
||||
"desc" :
|
||||
{
|
||||
"type" : "array",
|
||||
"description" : "List of regions in this campaign",
|
||||
"items" : {
|
||||
"type" : "object",
|
||||
"additionalProperties" : false,
|
||||
"properties" : {
|
||||
"infix" : {
|
||||
"type" : "string"
|
||||
},
|
||||
"x" : {
|
||||
"type" : "number"
|
||||
},
|
||||
"y" : {
|
||||
"type" : "number"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -89,6 +89,8 @@ set(lib_MAIN_SRCS
|
||||
campaign/CampaignBonus.cpp
|
||||
campaign/CampaignHandler.cpp
|
||||
campaign/CampaignState.cpp
|
||||
campaign/CampaignRegions.cpp
|
||||
campaign/CampaignRegionsHandler.cpp
|
||||
|
||||
constants/EntityIdentifiers.cpp
|
||||
|
||||
@@ -485,6 +487,8 @@ set(lib_MAIN_HEADERS
|
||||
campaign/CampaignBonus.h
|
||||
campaign/CampaignConstants.h
|
||||
campaign/CampaignHandler.h
|
||||
campaign/CampaignRegions.h
|
||||
campaign/CampaignRegionsHandler.h
|
||||
campaign/CampaignScenarioPrologEpilog.h
|
||||
campaign/CampaignState.h
|
||||
|
||||
|
@@ -26,6 +26,7 @@
|
||||
#include "entities/hero/CHeroClassHandler.h"
|
||||
#include "entities/hero/CHeroHandler.h"
|
||||
#include "texts/CGeneralTextHandler.h"
|
||||
#include "campaign/CampaignRegionsHandler.h"
|
||||
#include "mapping/MapFormatSettings.h"
|
||||
#include "modding/CModHandler.h"
|
||||
#include "modding/IdentifierStorage.h"
|
||||
@@ -184,6 +185,7 @@ void GameLibrary::initializeLibrary()
|
||||
createHandler(spellh);
|
||||
createHandler(skillh);
|
||||
createHandler(terviewh);
|
||||
createHandler(campaignRegions);
|
||||
createHandler(tplh); //templates need already resolved identifiers (refactor?)
|
||||
#if SCRIPTING_ENABLED
|
||||
createHandler(scriptHandler);
|
||||
|
@@ -42,6 +42,7 @@ class GameSettings;
|
||||
class CIdentifierStorage;
|
||||
class SpellSchoolHandler;
|
||||
class MapFormatSettings;
|
||||
class CampaignRegionsHandler;
|
||||
|
||||
#if SCRIPTING_ENABLED
|
||||
namespace scripting
|
||||
@@ -99,6 +100,7 @@ public:
|
||||
std::unique_ptr<GameSettings> settingsHandler;
|
||||
std::unique_ptr<ObstacleSetHandler> biomeHandler;
|
||||
std::unique_ptr<MapFormatSettings> mapFormat;
|
||||
std::unique_ptr<CampaignRegionsHandler> campaignRegions;
|
||||
|
||||
#if SCRIPTING_ENABLED
|
||||
std::unique_ptr<scripting::ScriptHandler> scriptHandler;
|
||||
|
@@ -15,7 +15,7 @@ class JsonNode;
|
||||
class Entity;
|
||||
|
||||
/// base class for all handlers that can be accessed from mod system
|
||||
class DLL_LINKAGE IHandlerBase
|
||||
class DLL_LINKAGE IHandlerBase : boost::noncopyable
|
||||
{
|
||||
protected:
|
||||
static std::string getScopeBuiltin();
|
||||
@@ -44,7 +44,8 @@ public:
|
||||
virtual ~IHandlerBase() = default;
|
||||
};
|
||||
|
||||
template <class _ObjectID, class _ObjectBase, class _Object, class _ServiceBase> class CHandlerBase : public _ServiceBase, public IHandlerBase
|
||||
template <class _ObjectID, class _ObjectBase, class _Object, class _ServiceBase>
|
||||
class CHandlerBase : public _ServiceBase, public IHandlerBase
|
||||
{
|
||||
const _Object * getObjectImpl(const int32_t index) const
|
||||
{
|
||||
|
@@ -11,6 +11,7 @@
|
||||
#include "CampaignHandler.h"
|
||||
|
||||
#include "CampaignState.h"
|
||||
#include "CampaignRegionsHandler.h"
|
||||
|
||||
#include "../filesystem/Filesystem.h"
|
||||
#include "../filesystem/CCompressedStream.h"
|
||||
@@ -152,7 +153,7 @@ void CampaignHandler::readHeaderFromJson(CampaignHeader & ret, JsonNode & reader
|
||||
}
|
||||
|
||||
ret.version = CampaignVersion::VCMI;
|
||||
ret.campaignRegions = CampaignRegions::fromJson(reader["regions"]);
|
||||
ret.campaignRegions = CampaignRegions(reader["regions"]);
|
||||
ret.numberOfScenarios = reader["scenarios"].Vector().size();
|
||||
ret.name.appendTextID(readLocalizedString(ret, reader["name"].String(), filename, modName, "name"));
|
||||
ret.description.appendTextID(readLocalizedString(ret, reader["description"].String(), filename, modName, "description"));
|
||||
@@ -350,14 +351,14 @@ void CampaignHandler::readHeaderFromMemory( CampaignHeader & ret, CBinaryReader
|
||||
assert(unknownB == 1);
|
||||
assert(unknownC == 0);
|
||||
assert(ret.numberOfScenarios <= 8);
|
||||
|
||||
// TODO. Or they are hardcoded in this hota version?
|
||||
// ret.campaignRegions = ???;
|
||||
}
|
||||
|
||||
ui8 campId = reader.readUInt8() - 1;//change range of it from [1, 20] to [0, 19]
|
||||
if(ret.version < CampaignVersion::Chr) // For chronicles: Will be overridden later; Chronicles uses own logic (reusing OH3 ID's)
|
||||
ret.loadLegacyData(campId);
|
||||
const auto & mapping = LIBRARY->mapFormat->getMapping(ret.version);
|
||||
|
||||
CampaignRegionID campaignMapId(reader.readUInt8());
|
||||
ret.campaignRegions = *LIBRARY->campaignRegions->getByIndex(mapping.remap(campaignMapId));
|
||||
if(ret.version != CampaignVersion::HotA)
|
||||
ret.numberOfScenarios = ret.campaignRegions.regionsCount();
|
||||
ret.name.appendTextID(readLocalizedString(ret, reader, filename, modName, encoding, "name"));
|
||||
ret.description.appendTextID(readLocalizedString(ret, reader, filename, modName, encoding, "description"));
|
||||
ret.author.appendRawString("");
|
||||
|
148
lib/campaign/CampaignRegions.cpp
Normal file
148
lib/campaign/CampaignRegions.cpp
Normal file
@@ -0,0 +1,148 @@
|
||||
/*
|
||||
* CampaignRegions.cpp, part of VCMI engine
|
||||
*
|
||||
* Authors: listed in file AUTHORS in main folder
|
||||
*
|
||||
* License: GNU General Public License v2.0 or later
|
||||
* Full text of license available in license.txt file, in main folder
|
||||
*
|
||||
*/
|
||||
#include "StdInc.h"
|
||||
#include "CampaignRegions.h"
|
||||
|
||||
#include "../json/JsonNode.h"
|
||||
|
||||
CampaignRegions::RegionDescription CampaignRegions::RegionDescription::fromJson(const JsonNode & node)
|
||||
{
|
||||
CampaignRegions::RegionDescription rd;
|
||||
rd.infix = node["infix"].String();
|
||||
rd.pos = Point(static_cast<int>(node["x"].Float()), static_cast<int>(node["y"].Float()));
|
||||
if(!node["labelPos"].isNull())
|
||||
rd.labelPos = Point(static_cast<int>(node["labelPos"]["x"].Float()), static_cast<int>(node["labelPos"]["y"].Float()));
|
||||
else
|
||||
rd.labelPos = std::nullopt;
|
||||
return rd;
|
||||
}
|
||||
|
||||
JsonNode CampaignRegions::RegionDescription::toJson(CampaignRegions::RegionDescription & rd)
|
||||
{
|
||||
JsonNode node;
|
||||
node["infix"].String() = rd.infix;
|
||||
node["x"].Float() = rd.pos.x;
|
||||
node["y"].Float() = rd.pos.y;
|
||||
if(rd.labelPos != std::nullopt)
|
||||
{
|
||||
node["labelPos"]["x"].Float() = (*rd.labelPos).x;
|
||||
node["labelPos"]["y"].Float() = (*rd.labelPos).y;
|
||||
}
|
||||
else
|
||||
node["labelPos"].clear();
|
||||
return node;
|
||||
}
|
||||
|
||||
CampaignRegions::CampaignRegions(const JsonNode & node)
|
||||
{
|
||||
campPrefix = node["prefix"].String();
|
||||
colorSuffixLength = static_cast<int>(node["colorSuffixLength"].Float());
|
||||
campSuffix = node["suffix"].isNull() ? std::vector<std::string>() : std::vector<std::string>{node["suffix"].Vector()[0].String(), node["suffix"].Vector()[1].String(), node["suffix"].Vector()[2].String()};
|
||||
campBackground = node["background"].isNull() ? "" : node["background"].String();
|
||||
|
||||
for(const JsonNode & desc : node["desc"].Vector())
|
||||
regions.push_back(CampaignRegions::RegionDescription::fromJson(desc));
|
||||
}
|
||||
|
||||
JsonNode CampaignRegions::toJson(CampaignRegions cr)
|
||||
{
|
||||
JsonNode node;
|
||||
node["prefix"].String() = cr.campPrefix;
|
||||
node["colorSuffixLength"].Float() = cr.colorSuffixLength;
|
||||
if(cr.campSuffix.empty())
|
||||
node["suffix"].clear();
|
||||
else
|
||||
node["suffix"].Vector() = JsonVector{ JsonNode(cr.campSuffix[0]), JsonNode(cr.campSuffix[1]), JsonNode(cr.campSuffix[2]) };
|
||||
if(cr.campBackground.empty())
|
||||
node["background"].clear();
|
||||
else
|
||||
node["background"].String() = cr.campBackground;
|
||||
node["desc"].Vector() = JsonVector();
|
||||
for(auto & region : cr.regions)
|
||||
node["desc"].Vector().push_back(CampaignRegions::RegionDescription::toJson(region));
|
||||
return node;
|
||||
}
|
||||
|
||||
CampaignRegions CampaignRegions::getLegacy(int campId)
|
||||
{
|
||||
static std::vector<CampaignRegions> campDescriptions;
|
||||
if(campDescriptions.empty()) //read once
|
||||
{
|
||||
const JsonNode config(JsonPath::builtin("config/campaign_regions.json"));
|
||||
for(const JsonNode & campaign : config["campaign_regions"].Vector())
|
||||
campDescriptions.push_back(CampaignRegions(campaign));
|
||||
}
|
||||
|
||||
return campDescriptions.at(campId);
|
||||
}
|
||||
|
||||
ImagePath CampaignRegions::getBackgroundName() const
|
||||
{
|
||||
if(campBackground.empty())
|
||||
return ImagePath::builtin(campPrefix + "_BG.BMP");
|
||||
else
|
||||
return ImagePath::builtin(campBackground);
|
||||
}
|
||||
|
||||
Point CampaignRegions::getPosition(CampaignScenarioID which) const
|
||||
{
|
||||
const auto & region = regions[which.getNum()];
|
||||
return region.pos;
|
||||
}
|
||||
|
||||
std::optional<Point> CampaignRegions::getLabelPosition(CampaignScenarioID which) const
|
||||
{
|
||||
const auto & region = regions[which.getNum()];
|
||||
return region.labelPos;
|
||||
}
|
||||
|
||||
ImagePath CampaignRegions::getNameFor(CampaignScenarioID which, int colorIndex, const std::string & type) const
|
||||
{
|
||||
const auto & region = regions[which.getNum()];
|
||||
|
||||
static const std::array<std::array<std::string, 8>, 3> colors = {{
|
||||
{ "", "", "", "", "", "", "", "" },
|
||||
{ "R", "B", "N", "G", "O", "V", "T", "P" },
|
||||
{ "Re", "Bl", "Br", "Gr", "Or", "Vi", "Te", "Pi" }
|
||||
}};
|
||||
|
||||
std::string color = colors[colorSuffixLength][colorIndex];
|
||||
|
||||
return ImagePath::builtin(campPrefix + region.infix + "_" + type + color + ".BMP");
|
||||
}
|
||||
|
||||
ImagePath CampaignRegions::getAvailableName(CampaignScenarioID which, int color) const
|
||||
{
|
||||
if(campSuffix.empty())
|
||||
return getNameFor(which, color, "En");
|
||||
else
|
||||
return getNameFor(which, color, campSuffix[0]);
|
||||
}
|
||||
|
||||
ImagePath CampaignRegions::getSelectedName(CampaignScenarioID which, int color) const
|
||||
{
|
||||
if(campSuffix.empty())
|
||||
return getNameFor(which, color, "Se");
|
||||
else
|
||||
return getNameFor(which, color, campSuffix[1]);
|
||||
}
|
||||
|
||||
ImagePath CampaignRegions::getConqueredName(CampaignScenarioID which, int color) const
|
||||
{
|
||||
if(campSuffix.empty())
|
||||
return getNameFor(which, color, "Co");
|
||||
else
|
||||
return getNameFor(which, color, campSuffix[2]);
|
||||
}
|
||||
|
||||
int CampaignRegions::regionsCount() const
|
||||
{
|
||||
return regions.size();
|
||||
}
|
77
lib/campaign/CampaignRegions.h
Normal file
77
lib/campaign/CampaignRegions.h
Normal file
@@ -0,0 +1,77 @@
|
||||
/*
|
||||
* CampaignRegions.h, part of VCMI engine
|
||||
*
|
||||
* Authors: listed in file AUTHORS in main folder
|
||||
*
|
||||
* License: GNU General Public License v2.0 or later
|
||||
* Full text of license available in license.txt file, in main folder
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "../Point.h"
|
||||
#include "../filesystem/ResourcePath.h"
|
||||
#include "../constants/EntityIdentifiers.h"
|
||||
|
||||
VCMI_LIB_NAMESPACE_BEGIN
|
||||
|
||||
class DLL_LINKAGE CampaignRegions
|
||||
{
|
||||
// Campaign editor
|
||||
friend class CampaignEditor;
|
||||
friend class CampaignProperties;
|
||||
friend class ScenarioProperties;
|
||||
|
||||
std::string campPrefix;
|
||||
std::vector<std::string> campSuffix;
|
||||
std::string campBackground;
|
||||
int colorSuffixLength = 0;
|
||||
|
||||
struct DLL_LINKAGE RegionDescription
|
||||
{
|
||||
std::string infix;
|
||||
Point pos;
|
||||
std::optional<Point> labelPos;
|
||||
|
||||
template <typename Handler> void serialize(Handler &h)
|
||||
{
|
||||
h & infix;
|
||||
h & pos;
|
||||
h & labelPos;
|
||||
}
|
||||
|
||||
static CampaignRegions::RegionDescription fromJson(const JsonNode & node);
|
||||
static JsonNode toJson(CampaignRegions::RegionDescription & rd);
|
||||
};
|
||||
|
||||
std::vector<RegionDescription> regions;
|
||||
|
||||
ImagePath getNameFor(CampaignScenarioID which, int color, const std::string & type) const;
|
||||
|
||||
public:
|
||||
CampaignRegions() = default;
|
||||
explicit CampaignRegions(const JsonNode & node);
|
||||
|
||||
ImagePath getBackgroundName() const;
|
||||
Point getPosition(CampaignScenarioID which) const;
|
||||
std::optional<Point> getLabelPosition(CampaignScenarioID which) const;
|
||||
ImagePath getAvailableName(CampaignScenarioID which, int color) const;
|
||||
ImagePath getSelectedName(CampaignScenarioID which, int color) const;
|
||||
ImagePath getConqueredName(CampaignScenarioID which, int color) const;
|
||||
int regionsCount() const;
|
||||
|
||||
template <typename Handler> void serialize(Handler &h)
|
||||
{
|
||||
h & campPrefix;
|
||||
h & colorSuffixLength;
|
||||
h & regions;
|
||||
h & campSuffix;
|
||||
h & campBackground;
|
||||
}
|
||||
|
||||
|
||||
static JsonNode toJson(CampaignRegions cr);
|
||||
static CampaignRegions getLegacy(int campId);
|
||||
};
|
||||
|
||||
VCMI_LIB_NAMESPACE_END
|
30
lib/campaign/CampaignRegionsHandler.cpp
Normal file
30
lib/campaign/CampaignRegionsHandler.cpp
Normal file
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* CampaignRegionsHandler.cpp, part of VCMI engine
|
||||
*
|
||||
* Authors: listed in file AUTHORS in main folder
|
||||
*
|
||||
* License: GNU General Public License v2.0 or later
|
||||
* Full text of license available in license.txt file, in main folder
|
||||
*
|
||||
*/
|
||||
#include "StdInc.h"
|
||||
#include "CampaignRegionsHandler.h"
|
||||
|
||||
#include "../json/JsonNode.h"
|
||||
|
||||
std::vector<JsonNode> CampaignRegionsHandler::loadLegacyData()
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
void CampaignRegionsHandler::loadObject(std::string scope, std::string name, const JsonNode & data)
|
||||
{
|
||||
auto object = std::make_shared<CampaignRegions>(data);
|
||||
registerObject(scope, "campaignRegion", name, objects.size());
|
||||
objects.push_back(object);
|
||||
}
|
||||
|
||||
void CampaignRegionsHandler::loadObject(std::string scope, std::string name, const JsonNode & data, size_t index)
|
||||
{
|
||||
throw std::runtime_error("CampaignRegionsHandler::loadObject - load by index is not supported!");
|
||||
}
|
38
lib/campaign/CampaignRegionsHandler.h
Normal file
38
lib/campaign/CampaignRegionsHandler.h
Normal file
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* CampaignRegionsHandler.h, part of VCMI engine
|
||||
*
|
||||
* Authors: listed in file AUTHORS in main folder
|
||||
*
|
||||
* License: GNU General Public License v2.0 or later
|
||||
* Full text of license available in license.txt file, in main folder
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "CampaignRegions.h"
|
||||
|
||||
#include "../IHandlerBase.h"
|
||||
|
||||
VCMI_LIB_NAMESPACE_BEGIN
|
||||
|
||||
/// Managed campaign region sets - "map" of campaign locations, with selectable scenarios
|
||||
/// Used only for .h3c campaigns. .vmap's embed campaign regions layout in its format
|
||||
class DLL_LINKAGE CampaignRegionsHandler : public IHandlerBase
|
||||
{
|
||||
public:
|
||||
std::vector<JsonNode> loadLegacyData() override;
|
||||
|
||||
/// loads single object into game. Scope is namespace of this object, same as name of source mod
|
||||
void loadObject(std::string scope, std::string name, const JsonNode & data) override;
|
||||
void loadObject(std::string scope, std::string name, const JsonNode & data, size_t index) override;
|
||||
|
||||
const CampaignRegions * getByIndex(int index) const
|
||||
{
|
||||
return objects.at(index).get();
|
||||
}
|
||||
|
||||
private:
|
||||
std::vector<std::shared_ptr<CampaignRegions>> objects;
|
||||
};
|
||||
|
||||
VCMI_LIB_NAMESPACE_END
|
@@ -33,151 +33,6 @@ void CampaignScenario::loadPreconditionRegions(ui32 regions)
|
||||
}
|
||||
}
|
||||
|
||||
CampaignRegions::RegionDescription CampaignRegions::RegionDescription::fromJson(const JsonNode & node)
|
||||
{
|
||||
CampaignRegions::RegionDescription rd;
|
||||
rd.infix = node["infix"].String();
|
||||
rd.pos = Point(static_cast<int>(node["x"].Float()), static_cast<int>(node["y"].Float()));
|
||||
if(!node["labelPos"].isNull())
|
||||
rd.labelPos = Point(static_cast<int>(node["labelPos"]["x"].Float()), static_cast<int>(node["labelPos"]["y"].Float()));
|
||||
else
|
||||
rd.labelPos = std::nullopt;
|
||||
return rd;
|
||||
}
|
||||
|
||||
JsonNode CampaignRegions::RegionDescription::toJson(CampaignRegions::RegionDescription & rd)
|
||||
{
|
||||
JsonNode node;
|
||||
node["infix"].String() = rd.infix;
|
||||
node["x"].Float() = rd.pos.x;
|
||||
node["y"].Float() = rd.pos.y;
|
||||
if(rd.labelPos != std::nullopt)
|
||||
{
|
||||
node["labelPos"]["x"].Float() = (*rd.labelPos).x;
|
||||
node["labelPos"]["y"].Float() = (*rd.labelPos).y;
|
||||
}
|
||||
else
|
||||
node["labelPos"].clear();
|
||||
return node;
|
||||
}
|
||||
|
||||
CampaignRegions CampaignRegions::fromJson(const JsonNode & node)
|
||||
{
|
||||
CampaignRegions cr;
|
||||
cr.campPrefix = node["prefix"].String();
|
||||
cr.colorSuffixLength = static_cast<int>(node["colorSuffixLength"].Float());
|
||||
cr.campSuffix = node["suffix"].isNull() ? std::vector<std::string>() : std::vector<std::string>{node["suffix"].Vector()[0].String(), node["suffix"].Vector()[1].String(), node["suffix"].Vector()[2].String()};
|
||||
cr.campBackground = node["background"].isNull() ? "" : node["background"].String();
|
||||
|
||||
for(const JsonNode & desc : node["desc"].Vector())
|
||||
cr.regions.push_back(CampaignRegions::RegionDescription::fromJson(desc));
|
||||
|
||||
return cr;
|
||||
}
|
||||
|
||||
JsonNode CampaignRegions::toJson(CampaignRegions cr)
|
||||
{
|
||||
JsonNode node;
|
||||
node["prefix"].String() = cr.campPrefix;
|
||||
node["colorSuffixLength"].Float() = cr.colorSuffixLength;
|
||||
if(cr.campSuffix.empty())
|
||||
node["suffix"].clear();
|
||||
else
|
||||
node["suffix"].Vector() = JsonVector{ JsonNode(cr.campSuffix[0]), JsonNode(cr.campSuffix[1]), JsonNode(cr.campSuffix[2]) };
|
||||
if(cr.campBackground.empty())
|
||||
node["background"].clear();
|
||||
else
|
||||
node["background"].String() = cr.campBackground;
|
||||
node["desc"].Vector() = JsonVector();
|
||||
for(auto & region : cr.regions)
|
||||
node["desc"].Vector().push_back(CampaignRegions::RegionDescription::toJson(region));
|
||||
return node;
|
||||
}
|
||||
|
||||
CampaignRegions CampaignRegions::getLegacy(int campId)
|
||||
{
|
||||
static std::vector<CampaignRegions> campDescriptions;
|
||||
if(campDescriptions.empty()) //read once
|
||||
{
|
||||
const JsonNode config(JsonPath::builtin("config/campaign_regions.json"));
|
||||
for(const JsonNode & campaign : config["campaign_regions"].Vector())
|
||||
campDescriptions.push_back(CampaignRegions::fromJson(campaign));
|
||||
}
|
||||
|
||||
return campDescriptions.at(campId);
|
||||
}
|
||||
|
||||
ImagePath CampaignRegions::getBackgroundName() const
|
||||
{
|
||||
if(campBackground.empty())
|
||||
return ImagePath::builtin(campPrefix + "_BG.BMP");
|
||||
else
|
||||
return ImagePath::builtin(campBackground);
|
||||
}
|
||||
|
||||
Point CampaignRegions::getPosition(CampaignScenarioID which) const
|
||||
{
|
||||
auto const & region = regions[which.getNum()];
|
||||
return region.pos;
|
||||
}
|
||||
|
||||
std::optional<Point> CampaignRegions::getLabelPosition(CampaignScenarioID which) const
|
||||
{
|
||||
auto const & region = regions[which.getNum()];
|
||||
return region.labelPos;
|
||||
}
|
||||
|
||||
ImagePath CampaignRegions::getNameFor(CampaignScenarioID which, int colorIndex, const std::string & type) const
|
||||
{
|
||||
auto const & region = regions[which.getNum()];
|
||||
|
||||
static const std::array<std::array<std::string, 8>, 3> colors = {{
|
||||
{ "", "", "", "", "", "", "", "" },
|
||||
{ "R", "B", "N", "G", "O", "V", "T", "P" },
|
||||
{ "Re", "Bl", "Br", "Gr", "Or", "Vi", "Te", "Pi" }
|
||||
}};
|
||||
|
||||
std::string color = colors[colorSuffixLength][colorIndex];
|
||||
|
||||
return ImagePath::builtin(campPrefix + region.infix + "_" + type + color + ".BMP");
|
||||
}
|
||||
|
||||
ImagePath CampaignRegions::getAvailableName(CampaignScenarioID which, int color) const
|
||||
{
|
||||
if(campSuffix.empty())
|
||||
return getNameFor(which, color, "En");
|
||||
else
|
||||
return getNameFor(which, color, campSuffix[0]);
|
||||
}
|
||||
|
||||
ImagePath CampaignRegions::getSelectedName(CampaignScenarioID which, int color) const
|
||||
{
|
||||
if(campSuffix.empty())
|
||||
return getNameFor(which, color, "Se");
|
||||
else
|
||||
return getNameFor(which, color, campSuffix[1]);
|
||||
}
|
||||
|
||||
ImagePath CampaignRegions::getConqueredName(CampaignScenarioID which, int color) const
|
||||
{
|
||||
if(campSuffix.empty())
|
||||
return getNameFor(which, color, "Co");
|
||||
else
|
||||
return getNameFor(which, color, campSuffix[2]);
|
||||
}
|
||||
|
||||
void CampaignHeader::loadLegacyData(ui8 campId)
|
||||
{
|
||||
campaignRegions = CampaignRegions::getLegacy(campId);
|
||||
numberOfScenarios = LIBRARY->generaltexth->getCampaignLength(campId);
|
||||
}
|
||||
|
||||
void CampaignHeader::loadLegacyData(const CampaignRegions & regions, int numOfScenario)
|
||||
{
|
||||
campaignRegions = regions;
|
||||
numberOfScenarios = numOfScenario;
|
||||
}
|
||||
|
||||
bool CampaignHeader::playerSelectedDifficulty() const
|
||||
{
|
||||
return difficultyChosenByPlayer;
|
||||
@@ -526,8 +381,10 @@ void Campaign::overrideCampaign()
|
||||
for (auto & entry : node.Struct())
|
||||
if(filename == entry.first)
|
||||
{
|
||||
if(!entry.second["regions"].isNull() && !entry.second["scenarioCount"].isNull())
|
||||
loadLegacyData(CampaignRegions::fromJson(entry.second["regions"]), entry.second["scenarioCount"].Integer());
|
||||
if(!entry.second["regions"].isNull())
|
||||
campaignRegions = CampaignRegions(entry.second["regions"]);
|
||||
if (!entry.second["scenarioCount"].isNull())
|
||||
numberOfScenarios = entry.second["scenarioCount"].Integer();
|
||||
if(!entry.second["loadingBackground"].isNull())
|
||||
loadingBackground = ImagePath::builtin(entry.second["loadingBackground"].String());
|
||||
if(!entry.second["videoRim"].isNull())
|
||||
|
@@ -9,13 +9,14 @@
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "CampaignBonus.h"
|
||||
#include "CampaignRegions.h"
|
||||
#include "CampaignScenarioPrologEpilog.h"
|
||||
|
||||
#include "../filesystem/ResourcePath.h"
|
||||
#include "../gameState/HighScore.h"
|
||||
#include "../serializer/Serializeable.h"
|
||||
#include "../texts/TextLocalizationContainer.h"
|
||||
#include "CampaignBonus.h"
|
||||
#include "CampaignScenarioPrologEpilog.h"
|
||||
#include "../gameState/HighScore.h"
|
||||
#include "../Point.h"
|
||||
|
||||
VCMI_LIB_NAMESPACE_BEGIN
|
||||
|
||||
@@ -29,61 +30,6 @@ class CMapInfo;
|
||||
class JsonNode;
|
||||
class IGameInfoCallback;
|
||||
|
||||
class DLL_LINKAGE CampaignRegions
|
||||
{
|
||||
// Campaign editor
|
||||
friend class CampaignEditor;
|
||||
friend class CampaignProperties;
|
||||
friend class ScenarioProperties;
|
||||
|
||||
std::string campPrefix;
|
||||
std::vector<std::string> campSuffix;
|
||||
std::string campBackground;
|
||||
int colorSuffixLength;
|
||||
|
||||
struct DLL_LINKAGE RegionDescription
|
||||
{
|
||||
std::string infix;
|
||||
Point pos;
|
||||
std::optional<Point> labelPos;
|
||||
|
||||
template <typename Handler> void serialize(Handler &h)
|
||||
{
|
||||
h & infix;
|
||||
h & pos;
|
||||
h & labelPos;
|
||||
}
|
||||
|
||||
static CampaignRegions::RegionDescription fromJson(const JsonNode & node);
|
||||
static JsonNode toJson(CampaignRegions::RegionDescription & rd);
|
||||
};
|
||||
|
||||
std::vector<RegionDescription> regions;
|
||||
|
||||
ImagePath getNameFor(CampaignScenarioID which, int color, const std::string & type) const;
|
||||
|
||||
public:
|
||||
ImagePath getBackgroundName() const;
|
||||
Point getPosition(CampaignScenarioID which) const;
|
||||
std::optional<Point> getLabelPosition(CampaignScenarioID which) const;
|
||||
ImagePath getAvailableName(CampaignScenarioID which, int color) const;
|
||||
ImagePath getSelectedName(CampaignScenarioID which, int color) const;
|
||||
ImagePath getConqueredName(CampaignScenarioID which, int color) const;
|
||||
|
||||
template <typename Handler> void serialize(Handler &h)
|
||||
{
|
||||
h & campPrefix;
|
||||
h & colorSuffixLength;
|
||||
h & regions;
|
||||
h & campSuffix;
|
||||
h & campBackground;
|
||||
}
|
||||
|
||||
static CampaignRegions fromJson(const JsonNode & node);
|
||||
static JsonNode toJson(CampaignRegions cr);
|
||||
static CampaignRegions getLegacy(int campId);
|
||||
};
|
||||
|
||||
class DLL_LINKAGE CampaignHeader : public boost::noncopyable
|
||||
{
|
||||
friend class CampaignHandler;
|
||||
@@ -114,9 +60,6 @@ class DLL_LINKAGE CampaignHeader : public boost::noncopyable
|
||||
int numberOfScenarios = 0;
|
||||
bool difficultyChosenByPlayer = false;
|
||||
|
||||
void loadLegacyData(ui8 campId);
|
||||
void loadLegacyData(const CampaignRegions & regions, int numOfScenario);
|
||||
|
||||
TextContainerRegistrable textContainer;
|
||||
|
||||
public:
|
||||
|
@@ -1122,6 +1122,13 @@ public:
|
||||
static const CampaignScenarioID NONE;
|
||||
};
|
||||
|
||||
class DLL_LINKAGE CampaignRegionID : public StaticIdentifier<CampaignRegionID>
|
||||
{
|
||||
public:
|
||||
using StaticIdentifier<CampaignRegionID>::StaticIdentifier;
|
||||
};
|
||||
|
||||
|
||||
// Deprecated
|
||||
// TODO: remove
|
||||
using Obj = MapObjectID;
|
||||
|
@@ -239,6 +239,8 @@ static void loadBonusAddInfo(CAddInfo & var, BonusType type, const JsonNode & va
|
||||
case BonusType::SPELL_BEFORE_ATTACK:
|
||||
case BonusType::SPELL_AFTER_ATTACK:
|
||||
// 3 numbers
|
||||
if (!value.isVector())
|
||||
break;
|
||||
var.resize(3);
|
||||
var[0] = value[0].Integer();
|
||||
var[1] = value[1].Integer();
|
||||
|
@@ -45,7 +45,7 @@ public:
|
||||
};
|
||||
|
||||
/// Main class responsible for creation of all adventure map objects
|
||||
class DLL_LINKAGE CObjectClassesHandler : public IHandlerBase, boost::noncopyable
|
||||
class DLL_LINKAGE CObjectClassesHandler : public IHandlerBase
|
||||
{
|
||||
/// list of object handlers, each of them handles only one type
|
||||
std::vector< std::unique_ptr<ObjectClass> > mapObjectTypes;
|
||||
@@ -106,4 +106,4 @@ public:
|
||||
std::string getJsonKey(MapObjectID type) const;
|
||||
};
|
||||
|
||||
VCMI_LIB_NAMESPACE_END
|
||||
VCMI_LIB_NAMESPACE_END
|
||||
|
@@ -750,16 +750,14 @@ uint64_t CGHeroInstance::getValueForDiplomacy() const
|
||||
|
||||
uint32_t CGHeroInstance::getValueForCampaign() const
|
||||
{
|
||||
/// Determined by testing H3: hero is preferred for transfer in campaigns if total sum of his primary skills and his secondary skill levels is greatest
|
||||
uint32_t score = 0;
|
||||
// Determined by testing H3: hero is preferred for transfer in campaigns if total sum of his primary skills and his secondary skill levels is greatest
|
||||
// Additional info from wiki: https://heroes.thelazy.net/index.php/Power_rating
|
||||
uint32_t score = level;
|
||||
score += getPrimSkillLevel(PrimarySkill::ATTACK);
|
||||
score += getPrimSkillLevel(PrimarySkill::DEFENSE);
|
||||
score += getPrimSkillLevel(PrimarySkill::SPELL_POWER);
|
||||
score += getPrimSkillLevel(PrimarySkill::DEFENSE);
|
||||
|
||||
for (const auto& secondary : secSkills)
|
||||
score += secondary.second;
|
||||
|
||||
return score;
|
||||
}
|
||||
|
||||
|
@@ -102,7 +102,7 @@ private:
|
||||
};
|
||||
|
||||
// TODO: Instantiate ObstacleSetHandler
|
||||
class DLL_LINKAGE ObstacleSetHandler : public IHandlerBase, boost::noncopyable
|
||||
class DLL_LINKAGE ObstacleSetHandler : public IHandlerBase
|
||||
{
|
||||
public:
|
||||
|
||||
|
@@ -15,6 +15,7 @@
|
||||
|
||||
#include "../GameLibrary.h"
|
||||
#include "../IGameSettings.h"
|
||||
#include "../json/JsonUtils.h"
|
||||
|
||||
MapIdentifiersH3M MapFormatSettings::generateMapping(EMapFormat format)
|
||||
{
|
||||
@@ -79,6 +80,8 @@ std::map<EMapFormat, MapIdentifiersH3M> MapFormatSettings::generateMappings()
|
||||
MapFormatSettings::MapFormatSettings()
|
||||
: mapping(generateMappings())
|
||||
, campaignToMap(generateCampaignMapping())
|
||||
, campaignOverridesConfig(JsonUtils::assembleFromFiles("config/campaignOverrides.json"))
|
||||
, mapOverridesConfig(JsonUtils::assembleFromFiles("config/mapOverrides.json"))
|
||||
{
|
||||
}
|
||||
|
||||
|
@@ -13,10 +13,11 @@
|
||||
#include "MapIdentifiersH3M.h"
|
||||
#include "MapFormat.h"
|
||||
#include "../campaign/CampaignConstants.h"
|
||||
#include "../json/JsonNode.h"
|
||||
|
||||
VCMI_LIB_NAMESPACE_BEGIN
|
||||
|
||||
class MapFormatSettings
|
||||
class MapFormatSettings : boost::noncopyable
|
||||
{
|
||||
static MapIdentifiersH3M generateMapping(EMapFormat format);
|
||||
static std::map<EMapFormat, MapIdentifiersH3M> generateMappings();
|
||||
@@ -24,6 +25,9 @@ class MapFormatSettings
|
||||
|
||||
std::map<EMapFormat, MapIdentifiersH3M> mapping;
|
||||
std::map<CampaignVersion, EMapFormat> campaignToMap;
|
||||
|
||||
JsonNode campaignOverridesConfig;
|
||||
JsonNode mapOverridesConfig;
|
||||
public:
|
||||
MapFormatSettings();
|
||||
|
||||
@@ -46,6 +50,16 @@ public:
|
||||
{
|
||||
return mapping.at(campaignToMap.at(format));
|
||||
}
|
||||
|
||||
const JsonNode & campaignOverrides(std::string & campaignName)
|
||||
{
|
||||
return campaignOverridesConfig[campaignName];
|
||||
}
|
||||
|
||||
const JsonNode & mapOverrides(std::string & mapName)
|
||||
{
|
||||
return mapOverridesConfig[mapName];
|
||||
}
|
||||
};
|
||||
|
||||
VCMI_LIB_NAMESPACE_END
|
||||
|
@@ -98,6 +98,7 @@ void MapIdentifiersH3M::loadMapping(const JsonNode & mapping)
|
||||
loadMapping(mappingTerrain, mapping["terrains"], "terrain");
|
||||
loadMapping(mappingArtifact, mapping["artifacts"], "artifact");
|
||||
loadMapping(mappingSecondarySkill, mapping["skills"], "skill");
|
||||
loadMapping(mappingCampaignRegions, mapping["campaignRegions"], "campaignRegion");
|
||||
}
|
||||
|
||||
void MapIdentifiersH3M::remapTemplate(ObjectTemplate & objectTemplate)
|
||||
@@ -213,4 +214,11 @@ SecondarySkill MapIdentifiersH3M::remap(SecondarySkill input) const
|
||||
return input;
|
||||
}
|
||||
|
||||
CampaignRegionID MapIdentifiersH3M::remap(CampaignRegionID input) const
|
||||
{
|
||||
if (mappingCampaignRegions.count(input))
|
||||
return mappingCampaignRegions.at(input);
|
||||
return input;
|
||||
}
|
||||
|
||||
VCMI_LIB_NAMESPACE_END
|
||||
|
@@ -43,6 +43,7 @@ class MapIdentifiersH3M
|
||||
std::map<TerrainId, TerrainId> mappingTerrain;
|
||||
std::map<ArtifactID, ArtifactID> mappingArtifact;
|
||||
std::map<SecondarySkill, SecondarySkill> mappingSecondarySkill;
|
||||
std::map<CampaignRegionID, CampaignRegionID> mappingCampaignRegions;
|
||||
|
||||
std::map<AnimationPath, AnimationPath> mappingObjectTemplate;
|
||||
std::map<ObjectTypeIdentifier, ObjectTypeIdentifier> mappingObjectIndex;
|
||||
@@ -63,6 +64,7 @@ public:
|
||||
TerrainId remap(TerrainId input) const;
|
||||
ArtifactID remap(ArtifactID input) const;
|
||||
SecondarySkill remap(SecondarySkill input) const;
|
||||
CampaignRegionID remap(CampaignRegionID input) const;
|
||||
|
||||
};
|
||||
|
||||
|
@@ -18,6 +18,7 @@
|
||||
#include "../BattleFieldHandler.h"
|
||||
#include "../CCreatureHandler.h"
|
||||
#include "../CConfigHandler.h"
|
||||
#include "../campaign/CampaignRegionsHandler.h"
|
||||
#include "../entities/artifact/CArtHandler.h"
|
||||
#include "../entities/faction/CTownHandler.h"
|
||||
#include "../entities/hero/CHeroClassHandler.h"
|
||||
@@ -245,6 +246,7 @@ void CContentHandler::init()
|
||||
handlers.insert(std::make_pair("artifacts", ContentTypeHandler(LIBRARY->arth.get(), "artifact")));
|
||||
handlers.insert(std::make_pair("bonuses", ContentTypeHandler(LIBRARY->bth.get(), "bonus")));
|
||||
handlers.insert(std::make_pair("creatures", ContentTypeHandler(LIBRARY->creh.get(), "creature")));
|
||||
handlers.insert(std::make_pair("campaignRegions", ContentTypeHandler(LIBRARY->campaignRegions.get(), "campaignRegion")));
|
||||
handlers.insert(std::make_pair("factions", ContentTypeHandler(LIBRARY->townh.get(), "faction")));
|
||||
handlers.insert(std::make_pair("objects", ContentTypeHandler(LIBRARY->objtypeh.get(), "object")));
|
||||
handlers.insert(std::make_pair("heroes", ContentTypeHandler(LIBRARY->heroh.get(), "hero")));
|
||||
|
@@ -288,8 +288,6 @@ CGeneralTextHandler::CGeneralTextHandler():
|
||||
}
|
||||
}
|
||||
while (parser.endLine() && !text.empty());
|
||||
|
||||
scenariosCountPerCampaign.push_back(region);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -306,15 +304,6 @@ int32_t CGeneralTextHandler::pluralText(const int32_t textIndex, const int32_t c
|
||||
return textIndex + 1;
|
||||
}
|
||||
|
||||
size_t CGeneralTextHandler::getCampaignLength(size_t campaignID) const
|
||||
{
|
||||
assert(campaignID < scenariosCountPerCampaign.size());
|
||||
|
||||
if(campaignID < scenariosCountPerCampaign.size())
|
||||
return scenariosCountPerCampaign[campaignID];
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::string CGeneralTextHandler::getPreferredLanguage()
|
||||
{
|
||||
assert(!settings["general"]["language"].String().empty());
|
||||
|
@@ -42,9 +42,6 @@ class DLL_LINKAGE CGeneralTextHandler: public TextLocalizationContainer
|
||||
{
|
||||
void readToVector(const std::string & sourceID, const std::string & sourceName);
|
||||
|
||||
/// number of scenarios in specific campaign. TODO: move to a better location
|
||||
std::vector<size_t> scenariosCountPerCampaign;
|
||||
|
||||
public:
|
||||
LegacyTextContainer allTexts;
|
||||
|
||||
@@ -78,8 +75,6 @@ public:
|
||||
|
||||
int32_t pluralText(int32_t textIndex, int32_t count) const;
|
||||
|
||||
size_t getCampaignLength(size_t campaignID) const;
|
||||
|
||||
CGeneralTextHandler();
|
||||
CGeneralTextHandler(const CGeneralTextHandler&) = delete;
|
||||
CGeneralTextHandler operator=(const CGeneralTextHandler&) = delete;
|
||||
|
Reference in New Issue
Block a user