mirror of
https://github.com/vcmi/vcmi.git
synced 2024-11-24 08:32:34 +02:00
Merge pull request #30 from vcmi/RMG
Since there are no objections, I finally merge this branch.
This commit is contained in:
commit
a842068d54
@ -1,11 +0,0 @@
|
||||
{
|
||||
"textData" :
|
||||
{
|
||||
"heroClass" : 18,
|
||||
"artifact" : 171,
|
||||
"creature" : 197,
|
||||
"faction" : 9,
|
||||
"hero" : 156,
|
||||
"mapVersion" : 51 // WoG
|
||||
}
|
||||
}
|
@ -1,309 +0,0 @@
|
||||
{
|
||||
"art144": // placeholder for selection image
|
||||
{
|
||||
"index" : 144,
|
||||
"type" : ["HERO"]
|
||||
},
|
||||
"art145": // placeholder for lock image
|
||||
{
|
||||
"index" : 145,
|
||||
"type" : ["HERO"]
|
||||
},
|
||||
"axeOfSmashing": //TODO: move growing bonuses to this config, someday
|
||||
{
|
||||
"bonuses" : [
|
||||
{
|
||||
"subtype" : "primSkill.attack",
|
||||
"type" : "PRIMARY_SKILL",
|
||||
"val" : 6,
|
||||
"valueType" : "BASE_NUMBER"
|
||||
}
|
||||
],
|
||||
"index" : 146,
|
||||
"type" : ["COMMANDER"],
|
||||
"growing":
|
||||
{
|
||||
"bonusesPerLevel":
|
||||
[
|
||||
{
|
||||
"level": 6,
|
||||
"bonus":
|
||||
{
|
||||
"type" : "PRIMARY_SKILL",
|
||||
"subtype" : "primSkill.attack",
|
||||
"val" : 1
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"mithrilMail":
|
||||
{
|
||||
"bonuses" : [
|
||||
{
|
||||
"type" : "STACK_HEALTH",
|
||||
"val" : 12,
|
||||
"valueType" : "PERCENT_TO_ALL"
|
||||
}
|
||||
],
|
||||
"index" : 147,
|
||||
"type" : ["COMMANDER"],
|
||||
"growing":
|
||||
{
|
||||
"bonusesPerLevel":
|
||||
[
|
||||
{
|
||||
"level": 1,
|
||||
"bonus":
|
||||
{
|
||||
"type" : "STACK_HEALTH",
|
||||
"val" : 1
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"swordOfSharpness":
|
||||
{
|
||||
"bonuses" : [
|
||||
{
|
||||
"subtype" : 0,
|
||||
"type" : "CREATURE_DAMAGE",
|
||||
"val" : 12,
|
||||
"valueType" : "PERCENT_TO_ALL"
|
||||
}
|
||||
],
|
||||
"index" : 148,
|
||||
"type" : ["COMMANDER"],
|
||||
"growing":
|
||||
{
|
||||
"bonusesPerLevel":
|
||||
[
|
||||
{
|
||||
"level": 1,
|
||||
"bonus":
|
||||
{
|
||||
"type" : "CREATURE_DAMAGE",
|
||||
"val" : 1
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"helmOfImmortality": //TODO: implement
|
||||
{
|
||||
"index" : 149,
|
||||
"type" : ["COMMANDER"]
|
||||
},
|
||||
"pendantOfSorcery":
|
||||
{
|
||||
"bonuses" : [
|
||||
{
|
||||
"type" : "CASTS",
|
||||
"val" : 1,
|
||||
"valueType" : "BASE_NUMBER"
|
||||
}
|
||||
],
|
||||
"index" : 150,
|
||||
"type" : ["COMMANDER"],
|
||||
"growing":
|
||||
{
|
||||
"bonusesPerLevel":
|
||||
[
|
||||
{
|
||||
"level": 10,
|
||||
"bonus":
|
||||
{
|
||||
"type" : "CREATURE_ENCHANT_POWER",
|
||||
"val" : 1
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"bootsOfHaste":
|
||||
{
|
||||
"bonuses" : [
|
||||
{
|
||||
"type" : "STACKS_SPEED",
|
||||
"val" : 1,
|
||||
"valueType" : "BASE_NUMBER"
|
||||
}
|
||||
],
|
||||
"index" : 151,
|
||||
"type" : ["COMMANDER"],
|
||||
"growing":
|
||||
{
|
||||
"bonusesPerLevel":
|
||||
[
|
||||
{
|
||||
"level": 10,
|
||||
"bonus":
|
||||
{
|
||||
"type" : "STACKS_SPEED",
|
||||
"val" : 1
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"bowOfSeeking":
|
||||
{
|
||||
"index" : 152,
|
||||
"type" : ["COMMANDER"],
|
||||
"growing":
|
||||
{
|
||||
"thresholdBonuses":
|
||||
[
|
||||
{
|
||||
"level": 5,
|
||||
"bonus":
|
||||
{
|
||||
"type" : "SHOOTER"
|
||||
}
|
||||
},
|
||||
{
|
||||
"level": 25,
|
||||
"bonus":
|
||||
{
|
||||
"type" : "NO_WALL_PENALTY"
|
||||
}
|
||||
},
|
||||
{
|
||||
"level": 50,
|
||||
"bonus":
|
||||
{
|
||||
"type" : "NO_DISTANCE_PENALTY"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"dragonEyeRing": //TODO: implement
|
||||
{
|
||||
"index" : 153,
|
||||
"type" : ["COMMANDER"],
|
||||
},
|
||||
"hardenedShield":
|
||||
{
|
||||
"bonuses" : [
|
||||
{
|
||||
"subtype" : "primSkill.attack",
|
||||
"type" : "PRIMARY_SKILL",
|
||||
"val" : 6,
|
||||
"valueType" : "BASE_NUMBER"
|
||||
}
|
||||
],
|
||||
"index" : 154,
|
||||
"type" : ["COMMANDER"],
|
||||
"growing":
|
||||
{
|
||||
"bonusesPerLevel":
|
||||
[
|
||||
{
|
||||
"level": 6,
|
||||
"bonus":
|
||||
{
|
||||
"type" : "PRIMARY_SKILL",
|
||||
"subtype" : "primSkill.defence",
|
||||
"val" : 1
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"slavasRingOfPower": //TODO: implement if possible
|
||||
{
|
||||
"index" : 155,
|
||||
"type" : ["COMMANDER"]
|
||||
},
|
||||
"warlordsBanner":
|
||||
{
|
||||
"bonuses" : [
|
||||
{
|
||||
"type" : "STACK_HEALTH",
|
||||
"val" : 2,
|
||||
"valueType" : "BASE_NUMBER"
|
||||
}
|
||||
],
|
||||
"index" : 156,
|
||||
"type" : ["CREATURE"]
|
||||
},
|
||||
"crimsonShieldOfRetribution": //TODO: implement
|
||||
{
|
||||
"index" : 157,
|
||||
"type" : ["HERO"]
|
||||
},
|
||||
"barbarianLordsAxeOfFerocity": //TODO: implement
|
||||
{
|
||||
"index" : 158,
|
||||
"type" : ["HERO"],
|
||||
"components":
|
||||
[
|
||||
"ogresClubOfHavoc",
|
||||
"targOfTheRampagingOgre",
|
||||
"crownOfTheSupremeMagi",
|
||||
"tunicOfTheCyclopsKing"
|
||||
]
|
||||
},
|
||||
"dragonheart":
|
||||
{
|
||||
"index" : 159,
|
||||
"type" : ["HERO"]
|
||||
},
|
||||
"gateKey":
|
||||
{
|
||||
"index" : 160,
|
||||
"type" : ["HERO"]
|
||||
},
|
||||
"art161":
|
||||
{
|
||||
"index" : 161,
|
||||
"type" : ["HERO"]
|
||||
},
|
||||
"art162":
|
||||
{
|
||||
"index" : 162,
|
||||
"type" : ["HERO"]
|
||||
},
|
||||
"art163":
|
||||
{
|
||||
"index" : 163,
|
||||
"type" : ["HERO"]
|
||||
},
|
||||
"art164":
|
||||
{
|
||||
"index" : 164,
|
||||
"type" : ["HERO"]
|
||||
},
|
||||
"art165":
|
||||
{
|
||||
"index" : 165,
|
||||
"type" : ["HERO"]
|
||||
},
|
||||
"art166":
|
||||
{
|
||||
"index" : 166,
|
||||
"type" : ["HERO"]
|
||||
},
|
||||
"art167":
|
||||
{
|
||||
"index" : 167,
|
||||
"type" : ["HERO"]
|
||||
},
|
||||
"art168":
|
||||
{
|
||||
"index" : 168,
|
||||
"type" : ["HERO"]
|
||||
},
|
||||
"art169":
|
||||
{
|
||||
"index" : 169,
|
||||
"type" : ["HERO"]
|
||||
},
|
||||
"art170":
|
||||
{
|
||||
"index" : 170,
|
||||
"type" : ["HERO"]
|
||||
}
|
||||
}
|
@ -1,817 +0,0 @@
|
||||
{
|
||||
"core:creatureBank" : {
|
||||
"types" : {
|
||||
"huntingLodge" : {
|
||||
"name" : "Hunting Lodge",
|
||||
"index" : 11,
|
||||
"levels": [
|
||||
{
|
||||
"chance": 30,
|
||||
"guards": [
|
||||
{ "amount": 3, "type" : "dendroidGuard" },
|
||||
{ "amount": 4, "type" : "woodElf" },
|
||||
{ "amount": 3, "type" : "dendroidGuard" },
|
||||
{ "amount": 4, "type" : "woodElf" }
|
||||
],
|
||||
"combat_value": 100,
|
||||
"reward" : {
|
||||
"resources":
|
||||
{
|
||||
"wood" : 15,
|
||||
"gold" : 500
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"chance": 30,
|
||||
"guards": [
|
||||
{ "amount": 4, "type" : "dendroidGuard" },
|
||||
{ "amount": 6, "type" : "woodElf" },
|
||||
{ "amount": 4, "type" : "dendroidGuard" },
|
||||
{ "amount": 6, "type" : "woodElf" }
|
||||
],
|
||||
"combat_value": 150,
|
||||
"reward" : {
|
||||
"resources":
|
||||
{
|
||||
"wood" : 20,
|
||||
"gold" : 500
|
||||
},
|
||||
"value": 3000
|
||||
}
|
||||
},
|
||||
{
|
||||
"chance": 30,
|
||||
"guards": [
|
||||
{ "amount": 5, "type" : "dendroidGuard" },
|
||||
{ "amount": 8, "type" : "woodElf" },
|
||||
{ "amount": 5, "type" : "dendroidGuard" },
|
||||
{ "amount": 8, "type" : "woodElf" }
|
||||
],
|
||||
"combat_value": 200,
|
||||
"reward" : {
|
||||
"resources":
|
||||
{
|
||||
"wood" : 25,
|
||||
"gold" : 500
|
||||
},
|
||||
"value": 4000
|
||||
}
|
||||
},
|
||||
{
|
||||
"chance": 10,
|
||||
"guards": [
|
||||
{ "amount": 6, "type" : "dendroidGuard" },
|
||||
{ "amount": 10, "type" : "woodElf" },
|
||||
{ "amount": 6, "type" : "dendroidGuard" },
|
||||
{ "amount": 10, "type" : "woodElf" }
|
||||
],
|
||||
"combat_value": 300,
|
||||
"reward" : {
|
||||
"resources":
|
||||
{
|
||||
"wood" : 40,
|
||||
"gold" : 1000
|
||||
},
|
||||
"value": 6000
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"snowGrotto" :
|
||||
{
|
||||
"name" : "Snow-covered Grotto",
|
||||
"index" : 12,
|
||||
"levels": [
|
||||
{
|
||||
"chance": 30,
|
||||
"guards": [
|
||||
{ "amount": 5, "type" : "ironGolem" },
|
||||
{ "amount": 20, "type" : "masterGremlin" },
|
||||
{ "amount": 5, "type" : "ironGolem" },
|
||||
{ "amount": 20, "type" : "masterGremlin" }
|
||||
],
|
||||
"combat_value": 100,
|
||||
"reward" : {
|
||||
"resources":
|
||||
{
|
||||
"ore" : 15,
|
||||
"gold" : 500
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"chance": 30,
|
||||
"guards": [
|
||||
{ "amount": 6, "type" : "ironGolem" },
|
||||
{ "amount": 30, "type" : "masterGremlin" },
|
||||
{ "amount": 6, "type" : "ironGolem" },
|
||||
{ "amount": 30, "type" : "masterGremlin" }
|
||||
],
|
||||
"combat_value": 150,
|
||||
"reward" : {
|
||||
"resources":
|
||||
{
|
||||
"ore" : 20,
|
||||
"gold" : 500
|
||||
},
|
||||
"value": 3000
|
||||
}
|
||||
},
|
||||
{
|
||||
"chance": 30,
|
||||
"guards": [
|
||||
{ "amount": 7, "type" : "ironGolem" },
|
||||
{ "amount": 40, "type" : "masterGremlin" },
|
||||
{ "amount": 7, "type" : "ironGolem" },
|
||||
{ "amount": 40, "type" : "masterGremlin" }
|
||||
],
|
||||
"combat_value": 200,
|
||||
"reward" : {
|
||||
"resources":
|
||||
{
|
||||
"ore" : 30,
|
||||
"gold" : 500
|
||||
},
|
||||
"value": 4000
|
||||
}
|
||||
},
|
||||
{
|
||||
"chance": 10,
|
||||
"guards": [
|
||||
{ "amount": 8, "type" : "ironGolem" },
|
||||
{ "amount": 50, "type" : "masterGremlin" },
|
||||
{ "amount": 8, "type" : "ironGolem" },
|
||||
{ "amount": 50, "type" : "masterGremlin" }
|
||||
],
|
||||
"combat_value": 300,
|
||||
"reward" : {
|
||||
"resources":
|
||||
{
|
||||
"ore" : 40,
|
||||
"gold" : 1000
|
||||
},
|
||||
"value": 6000
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"martialSpiritPalace" :
|
||||
{
|
||||
"name" : "Palace of Martial Spirit",
|
||||
"index" : 13,
|
||||
"levels": [
|
||||
{
|
||||
"chance": 30,
|
||||
"guards": [
|
||||
{ "amount": 10, "type" : "godWar" },
|
||||
{ "amount": 10, "type" : "godWar" },
|
||||
{ "amount": 10, "type" : "godWar" },
|
||||
{ "amount": 10, "type" : "godWar" }
|
||||
],
|
||||
"combat_value": 2000,
|
||||
"reward" : {
|
||||
"creatures": [
|
||||
{ "amount": 1, "type" : "godWar" }
|
||||
],
|
||||
"value": 38000
|
||||
}
|
||||
},
|
||||
{
|
||||
"chance": 30,
|
||||
"guards": [
|
||||
{ "amount": 15, "type" : "godWar" },
|
||||
{ "amount": 15, "type" : "godWar" },
|
||||
{ "amount": 15, "type" : "godWar" },
|
||||
{ "amount": 15, "type" : "godWar" }
|
||||
],
|
||||
"combat_value": 2000,
|
||||
"reward" : {
|
||||
"creatures": [
|
||||
{ "amount": 1, "type" : "godWar" }
|
||||
],
|
||||
"value": 57000
|
||||
}
|
||||
},
|
||||
{
|
||||
"chance": 30,
|
||||
"guards": [
|
||||
{ "amount": 20, "type" : "godWar" },
|
||||
{ "amount": 20, "type" : "godWar" },
|
||||
{ "amount": 20, "type" : "godWar" },
|
||||
{ "amount": 20, "type" : "godWar" }
|
||||
],
|
||||
"combat_value": 2000,
|
||||
"reward" : {
|
||||
"creatures": [
|
||||
{ "amount": 1, "type" : "godWar" }
|
||||
],
|
||||
"value": 75000
|
||||
}
|
||||
},
|
||||
{
|
||||
"chance": 10,
|
||||
"guards": [
|
||||
{ "amount": 30, "type" : "godWar" },
|
||||
{ "amount": 30, "type" : "godWar" },
|
||||
{ "amount": 30, "type" : "godWar" },
|
||||
{ "amount": 30, "type" : "godWar" }
|
||||
],
|
||||
"combat_value": 2000,
|
||||
"reward" : {
|
||||
"creatures": [
|
||||
{ "amount": 1, "type" : "godWar" }
|
||||
],
|
||||
"value": 90000
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"pacificationCitadel" :
|
||||
{
|
||||
"name" : "Citadel of Pacification",
|
||||
"index" : 14,
|
||||
"levels": [
|
||||
{
|
||||
"chance": 30,
|
||||
"guards": [
|
||||
{ "amount": 10, "type" : "godPeace" },
|
||||
{ "amount": 10, "type" : "godPeace" },
|
||||
{ "amount": 10, "type" : "godPeace" },
|
||||
{ "amount": 10, "type" : "godPeace" }
|
||||
],
|
||||
"combat_value": 2000,
|
||||
"reward" : {
|
||||
"creatures": [
|
||||
{ "amount": 1, "type" : "godPeace" }
|
||||
],
|
||||
"value": 38000
|
||||
}
|
||||
},
|
||||
{
|
||||
"chance": 30,
|
||||
"guards": [
|
||||
{ "amount": 15, "type" : "godPeace" },
|
||||
{ "amount": 15, "type" : "godPeace" },
|
||||
{ "amount": 15, "type" : "godPeace" },
|
||||
{ "amount": 15, "type" : "godPeace" }
|
||||
],
|
||||
"combat_value": 2000,
|
||||
"reward" : {
|
||||
"creatures": [
|
||||
{ "amount": 1, "type" : "godPeace" }
|
||||
],
|
||||
"value": 57000
|
||||
}
|
||||
},
|
||||
{
|
||||
"chance": 30,
|
||||
"guards": [
|
||||
{ "amount": 20, "type" : "godPeace" },
|
||||
{ "amount": 20, "type" : "godPeace" },
|
||||
{ "amount": 20, "type" : "godPeace" },
|
||||
{ "amount": 20, "type" : "godPeace" }
|
||||
],
|
||||
"combat_value": 2000,
|
||||
"reward" : {
|
||||
"creatures": [
|
||||
{ "amount": 1, "type" : "godPeace" }
|
||||
],
|
||||
"value": 75000
|
||||
}
|
||||
},
|
||||
{
|
||||
"chance": 10,
|
||||
"guards": [
|
||||
{ "amount": 30, "type" : "godPeace" },
|
||||
{ "amount": 30, "type" : "godPeace" },
|
||||
{ "amount": 30, "type" : "godPeace" },
|
||||
{ "amount": 30, "type" : "godPeace" }
|
||||
],
|
||||
"combat_value": 2000,
|
||||
"reward" : {
|
||||
"creatures": [
|
||||
{ "amount": 1, "type" : "godPeace" }
|
||||
],
|
||||
"value": 90000
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"magiciansMonastery" :
|
||||
{
|
||||
"name" : "Monastery of Magicians",
|
||||
"index" : 15,
|
||||
"levels": [
|
||||
{
|
||||
"chance": 30,
|
||||
"guards": [
|
||||
{ "amount": 10, "type" : "godMana" },
|
||||
{ "amount": 10, "type" : "godMana" },
|
||||
{ "amount": 10, "type" : "godMana" },
|
||||
{ "amount": 10, "type" : "godMana" }
|
||||
],
|
||||
"combat_value": 2000,
|
||||
"reward" : {
|
||||
"creatures": [
|
||||
{ "amount": 1, "type" : "godMana" }
|
||||
],
|
||||
"value": 38000
|
||||
}
|
||||
},
|
||||
{
|
||||
"chance": 30,
|
||||
"guards": [
|
||||
{ "amount": 15, "type" : "godMana" },
|
||||
{ "amount": 15, "type" : "godMana" },
|
||||
{ "amount": 15, "type" : "godMana" },
|
||||
{ "amount": 15, "type" : "godMana" }
|
||||
],
|
||||
"combat_value": 2000,
|
||||
"reward" : {
|
||||
"creatures": [
|
||||
{ "amount": 1, "type" : "godMana" }
|
||||
],
|
||||
"value": 57000
|
||||
}
|
||||
},
|
||||
{
|
||||
"chance": 30,
|
||||
"guards": [
|
||||
{ "amount": 20, "type" : "godMana" },
|
||||
{ "amount": 20, "type" : "godMana" },
|
||||
{ "amount": 20, "type" : "godMana" },
|
||||
{ "amount": 20, "type" : "godMana" }
|
||||
],
|
||||
"combat_value": 2000,
|
||||
"reward" : {
|
||||
"creatures": [
|
||||
{ "amount": 1, "type" : "godMana" }
|
||||
],
|
||||
"value": 75000
|
||||
}
|
||||
},
|
||||
{
|
||||
"chance": 10,
|
||||
"guards": [
|
||||
{ "amount": 30, "type" : "godMana" },
|
||||
{ "amount": 30, "type" : "godMana" },
|
||||
{ "amount": 30, "type" : "godMana" },
|
||||
{ "amount": 30, "type" : "godMana" }
|
||||
],
|
||||
"combat_value": 2000,
|
||||
"reward" : {
|
||||
"creatures": [
|
||||
{ "amount": 1, "type" : "godMana" }
|
||||
],
|
||||
"value": 90000
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"legendsLibrary" :
|
||||
{
|
||||
"name" : "Library of Legends",
|
||||
"index" : 16,
|
||||
"levels": [
|
||||
{
|
||||
"chance": 30,
|
||||
"guards": [
|
||||
{ "amount": 10, "type" : "godLore" },
|
||||
{ "amount": 10, "type" : "godLore" },
|
||||
{ "amount": 10, "type" : "godLore" },
|
||||
{ "amount": 10, "type" : "godLore" }
|
||||
],
|
||||
"combat_value": 2000,
|
||||
"reward" : {
|
||||
"creatures": [
|
||||
{ "amount": 1, "type" : "godLore" }
|
||||
],
|
||||
"value": 38000
|
||||
}
|
||||
},
|
||||
{
|
||||
"chance": 30,
|
||||
"guards": [
|
||||
{ "amount": 15, "type" : "godLore" },
|
||||
{ "amount": 15, "type" : "godLore" },
|
||||
{ "amount": 15, "type" : "godLore" },
|
||||
{ "amount": 15, "type" : "godLore" }
|
||||
],
|
||||
"combat_value": 2000,
|
||||
"reward" : {
|
||||
"creatures": [
|
||||
{ "amount": 1, "type" : "godLore" }
|
||||
],
|
||||
"value": 57000
|
||||
}
|
||||
},
|
||||
{
|
||||
"chance": 30,
|
||||
"guards": [
|
||||
{ "amount": 20, "type" : "godLore" },
|
||||
{ "amount": 20, "type" : "godLore" },
|
||||
{ "amount": 20, "type" : "godLore" },
|
||||
{ "amount": 20, "type" : "godLore" }
|
||||
],
|
||||
"combat_value": 2000,
|
||||
"reward" : {
|
||||
"creatures": [
|
||||
{ "amount": 1, "type" : "godLore" }
|
||||
],
|
||||
"value": 75000
|
||||
}
|
||||
},
|
||||
{
|
||||
"chance": 10,
|
||||
"guards": [
|
||||
{ "amount": 30, "type" : "godLore" },
|
||||
{ "amount": 30, "type" : "godLore" },
|
||||
{ "amount": 30, "type" : "godLore" },
|
||||
{ "amount": 30, "type" : "godLore" }
|
||||
],
|
||||
"combat_value": 2000,
|
||||
"reward" : {
|
||||
"creatures": [
|
||||
{ "amount": 1, "type" : "godLore" }
|
||||
],
|
||||
"value": 90000
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"transylvanianTavern" :
|
||||
{
|
||||
"name" : "Transylvanian Tavern",
|
||||
"index" : 17,
|
||||
"levels": [
|
||||
{
|
||||
"chance": 30,
|
||||
"guards": [
|
||||
{ "amount": 2, "type" : "vampire" },
|
||||
{ "amount": 2, "type" : "vampire" },
|
||||
{ "amount": 2, "type" : "vampire" },
|
||||
{ "amount": 2, "type" : "vampire" },
|
||||
{ "amount": 2, "type" : "vampire" }
|
||||
],
|
||||
"combat_value": 100,
|
||||
"reward" : {
|
||||
"resources":
|
||||
{
|
||||
"gold" : 1500
|
||||
},
|
||||
"creatures": [
|
||||
{ "amount": 3, "type" : "vampireLord" }
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"chance": 30,
|
||||
"guards": [
|
||||
{ "amount": 3, "type" : "vampire" },
|
||||
{ "amount": 3, "type" : "vampire" },
|
||||
{ "amount": 3, "type" : "vampire" },
|
||||
{ "amount": 3, "type" : "vampire" },
|
||||
{ "amount": 3, "type" : "vampire" }
|
||||
],
|
||||
"combat_value": 150,
|
||||
"reward" : {
|
||||
"resources":
|
||||
{
|
||||
"gold" : 2500
|
||||
},
|
||||
"creatures": [
|
||||
{ "amount": 5, "type" : "vampireLord" }
|
||||
],
|
||||
"value": 3000
|
||||
}
|
||||
},
|
||||
{
|
||||
"chance": 30,
|
||||
"guards": [
|
||||
{ "amount": 4, "type" : "vampire" },
|
||||
{ "amount": 4, "type" : "vampire" },
|
||||
{ "amount": 4, "type" : "vampire" },
|
||||
{ "amount": 4, "type" : "vampire" },
|
||||
{ "amount": 4, "type" : "vampire" }
|
||||
],
|
||||
"combat_value": 200,
|
||||
"reward" : {
|
||||
"resources":
|
||||
{
|
||||
"gold" : 3500
|
||||
},
|
||||
"creatures": [
|
||||
{ "amount": 7, "type" : "vampireLord" }
|
||||
],
|
||||
"value": 4000
|
||||
}
|
||||
},
|
||||
{
|
||||
"chance": 10,
|
||||
"guards": [
|
||||
{ "amount": 6, "type" : "vampire" },
|
||||
{ "amount": 6, "type" : "vampire" },
|
||||
{ "amount": 6, "type" : "vampire" },
|
||||
{ "amount": 6, "type" : "vampire" },
|
||||
{ "amount": 6, "type" : "vampire" }
|
||||
],
|
||||
"combat_value": 250,
|
||||
"reward" : {
|
||||
"resources":
|
||||
{
|
||||
"gold" : 5000
|
||||
},
|
||||
"creatures": [
|
||||
{ "amount": 9, "type" : "vampireLord" }
|
||||
],
|
||||
"value": 5000
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"homeofthebat" :
|
||||
{
|
||||
"name" : "Home of the Bat",
|
||||
"index" : 18,
|
||||
"levels": [
|
||||
{
|
||||
"chance": 30,
|
||||
"guards": [
|
||||
{ "amount": 2, "type" : "vampire" },
|
||||
{ "amount": 2, "type" : "vampire" },
|
||||
{ "amount": 2, "type" : "vampire", "upgrade_chance": 50 },
|
||||
{ "amount": 2, "type" : "vampire" },
|
||||
{ "amount": 2, "type" : "vampire" }
|
||||
],
|
||||
"combat_value": 100,
|
||||
"reward" : {
|
||||
"resources":
|
||||
{
|
||||
"mercury" : 2,
|
||||
"sulfur" : 2,
|
||||
"crystal" : 2,
|
||||
"gems" : 2
|
||||
},
|
||||
"creatures": [
|
||||
{ "amount": 3, "type" : "vampireLord" }
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"chance": 30,
|
||||
"guards": [
|
||||
{ "amount": 3, "type" : "vampire" },
|
||||
{ "amount": 3, "type" : "vampire" },
|
||||
{ "amount": 3, "type" : "vampire", "upgrade_chance": 70 },
|
||||
{ "amount": 3, "type" : "vampire" },
|
||||
{ "amount": 3, "type" : "vampire" }
|
||||
],
|
||||
"combat_value": 150,
|
||||
"reward" : {
|
||||
"resources":
|
||||
{
|
||||
"mercury" : 3,
|
||||
"sulfur" : 3,
|
||||
"crystal" : 3,
|
||||
"gems" : 3
|
||||
},
|
||||
"creatures": [
|
||||
{ "amount": 5, "type" : "vampireLord" }
|
||||
],
|
||||
"value": 3000
|
||||
}
|
||||
},
|
||||
{
|
||||
"chance": 30,
|
||||
"guards": [
|
||||
{ "amount": 4, "type" : "vampire" },
|
||||
{ "amount": 4, "type" : "vampire" },
|
||||
{ "amount": 4, "type" : "vampire", "upgrade_chance": 80 },
|
||||
{ "amount": 4, "type" : "vampire" },
|
||||
{ "amount": 4, "type" : "vampire" }
|
||||
],
|
||||
"combat_value": 200,
|
||||
"reward" : {
|
||||
"resources":
|
||||
{
|
||||
"mercury" : 4,
|
||||
"sulfur" : 4,
|
||||
"crystal" : 4,
|
||||
"gems" : 4
|
||||
},
|
||||
"creatures": [
|
||||
{ "amount": 7, "type" : "vampireLord" }
|
||||
],
|
||||
"value": 4000
|
||||
}
|
||||
},
|
||||
{
|
||||
"chance": 10,
|
||||
"guards": [
|
||||
{ "amount": 6, "type" : "vampire" },
|
||||
{ "amount": 6, "type" : "vampire" },
|
||||
{ "amount": 6, "type" : "vampire", "upgrade_chance": 50 },
|
||||
{ "amount": 6, "type" : "vampire" },
|
||||
{ "amount": 6, "type" : "vampire" }
|
||||
],
|
||||
"combat_value": 250,
|
||||
"reward" : {
|
||||
"resources":
|
||||
{
|
||||
"mercury" : 5,
|
||||
"sulfur" : 5,
|
||||
"crystal" : 5,
|
||||
"gems" : 5
|
||||
},
|
||||
"creatures": [
|
||||
{ "amount": 9, "type" : "vampireLord" }
|
||||
],
|
||||
"value": 5000
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"lostBottle" :
|
||||
{
|
||||
"name" : "Lost Bottle",
|
||||
"index" : 19,
|
||||
"levels": [
|
||||
{
|
||||
"chance": 30,
|
||||
"guards": [
|
||||
{ "amount": 2, "type" : "genie" },
|
||||
{ "amount": 2, "type" : "genie" },
|
||||
{ "amount": 2, "type" : "genie", "upgrade_chance": 50 },
|
||||
{ "amount": 2, "type" : "genie" },
|
||||
{ "amount": 2, "type" : "genie" }
|
||||
],
|
||||
"combat_value": 100,
|
||||
"reward" : {
|
||||
"resources":
|
||||
{
|
||||
"mercury" : 2,
|
||||
"sulfur" : 2,
|
||||
"crystal" : 2,
|
||||
"gems" : 2
|
||||
},
|
||||
"creatures": [
|
||||
{ "amount": 3, "type" : "genie" }
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"chance": 30,
|
||||
"guards": [
|
||||
{ "amount": 3, "type" : "genie" },
|
||||
{ "amount": 3, "type" : "genie" },
|
||||
{ "amount": 3, "type" : "genie", "upgrade_chance": 70 },
|
||||
{ "amount": 3, "type" : "genie" },
|
||||
{ "amount": 3, "type" : "genie" }
|
||||
],
|
||||
"combat_value": 150,
|
||||
"reward" : {
|
||||
"resources":
|
||||
{
|
||||
"mercury" : 3,
|
||||
"sulfur" : 3,
|
||||
"crystal" : 3,
|
||||
"gems" : 3
|
||||
},
|
||||
"creatures": [
|
||||
{ "amount": 5, "type" : "genie" }
|
||||
],
|
||||
"value": 3000
|
||||
}
|
||||
},
|
||||
{
|
||||
"chance": 30,
|
||||
"guards": [
|
||||
{ "amount": 4, "type" : "genie" },
|
||||
{ "amount": 4, "type" : "genie" },
|
||||
{ "amount": 4, "type" : "genie", "upgrade_chance": 80 },
|
||||
{ "amount": 4, "type" : "genie" },
|
||||
{ "amount": 4, "type" : "genie" }
|
||||
],
|
||||
"combat_value": 200,
|
||||
"reward" : {
|
||||
"resources":
|
||||
{
|
||||
"mercury" : 4,
|
||||
"sulfur" : 4,
|
||||
"crystal" : 4,
|
||||
"gems" : 4
|
||||
},
|
||||
"creatures": [
|
||||
{ "amount": 7, "type" : "genie" }
|
||||
],
|
||||
"value": 4000
|
||||
}
|
||||
},
|
||||
{
|
||||
"chance": 10,
|
||||
"guards": [
|
||||
{ "amount": 6, "type" : "genie" },
|
||||
{ "amount": 6, "type" : "genie" },
|
||||
{ "amount": 6, "type" : "genie", "upgrade_chance": 90 },
|
||||
{ "amount": 6, "type" : "genie" },
|
||||
{ "amount": 6, "type" : "genie" }
|
||||
],
|
||||
"combat_value": 250,
|
||||
"reward" : {
|
||||
"resources":
|
||||
{
|
||||
"mercury" : 5,
|
||||
"sulfur" : 5,
|
||||
"crystal" : 5,
|
||||
"gems" : 5
|
||||
},
|
||||
"creatures": [
|
||||
{ "amount": 9, "type" : "genie" }
|
||||
],
|
||||
"value": 5000
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"grotto" :
|
||||
{
|
||||
"name" : "Grotto",
|
||||
"index" : 20,
|
||||
"levels": [
|
||||
{
|
||||
"chance": 30,
|
||||
"guards": [
|
||||
{ "amount": 3, "type" : "harpy" },
|
||||
{ "amount": 3, "type" : "beholder" },
|
||||
{ "amount": 3, "type" : "harpy" },
|
||||
{ "amount": 3, "type" : "beholder" }
|
||||
],
|
||||
"combat_value": 200,
|
||||
"reward" : {
|
||||
"resources":
|
||||
{
|
||||
"ore" : 20,
|
||||
"gold" : 1000
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"chance": 30,
|
||||
"guards": [
|
||||
{ "amount": 4, "type" : "harpy" },
|
||||
{ "amount": 4, "type" : "beholder" },
|
||||
{ "amount": 4, "type" : "harpy" },
|
||||
{ "amount": 4, "type" : "beholder" }
|
||||
],
|
||||
"combat_value": 300,
|
||||
"reward" : {
|
||||
"resources":
|
||||
{
|
||||
"ore" : 25,
|
||||
"gold" : 1000
|
||||
},
|
||||
"value": 3000
|
||||
}
|
||||
},
|
||||
{
|
||||
"chance": 30,
|
||||
"guards": [
|
||||
{ "amount": 5, "type" : "harpy" },
|
||||
{ "amount": 5, "type" : "beholder" },
|
||||
{ "amount": 5, "type" : "harpy" },
|
||||
{ "amount": 5, "type" : "beholder" }
|
||||
],
|
||||
"combat_value": 400,
|
||||
"reward" : {
|
||||
"resources":
|
||||
{
|
||||
"ore" : 30,
|
||||
"gold" : 1500
|
||||
},
|
||||
"value": 4000
|
||||
}
|
||||
},
|
||||
{
|
||||
"chance": 10,
|
||||
"guards": [
|
||||
{ "amount": 6, "type" : "harpy" },
|
||||
{ "amount": 6, "type" : "beholder" },
|
||||
{ "amount": 6, "type" : "harpy" },
|
||||
{ "amount": 6, "type" : "beholder" }
|
||||
],
|
||||
"combat_value": 500,
|
||||
"reward" : {
|
||||
"resources":
|
||||
{
|
||||
"ore" : 35,
|
||||
"gold" : 2000
|
||||
},
|
||||
"value": 5000
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
@ -1,31 +0,0 @@
|
||||
{
|
||||
"core:creatureGeneratorCommon" : {
|
||||
"types" : {
|
||||
"supremeArchangel" : { "index" : 80, "creatures" : [[ "supremeArchangel" ]] },
|
||||
"diamondDragon" : { "index" : 81, "creatures" : [[ "diamondDragon" ]] },
|
||||
"lordofThunder" : { "index" : 82, "creatures" : [[ "lordofThunder" ]] },
|
||||
"hellBaron" : { "index" : 83, "creatures" : [[ "hellBaron" ]] },
|
||||
"bloodDragon" : { "index" : 84, "creatures" : [[ "bloodDragon" ]] },
|
||||
|
||||
"darknessDragon" : { "index" : 85, "creatures" : [[ "darknessDragon" ]] },
|
||||
"ghostBehemoth" : { "index" : 86, "creatures" : [[ "ghostBehemoth" ]] },
|
||||
"hellHydra" : { "index" : 87, "creatures" : [[ "hellHydra" ]] },
|
||||
"sacredPhoenix" : { "index" : 88, "creatures" : [[ "sacredPhoenix" ]] },
|
||||
"lavaSharpshooter" : { "index" : 89, "creatures" : [[ "lavaSharpshooter" ]] },
|
||||
|
||||
"arcticSharpshooter" : { "index" : 90, "creatures" : [[ "arcticSharpshooter" ]] },
|
||||
"gorynych" : { "index" : 91, "creatures" : [[ "gorynych" ]] },
|
||||
"nightmare" : { "index" : 92, "creatures" : [[ "nightmare" ]] },
|
||||
"minotaurKing2" : { "index" : 93, "creatures" : [[ "minotaurKing2" ]] },
|
||||
"warZealot" : { "index" : 94, "creatures" : [[ "warZealot" ]] },
|
||||
|
||||
"santaGremlin" : { "index" : 95, "creatures" : [[ "santaGremlin" ]] },
|
||||
"sylvanCentaur" : { "index" : 96, "creatures" : [[ "sylvanCentaur" ]] },
|
||||
"sorceress" : { "index" : 97, "creatures" : [[ "sorceress" ]] },
|
||||
"werewolf" : { "index" : 98, "creatures" : [[ "werewolf" ]] },
|
||||
"hellSteed" : { "index" : 99, "creatures" : [[ "hellSteed" ]] },
|
||||
|
||||
"dracolich" : { "index" :100, "creatures" : [[ "dracolich" ]] }
|
||||
}
|
||||
}
|
||||
}
|
@ -1,74 +0,0 @@
|
||||
{
|
||||
"core:knight" :
|
||||
{
|
||||
"commander" : "paladin1"
|
||||
},
|
||||
"core:cleric" :
|
||||
{
|
||||
"commander" : "paladin1"
|
||||
},
|
||||
"core:planeswalker" :
|
||||
{
|
||||
"commander" : "astralSpirit1"
|
||||
},
|
||||
"core:elementalist" :
|
||||
{
|
||||
"commander" : "astralSpirit1"
|
||||
},
|
||||
"core:warlock" :
|
||||
{
|
||||
"commander" : "brute1"
|
||||
},
|
||||
"core:overlord" :
|
||||
{
|
||||
"commander" : "brute1"
|
||||
},
|
||||
"core:beastmaster" :
|
||||
{
|
||||
"commander" : "shaman1"
|
||||
},
|
||||
"core:witch" :
|
||||
{
|
||||
"commander" : "shaman1"
|
||||
},
|
||||
"core:demoniac" :
|
||||
{
|
||||
"commander" : "succubus1"
|
||||
},
|
||||
"core:heretic" :
|
||||
{
|
||||
"commander" : "succubus1"
|
||||
},
|
||||
"core:deathknight" :
|
||||
{
|
||||
"commander" : "soulEater1"
|
||||
},
|
||||
"core:necromancer" :
|
||||
{
|
||||
"commander" : "soulEater1"
|
||||
},
|
||||
"core:ranger" :
|
||||
{
|
||||
"commander" : "hierophant1"
|
||||
},
|
||||
"core:druid" :
|
||||
{
|
||||
"commander" : "hierophant1"
|
||||
},
|
||||
"core:barbarian" :
|
||||
{
|
||||
"commander" : "ogreLeader1"
|
||||
},
|
||||
"core:battlemage" :
|
||||
{
|
||||
"commander" : "ogreLeader1"
|
||||
},
|
||||
"core:alchemist" :
|
||||
{
|
||||
"commander" : "templeGuardian1"
|
||||
},
|
||||
"core:wizard" :
|
||||
{
|
||||
"commander" : "templeGuardian1"
|
||||
}
|
||||
}
|
@ -1,57 +0,0 @@
|
||||
{
|
||||
|
||||
"core:implosion" :
|
||||
{
|
||||
"graphics" : {
|
||||
"iconImmune" : "ZVS/LIB1.RES/E_SPIMP"
|
||||
}
|
||||
},
|
||||
|
||||
"core:meteorShower" : {
|
||||
"graphics" : {
|
||||
"iconImmune" : "ZVS/LIB1.RES/E_SPMET"
|
||||
}
|
||||
},
|
||||
"core:armageddon" : {
|
||||
|
||||
"graphics" : {
|
||||
"iconImmune" : "ZVS/LIB1.RES/E_SPARM"
|
||||
}
|
||||
|
||||
},
|
||||
"core:dispel" : {
|
||||
|
||||
"graphics" : {
|
||||
"iconImmune" : "ZVS/LIB1.RES/E_SPDISP"
|
||||
}
|
||||
|
||||
},
|
||||
"core:slow" : {
|
||||
"graphics" : {
|
||||
"iconImmune" : "ZVS/LIB1.RES/E_SPSLOW"
|
||||
}
|
||||
},
|
||||
|
||||
"core:berserk" : {
|
||||
"graphics" : {
|
||||
"iconImmune" : "ZVS/LIB1.RES/E_SPBERS"
|
||||
}
|
||||
},
|
||||
"core:hypnotize" : {
|
||||
"graphics" : {
|
||||
"iconImmune" : "ZVS/LIB1.RES/E_SPHYPN"
|
||||
}
|
||||
},
|
||||
|
||||
"core:blind" : {
|
||||
"graphics" : {
|
||||
"iconImmune" : "ZVS/LIB1.RES/E_SPBLIND"
|
||||
}
|
||||
},
|
||||
|
||||
"core:dispelHelpful" : {
|
||||
"graphics" : {
|
||||
"iconImmune" : "ZVS/LIB1.RES/E_SPDISB"
|
||||
}
|
||||
}
|
||||
}
|
@ -1,45 +0,0 @@
|
||||
{
|
||||
// Text configs
|
||||
"data/crgen1.txt" : "data/zcrgn1.txt",
|
||||
"data/crtraits.txt" : "data/zcrtrait.txt",
|
||||
"data/help.txt" : "data/zelp.txt",
|
||||
"data/objects.txt" : "data/zobjcts.txt",
|
||||
|
||||
// main menu images
|
||||
"data/gamselb0.bmp" : "data/ZPIC1000.bmp", // map selection screen
|
||||
"data/gamselb1.bmp" : "data/ZPIC1001.bmp", // map selection screen
|
||||
"data/loadbar.bmp" : "data/ZPIC106.bmp", // loading screen
|
||||
"data/gamselbk.bmp" : "data/ZPIC1005.bmp", // background
|
||||
"data/newgame.bmp" : "data/ZNEWGAM.bmp", // "new game" text
|
||||
"data/loadgame.bmp" : "data/ZLOADGAM.bmp", // "load game" text
|
||||
|
||||
// main menu buttons
|
||||
"sprites/mmenung.def" : "sprites/zmenung.def",
|
||||
"sprites/mmenulg.def" : "sprites/zmenulg.def",
|
||||
"sprites/mmenuhs.def" : "sprites/zmenuhs.def",
|
||||
"sprites/mmenucr.def" : "sprites/zmenucr.def",
|
||||
"sprites/mmenuqt.def" : "sprites/zmenuqt.def",
|
||||
|
||||
// game type select (single/multi/campaign)
|
||||
"sprites/gtsingl.def" : "sprites/ztsingl.def",
|
||||
"sprites/gtmulti.def" : "sprites/ztmulti.def",
|
||||
"sprites/gtcampn.def" : "sprites/ztcampn.def",
|
||||
"sprites/gttutor.def" : "sprites/zttutor.def",
|
||||
"sprites/gtback.def" : "sprites/ztback.def",
|
||||
|
||||
// campaigns
|
||||
"sprites/csssod.def" : "sprites/zsssod.def",
|
||||
"sprites/cssroe.def" : "sprites/zssroe.def",
|
||||
"sprites/cssarm.def" : "sprites/zssarm.def",
|
||||
"sprites/csscus.def" : "sprites/zsscus.def",
|
||||
|
||||
// resource bars
|
||||
"data/tresbar.bmp" : "data/zresbar.bmp",
|
||||
"data/kresbar.bmp" : "data/z2esbar.bmp",
|
||||
"data/aresbar.bmp" : "data/zresbar.bmp",
|
||||
|
||||
// misc
|
||||
"data/tpcainfo.bmp" : "data/zpcainfo.bmp", // stats images for town fort
|
||||
"music/mainmenu.mp3" : "music/mainmenuwog.mp3",
|
||||
"video/credits.bik" : "video/acredit.bik"
|
||||
}
|
@ -1,72 +0,0 @@
|
||||
{
|
||||
"name" : "In The Wake of Gods",
|
||||
"description" : "Unnofficial addon for Heroes of Might and Magic III",
|
||||
|
||||
"version" : "0.0.0",
|
||||
"author" : "WoG Team",
|
||||
"contact" : "http://forum.vcmi.eu/index.php",
|
||||
"modType" : "Expansion",
|
||||
|
||||
"artifacts" :
|
||||
[
|
||||
"config/wog/artifacts.json"
|
||||
],
|
||||
|
||||
"creatures" :
|
||||
[
|
||||
"config/wog/creatures.json"
|
||||
],
|
||||
|
||||
"heroClasses" :
|
||||
[
|
||||
"config/wog/heroClasses.json"
|
||||
],
|
||||
|
||||
"objects" :
|
||||
[
|
||||
"config/wog/dwellings.json",
|
||||
"config/wog/creatureBanks.json"
|
||||
],
|
||||
|
||||
"filesystem":
|
||||
{
|
||||
"" :
|
||||
[
|
||||
{ "type" : "map", "path" : "/Config/wogFileOverrides.json"}
|
||||
],
|
||||
"CONFIG/" :
|
||||
[
|
||||
{ "type" : "dir", "path" : "/Config"}
|
||||
],
|
||||
"DATA/" :
|
||||
[
|
||||
{"type" : "lod", "path" : "/Data/hmm35wog.pac"},
|
||||
{"type" : "dir", "path" : "/Data"}
|
||||
],
|
||||
"SPRITES/":
|
||||
[
|
||||
{"type" : "lod", "path" : "/Data/hmm35wog.pac"},
|
||||
{"type" : "lod", "path" : "/Data/wog - animated objects.pac"},
|
||||
{"type" : "lod", "path" : "/Data/wog - animated trees.pac"},
|
||||
{"type" : "lod", "path" : "/Data/wog - battle decorations.pac"}
|
||||
],
|
||||
"SOUNDS/":
|
||||
[
|
||||
{"type" : "snd", "path" : "/Data/wog - sounds.snd"},
|
||||
{"type" : "snd", "path" : "/Data/wog.snd"}
|
||||
],
|
||||
"MUSIC/":
|
||||
[
|
||||
{"type" : "dir", "path" : "/Mp3"}
|
||||
],
|
||||
"VIDEO/":
|
||||
[
|
||||
{"type" : "vid", "path" : "/Data/wog - video.vid"},
|
||||
{"type" : "vid", "path" : "/Data/wog.vid"}
|
||||
],
|
||||
"MAPS/":
|
||||
[
|
||||
{"type" : "dir", "path" : "/Maps"}
|
||||
]
|
||||
}
|
||||
}
|
@ -881,6 +881,9 @@ void CSelectionScreen::startScenario()
|
||||
|
||||
if(sInfo.mapGenOptions)
|
||||
{
|
||||
//copy settings from interface to actual options. TODO: refactor, it used to have no effect at all -.-
|
||||
sInfo.mapGenOptions = std::shared_ptr<CMapGenOptions>(new CMapGenOptions(randMapTab->getMapGenOptions()));
|
||||
|
||||
// Update player settings for RMG
|
||||
for(const auto & psetPair : sInfo.playerInfos)
|
||||
{
|
||||
|
@ -7,6 +7,10 @@
|
||||
{
|
||||
"index" : 0,
|
||||
"name" : "Cyclops Stockpile",
|
||||
"rmg" : {
|
||||
"value" : 3000,
|
||||
"rarity" : 100
|
||||
},
|
||||
"levels": [
|
||||
{
|
||||
"chance": 30,
|
||||
@ -17,7 +21,7 @@
|
||||
{ "amount": 4, "type": "cyclop" },
|
||||
{ "amount": 4, "type": "cyclop" }
|
||||
],
|
||||
|
||||
|
||||
"combat_value": 506,
|
||||
"reward" : {
|
||||
"value": 10000,
|
||||
@ -108,6 +112,10 @@
|
||||
"index" : 1,
|
||||
"resetDuraition" : 28,
|
||||
"name" : "Dwarven Treasury",
|
||||
"rmg" : {
|
||||
"value" : 2000,
|
||||
"rarity" : 100
|
||||
},
|
||||
"levels": [
|
||||
{
|
||||
"chance": 30,
|
||||
@ -191,6 +199,10 @@
|
||||
"index" : 2,
|
||||
"resetDuraition" : 28,
|
||||
"name" : "Griffin Conservatory",
|
||||
"rmg" : {
|
||||
"value" : 2000,
|
||||
"rarity" : 100
|
||||
},
|
||||
"levels": [
|
||||
{
|
||||
"chance": 30,
|
||||
@ -258,6 +270,10 @@
|
||||
"index" : 3,
|
||||
"resetDuraition" : 28,
|
||||
"name" : "Imp Cache",
|
||||
"rmg" : {
|
||||
"value" : 5000,
|
||||
"rarity" : 100
|
||||
},
|
||||
"levels": [
|
||||
{
|
||||
"chance": 30,
|
||||
@ -340,6 +356,10 @@
|
||||
"index" : 4,
|
||||
"resetDuraition" : 28,
|
||||
"name" : "Medusa Stores",
|
||||
"rmg" : {
|
||||
"value" : 1500,
|
||||
"rarity" : 100
|
||||
},
|
||||
"levels": [
|
||||
{
|
||||
"chance": 30,
|
||||
@ -423,6 +443,10 @@
|
||||
"index" : 5,
|
||||
"resetDuraition" : 28,
|
||||
"name" : "Naga Bank",
|
||||
"rmg" : {
|
||||
"value" : 3000,
|
||||
"rarity" : 100
|
||||
},
|
||||
"levels": [
|
||||
{
|
||||
"chance": 30,
|
||||
@ -506,6 +530,10 @@
|
||||
"index" : 6,
|
||||
"resetDuraition" : 28,
|
||||
"name" : "Dragon Fly Hive",
|
||||
"rmg" : {
|
||||
"value" : 9000,
|
||||
"rarity" : 100
|
||||
},
|
||||
"levels": [
|
||||
{
|
||||
"chance": 30,
|
||||
@ -579,6 +607,10 @@
|
||||
"index" : 0,
|
||||
"resetDuraition" : 28,
|
||||
"name" : "Shipwreck",
|
||||
"rmg" : {
|
||||
"value" : 2000,
|
||||
"rarity" : 100
|
||||
},
|
||||
"levels": [
|
||||
{
|
||||
"chance": 30,
|
||||
@ -666,6 +698,10 @@
|
||||
"index" : 0,
|
||||
"resetDuraition" : 28,
|
||||
"name" : "Derelict Ship",
|
||||
"rmg" : {
|
||||
"value" : 4000,
|
||||
"rarity" : 20
|
||||
},
|
||||
"levels": [
|
||||
{
|
||||
"chance": 30,
|
||||
@ -754,6 +790,10 @@
|
||||
"index" : 0,
|
||||
"resetDuraition" : 28,
|
||||
"name" : "Crypt",
|
||||
"rmg" : {
|
||||
"value" : 1000,
|
||||
"rarity" : 100
|
||||
},
|
||||
"levels": [
|
||||
{
|
||||
"chance": 30,
|
||||
@ -839,6 +879,10 @@
|
||||
"index" : 0,
|
||||
"resetDuraition" : 28,
|
||||
"name" : "Dragon Utopia",
|
||||
"rmg" : {
|
||||
"value" : 10000,
|
||||
"rarity" : 100
|
||||
},
|
||||
"levels": [
|
||||
{
|
||||
"chance": 30,
|
||||
@ -944,6 +988,10 @@
|
||||
"index" : 0,
|
||||
"resetDuraition" : 28,
|
||||
"name" : "Pyramid",
|
||||
"rmg" : {
|
||||
"value" : 5000,
|
||||
"rarity" : 20
|
||||
},
|
||||
"levels": [
|
||||
{
|
||||
"chance": 100,
|
||||
@ -963,4 +1011,4 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -9,56 +9,402 @@
|
||||
}
|
||||
},
|
||||
|
||||
"altarOfSacrifice" : { "index" :2, "handler": "market", "types" : { "object" : { "index" : 0} } },
|
||||
"tradingPost" : { "index" :221, "handler": "market", "types" : { "object" : { "index" : 0} } },
|
||||
"tradingPostDUPLICATE" : { "index" :99, "handler": "market", "types" : { "object" : { "index" : 0} } },
|
||||
"freelancersGuild" : { "index" :213, "handler": "market", "types" : { "object" : { "index" : 0} } },
|
||||
"altarOfSacrifice" : {
|
||||
"index" :2,
|
||||
"handler" : "market",
|
||||
"types" : {
|
||||
"object" : {
|
||||
"index" : 0,
|
||||
"rmg" : {
|
||||
"zoneLimit" : 1,
|
||||
"value" : 100,
|
||||
"rarity" : 20
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"tradingPost" : {
|
||||
"index" :221,
|
||||
"handler" : "market",
|
||||
"types" : {
|
||||
"object" : {
|
||||
"index" : 0,
|
||||
"rmg" : {
|
||||
"zoneLimit" : 1,
|
||||
"value" : 100,
|
||||
"rarity" : 100
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"tradingPostDUPLICATE" : {
|
||||
"index" :99,
|
||||
"handler" : "market",
|
||||
"types" : {
|
||||
"object" : {
|
||||
"index" : 0,
|
||||
"rmg" : {
|
||||
"zoneLimit" : 1,
|
||||
"value" : 100,
|
||||
"rarity" : 100
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"freelancersGuild" : {
|
||||
"index" :213,
|
||||
"handler" : "market",
|
||||
"types" : {
|
||||
"object" : {
|
||||
"index" : 0,
|
||||
"rmg" : {
|
||||
"value" : 100,
|
||||
"rarity" : 100
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
"blackMarket" : { "index" :7, "handler": "blackMarket", "types" : { "object" : { "index" : 0} } },
|
||||
"blackMarket" : {
|
||||
"index" :7,
|
||||
"handler" : "blackMarket",
|
||||
"types" : {
|
||||
"object" : {
|
||||
"index" : 0,
|
||||
"rmg" : {
|
||||
"mapLimit" : 32,
|
||||
"value" : 8000,
|
||||
"rarity" : 20
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
"pandoraBox" : { "index" :6, "handler": "pandora", "types" : { "object" : { "index" : 0} } },
|
||||
"event" : { "index" :26, "handler": "event", "types" : { "object" : { "index" : 0} } },
|
||||
"pandoraBox" : {
|
||||
"index" :6,
|
||||
"handler" : "pandora",
|
||||
"types" : {
|
||||
"object" : {
|
||||
"index" : 0,
|
||||
"templates" : {
|
||||
"normal" : { "animation" : "ava0128.def", "visitableFrom" : [ "+++", "+-+", "+++" ], "mask" : [ "VV", "VA"] }
|
||||
},
|
||||
"rmg" : {
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"event" : {
|
||||
"index" :26,
|
||||
"handler" : "event",
|
||||
"types" : {
|
||||
"object" : {
|
||||
"index" : 0,
|
||||
"rmg" : {
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
"redwoodObservatory" : { "index" :58, "handler": "observatory", "types" : { "object" : { "index" : 0} } },
|
||||
"pillarOfFire" : { "index" :60, "handler": "observatory", "types" : { "object" : { "index" : 0} } },
|
||||
"coverOfDarkness" : { "index" :15, "handler": "observatory", "types" : { "object" : { "index" : 0} } },
|
||||
"redwoodObservatory" : {
|
||||
"index" :58,
|
||||
"handler" : "observatory",
|
||||
"types" : {
|
||||
"object" : {
|
||||
"index" : 0,
|
||||
"rmg" : {
|
||||
"zoneLimit" : 1,
|
||||
"value" : 750,
|
||||
"rarity" : 100
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"pillarOfFire" : {
|
||||
"index" :60,
|
||||
"handler" : "observatory",
|
||||
"types" : {
|
||||
"object" : {
|
||||
"index" : 0,
|
||||
"rmg" : {
|
||||
"zoneLimit" : 1,
|
||||
"value" : 750,
|
||||
"rarity" : 100
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"coverOfDarkness" : {
|
||||
"index" :15,
|
||||
"handler" : "observatory",
|
||||
"types" : {
|
||||
"object" : {
|
||||
"index" : 0,
|
||||
"rmg" : {
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
"whirlpool" : { "index" :111, "handler": "teleport", "types" : { "object" : { "index" : 0} } },
|
||||
"whirlpool" : {
|
||||
"index" :111,
|
||||
"handler" : "teleport",
|
||||
"types" : {
|
||||
"object" : {
|
||||
"index" : 0,
|
||||
"rmg" : {
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"subterraneanGate" : {
|
||||
"index" :103,
|
||||
"handler": "teleport",
|
||||
"handler" : "teleport",
|
||||
"types" : {
|
||||
"object" : { "index" : 0 },
|
||||
"object" : {
|
||||
"index" : 0 },
|
||||
"objectWoG" : { "index" : 1 } // WoG object? Present on VCMI Test 2011b
|
||||
}
|
||||
},
|
||||
|
||||
"refugeeCamp" : { "index" :78, "handler": "dwelling", "types" : { "object" : { "index" : 0} } },
|
||||
"warMachineFactory" : { "index" :106, "handler": "dwelling", "types" : { "object" : { "index" : 0} } },
|
||||
|
||||
"shrineOfMagicLevel1" : { "index" :88, "handler": "shrine", "types" : { "object" : { "index" : 0} } },
|
||||
"shrineOfMagicLevel2" : { "index" :89, "handler": "shrine", "types" : { "object" : { "index" : 0} } },
|
||||
"shrineOfMagicLevel3" : { "index" :90, "handler": "shrine", "types" : { "object" : { "index" : 0} } },
|
||||
|
||||
"eyeOfTheMagi" : { "index" :27, "handler": "magi", "types" : { "object" : { "index" : 0} } },
|
||||
"hutOfTheMagi" : { "index" :37, "handler": "magi", "types" : { "object" : { "index" : 0} } },
|
||||
|
||||
"lighthouse" : { "index" :42, "handler": "lighthouse", "types" : { "object" : { "index" : 0} } },
|
||||
"obelisk" : { "index" :57, "handler": "obelisk", "types" : { "object" : { "index" : 0} } },
|
||||
"oceanBottle" : { "index" :59, "handler": "sign", "types" : { "object" : { "index" : 0} } },
|
||||
"scholar" : { "index" :81, "handler": "scholar", "types" : { "object" : { "index" : 0} } },
|
||||
"shipyard" : { "index" :87, "handler": "shipyard", "types" : { "object" : { "index" : 0} } },
|
||||
"sign" : { "index" :91, "handler": "sign", "types" : { "object" : { "index" : 0} } },
|
||||
"sirens" : { "index" :92, "handler": "siren", "types" : { "object" : { "index" : 0} } },
|
||||
"denOfThieves" : { "index" :97, "handler": "denOfThieves", "types" : { "object" : { "index" : 0} } },
|
||||
"university" : { "index" :104, "handler": "university", "types" : { "object" : { "index" : 0} } },
|
||||
"witchHut" : { "index" :113, "handler": "witch", "types" : { "object" : { "index" : 0} } },
|
||||
"questGuard" : { "index" :215, "handler": "questGuard", "types" : { "object" : { "index" : 0} } },
|
||||
"refugeeCamp" : {
|
||||
"index" :78,
|
||||
"handler" : "dwelling",
|
||||
"types" : {
|
||||
"object" : {
|
||||
"index" : 0,
|
||||
"rmg" : {
|
||||
"value" : 5000,
|
||||
"rarity" : 20
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"warMachineFactory" : {
|
||||
"index" :106,
|
||||
"handler" : "dwelling",
|
||||
"types" : {
|
||||
"object" : {
|
||||
"index" : 0,
|
||||
"rmg" : {
|
||||
"zoneLimit" : 1,
|
||||
"value" : 1500,
|
||||
"rarity" : 50
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"shrineOfMagicLevel1" : {//incantation
|
||||
"index" :88,
|
||||
"handler" : "shrine",
|
||||
"types" : {
|
||||
"object" : {
|
||||
"index" : 0,
|
||||
"rmg" : {
|
||||
"mapLimit" : 32,
|
||||
"value" : 500,
|
||||
"rarity" : 100
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"shrineOfMagicLevel2" : {//gesture
|
||||
"index" :89,
|
||||
"handler" : "shrine",
|
||||
"types" : {
|
||||
"object" : {
|
||||
"index" : 0,
|
||||
"rmg" : {
|
||||
"mapLimit" : 32,
|
||||
"value" : 2000,
|
||||
"rarity" : 100
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"shrineOfMagicLevel3" : {//thinking
|
||||
"index" :90,
|
||||
"handler" : "shrine",
|
||||
"types" : {
|
||||
"object" : {
|
||||
"index" : 0,
|
||||
"rmg" : {
|
||||
"mapLimit" : 32,
|
||||
"value" : 3000,
|
||||
"rarity" : 100
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"eyeOfTheMagi" : {
|
||||
"index" :27,
|
||||
"handler" : "magi",
|
||||
"types" : {
|
||||
"object" : {
|
||||
"index" : 0,
|
||||
"rmg" : {
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"hutOfTheMagi" : {
|
||||
"index" :37,
|
||||
"handler" : "magi",
|
||||
"types" : {
|
||||
"object" : {
|
||||
"index" : 0,
|
||||
"rmg" : {
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"lighthouse" : {
|
||||
"index" :42,
|
||||
"handler" : "lighthouse",
|
||||
"types" : {
|
||||
"object" : {
|
||||
"index" : 0,
|
||||
"rmg" : {
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"obelisk" : {
|
||||
"index" :57,
|
||||
"handler" : "obelisk",
|
||||
"types" : {
|
||||
"object" : {
|
||||
"index" : 0,
|
||||
"rmg" : {
|
||||
"mapLimit" : 48,
|
||||
"value" : 3500,
|
||||
"rarity" : 200
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"oceanBottle" : {
|
||||
"index" :59,
|
||||
"handler" : "sign",
|
||||
"types" : {
|
||||
"object" : {
|
||||
"index" : 0,
|
||||
"rmg" : {
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"scholar" : {
|
||||
"index" :81,
|
||||
"handler" : "scholar",
|
||||
"types" : {
|
||||
"object" : {
|
||||
"index" : 0,
|
||||
"rmg" : {
|
||||
"value" : 1500,
|
||||
"rarity" : 100
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"shipyard" : {
|
||||
"index" :87,
|
||||
"handler" : "shipyard",
|
||||
"types" : {
|
||||
"object" : {
|
||||
"index" : 0,
|
||||
"rmg" : {
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"sign" : {
|
||||
"index" :91,
|
||||
"handler" : "sign",
|
||||
"types" : {
|
||||
"object" : {
|
||||
"index" : 0,
|
||||
"rmg" : {
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"sirens" : {
|
||||
"index" :92,
|
||||
"handler" : "siren",
|
||||
"types" : {
|
||||
"object" : {
|
||||
"index" : 0,
|
||||
"rmg" : {
|
||||
"mapLimit" : 32,
|
||||
"value" : 100,
|
||||
"rarity" : 20
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"denOfThieves" : {
|
||||
"index" :97,
|
||||
"handler" : "denOfThieves",
|
||||
"types" : {
|
||||
"object" : {
|
||||
"index" : 0,
|
||||
"rmg" : {
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"university" : {
|
||||
"index" :104,
|
||||
"handler" : "university",
|
||||
"types" : {
|
||||
"object" : {
|
||||
"index" : 0,
|
||||
"rmg" : {
|
||||
"mapLimit" : 32,
|
||||
"value" : 2500,
|
||||
"rarity" : 20
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"witchHut" : {
|
||||
"index" :113,
|
||||
"handler" : "witch",
|
||||
"types" : {
|
||||
"object" : {
|
||||
"index" : 0,
|
||||
"rmg" : {
|
||||
"zoneLimit" : 3,
|
||||
"mapLimit" : 32,
|
||||
"value" : 1500,
|
||||
"rarity" : 80
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"questGuard" : {
|
||||
"index" :215,
|
||||
"handler" : "questGuard",
|
||||
"types" : {
|
||||
"object" : {
|
||||
"index" : 0,
|
||||
"rmg" : {
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"magicWell" : {
|
||||
"index" :49,
|
||||
"handler": "magicWell",
|
||||
"handler" : "magicWell",
|
||||
"types" : {
|
||||
"object" : { "index" : 0},
|
||||
"object" : {
|
||||
"index" : 0,
|
||||
"rmg" : {
|
||||
"value" : 250,
|
||||
"rarity" : 100
|
||||
}
|
||||
},
|
||||
"objectWoG" : { "index" : 1} // WoG object? Present on VCMI_Test 2011b
|
||||
}
|
||||
},
|
||||
@ -99,6 +445,10 @@
|
||||
"types" : {
|
||||
"object" : {
|
||||
"index" : 0,
|
||||
"rmg" : {
|
||||
"value" : 2000,
|
||||
"rarity" : 150
|
||||
},
|
||||
"templates" : {
|
||||
"normal" : { "animation" : "AVArnd1", "visitableFrom" : [ "+++", "+-+", "+++" ], "mask" : [ "VV", "VA"] }
|
||||
}
|
||||
@ -111,6 +461,10 @@
|
||||
"types" : {
|
||||
"object" : {
|
||||
"index" : 0,
|
||||
"rmg" : {
|
||||
"value" : 5000,
|
||||
"rarity" : 150
|
||||
},
|
||||
"templates" : {
|
||||
"normal" : { "animation" : "AVArnd2", "visitableFrom" : [ "+++", "+-+", "+++" ], "mask" : [ "VV", "VA"] }
|
||||
}
|
||||
@ -123,6 +477,10 @@
|
||||
"types" : {
|
||||
"object" : {
|
||||
"index" : 0,
|
||||
"rmg" : {
|
||||
"value" : 10000,
|
||||
"rarity" : 150
|
||||
},
|
||||
"templates" : {
|
||||
"normal" : { "animation" : "AVArnd3", "visitableFrom" : [ "+++", "+-+", "+++" ], "mask" : [ "VV", "VA"] }
|
||||
}
|
||||
@ -135,6 +493,10 @@
|
||||
"types" : {
|
||||
"object" : {
|
||||
"index" : 0,
|
||||
"rmg" : {
|
||||
"value" : 20000,
|
||||
"rarity" : 150
|
||||
},
|
||||
"templates" : {
|
||||
"normal" : { "animation" : "AVArnd4", "visitableFrom" : [ "+++", "+-+", "+++" ], "mask" : [ "VV", "VA"] }
|
||||
}
|
||||
@ -240,10 +602,58 @@
|
||||
},
|
||||
|
||||
/// Classes without dedicated object
|
||||
"hillFort" : { "index" :35, "handler": "generic", "types" : { "object" : { "index" : 0} } },
|
||||
"grail" : { "index" :36, "handler": "generic", "types" : { "object" : { "index" : 0} } },
|
||||
"tavern" : { "index" :95, "handler": "generic", "types" : { "object" : { "index" : 0} } },
|
||||
"sanctuary" : { "index" :80, "handler": "generic", "types" : { "object" : { "index" : 0} } },
|
||||
"hillFort" : {
|
||||
"index" :35,
|
||||
"handler": "generic",
|
||||
"types" : {
|
||||
"object" : {
|
||||
"index" : 0,
|
||||
"rmg" : {
|
||||
"zoneLimit" : 1,
|
||||
"value" : 7000,
|
||||
"rarity" : 20
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"grail" : {
|
||||
"index" :36,
|
||||
"handler": "generic",
|
||||
"types" : {
|
||||
"object" : {
|
||||
"index" : 0,
|
||||
"rmg" : {
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"tavern" : {
|
||||
"index" :95,
|
||||
"handler": "generic",
|
||||
"types" : {
|
||||
"object" : {
|
||||
"index" : 0,
|
||||
"rmg" : {
|
||||
"value" : 100,
|
||||
"rarity" : 20
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"sanctuary" : {
|
||||
"index" :80,
|
||||
"handler": "generic",
|
||||
"types" : {
|
||||
"object" : {
|
||||
"index" : 0,
|
||||
"rmg" : {
|
||||
"zoneLimit" : 1,
|
||||
"value" : 100,
|
||||
"rarity" : 50
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
/// Passive objects, terrain overlays
|
||||
"cursedGround" : { "index" :21, "handler": "generic", "types" : { "object" : { "index" : 0} } },
|
||||
|
@ -50,13 +50,13 @@
|
||||
}
|
||||
},
|
||||
"types" : {
|
||||
"wood" : { "index" : 0, "templates" : { "res" : { "animation" : "AVTwood0.def" } } },
|
||||
"mercury" : { "index" : 1, "templates" : { "res" : { "animation" : "AVTmerc0.def" } } },
|
||||
"ore" : { "index" : 2, "templates" : { "res" : { "animation" : "AVTore0.def" } } },
|
||||
"sulfur" : { "index" : 3, "templates" : { "res" : { "animation" : "AVTsulf0.def" } } },
|
||||
"crystal" : { "index" : 4, "templates" : { "res" : { "animation" : "AVTcrys0.def" } } },
|
||||
"gems" : { "index" : 5, "templates" : { "res" : { "animation" : "AVTgems0.def" } } },
|
||||
"gold" : { "index" : 6, "templates" : { "res" : { "animation" : "AVTgold0.def" } } },
|
||||
"wood" : { "index" : 0, "rmg" : { "value" : 1400, "rarity" : 300 }, "templates" : { "res" : { "animation" : "AVTwood0.def" } } },
|
||||
"mercury" : { "index" : 1, "rmg" : { "value" : 2000, "rarity" : 300 }, "templates" : { "res" : { "animation" : "AVTmerc0.def" } } },
|
||||
"ore" : { "index" : 2, "rmg" : { "value" : 1400, "rarity" : 300 }, "templates" : { "res" : { "animation" : "AVTore0.def" } } },
|
||||
"sulfur" : { "index" : 3, "rmg" : { "value" : 2000, "rarity" : 300 }, "templates" : { "res" : { "animation" : "AVTsulf0.def" } } },
|
||||
"crystal" : { "index" : 4, "rmg" : { "value" : 2000, "rarity" : 300 }, "templates" : { "res" : { "animation" : "AVTcrys0.def" } } },
|
||||
"gems" : { "index" : 5, "rmg" : { "value" : 2000, "rarity" : 300 }, "templates" : { "res" : { "animation" : "AVTgems0.def" } } },
|
||||
"gold" : { "index" : 6, "rmg" : { "value" : 750, "rarity" : 300 }, "templates" : { "res" : { "animation" : "AVTgold0.def" } } },
|
||||
"mithril" : { "index" : 7 } // TODO: move to WoG?
|
||||
}
|
||||
},
|
||||
@ -101,9 +101,9 @@
|
||||
}
|
||||
},
|
||||
"types" : {
|
||||
"evil" : { "index" : 0 },
|
||||
"good" : { "index" : 1 },
|
||||
"neutral" : { "index" : 2 },
|
||||
"evil" : { "index" : 0, "rmg" : { "mapLimit" : 64 } },
|
||||
"good" : { "index" : 1, "rmg" : { "mapLimit" : 64 } },
|
||||
"neutral" : { "index" : 2, "rmg" : { "mapLimit" : 64 } },
|
||||
}
|
||||
},
|
||||
|
||||
@ -156,9 +156,9 @@
|
||||
"index" :13,
|
||||
"handler": "cartographer",
|
||||
"types" : {
|
||||
"water" : { "index" : 0 },
|
||||
"land" : { "index" : 1 },
|
||||
"subterra" : { "index" : 2 }
|
||||
"water" : { "index" : 0, "rmg" : { "zoneLimit" : 1, "value" : 5000, "rarity" : 20 } },
|
||||
"land" : { "index" : 1, "rmg" : { "zoneLimit" : 1, "value" : 10000, "rarity" : 20 } },
|
||||
"subterra" : { "index" : 2, "rmg" : { "zoneLimit" : 1, "value" : 7500, "rarity" : 20 } }
|
||||
}
|
||||
},
|
||||
|
||||
@ -167,13 +167,13 @@
|
||||
"index" :53,
|
||||
"handler": "mine",
|
||||
"types" : {
|
||||
"sawmill" : { "index" : 0 },
|
||||
"alchemistLab" : { "index" : 1 },
|
||||
"orePit" : { "index" : 2 },
|
||||
"sulfurDune" : { "index" : 3 },
|
||||
"crystalCavern" : { "index" : 4 },
|
||||
"gemPond" : { "index" : 5 },
|
||||
"goldMine" : { "index" : 6 },
|
||||
"sawmill" : { "index" : 0, "rmg" : { "value" : 1500 } },
|
||||
"alchemistLab" : { "index" : 1, "rmg" : { "value" : 3500 } },
|
||||
"orePit" : { "index" : 2, "rmg" : { "value" : 1500 } },
|
||||
"sulfurDune" : { "index" : 3, "rmg" : { "value" : 3500 } },
|
||||
"crystalCavern" : { "index" : 4, "rmg" : { "value" : 3500 } },
|
||||
"gemPond" : { "index" : 5, "rmg" : { "value" : 3500 } },
|
||||
"goldMine" : { "index" : 6, "rmg" : { "value" : 7000 } },
|
||||
}
|
||||
},
|
||||
"abandonedMine" : {
|
||||
|
@ -1,51 +1,496 @@
|
||||
{
|
||||
/// These are objects that covered by concept of "configurable object"
|
||||
/// Most or even all of their configuration located in this file
|
||||
"magicSpring" : { "index" :48, "handler": "magicSpring", "types" : { "object" : { "index" : 0} } },
|
||||
|
||||
"mysticalGarden" : { "index" :55, "handler": "oncePerWeek", "types" : { "object" : { "index" : 0} } },
|
||||
"windmill" : { "index" :112, "handler": "oncePerWeek", "types" : { "object" : { "index" : 0} } },
|
||||
"waterWheel" : { "index" :109, "handler": "oncePerWeek", "types" : { "object" : { "index" : 0} } },
|
||||
|
||||
"leanTo" : { "index" :39, "handler": "onceVisitable", "types" : { "object" : { "index" : 0} } },
|
||||
"corpse" : { "index" :22, "handler": "onceVisitable", "types" : { "object" : { "index" : 0} } },
|
||||
"wagon" : { "index" :105, "handler": "onceVisitable", "types" : { "object" : { "index" : 0} } },
|
||||
"warriorTomb" : { "index" :108, "handler": "onceVisitable", "types" : { "object" : { "index" : 0} } },
|
||||
|
||||
"campfire" : { "index" :12, "handler": "pickable", "types" : { "object" : { "index" : 0} } },
|
||||
"flotsam" : { "index" :29, "handler": "pickable", "types" : { "object" : { "index" : 0} } },
|
||||
"seaChest" : { "index" :82, "handler": "pickable", "types" : { "object" : { "index" : 0} } },
|
||||
"shipwreckSurvivor" : { "index" :86, "handler": "pickable", "types" : { "object" : { "index" : 0} } },
|
||||
"treasureChest" : { "index" :101, "handler": "pickable", "types" : { "object" : { "index" : 0} } },
|
||||
|
||||
"arena" : { "index" :4, "handler": "oncePerHero", "types" : { "object" : { "index" : 0} } },
|
||||
"marlettoTower" : { "index" :23, "handler": "oncePerHero", "types" : { "object" : { "index" : 0} } },
|
||||
"gardenOfRevelation" : { "index" :32, "handler": "oncePerHero", "types" : { "object" : { "index" : 0} } },
|
||||
"libraryOfEnlightenment" : { "index" :41, "handler": "oncePerHero", "types" : { "object" : { "index" : 0} } },
|
||||
"mercenaryCamp" : { "index" :51, "handler": "oncePerHero", "types" : { "object" : { "index" : 0} } },
|
||||
"starAxis" : { "index" :61, "handler": "oncePerHero", "types" : { "object" : { "index" : 0} } },
|
||||
"treeOfKnowledge" : { "index" :102, "handler": "oncePerHero", "types" : { "object" : { "index" : 0} } },
|
||||
"schoolOfMagic" : { "index" :47, "handler": "oncePerHero", "types" : { "object" : { "index" : 0} } },
|
||||
"schoolOfWar" : { "index" :107, "handler": "oncePerHero", "types" : { "object" : { "index" : 0} } },
|
||||
"learningStone" : {
|
||||
"index" :100,
|
||||
"handler": "oncePerHero",
|
||||
"magicSpring" : {//magic source
|
||||
"index" : 48,
|
||||
"handler": "magicSpring",
|
||||
"types" : {
|
||||
"object" : { "index" : 0},
|
||||
"objectWoG" : { "index" : 1} // WoG object? Present on VCMI_Tests 2011
|
||||
"object" : {
|
||||
"index" : 0//,
|
||||
//"rmg" : {
|
||||
// "zoneLimit" : 1,
|
||||
// "mapLimit" : 32,
|
||||
// "value" : 500,
|
||||
// "rarity" : 50
|
||||
//}
|
||||
//banned due to problems with 2 viistable offsets
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
"buoy" : { "index" :11, "handler": "bonusingObject", "types" : { "object" : { "index" : 0} } },
|
||||
"swanPond" : { "index" :14, "handler": "bonusingObject", "types" : { "object" : { "index" : 0} } },
|
||||
"faerieRing" : { "index" :28, "handler": "bonusingObject", "types" : { "object" : { "index" : 0} } },
|
||||
"fountainOfFortune" : { "index" :30, "handler": "bonusingObject", "types" : { "object" : { "index" : 0} } },
|
||||
"fountainOfYouth" : { "index" :31, "handler": "bonusingObject", "types" : { "object" : { "index" : 0} } },
|
||||
"idolOfFortune" : { "index" :38, "handler": "bonusingObject", "types" : { "object" : { "index" : 0} } },
|
||||
"mermaids" : { "index" :52, "handler": "bonusingObject", "types" : { "object" : { "index" : 0} } },
|
||||
"oasis" : { "index" :56, "handler": "bonusingObject", "types" : { "object" : { "index" : 0} } },
|
||||
"stables" : { "index" :94, "handler": "bonusingObject", "types" : { "object" : { "index" : 0} } },
|
||||
"temple" : { "index" :96, "handler": "bonusingObject", "types" : { "object" : { "index" : 0} } },
|
||||
"rallyFlag" : { "index" :64, "handler": "bonusingObject", "types" : { "object" : { "index" : 0} } },
|
||||
"wateringHole" : { "index" :110, "handler": "bonusingObject", "types" : { "object" : { "index" : 0} } }
|
||||
"mysticalGarden" : {
|
||||
"index" : 55,
|
||||
"handler": "oncePerWeek",
|
||||
"types" : {
|
||||
"object" : {
|
||||
"index" : 0,
|
||||
"rmg" : {
|
||||
"mapLimit" : 32,
|
||||
"value" : 500,
|
||||
"rarity" : 50
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"windmill" :{
|
||||
"index" : 112,
|
||||
"handler": "oncePerWeek",
|
||||
"types" : {
|
||||
"object" : {
|
||||
"index" : 0,
|
||||
"rmg" : {
|
||||
"mapLimit" : 32,
|
||||
"value" : 1500,
|
||||
"rarity" : 80
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"waterWheel" : {
|
||||
"index" : 109,
|
||||
"handler": "oncePerWeek",
|
||||
"types" : {
|
||||
"object" : {
|
||||
"index" : 0,
|
||||
"rmg" : {
|
||||
"mapLimit" : 32,
|
||||
"value" : 750,
|
||||
"rarity" : 50
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
"leanTo" :{
|
||||
"index" : 39,
|
||||
"handler": "onceVisitable",
|
||||
"types" : {
|
||||
"object" : {
|
||||
"index" : 0,
|
||||
"rmg" : {
|
||||
"mapLimit" : 32,
|
||||
"value" : 500,
|
||||
"rarity" : 100
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"corpse" :{
|
||||
"index" : 22,
|
||||
"handler": "onceVisitable",
|
||||
"types" : {
|
||||
"object" : {
|
||||
"index" : 0,
|
||||
"rmg" : {
|
||||
"mapLimit" : 32,
|
||||
"value" : 500,
|
||||
"rarity" : 100
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"wagon" :{
|
||||
"index" : 105,
|
||||
"handler": "onceVisitable",
|
||||
"types" : {
|
||||
"object" : {
|
||||
"index" : 0,
|
||||
"rmg" : {
|
||||
"mapLimit" : 32,
|
||||
"value" : 500,
|
||||
"rarity" : 50
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"warriorTomb" : {
|
||||
"index" : 108,
|
||||
"handler": "onceVisitable",
|
||||
"types" : {
|
||||
"object" : {
|
||||
"index" : 0,
|
||||
"rmg" : {
|
||||
"mapLimit" : 32,
|
||||
"value" : 6000,
|
||||
"rarity" : 20
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
"campfire" :{
|
||||
"index" : 12,
|
||||
"handler": "pickable",
|
||||
"types" : {
|
||||
"object" : {
|
||||
"index" : 0,
|
||||
"rmg" : {
|
||||
"value" : 2000,
|
||||
"rarity" : 500
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"flotsam" :{
|
||||
"index" : 29,
|
||||
"handler": "pickable",
|
||||
"types" : {
|
||||
"object" : {
|
||||
"index" : 0,
|
||||
"rmg" : {
|
||||
"value" : 2000,
|
||||
"rarity" : 100
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"seaChest" :{
|
||||
"index" : 82,
|
||||
"handler": "pickable",
|
||||
"types" : {
|
||||
"object" : {
|
||||
"index" : 0,
|
||||
"rmg" : {
|
||||
"value" : 1500,
|
||||
"rarity" : 500
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"shipwreckSurvivor" : {
|
||||
"index" : 86,
|
||||
"handler": "pickable",
|
||||
"types" : {
|
||||
"object" : {
|
||||
"index" : 0,
|
||||
"rmg" : {
|
||||
"value" : 1500,
|
||||
"rarity" : 50
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"treasureChest" : {
|
||||
"index" : 101,
|
||||
"handler": "pickable",
|
||||
"types" : {
|
||||
"object" : {
|
||||
"index" : 0,
|
||||
"rmg" : {
|
||||
"value" : 1500,
|
||||
"rarity" : 1000
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
"arena" : {
|
||||
"index" : 4,
|
||||
"handler": "oncePerHero",
|
||||
"types" : {
|
||||
"object" : {
|
||||
"index" : 0,
|
||||
"rmg" : {
|
||||
"mapLimit" : 32,
|
||||
"value" : 3000,
|
||||
"rarity" : 50
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"marlettoTower" : {
|
||||
"index" : 23,
|
||||
"handler": "oncePerHero",
|
||||
"types" : {
|
||||
"object" : {
|
||||
"index" : 0,
|
||||
"rmg" : {
|
||||
"mapLimit" : 32,
|
||||
"value" : 1500,
|
||||
"rarity" : 100
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"gardenOfRevelation" : {
|
||||
"index" : 32,
|
||||
"handler": "oncePerHero",
|
||||
"types" : {
|
||||
"object" : {
|
||||
"index" : 0,
|
||||
"rmg" : {
|
||||
"mapLimit" : 32,
|
||||
"value" : 1500,
|
||||
"rarity" : 100
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"libraryOfEnlightenment" : {
|
||||
"index" : 41,
|
||||
"handler": "oncePerHero",
|
||||
"types" : {
|
||||
"object" : {
|
||||
"index" : 0,
|
||||
"rmg" : {
|
||||
"mapLimit" : 32,
|
||||
"value" : 12000,
|
||||
"rarity" : 20
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"mercenaryCamp" : {
|
||||
"index" : 51,
|
||||
"handler": "oncePerHero",
|
||||
"types" : {
|
||||
"object" : {
|
||||
"index" : 0,
|
||||
"rmg" : {
|
||||
"mapLimit" : 32,
|
||||
"value" : 1500,
|
||||
"rarity" : 100
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"starAxis" :{
|
||||
"index" : 61,
|
||||
"handler": "oncePerHero",
|
||||
"types" : {
|
||||
"object" : {
|
||||
"index" : 0,
|
||||
"rmg" : {
|
||||
"mapLimit" : 32,
|
||||
"value" : 1500,
|
||||
"rarity" : 100
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"treeOfKnowledge" : {
|
||||
"index" : 102,
|
||||
"handler": "oncePerHero",
|
||||
"types" : {
|
||||
"object" : {
|
||||
"index" : 0,
|
||||
"rmg" : {
|
||||
"mapLimit" : 32,
|
||||
"value" : 2500,
|
||||
"rarity" : 50
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"schoolOfMagic" : {
|
||||
"index" : 47,
|
||||
"handler": "oncePerHero",
|
||||
"types" : {
|
||||
"object" : {
|
||||
"index" : 0,
|
||||
"rmg" : {
|
||||
"mapLimit" : 32,
|
||||
"value" : 1000,
|
||||
"rarity" : 50
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"schoolOfWar" : {
|
||||
"index" : 107,
|
||||
"handler": "oncePerHero",
|
||||
"types" : {
|
||||
"object" : {
|
||||
"index" : 0,
|
||||
"rmg" : {
|
||||
"mapLimit" : 32,
|
||||
"value" : 1000,
|
||||
"rarity" : 50
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"learningStone" : {
|
||||
"index" : 100,
|
||||
"handler": "oncePerHero",
|
||||
"types" : {
|
||||
"object" : {
|
||||
"index" : 0,
|
||||
"rmg" : {
|
||||
"mapLimit" : 32,
|
||||
"value" : 1500,
|
||||
"rarity" : 200
|
||||
}
|
||||
},
|
||||
"objectWoG" : { "index" : 1 } // WoG object? Present on VCMI_Tests 2011
|
||||
}
|
||||
},
|
||||
|
||||
"buoy" : {
|
||||
"index" : 11,
|
||||
"handler": "bonusingObject",
|
||||
"types" : {
|
||||
"object" : {
|
||||
"index" : 0,
|
||||
"rmg" : {
|
||||
"value" : 100,
|
||||
"rarity" : 100
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"swanPond" : {
|
||||
"index" : 14,
|
||||
"handler": "bonusingObject",
|
||||
"types" : {
|
||||
"object" : {
|
||||
"index" : 0,
|
||||
"rmg" : {
|
||||
"zoneLimit" : 1,
|
||||
"value" : 100,
|
||||
"rarity" : 100
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"faerieRing" : {
|
||||
"index" : 28,
|
||||
"handler": "bonusingObject",
|
||||
"types" : {
|
||||
"object" : {
|
||||
"index" : 0,
|
||||
"rmg" : {
|
||||
"zoneLimit" : 1,
|
||||
"value" : 100,
|
||||
"rarity" : 100
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"fountainOfFortune" : {
|
||||
"index" : 30,
|
||||
"handler": "bonusingObject",
|
||||
"types" : {
|
||||
"object" : {
|
||||
"index" : 0,
|
||||
"rmg" : {
|
||||
"zoneLimit" : 1,
|
||||
"value" : 100,
|
||||
"rarity" : 100
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"fountainOfYouth" : {
|
||||
"index" : 31,
|
||||
"handler": "bonusingObject",
|
||||
"types" : {
|
||||
"object" : {
|
||||
"index" : 0,
|
||||
"rmg" : {
|
||||
"zoneLimit" : 1,
|
||||
"value" : 100,
|
||||
"rarity" : 50
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"idolOfFortune" : {
|
||||
"index" : 38,
|
||||
"handler": "bonusingObject",
|
||||
"types" : {
|
||||
"object" : {
|
||||
"index" : 0,
|
||||
"rmg" : {
|
||||
"zoneLimit" : 1,
|
||||
"value" : 100,
|
||||
"rarity" : 100
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"mermaids" : {
|
||||
"index" : 52,
|
||||
"handler": "bonusingObject",
|
||||
"types" : {
|
||||
"object" : {
|
||||
"index" : 0,
|
||||
"rmg" : {
|
||||
"mapLimit" : 32,
|
||||
"value" : 100,
|
||||
"rarity" : 20
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"oasis" : {
|
||||
"index" : 56,
|
||||
"handler": "bonusingObject",
|
||||
"types" : {
|
||||
"object" : {
|
||||
"index" : 0,
|
||||
"rmg" : {
|
||||
"zoneLimit" : 1,
|
||||
"value" : 100,
|
||||
"rarity" : 50
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"stables" : {
|
||||
"index" : 94,
|
||||
"handler": "bonusingObject",
|
||||
"types" : {
|
||||
"object" : {
|
||||
"index" : 0,
|
||||
"rmg" : {
|
||||
"zoneLimit" : 1,
|
||||
"value" : 200,
|
||||
"rarity" : 40
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"temple" : {
|
||||
"index" : 96,
|
||||
"handler": "bonusingObject",
|
||||
"types" : {
|
||||
"object" : {
|
||||
"index" : 0,
|
||||
"rmg" : {
|
||||
"zoneLimit" : 1,
|
||||
"value" : 100,
|
||||
"rarity" : 100
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"rallyFlag" : {
|
||||
"index" : 64,
|
||||
"handler": "bonusingObject",
|
||||
"types" : {
|
||||
"object" : {
|
||||
"index" : 0,
|
||||
"rmg" : {
|
||||
"zoneLimit" : 1,
|
||||
"value" : 100,
|
||||
"rarity" : 100
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"wateringHole" : {//waters
|
||||
"index" : 110,
|
||||
"handler": "bonusingObject",
|
||||
"types" : {
|
||||
"object" : {
|
||||
"index" : 0,
|
||||
"rmg" : {
|
||||
"zoneLimit" : 1,
|
||||
"value" : 500,
|
||||
"rarity" : 50
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2,13 +2,13 @@
|
||||
{
|
||||
"Analogy" :
|
||||
{
|
||||
"minSize" : "m", "maxSize" : "m",
|
||||
"minSize" : "m", "maxSize" : "m+u",
|
||||
"players" : "4",
|
||||
"zones" :
|
||||
{
|
||||
"1" :
|
||||
{
|
||||
"type" : "playerStart", "size" : 1, "owner" : 1,
|
||||
"type" : "playerStart", "size" : 2, "owner" : 1,
|
||||
"playerTowns" : { "castles" : 1 }, "neutralTowns" : { "towns" : 1 }, "townsAreSameType" : true,
|
||||
"monsters" : "normal",
|
||||
"mines" : {"wood" : 1, "ore" : 1, "gems" : 1, "crystal" : 1, "sulfur" : 1, "mercury" : 1},
|
||||
@ -19,7 +19,7 @@
|
||||
},
|
||||
"2" :
|
||||
{
|
||||
"type" : "playerStart", "size" : 1, "owner" : 2,
|
||||
"type" : "playerStart", "size" : 2, "owner" : 2,
|
||||
"playerTowns" : { "castles" : 1 }, "neutralTowns" : { "towns" : 1 }, "townsAreSameType" : true,
|
||||
"monsters" : "normal",
|
||||
"minesLikeZone" : 1,
|
||||
@ -27,7 +27,7 @@
|
||||
},
|
||||
"3" :
|
||||
{
|
||||
"type" : "playerStart", "size" : 1, "owner" : 3,
|
||||
"type" : "playerStart", "size" : 2, "owner" : 3,
|
||||
"playerTowns" : { "castles" : 1 }, "neutralTowns" : { "towns" : 1 }, "townsAreSameType" : true,
|
||||
"monsters" : "normal",
|
||||
"minesLikeZone" : 1,
|
||||
@ -35,7 +35,7 @@
|
||||
},
|
||||
"4" :
|
||||
{
|
||||
"type" : "playerStart", "size" : 1, "owner" : 4,
|
||||
"type" : "playerStart", "size" : 2, "owner" : 4,
|
||||
"playerTowns" : { "castles" : 1 }, "neutralTowns" : { "towns" : 1 }, "townsAreSameType" : true,
|
||||
"monsters" : "normal",
|
||||
"minesLikeZone" : 1,
|
||||
@ -43,7 +43,7 @@
|
||||
},
|
||||
"5" :
|
||||
{
|
||||
"type" : "treasure", "size" : 2, "terrainTypes" : [ "sand" ], "matchTerrainToTown" : false,
|
||||
"type" : "treasure", "size" : 3, "terrainTypes" : [ "sand" ], "matchTerrainToTown" : false,
|
||||
"neutralTowns" : { "castles" : 1 },
|
||||
"monsters" : "strong",
|
||||
"mines" : {"gold" : 2},
|
||||
@ -63,13 +63,13 @@
|
||||
},
|
||||
"Upgrade" :
|
||||
{
|
||||
"minSize" : "s", "maxSize" : "m",
|
||||
"minSize" : "s+u", "maxSize" : "m",
|
||||
"players" : "2",
|
||||
"zones" :
|
||||
{
|
||||
"1" :
|
||||
{
|
||||
"type" : "playerStart", "size" : 1, "owner" : 1,
|
||||
"type" : "playerStart", "size" : 3, "owner" : 1,
|
||||
"playerTowns" : { "castles" : 1 },
|
||||
"monsters" : "normal",
|
||||
"mines" : {"wood" : 1, "ore" : 1},
|
||||
@ -80,7 +80,7 @@
|
||||
},
|
||||
"2" :
|
||||
{
|
||||
"type" : "playerStart", "size" : 1, "owner" : 2,
|
||||
"type" : "playerStart", "size" : 3, "owner" : 2,
|
||||
"playerTowns" : { "castles" : 1 },
|
||||
"monsters" : "normal",
|
||||
"minesLikeZone" : 1,
|
||||
@ -88,7 +88,7 @@
|
||||
},
|
||||
"3" :
|
||||
{
|
||||
"type" : "treasure", "size" : 2, "neutralTowns" : { "towns" : 1 }, "townTypeLikeZone" : 1,
|
||||
"type" : "treasure", "size" : 4, "neutralTowns" : { "towns" : 1 }, "townTypeLikeZone" : 1,
|
||||
"monsters" : "weak",
|
||||
"mines" : {"gems" : 1, "crystal" : 1, "sulfur" : 1, "mercury" : 1, "gold" : 1},
|
||||
"treasure" : [
|
||||
@ -98,14 +98,14 @@
|
||||
},
|
||||
"4" :
|
||||
{
|
||||
"type" : "treasure", "size" : 2, "neutralTowns" : { "towns" : 1 }, "townTypeLikeZone" : 2,
|
||||
"type" : "treasure", "size" : 4, "neutralTowns" : { "towns" : 1 }, "townTypeLikeZone" : 2,
|
||||
"monsters" : "weak",
|
||||
"minesLikeZone" : 3,
|
||||
"treasureLikeZone" : 3
|
||||
},
|
||||
"5" :
|
||||
{
|
||||
"type" : "treasure", "size" : 3, "neutralTowns" : { "castles" : 1 }, "terrainTypes" : [ "sand" ],
|
||||
"type" : "treasure", "size" : 5, "neutralTowns" : { "castles" : 1 }, "terrainTypes" : [ "sand" ],
|
||||
"monsters" : "strong",
|
||||
"mines" : {"gold" : 2},
|
||||
"treasure" : [
|
||||
@ -126,13 +126,13 @@
|
||||
},
|
||||
"Golden Ring" :
|
||||
{
|
||||
"minSize" : "m", "maxSize" : "l",
|
||||
"minSize" : "m+u", "maxSize" : "l",
|
||||
"players" : "3",
|
||||
"zones" :
|
||||
{
|
||||
"1" :
|
||||
{
|
||||
"type" : "playerStart", "size" : 3, "owner" : 1,
|
||||
"type" : "playerStart", "size" : 2, "owner" : 1,
|
||||
"playerTowns" : { "castles" : 1 },
|
||||
"monsters" : "normal",
|
||||
"mines" : {"wood" : 1, "ore" : 1},
|
||||
@ -143,7 +143,7 @@
|
||||
},
|
||||
"2" :
|
||||
{
|
||||
"type" : "playerStart", "size" : 3, "owner" : 2,
|
||||
"type" : "playerStart", "size" : 2, "owner" : 2,
|
||||
"playerTowns" : { "castles" : 1 },
|
||||
"monsters" : "normal",
|
||||
"minesLikeZone" : 1,
|
||||
@ -151,7 +151,7 @@
|
||||
},
|
||||
"3" :
|
||||
{
|
||||
"type" : "playerStart", "size" : 3, "owner" : 3,
|
||||
"type" : "playerStart", "size" : 2, "owner" : 3,
|
||||
"playerTowns" : { "castles" : 1 },
|
||||
"monsters" : "normal",
|
||||
"minesLikeZone" : 1,
|
||||
@ -243,7 +243,7 @@
|
||||
},
|
||||
"Jebus Cross":
|
||||
{
|
||||
"minSize" : "l", "maxSize" : "xl",
|
||||
"minSize" : "l+u", "maxSize" : "xl+u",
|
||||
"players" : "4",
|
||||
"zones":
|
||||
{
|
||||
|
@ -117,7 +117,7 @@ namespace RandomGeneratorUtil
|
||||
int n = (container.end() - container.begin());
|
||||
for (int i = n-1; i>0; --i)
|
||||
{
|
||||
std::swap (container.begin()[i],container.begin()[rand.nextInt(i+1)]);
|
||||
std::swap (container.begin()[i],container.begin()[rand.nextInt(i)]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -241,13 +241,7 @@ int CGObjectInstance::getSightRadious() const
|
||||
|
||||
int3 CGObjectInstance::getVisitableOffset() const
|
||||
{
|
||||
for(int y = 0; y < appearance.getHeight(); y++)
|
||||
for (int x = 0; x < appearance.getWidth(); x++)
|
||||
if (appearance.isVisitableAt(x, y))
|
||||
return int3(x,y,0);
|
||||
|
||||
//logGlobal->warnStream() << "Warning: getVisitableOffset called on non-visitable obj!";
|
||||
return int3(0,0,0);
|
||||
return appearance.getVisitableOffset();
|
||||
}
|
||||
|
||||
void CGObjectInstance::giveDummyBonus(ObjectInstanceID heroID, ui8 duration) const
|
||||
|
@ -218,6 +218,17 @@ bool CDwellingInstanceConstructor::producesCreature(const CCreature * crea) cons
|
||||
return false;
|
||||
}
|
||||
|
||||
std::vector<const CCreature *> CDwellingInstanceConstructor::getProducedCreatures() const
|
||||
{
|
||||
std::vector<const CCreature *> creatures; //no idea why it's 2D, to be honest
|
||||
for (auto & entry : availableCreatures)
|
||||
{
|
||||
for (const CCreature * cre : entry)
|
||||
creatures.push_back(cre);
|
||||
}
|
||||
return creatures;
|
||||
}
|
||||
|
||||
CBankInstanceConstructor::CBankInstanceConstructor()
|
||||
{
|
||||
}
|
||||
|
@ -13,6 +13,7 @@
|
||||
*
|
||||
*/
|
||||
|
||||
class CGObjectInstance;
|
||||
class CGTownInstance;
|
||||
class CGHeroInstance;
|
||||
class CGDwelling;
|
||||
@ -123,6 +124,7 @@ public:
|
||||
void configureObject(CGObjectInstance * object, CRandomGenerator & rng) const;
|
||||
|
||||
bool producesCreature(const CCreature * crea) const;
|
||||
std::vector<const CCreature *> getProducedCreatures() const;
|
||||
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{
|
||||
|
@ -871,6 +871,12 @@ void CGArtifact::initObj()
|
||||
blockVisit = true;
|
||||
if(ID == Obj::ARTIFACT)
|
||||
{
|
||||
if (!storedArtifact)
|
||||
{
|
||||
auto a = new CArtifactInstance();
|
||||
cb->gameState()->map->addNewArtifactInstance(a);
|
||||
storedArtifact = a;
|
||||
}
|
||||
if(!storedArtifact->artType)
|
||||
storedArtifact->setType(VLC->arth->artifacts[subID]);
|
||||
}
|
||||
@ -963,6 +969,11 @@ void CGArtifact::blockingDialogAnswered(const CGHeroInstance *hero, ui32 answer)
|
||||
|
||||
void CGWitchHut::initObj()
|
||||
{
|
||||
if (allowedAbilities.empty()) //this can happen for RMG. regular maps load abilities from map file
|
||||
{
|
||||
for (int i = 0; i < GameConstants::SKILL_QUANTITY; i++)
|
||||
allowedAbilities.push_back(i);
|
||||
}
|
||||
ability = *RandomGeneratorUtil::nextItem(allowedAbilities, cb->gameState()->getRandomGenerator());
|
||||
}
|
||||
|
||||
|
@ -158,6 +158,8 @@ public:
|
||||
CArtifactInstance *storedArtifact;
|
||||
std::string message;
|
||||
|
||||
CGArtifact() : CArmedInstance() {storedArtifact = nullptr;};
|
||||
|
||||
void onHeroVisit(const CGHeroInstance * h) const override;
|
||||
void battleFinished(const CGHeroInstance *hero, const BattleResult &result) const override;
|
||||
void blockingDialogAnswered(const CGHeroInstance *hero, ui32 answer) const override;
|
||||
|
@ -23,7 +23,7 @@
|
||||
*
|
||||
*/
|
||||
|
||||
static bool isVisitableFromTop(int identifier, int type)
|
||||
static bool isOnVisitableFromTopList(int identifier, int type)
|
||||
{
|
||||
if(type == 2 || type == 3 || type == 4 || type == 5) //creature, hero, artifact, resource
|
||||
return true;
|
||||
@ -106,7 +106,7 @@ void ObjectTemplate::readTxt(CLegacyConfigParser & parser)
|
||||
int type = boost::lexical_cast<int>(strings[7]);
|
||||
printPriority = boost::lexical_cast<int>(strings[8]) * 100; // to have some space in future
|
||||
|
||||
if (isVisitableFromTop(id, type))
|
||||
if (isOnVisitableFromTopList(id, type))
|
||||
visitDir = 0xff;
|
||||
else
|
||||
visitDir = (8|16|32|64|128);
|
||||
@ -168,7 +168,7 @@ void ObjectTemplate::readMap(CBinaryReader & reader)
|
||||
int type = reader.readUInt8();
|
||||
printPriority = reader.readUInt8() * 100; // to have some space in future
|
||||
|
||||
if (isVisitableFromTop(id, type))
|
||||
if (isOnVisitableFromTopList(id, type))
|
||||
visitDir = 0xff;
|
||||
else
|
||||
visitDir = (8|16|32|64|128);
|
||||
@ -354,6 +354,24 @@ bool ObjectTemplate::isVisitableFrom(si8 X, si8 Y) const
|
||||
return dirMap[dy][dx] != 0;
|
||||
}
|
||||
|
||||
int3 ObjectTemplate::getVisitableOffset() const
|
||||
{
|
||||
for(int y = 0; y < getHeight(); y++)
|
||||
for (int x = 0; x < getWidth(); x++)
|
||||
if (isVisitableAt(x, y))
|
||||
return int3(x,y,0);
|
||||
|
||||
//logGlobal->warnStream() << "Warning: getVisitableOffset called on non-visitable obj!";
|
||||
return int3(0,0,0);
|
||||
}
|
||||
|
||||
bool ObjectTemplate::isVisitableFromTop() const
|
||||
{
|
||||
return visitDir & 2;
|
||||
//for some reason the line below is never called :?
|
||||
//return isVisitableFrom (0, 1);
|
||||
}
|
||||
|
||||
bool ObjectTemplate::canBePlacedAt(ETerrainType terrain) const
|
||||
{
|
||||
return allowedTerrains.count(terrain) != 0;
|
||||
|
@ -62,6 +62,8 @@ public:
|
||||
|
||||
// Checks if object is visitable from certain direction. X and Y must be between -1..+1
|
||||
bool isVisitableFrom(si8 X, si8 Y) const;
|
||||
int3 getVisitableOffset() const;
|
||||
bool isVisitableFromTop() const;
|
||||
|
||||
// Checks if object can be placed on specific terrain
|
||||
bool canBePlacedAt(ETerrainType terrain) const;
|
||||
@ -73,6 +75,8 @@ public:
|
||||
void readMap(CBinaryReader & reader);
|
||||
void readJson(const JsonNode & node);
|
||||
|
||||
bool operator==(const ObjectTemplate& ot) const { return (id == ot.id && subid == ot.subid); }
|
||||
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{
|
||||
h & usedTiles & allowedTerrains & animationFile & stringID;
|
||||
|
@ -175,14 +175,11 @@ const std::map<std::string, CRmgTemplate *> & CMapGenOptions::getAvailableTempla
|
||||
return VLC->tplh->getTemplates();
|
||||
}
|
||||
|
||||
void CMapGenOptions::finalize()
|
||||
{
|
||||
CRandomGenerator rand;
|
||||
finalize(rand);
|
||||
}
|
||||
|
||||
void CMapGenOptions::finalize(CRandomGenerator & rand)
|
||||
{
|
||||
logGlobal->infoStream() << boost::format ("RMG settings: players %d, teams %d, computer players %d, computer teams %d, water %d, monsters %d")
|
||||
% playerCount % teamCount % compOnlyPlayerCount % compOnlyTeamCount % waterContent % monsterStrength;
|
||||
|
||||
if(!mapTemplate)
|
||||
{
|
||||
mapTemplate = getPossibleTemplate(rand);
|
||||
|
@ -145,7 +145,6 @@ public:
|
||||
/// Finalizes the options. All random sizes for various properties will be overwritten by numbers from
|
||||
/// a random number generator by keeping the options in a valid state. Check options should return true, otherwise
|
||||
/// this function fails.
|
||||
void finalize();
|
||||
void finalize(CRandomGenerator & rand);
|
||||
|
||||
/// Returns false if there is no template available which fits to the currently selected options.
|
||||
|
@ -11,6 +11,7 @@
|
||||
#include "CRmgTemplate.h"
|
||||
#include "CRmgTemplateZone.h"
|
||||
#include "CZonePlacer.h"
|
||||
#include "../mapObjects/CObjectClassesHandler.h"
|
||||
|
||||
void CMapGenerator::foreach_neighbour(const int3 &pos, std::function<void(int3& pos)> foo)
|
||||
{
|
||||
@ -24,7 +25,7 @@ void CMapGenerator::foreach_neighbour(const int3 &pos, std::function<void(int3&
|
||||
|
||||
|
||||
CMapGenerator::CMapGenerator(shared_ptr<CMapGenOptions> mapGenOptions, int RandomSeed /*= std::time(nullptr)*/) :
|
||||
mapGenOptions(mapGenOptions), randomSeed(RandomSeed), monolithIndex(0)
|
||||
mapGenOptions(mapGenOptions), randomSeed(RandomSeed), monolithIndex(0), zonesTotal(0)
|
||||
{
|
||||
rand.setSeed(randomSeed);
|
||||
}
|
||||
@ -215,9 +216,9 @@ void CMapGenerator::fillZones()
|
||||
logGlobal->infoStream() << "Started filling zones";
|
||||
|
||||
createConnections();
|
||||
//make sure all connections are passable before creating borders
|
||||
for (auto it : zones)
|
||||
{
|
||||
//make sure all connections are passable before creating borders
|
||||
it.second->createBorder(this);
|
||||
it.second->fill(this);
|
||||
}
|
||||
@ -239,25 +240,96 @@ void CMapGenerator::createConnections()
|
||||
int3 guardPos(-1,-1,-1);
|
||||
|
||||
auto otherZoneTiles = zoneB->getTileInfo();
|
||||
//auto otherZoneCenter = zoneB->getPos();
|
||||
|
||||
for (auto tile : tiles)
|
||||
int3 posA = zoneA->getPos();
|
||||
int3 posB = zoneB->getPos();
|
||||
|
||||
if (posA.z == posB.z)
|
||||
{
|
||||
foreach_neighbour (tile, [&guardPos, tile, &otherZoneTiles](int3 &pos)
|
||||
for (auto tile : tiles)
|
||||
{
|
||||
if (vstd::contains(otherZoneTiles, pos))
|
||||
guardPos = tile;
|
||||
});
|
||||
if (guardPos.valid())
|
||||
{
|
||||
setOccupied (guardPos, ETileType::FREE); //just in case monster is too weak to spawn
|
||||
zoneA->addMonster (this, guardPos, connection.getGuardStrength()); //TODO: set value according to template
|
||||
//zones can make paths only in their own area
|
||||
zoneA->crunchPath (this, guardPos, zoneA->getPos(), zoneA->getId(), zoneA->getFreePaths()); //make connection towards our zone center
|
||||
zoneB->crunchPath (this, guardPos, zoneB->getPos(), zoneB->getId(), zoneB->getFreePaths()); //make connection towards other zone center
|
||||
break; //we're done with this connection
|
||||
if (isBlocked(tile)) //tiles may be occupied by subterranean gates already placed
|
||||
continue;
|
||||
foreach_neighbour (tile, [&guardPos, tile, &otherZoneTiles, this](int3 &pos)
|
||||
{
|
||||
//if (vstd::contains(otherZoneTiles, pos) && !this->isBlocked(pos))
|
||||
if (vstd::contains(otherZoneTiles, pos))
|
||||
guardPos = tile;
|
||||
});
|
||||
if (guardPos.valid())
|
||||
{
|
||||
setOccupied (guardPos, ETileType::FREE); //just in case monster is too weak to spawn
|
||||
zoneA->addMonster (this, guardPos, connection.getGuardStrength(), false, true);
|
||||
//zones can make paths only in their own area
|
||||
zoneA->crunchPath (this, guardPos, posA, zoneA->getId(), zoneA->getFreePaths()); //make connection towards our zone center
|
||||
zoneB->crunchPath (this, guardPos, posB, zoneB->getId(), zoneB->getFreePaths()); //make connection towards other zone center
|
||||
break; //we're done with this connection
|
||||
}
|
||||
}
|
||||
}
|
||||
else //create subterranean gates between two zones
|
||||
{
|
||||
//find point on the path between zones
|
||||
float3 offset (posB.x - posA.x, posB.y - posA.y, 0);
|
||||
|
||||
float distance = posB.dist2d(posA);
|
||||
vstd::amax (distance, 0.5f);
|
||||
offset /= distance; //get unit vector
|
||||
float3 vec (0, 0, 0);
|
||||
//use reduced size of underground zone - make sure gate does not stand on rock
|
||||
int3 tile = posA;
|
||||
int3 otherTile = tile;
|
||||
|
||||
bool stop = false;
|
||||
while (!stop)
|
||||
{
|
||||
vec += offset; //this vector may extend beyond line between zone centers, in case they are directly over each other
|
||||
tile = posA + int3(vec.x, vec.y, 0);
|
||||
float distanceFromA = posA.dist2d(tile);
|
||||
float distanceFromB = posB.dist2d(tile);
|
||||
|
||||
if (distanceFromA + distanceFromB > std::max<int>(zoneA->getSize() + zoneB->getSize(), distance))
|
||||
break; //we are too far away to ever connect
|
||||
|
||||
//if zone is underground, gate must fit within its (reduced) radius
|
||||
if (distanceFromA > 5 && (!posA.z || distanceFromA < zoneA->getSize() - 3) &&
|
||||
distanceFromB > 5 && (!posB.z || distanceFromB < zoneB->getSize() - 3))
|
||||
{
|
||||
otherTile = tile;
|
||||
otherTile.z = posB.z;
|
||||
|
||||
if (vstd::contains(tiles, tile) && vstd::contains(otherZoneTiles, otherTile))
|
||||
{
|
||||
bool withinZone = true;
|
||||
|
||||
foreach_neighbour (tile, [&withinZone, &tiles](int3 &pos)
|
||||
{
|
||||
if (!vstd::contains(tiles, pos))
|
||||
withinZone = false;
|
||||
});
|
||||
foreach_neighbour (otherTile, [&withinZone, &otherZoneTiles](int3 &pos)
|
||||
{
|
||||
if (!vstd::contains(otherZoneTiles, pos))
|
||||
withinZone = false;
|
||||
});
|
||||
|
||||
if (withinZone)
|
||||
{
|
||||
auto gate1 = new CGTeleport;
|
||||
gate1->ID = Obj::SUBTERRANEAN_GATE;
|
||||
gate1->subID = 0;
|
||||
zoneA->placeAndGuardObject(this, gate1, tile, connection.getGuardStrength());
|
||||
auto gate2 = new CGTeleport(*gate1);
|
||||
zoneB->placeAndGuardObject(this, gate2, otherTile, connection.getGuardStrength());
|
||||
|
||||
stop = true; //we are done, go to next connection
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (stop)
|
||||
continue;
|
||||
}
|
||||
if (!guardPos.valid())
|
||||
{
|
||||
auto teleport1 = new CGTeleport;
|
||||
@ -299,28 +371,35 @@ bool CMapGenerator::isBlocked(const int3 &tile) const
|
||||
bool CMapGenerator::shouldBeBlocked(const int3 &tile) const
|
||||
{
|
||||
if (!map->isInTheMap(tile))
|
||||
throw rmgException(boost::to_string(boost::format("Tile %s is outside the map") % tile));
|
||||
throw rmgException(boost::to_string(boost::format("Tile %s is outside the map") % tile));
|
||||
|
||||
return tiles[tile.x][tile.y][tile.z].shouldBeBlocked();
|
||||
}
|
||||
bool CMapGenerator::isPossible(const int3 &tile) const
|
||||
{
|
||||
if (!map->isInTheMap(tile))
|
||||
throw rmgException(boost::to_string(boost::format("Tile %s is outside the map") % tile));
|
||||
throw rmgException(boost::to_string(boost::format("Tile %s is outside the map") % tile));
|
||||
|
||||
return tiles[tile.x][tile.y][tile.z].isPossible();
|
||||
}
|
||||
bool CMapGenerator::isFree(const int3 &tile) const
|
||||
{
|
||||
if (!map->isInTheMap(tile))
|
||||
throw rmgException(boost::to_string(boost::format("Tile %s is outside the map") % tile));
|
||||
throw rmgException(boost::to_string(boost::format("Tile %s is outside the map") % tile));
|
||||
|
||||
return tiles[tile.x][tile.y][tile.z].isFree();
|
||||
}
|
||||
bool CMapGenerator::isUsed(const int3 &tile) const
|
||||
{
|
||||
if (!map->isInTheMap(tile))
|
||||
throw rmgException(boost::to_string(boost::format("Tile %s is outside the map") % tile));
|
||||
|
||||
return tiles[tile.x][tile.y][tile.z].isUsed();
|
||||
}
|
||||
void CMapGenerator::setOccupied(const int3 &tile, ETileType::ETileType state)
|
||||
{
|
||||
if (!map->isInTheMap(tile))
|
||||
throw rmgException(boost::to_string(boost::format("Tile %s is outside the map") % tile));
|
||||
throw rmgException(boost::to_string(boost::format("Tile %s is outside the map") % tile));
|
||||
|
||||
tiles[tile.x][tile.y][tile.z].setOccupied(state);
|
||||
}
|
||||
@ -328,7 +407,7 @@ void CMapGenerator::setOccupied(const int3 &tile, ETileType::ETileType state)
|
||||
CTileInfo CMapGenerator::getTile(const int3& tile) const
|
||||
{
|
||||
if (!map->isInTheMap(tile))
|
||||
throw rmgException(boost::to_string(boost::format("Tile %s is outside the map") % tile));
|
||||
throw rmgException(boost::to_string(boost::format("Tile %s is outside the map") % tile));
|
||||
|
||||
return tiles[tile.x][tile.y][tile.z];
|
||||
}
|
||||
@ -336,7 +415,7 @@ CTileInfo CMapGenerator::getTile(const int3& tile) const
|
||||
void CMapGenerator::setNearestObjectDistance(int3 &tile, int value)
|
||||
{
|
||||
if (!map->isInTheMap(tile))
|
||||
throw rmgException(boost::to_string(boost::format("Tile %s is outside the map") % tile));
|
||||
throw rmgException(boost::to_string(boost::format("Tile %s is outside the map") % tile));
|
||||
|
||||
tiles[tile.x][tile.y][tile.z].setNearestObjectDistance(value);
|
||||
}
|
||||
@ -344,12 +423,29 @@ void CMapGenerator::setNearestObjectDistance(int3 &tile, int value)
|
||||
int CMapGenerator::getNearestObjectDistance(const int3 &tile) const
|
||||
{
|
||||
if (!map->isInTheMap(tile))
|
||||
throw rmgException(boost::to_string(boost::format("Tile %s is outside the map") % tile));
|
||||
throw rmgException(boost::to_string(boost::format("Tile %s is outside the map") % tile));
|
||||
|
||||
return tiles[tile.x][tile.y][tile.z].getNearestObjectDistance();
|
||||
}
|
||||
|
||||
int CMapGenerator::getNextMonlithIndex()
|
||||
{
|
||||
return monolithIndex++;
|
||||
if (monolithIndex >= VLC->objtypeh->knownSubObjects(Obj::MONOLITH_TWO_WAY).size())
|
||||
throw rmgException(boost::to_string(boost::format("There is no Monolith Two Way with index %d available!") % monolithIndex));
|
||||
else
|
||||
return monolithIndex++;
|
||||
}
|
||||
|
||||
void CMapGenerator::registerZone (TFaction faction)
|
||||
{
|
||||
zonesPerFaction[faction]++;
|
||||
zonesTotal++;
|
||||
}
|
||||
ui32 CMapGenerator::getZoneCount(TFaction faction)
|
||||
{
|
||||
return zonesPerFaction[faction];
|
||||
}
|
||||
ui32 CMapGenerator::getTotalZoneCount() const
|
||||
{
|
||||
return zonesTotal;
|
||||
}
|
||||
|
@ -70,6 +70,7 @@ public:
|
||||
bool shouldBeBlocked(const int3 &tile) const;
|
||||
bool isPossible(const int3 &tile) const;
|
||||
bool isFree(const int3 &tile) const;
|
||||
bool isUsed(const int3 &tile) const;
|
||||
void setOccupied(const int3 &tile, ETileType::ETileType state);
|
||||
CTileInfo getTile(const int3 & tile) const;
|
||||
|
||||
@ -77,9 +78,14 @@ public:
|
||||
void setNearestObjectDistance(int3 &tile, int value);
|
||||
|
||||
int getNextMonlithIndex();
|
||||
void registerZone (TFaction faction);
|
||||
ui32 getZoneCount(TFaction faction);
|
||||
ui32 getTotalZoneCount() const;
|
||||
|
||||
private:
|
||||
std::map<TRmgTemplateZoneId, CRmgTemplateZone*> zones;
|
||||
std::map<TFaction, ui32> zonesPerFaction;
|
||||
ui32 zonesTotal; //zones that have their main town only
|
||||
|
||||
CTileInfo*** tiles;
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -16,6 +16,7 @@
|
||||
#include "float3.h"
|
||||
#include "../int3.h"
|
||||
#include "../ResourceSet.h" //for TResource (?)
|
||||
#include "../mapObjects/ObjectTemplate.h"
|
||||
|
||||
class CMapGenerator;
|
||||
class CTileInfo;
|
||||
@ -45,6 +46,7 @@ public:
|
||||
bool shouldBeBlocked() const;
|
||||
bool isPossible() const;
|
||||
bool isFree() const;
|
||||
bool isUsed() const;
|
||||
void setOccupied(ETileType::ETileType value);
|
||||
ETerrainType getTerrainType() const;
|
||||
void setTerrainType(ETerrainType value);
|
||||
@ -66,9 +68,25 @@ public:
|
||||
|
||||
struct DLL_LINKAGE ObjectInfo
|
||||
{
|
||||
ObjectTemplate templ;
|
||||
ui32 value;
|
||||
ui16 probability;
|
||||
ui32 maxPerZone;
|
||||
ui32 maxPerMap;
|
||||
std::function<CGObjectInstance *()> generateObject;
|
||||
|
||||
void setTemplate (si32 type, si32 subtype, ETerrainType terrain);
|
||||
|
||||
bool operator==(const ObjectInfo& oi) const { return (templ == oi.templ); }
|
||||
};
|
||||
|
||||
struct DLL_LINKAGE CTreasurePileInfo
|
||||
{
|
||||
std::set<int3> visitableFromBottomPositions; //can be visited only from bottom or side
|
||||
std::set<int3> visitableFromTopPositions; //they can be visited from any direction
|
||||
std::set<int3> blockedPositions;
|
||||
std::set<int3> occupiedPositions; //blocked + visitable
|
||||
int3 nextTreasurePos;
|
||||
};
|
||||
|
||||
/// The CRmgTemplateZone describes a zone in a template.
|
||||
@ -128,13 +146,15 @@ public:
|
||||
|
||||
void addTile (const int3 &pos);
|
||||
std::set<int3> getTileInfo () const;
|
||||
void discardDistantTiles (CMapGenerator* gen, float distance);
|
||||
|
||||
void addRequiredObject(CGObjectInstance * obj, si32 guardStrength=0);
|
||||
bool addMonster(CMapGenerator* gen, int3 &pos, si32 strength);
|
||||
bool addMonster(CMapGenerator* gen, int3 &pos, si32 strength, bool clearSurroundingTiles = true, bool zoneGuard = false);
|
||||
bool createTreasurePile (CMapGenerator* gen, int3 &pos);
|
||||
bool fill (CMapGenerator* gen);
|
||||
bool placeMines (CMapGenerator* gen);
|
||||
void initTownType (CMapGenerator* gen);
|
||||
void paintZoneTerrain (CMapGenerator* gen, ETerrainType terrainType);
|
||||
void initTerrainType (CMapGenerator* gen);
|
||||
void createBorder(CMapGenerator* gen);
|
||||
void fractalize(CMapGenerator* gen);
|
||||
@ -152,7 +172,9 @@ public:
|
||||
std::vector<CTreasureInfo> getTreasureInfo();
|
||||
std::set<int3>* getFreePaths();
|
||||
|
||||
ObjectInfo getRandomObject (CMapGenerator* gen, ui32 value);
|
||||
ObjectInfo getRandomObject (CMapGenerator* gen, CTreasurePileInfo &info, ui32 value);
|
||||
|
||||
void placeAndGuardObject(CMapGenerator* gen, CGObjectInstance* object, const int3 &pos, si32 str, bool zoneGuard = false);
|
||||
|
||||
private:
|
||||
//template info
|
||||
@ -189,10 +211,11 @@ private:
|
||||
|
||||
bool pointIsIn(int x, int y);
|
||||
void addAllPossibleObjects (CMapGenerator* gen); //add objects, including zone-specific, to possibleObjects
|
||||
bool isAccessibleFromAnywhere (CMapGenerator* gen, ObjectTemplate &appearance, int3 &tile, const std::set<int3> &tilesBlockedByObject) const;
|
||||
bool findPlaceForObject(CMapGenerator* gen, CGObjectInstance* obj, si32 min_dist, int3 &pos);
|
||||
bool findPlaceForTreasurePile(CMapGenerator* gen, si32 min_dist, int3 &pos);
|
||||
bool canObstacleBePlacedHere(CMapGenerator* gen, ObjectTemplate &temp, int3 &pos);
|
||||
void checkAndPlaceObject(CMapGenerator* gen, CGObjectInstance* object, const int3 &pos);
|
||||
void placeObject(CMapGenerator* gen, CGObjectInstance* object, const int3 &pos);
|
||||
bool guardObject(CMapGenerator* gen, CGObjectInstance* object, si32 str);
|
||||
bool guardObject(CMapGenerator* gen, CGObjectInstance* object, si32 str, bool zoneGuard = false);
|
||||
};
|
||||
|
@ -43,7 +43,8 @@ void CZonePlacer::placeZones(shared_ptr<CMapGenOptions> mapGenOptions, CRandomGe
|
||||
//some relaxation-simmulated annealing algorithm
|
||||
|
||||
const int iterations = 100;
|
||||
float temperature = 1e-2;;
|
||||
float temperatureConstant = 1e-2;
|
||||
float currentTemperature = 2; //geater temperature - stronger gravity, weaker pushing away
|
||||
const float temperatureModifier = 0.99;
|
||||
|
||||
logGlobal->infoStream() << "Starting zone placement";
|
||||
@ -52,8 +53,7 @@ void CZonePlacer::placeZones(shared_ptr<CMapGenOptions> mapGenOptions, CRandomGe
|
||||
int height = mapGenOptions->getHeight();
|
||||
|
||||
auto zones = gen->getZones();
|
||||
|
||||
//TODO: consider underground zones
|
||||
bool underground = mapGenOptions->getHasTwoLevels();
|
||||
|
||||
/*
|
||||
let's assume we try to fit N circular zones with radius = size on a map
|
||||
@ -62,13 +62,37 @@ void CZonePlacer::placeZones(shared_ptr<CMapGenOptions> mapGenOptions, CRandomGe
|
||||
|
||||
prescaler = sqrt((WH)/(sum(n^2)*pi))
|
||||
*/
|
||||
std::vector<std::pair<TRmgTemplateZoneId, CRmgTemplateZone*>> zonesVector (zones.begin(), zones.end());
|
||||
assert (zonesVector.size());
|
||||
|
||||
RandomGeneratorUtil::randomShuffle(zonesVector, *rand);
|
||||
TRmgTemplateZoneId firstZone = zones.begin()->first; //we want lowest ID here
|
||||
bool undergroundFlag = false;
|
||||
|
||||
float totalSize = 0;
|
||||
for (auto zone : zones)
|
||||
for (auto zone : zonesVector)
|
||||
{
|
||||
//even distribution for surface / underground zones. Surface zones always have priority.
|
||||
int level = 0;
|
||||
if (underground) //only then consider underground zones
|
||||
{
|
||||
if (zone.first == firstZone)
|
||||
{
|
||||
level = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
level = undergroundFlag;
|
||||
undergroundFlag = !undergroundFlag; //toggle underground on/off
|
||||
}
|
||||
}
|
||||
|
||||
totalSize += (zone.second->getSize() * zone.second->getSize());
|
||||
zone.second->setCenter (float3(rand->nextDouble(0.2,0.8), rand->nextDouble(0.2,0.8), 0)); //start away from borders
|
||||
zone.second->setCenter (float3(rand->nextDouble(0.2, 0.8), rand->nextDouble(0.2, 0.8), level)); //start away from borders
|
||||
}
|
||||
//prescale zones
|
||||
if (underground) //map is twice as big, so zones occupy only half of normal space
|
||||
totalSize /= 2;
|
||||
float prescaler = sqrt ((width * height) / (totalSize * 3.14f));
|
||||
float mapSize = sqrt (width * height);
|
||||
for (auto zone : zones)
|
||||
@ -95,63 +119,66 @@ void CZonePlacer::placeZones(shared_ptr<CMapGenOptions> mapGenOptions, CRandomGe
|
||||
for (auto con : zone.second->getConnections())
|
||||
{
|
||||
auto otherZone = zones[con];
|
||||
float distance = pos.dist2d (otherZone->getCenter());
|
||||
float3 otherZoneCenter = otherZone->getCenter();
|
||||
float distance = pos.dist2d (otherZoneCenter);
|
||||
float minDistance = (zone.second->getSize() + otherZone->getSize())/mapSize; //scale down to (0,1) coordinates
|
||||
if (distance > minDistance)
|
||||
{
|
||||
forceVector += (otherZone->getCenter() - pos) / getDistance(distance); //positive value
|
||||
//WARNING: compiler used to 'optimize' that line so it never actually worked
|
||||
forceVector += (((otherZoneCenter - pos) / getDistance(distance)) * currentTemperature); //positive value
|
||||
}
|
||||
}
|
||||
//separate overlaping zones
|
||||
for (auto otherZone : zones)
|
||||
{
|
||||
if (zone == otherZone)
|
||||
float3 otherZoneCenter = otherZone.second->getCenter();
|
||||
//zones on different levels don't push away
|
||||
if (zone == otherZone || pos.z != otherZoneCenter.z)
|
||||
continue;
|
||||
|
||||
float distance = pos.dist2d (otherZone.second->getCenter());
|
||||
float distance = pos.dist2d (otherZoneCenter);
|
||||
float minDistance = (zone.second->getSize() + otherZone.second->getSize())/mapSize;
|
||||
if (distance < minDistance)
|
||||
{
|
||||
forceVector -= (otherZone.second->getCenter() - pos) / getDistance(distance); //negative value
|
||||
forceVector -= (otherZoneCenter - pos) / getDistance(distance) / currentTemperature; //negative value
|
||||
}
|
||||
}
|
||||
|
||||
//move zones away from boundaries
|
||||
float3 boundary(0,0,pos.z);
|
||||
float size = zone.second->getSize() / mapSize;
|
||||
|
||||
auto pushAwayFromBoundary = [&forceVector, pos, currentTemperature, &getDistance](float x, float y)
|
||||
{
|
||||
float3 boundary = float3 (x, y, pos.z);
|
||||
float distance = pos.dist2d(boundary);
|
||||
forceVector -= (boundary - pos) / getDistance(distance) / currentTemperature; //negative value
|
||||
};
|
||||
if (pos.x < size)
|
||||
{
|
||||
boundary = float3 (0, pos.y, pos.z);
|
||||
float distance = pos.dist2d(boundary);
|
||||
forceVector -= (boundary - pos) / getDistance(distance); //negative value
|
||||
pushAwayFromBoundary(0, pos.y);
|
||||
}
|
||||
if (pos.x > 1-size)
|
||||
{
|
||||
boundary = float3 (1, pos.y, pos.z);
|
||||
float distance = pos.dist2d(boundary);
|
||||
forceVector -= (boundary - pos) / getDistance(distance); //negative value
|
||||
pushAwayFromBoundary(1, pos.y);
|
||||
}
|
||||
if (pos.y < size)
|
||||
{
|
||||
boundary = float3 (pos.x, 0, pos.z);
|
||||
float distance = pos.dist2d(boundary);
|
||||
forceVector -= (boundary - pos) / getDistance(distance); //negative value
|
||||
pushAwayFromBoundary(pos.x, 0);
|
||||
}
|
||||
if (pos.y > 1-size)
|
||||
{
|
||||
boundary = float3 (pos.x, 1, pos.z);
|
||||
float distance = pos.dist2d(boundary);
|
||||
forceVector -= (boundary - pos) / getDistance(distance); //negative value
|
||||
pushAwayFromBoundary(pos.x, 1);
|
||||
}
|
||||
|
||||
forces[zone.second] = forceVector;
|
||||
forceVector.z = 0; //operator - doesn't preserve z coordinate :/
|
||||
forces[zone.second] = forceVector * temperatureConstant;
|
||||
}
|
||||
//update positions
|
||||
for (auto zone : forces)
|
||||
{
|
||||
zone.first->setCenter (zone.first->getCenter() + zone.second * temperature);
|
||||
zone.first->setCenter (zone.first->getCenter() + zone.second);
|
||||
}
|
||||
temperature *= temperatureModifier; //decrease temperature (needed?)
|
||||
currentTemperature *= temperatureModifier; //decrease temperature (needed?)
|
||||
}
|
||||
for (auto zone : zones) //finalize zone positions
|
||||
{
|
||||
@ -213,7 +240,10 @@ void CZonePlacer::assignZones(shared_ptr<CMapGenOptions> mapGenOptions)
|
||||
int3 pos(i, j, k);
|
||||
for (auto zone : zones)
|
||||
{
|
||||
distances.push_back (std::make_pair(zone.second, metric(pos, zone.second->getPos())));
|
||||
if (zone.second->getPos().z == k)
|
||||
distances.push_back (std::make_pair(zone.second, metric(pos, zone.second->getPos())));
|
||||
else
|
||||
distances.push_back (std::make_pair(zone.second, std::numeric_limits<float>::max()));
|
||||
}
|
||||
boost::sort (distances, compareByDistance);
|
||||
distances.front().first->addTile(pos); //closest tile belongs to zone
|
||||
@ -230,7 +260,18 @@ void CZonePlacer::assignZones(shared_ptr<CMapGenOptions> mapGenOptions)
|
||||
total += tile;
|
||||
}
|
||||
int size = tiles.size();
|
||||
assert (size);
|
||||
zone.second->setPos (int3(total.x/size, total.y/size, total.z/size));
|
||||
|
||||
//TODO: similiar for islands
|
||||
if (zone.second->getPos().z)
|
||||
{
|
||||
zone.second->discardDistantTiles(gen, zone.second->getSize() + 1);
|
||||
|
||||
//make sure that terrain inside zone is not a rock
|
||||
//FIXME: reorder actions?
|
||||
zone.second->paintZoneTerrain (gen, ETerrainType::SUBTERRANEAN);
|
||||
}
|
||||
}
|
||||
logGlobal->infoStream() << "Finished zone colouring";
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user