mirror of
https://github.com/vcmi/vcmi.git
synced 2024-12-24 22:14:36 +02:00
- console logger by default uses same format as previously (no extra data)
- a lot of changes in configs; - - update to creature format - abilities are now json structure - - multiple bugfixes revealed by validation - made schemas a bit more strict - creatures data can be replaced via mods - it is possible to validate vcmi configs using schemas (disabled)
This commit is contained in:
parent
f10ba48c77
commit
0cf969d508
@ -133,7 +133,7 @@ endif()
|
||||
# For apple this files will be already inside vcmiclient bundle
|
||||
if (NOT APPLE)
|
||||
# copy whole directory but .svn control files and user-specific settings.json
|
||||
install(DIRECTORY config DESTINATION ${DATA_DIR} PATTERN ".svn" EXCLUDE PATTERN "settings.json" EXCLUDE)
|
||||
install(DIRECTORY config DESTINATION ${DATA_DIR} PATTERN ".svn" EXCLUDE)
|
||||
# copy vcmi mod along with all its content
|
||||
install(DIRECTORY Mods/vcmi DESTINATION ${DATA_DIR}/Mods PATTERN ".svn" EXCLUDE)
|
||||
# copy only mod.json for WoG
|
||||
|
@ -139,8 +139,7 @@ bool CDefenceAnimation::init()
|
||||
int attackerAnimType = owner->creAnims[attacker->ID]->getType();
|
||||
if( ( attackerAnimType == CCreatureAnim::ATTACK_UP ||
|
||||
attackerAnimType == CCreatureAnim::ATTACK_FRONT ||
|
||||
attackerAnimType == CCreatureAnim::ATTACK_DOWN ) &&
|
||||
owner->creAnims[attacker->ID]->getFrame() < attacker->getCreature()->animation.attackClimaxFrame )
|
||||
attackerAnimType == CCreatureAnim::ATTACK_DOWN ) )
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -2194,7 +2194,7 @@
|
||||
"valueType" : "BASE_NUMBER"
|
||||
},
|
||||
{
|
||||
"additionalInfo" : 2,
|
||||
"addInfo" : 2,
|
||||
"subtype" : "spell.lightningBolt",
|
||||
"type" : "ENCHANTER",
|
||||
"val" : 0,
|
||||
@ -2256,28 +2256,28 @@
|
||||
"valueType" : "PERCENT_TO_BASE"
|
||||
},
|
||||
{
|
||||
"additionalInfo" : 1,
|
||||
"addInfo" : 1,
|
||||
"subtype" : "spell.age",
|
||||
"type" : "SPELL_BEFORE_ATTACK",
|
||||
"val" : 50,
|
||||
"valueType" : "BASE_NUMBER"
|
||||
},
|
||||
{
|
||||
"additionalInfo" : 1,
|
||||
"addInfo" : 1,
|
||||
"subtype" : "spell.berserk",
|
||||
"type" : "SPELL_AFTER_ATTACK",
|
||||
"val" : 50,
|
||||
"valueType" : "BASE_NUMBER"
|
||||
},
|
||||
{
|
||||
"additionalInfo" : 1,
|
||||
"addInfo" : 1,
|
||||
"subtype" : "spell.poison",
|
||||
"type" : "SPELL_AFTER_ATTACK",
|
||||
"val" : 50,
|
||||
"valueType" : "BASE_NUMBER"
|
||||
},
|
||||
{
|
||||
"additionalInfo" : 1,
|
||||
"addInfo" : 1,
|
||||
"subtype" : "spell.disruptingRay",
|
||||
"type" : "SPELL_AFTER_ATTACK",
|
||||
"val" : 50,
|
||||
@ -2363,7 +2363,12 @@
|
||||
[
|
||||
{
|
||||
"level": 6,
|
||||
"bonus": ["PRIMARY_SKILL", 1, "primSkill.attack", 0]
|
||||
"bonus":
|
||||
{
|
||||
"type" : "PRIMARY_SKILL",
|
||||
"subtype" : "primSkill.attack",
|
||||
"val" : 1
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -2385,7 +2390,11 @@
|
||||
[
|
||||
{
|
||||
"level": 1,
|
||||
"bonus": ["STACK_HEALTH", 1, 0, 0]
|
||||
"bonus":
|
||||
{
|
||||
"type" : "STACK_HEALTH",
|
||||
"val" : 1
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -2408,7 +2417,11 @@
|
||||
[
|
||||
{
|
||||
"level": 1,
|
||||
"bonus": ["CREATURE_DAMAGE", 1, 0, 0]
|
||||
"bonus":
|
||||
{
|
||||
"type" : "CREATURE_DAMAGE",
|
||||
"val" : 1
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -2435,7 +2448,11 @@
|
||||
[
|
||||
{
|
||||
"level": 10,
|
||||
"bonus": ["CREATURE_ENCHANT_POWER", 1, 0, 0]
|
||||
"bonus":
|
||||
{
|
||||
"type" : "CREATURE_ENCHANT_POWER",
|
||||
"val" : 1
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -2457,7 +2474,11 @@
|
||||
[
|
||||
{
|
||||
"level": 10,
|
||||
"bonus": ["STACKS_SPEED", 1, 0, 0]
|
||||
"bonus":
|
||||
{
|
||||
"type" : "STACKS_SPEED",
|
||||
"val" : 1
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -2468,20 +2489,28 @@
|
||||
"type" : ["COMMANDER"],
|
||||
"growing":
|
||||
{
|
||||
"id": 152, //bow of seeking
|
||||
"thresholdBonuses":
|
||||
[
|
||||
{
|
||||
"level": 5,
|
||||
"bonus": ["SHOOTER", 0, 0, 0]
|
||||
"bonus":
|
||||
{
|
||||
"type" : "SHOOTER"
|
||||
}
|
||||
},
|
||||
{
|
||||
"level": 25,
|
||||
"bonus": ["NO_WALL_PENALTY", 0, 0, 0]
|
||||
"bonus":
|
||||
{
|
||||
"type" : "NO_WALL_PENALTY"
|
||||
}
|
||||
},
|
||||
{
|
||||
"level": 50,
|
||||
"bonus": ["NO_DISTANCE_PENALTY", 0, 0, 0]
|
||||
"bonus":
|
||||
{
|
||||
"type" : "NO_DISTANCE_PENALTY"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -2505,12 +2534,16 @@
|
||||
"type" : ["COMMANDER"],
|
||||
"growing":
|
||||
{
|
||||
"id": 153, //hardened shield
|
||||
"bonusesPerLevel":
|
||||
[
|
||||
{
|
||||
"level": 6,
|
||||
"bonus": ["PRIMARY_SKILL", 1, "primSkill.defence", 0]
|
||||
"bonus":
|
||||
{
|
||||
"type" : "PRIMARY_SKILL",
|
||||
"subtype" : "primSkill.defence",
|
||||
"val" : 1
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
@ -5,7 +5,13 @@
|
||||
"level": 1,
|
||||
"faction": "castle",
|
||||
"upgrades": ["halberdier"],
|
||||
"abilities": [ [ "CHARGE_IMMUNITY", 0, 0, 0 ] ], //pikeman immunity to Champion charge bonus
|
||||
"abilities":
|
||||
{
|
||||
"cavalryChargeImmunity" :
|
||||
{
|
||||
"type" : "CHARGE_IMMUNITY"
|
||||
}
|
||||
},
|
||||
"graphics" :
|
||||
{
|
||||
"animation": "CPKMAN.DEF"
|
||||
@ -24,7 +30,13 @@
|
||||
"id": 1,
|
||||
"level": 1,
|
||||
"faction": "castle",
|
||||
"abilities": [ [ "CHARGE_IMMUNITY", 0, 0, 0 ] ], //halberdier immunity to Champion charge bonus
|
||||
"abilities":
|
||||
{
|
||||
"cavalryChargeImmunity" :
|
||||
{
|
||||
"type" : "CHARGE_IMMUNITY"
|
||||
}
|
||||
},
|
||||
"graphics" :
|
||||
{
|
||||
"animation": "CHALBD.DEF"
|
||||
@ -50,8 +62,7 @@
|
||||
"animation": "CLCBOW.DEF",
|
||||
"missile" :
|
||||
{
|
||||
"projectile": "PLCBOWX.DEF",
|
||||
"spinning": false
|
||||
"projectile": "PLCBOWX.DEF"
|
||||
}
|
||||
},
|
||||
"sound" :
|
||||
@ -69,20 +80,20 @@
|
||||
"id": 3,
|
||||
"level": 2,
|
||||
"faction": "castle",
|
||||
"abilities": [
|
||||
{
|
||||
"type": "ADDITIONAL_ATTACK",
|
||||
"val" : 1,
|
||||
"effectRange": "ONLY_DISTANCE_FIGHT"
|
||||
}
|
||||
],
|
||||
"abilities": {
|
||||
"extraAttack" :
|
||||
{
|
||||
"type": "ADDITIONAL_ATTACK",
|
||||
"val" : 1,
|
||||
"effectRange": "ONLY_DISTANCE_FIGHT"
|
||||
}
|
||||
},
|
||||
"graphics" :
|
||||
{
|
||||
"animation": "CHCBOW.DEF",
|
||||
"missile" :
|
||||
{
|
||||
"projectile": "PLCBOWX.DEF",
|
||||
"spinning": false
|
||||
"projectile": "PLCBOWX.DEF"
|
||||
}
|
||||
},
|
||||
"sound" :
|
||||
@ -100,7 +111,14 @@
|
||||
"id": 4,
|
||||
"level": 3,
|
||||
"faction": "castle",
|
||||
"abilities": [ [ "ADDITIONAL_RETALIATION", 1, 0, 0 ] ], //griffins retaliate twice
|
||||
"abilities":
|
||||
{
|
||||
"extraRetaliation" :
|
||||
{
|
||||
"type" : "ADDITIONAL_RETALIATION",
|
||||
"val" : 1
|
||||
}
|
||||
},
|
||||
"upgrades": ["royalGriffin"],
|
||||
"hasDoubleWeek": true,
|
||||
"graphics" :
|
||||
@ -121,7 +139,13 @@
|
||||
"id": 5,
|
||||
"level": 3,
|
||||
"faction": "castle",
|
||||
"abilities": [ [ "UNLIMITED_RETALIATIONS", 0, 0, 0 ] ], //royal griffins retaliate always
|
||||
"abilities":
|
||||
{
|
||||
"unlimitedRetaliation" :
|
||||
{
|
||||
"type" : "UNLIMITED_RETALIATIONS"
|
||||
}
|
||||
},
|
||||
"graphics" :
|
||||
{
|
||||
"animation": "CRGRIF.DEF"
|
||||
@ -159,7 +183,14 @@
|
||||
"id": 7,
|
||||
"level": 4,
|
||||
"faction": "castle",
|
||||
"abilities": [ [ "ADDITIONAL_ATTACK", 1, 0, 0 ] ],
|
||||
"abilities":
|
||||
{
|
||||
"extraAttack" :
|
||||
{
|
||||
"type" : "ADDITIONAL_ATTACK",
|
||||
"val" : 1
|
||||
}
|
||||
},
|
||||
"graphics" :
|
||||
{
|
||||
"animation": "CCRUSD.DEF"
|
||||
@ -184,8 +215,7 @@
|
||||
"animation": "CMONKK.DEF",
|
||||
"missile" :
|
||||
{
|
||||
"projectile": "CPRZEAX.DEF",
|
||||
"spinning": false
|
||||
"projectile": "CPRZEAX.DEF"
|
||||
}
|
||||
},
|
||||
"sound" :
|
||||
@ -208,8 +238,7 @@
|
||||
"animation": "CZEALT.DEF",
|
||||
"missile" :
|
||||
{
|
||||
"projectile": "CPRZEAX.DEF",
|
||||
"spinning": false
|
||||
"projectile": "CPRZEAX.DEF"
|
||||
}
|
||||
},
|
||||
"sound" :
|
||||
@ -264,11 +293,21 @@
|
||||
"id": 12,
|
||||
"level": 7,
|
||||
"faction": "castle",
|
||||
"abilities":
|
||||
[
|
||||
["HATE", 50, "creature.archDevil", 0], //angels hate archdevils
|
||||
["HATE", 50, "creature.devil", 0] //angels hate devil
|
||||
],
|
||||
"abilities":
|
||||
{
|
||||
"hateDevils" :
|
||||
{
|
||||
"type" : "HATE",
|
||||
"subtype" : "creature.devil",
|
||||
"val" : 50
|
||||
},
|
||||
"hateArchDevils" :
|
||||
{
|
||||
"type" : "HATE",
|
||||
"subtype" : "creature.archDevil",
|
||||
"val" : 50
|
||||
}
|
||||
},
|
||||
"upgrades": ["archangel"],
|
||||
"graphics" :
|
||||
{
|
||||
@ -288,14 +327,37 @@
|
||||
"id": 13,
|
||||
"level": 7,
|
||||
"faction": "castle",
|
||||
"abilities":
|
||||
[
|
||||
["SPECIFIC_SPELL_POWER", 100, "spell.resurrection", 0], // 100 hp per Archangel
|
||||
["SPELLCASTER", 0, "spell.resurrection", 0 ], //archangels cast resurrection
|
||||
["HATE", 50, "creature.archDevil", 0], //archangels hate archdevils
|
||||
["HATE", 50, "creature.devil", 0] , //archangels hate devils
|
||||
["CASTS", 1, 0, 0]
|
||||
],
|
||||
"abilities":
|
||||
{
|
||||
"resurrection100hp" :
|
||||
{
|
||||
"type" : "SPECIFIC_SPELL_POWER",
|
||||
"subtype" : "spell.resurrection",
|
||||
"val" : 100
|
||||
},
|
||||
"resurrects" :
|
||||
{
|
||||
"type" : "SPELLCASTER",
|
||||
"subtype" : "spell.resurrection"
|
||||
},
|
||||
"spellpoints" :
|
||||
{
|
||||
"type" : "CASTS",
|
||||
"val" : 1
|
||||
},
|
||||
"hateDevils" :
|
||||
{
|
||||
"type" : "HATE",
|
||||
"subtype" : "creature.devil",
|
||||
"val" : 50
|
||||
},
|
||||
"hateArchDevils" :
|
||||
{
|
||||
"type" : "HATE",
|
||||
"subtype" : "creature.archDevil",
|
||||
"val" : 50
|
||||
}
|
||||
},
|
||||
"graphics" :
|
||||
{
|
||||
"animation": "CRANGL.DEF"
|
||||
|
@ -5,14 +5,34 @@
|
||||
"level": 2,
|
||||
"extraNames": [ "airElementals" ],
|
||||
"faction": "conflux",
|
||||
"abilities":
|
||||
[
|
||||
["MIND_IMMUNITY", 0, 0, 0], //air elementals are immune to mind spells
|
||||
["SPELL_IMMUNITY", 0, "spell.meteorShower", 0], //air elementals are immune to meteor shower
|
||||
["NON_LIVING", 0, 0, 0 ], //air elementals are non-living
|
||||
["MORE_DAMAGE_FROM_SPELL", 100, "spell.chainLightning", 0],//air elementals are vulnerable to chain lightning
|
||||
["MORE_DAMAGE_FROM_SPELL", 100, "spell.lightningBolt", 0] //air elementals are vulnerable to lightning bolt
|
||||
],
|
||||
"abilities":
|
||||
{
|
||||
"nonLiving" :
|
||||
{
|
||||
"type" : "NON_LIVING"
|
||||
},
|
||||
"immuneToMind" :
|
||||
{
|
||||
"type" : "MIND_IMMUNITY"
|
||||
},
|
||||
"meteorShowerImmunity" :
|
||||
{
|
||||
"type" : "SPELL_IMMUNITY",
|
||||
"subtype" : "spell.meteorShower"
|
||||
},
|
||||
"lightingVulnerablity" :
|
||||
{
|
||||
"type" : "MORE_DAMAGE_FROM_SPELL",
|
||||
"subtype" : "spell.lightningBolt",
|
||||
"val" : 100
|
||||
},
|
||||
"chainLightingVulnerablity" :
|
||||
{
|
||||
"type" : "MORE_DAMAGE_FROM_SPELL",
|
||||
"subtype" : "spell.chainLightning",
|
||||
"val" : 100
|
||||
}
|
||||
},
|
||||
"upgrades": ["stormElemental"],
|
||||
"graphics" :
|
||||
{
|
||||
@ -32,14 +52,33 @@
|
||||
"id": 113,
|
||||
"level": 5,
|
||||
"faction": "conflux",
|
||||
"abilities":
|
||||
[
|
||||
["MIND_IMMUNITY", 0, 0, 0], //earth elementals are immune to mind spells
|
||||
["SPELL_IMMUNITY", 0, "spell.chainLightning", 0],//earth elementals are immune to chain lightning
|
||||
["SPELL_IMMUNITY", 0, "spell.lightningBolt", 0], //earth elementals are immune to lightning bolt
|
||||
["NON_LIVING", 0, 0, 0],
|
||||
[ "MORE_DAMAGE_FROM_SPELL", 100, "spell.meteorShower", 0 ] //earth elementals are vulnerable to meteor shower
|
||||
],
|
||||
"abilities":
|
||||
{
|
||||
"nonLiving" :
|
||||
{
|
||||
"type" : "NON_LIVING"
|
||||
},
|
||||
"immuneToMind" :
|
||||
{
|
||||
"type" : "MIND_IMMUNITY"
|
||||
},
|
||||
"meteorShowerVulnerability" :
|
||||
{
|
||||
"type" : "MORE_DAMAGE_FROM_SPELL",
|
||||
"subtype" : "spell.meteorShower",
|
||||
"val" : 100
|
||||
},
|
||||
"lightingImmunity" :
|
||||
{
|
||||
"type" : "SPELL_IMMUNITY",
|
||||
"subtype" : "spell.lightningBolt"
|
||||
},
|
||||
"chainLightingImmunity" :
|
||||
{
|
||||
"type" : "SPELL_IMMUNITY",
|
||||
"subtype" : "spell.chainLightning"
|
||||
}
|
||||
},
|
||||
"upgrades": ["magmaElemental"],
|
||||
"graphics" :
|
||||
{
|
||||
@ -59,13 +98,33 @@
|
||||
"id": 114,
|
||||
"level": 4,
|
||||
"faction": "conflux",
|
||||
"abilities":
|
||||
[
|
||||
["MIND_IMMUNITY", 0, 0, 0],//fire elementals are immune to mind spells
|
||||
["NON_LIVING", 0, 0, 0 ], //fire elementals are non-living
|
||||
[ "MORE_DAMAGE_FROM_SPELL", 100, "spell.frostRing", 0 ], //fire elementals are vulnerable to frost ring
|
||||
[ "MORE_DAMAGE_FROM_SPELL", 100, "spell.iceBolt", 0 ], //fire elementals are vulnerable to ice bolt
|
||||
[ "FIRE_IMMUNITY", 0, 0, 0 ] ], //fire elementals are immune to fire spells
|
||||
"abilities":
|
||||
{
|
||||
"nonLiving" :
|
||||
{
|
||||
"type" : "NON_LIVING"
|
||||
},
|
||||
"immuneToMind" :
|
||||
{
|
||||
"type" : "MIND_IMMUNITY"
|
||||
},
|
||||
"immuneToFire" :
|
||||
{
|
||||
"type" : "FIRE_IMMUNITY"
|
||||
},
|
||||
"frostRingVulnerablity" :
|
||||
{
|
||||
"type" : "MORE_DAMAGE_FROM_SPELL",
|
||||
"subtype" : "spell.frostRing",
|
||||
"val" : 100
|
||||
},
|
||||
"iceBoltVulnerablity" :
|
||||
{
|
||||
"type" : "MORE_DAMAGE_FROM_SPELL",
|
||||
"subtype" : "spell.iceBolt",
|
||||
"val" : 100
|
||||
}
|
||||
},
|
||||
"upgrades": ["energyElemental"],
|
||||
"graphics" :
|
||||
{
|
||||
@ -86,17 +145,52 @@
|
||||
"level": 3,
|
||||
"extraNames": [ "waterElementals" ],
|
||||
"faction": "conflux",
|
||||
"abilities": [
|
||||
["MIND_IMMUNITY", 0, 0, 0],//water elementals are immune to mind spells
|
||||
["SPELL_IMMUNITY", 0, "spell.frostRing", 0 ],//water elementals are immune to frost ring
|
||||
["SPELL_IMMUNITY", 0, "spell.iceBolt", 0 ],//water elementals are immune to ice bolt
|
||||
["NON_LIVING", 0, 0, 0 ], //water elementals are non-living
|
||||
["MORE_DAMAGE_FROM_SPELL", 100, "spell.fireShield", 0 ], //water elementals are vulnerable to fire shield
|
||||
["MORE_DAMAGE_FROM_SPELL", 100, "spell.inferno", 0 ], //water elementals are vulnerable to inferno
|
||||
["MORE_DAMAGE_FROM_SPELL", 100, "spell.fireball", 0 ], //water elementals are vulnerable to fireball
|
||||
["MORE_DAMAGE_FROM_SPELL", 100, "spell.fireWall", 0 ], //water elementals are vulnerable to fire wall
|
||||
["DOUBLE_WIDE", 0, 0, 0 ]
|
||||
],
|
||||
"abilities":
|
||||
{
|
||||
"nonLiving" :
|
||||
{
|
||||
"type" : "NON_LIVING"
|
||||
},
|
||||
"immuneToMind" :
|
||||
{
|
||||
"type" : "MIND_IMMUNITY"
|
||||
},
|
||||
"fireShieldVulnerablity" :
|
||||
{
|
||||
"type" : "MORE_DAMAGE_FROM_SPELL",
|
||||
"subtype" : "spell.fireShield",
|
||||
"val" : 100
|
||||
},
|
||||
"infernoVulnerablity" :
|
||||
{
|
||||
"type" : "MORE_DAMAGE_FROM_SPELL",
|
||||
"subtype" : "spell.inferno",
|
||||
"val" : 100
|
||||
},
|
||||
"fireballVulnerablity" :
|
||||
{
|
||||
"type" : "MORE_DAMAGE_FROM_SPELL",
|
||||
"subtype" : "spell.fireball",
|
||||
"val" : 100
|
||||
},
|
||||
"fireWallVulnerablity" :
|
||||
{
|
||||
"type" : "MORE_DAMAGE_FROM_SPELL",
|
||||
"subtype" : "spell.fireWall",
|
||||
"val" : 100
|
||||
},
|
||||
"iceBoltImmunity" :
|
||||
{
|
||||
"type" : "SPELL_IMMUNITY",
|
||||
"subtype" : "spell.iceBolt"
|
||||
},
|
||||
"frostRingImmunity" :
|
||||
{
|
||||
"type" : "SPELL_IMMUNITY",
|
||||
"subtype" : "spell.frostRing"
|
||||
}
|
||||
},
|
||||
"doubleWide" : true,
|
||||
"upgrades": ["iceElemental"],
|
||||
"graphics" :
|
||||
{
|
||||
@ -154,8 +248,14 @@
|
||||
"id": 120,
|
||||
"level": 6,
|
||||
"faction": "conflux",
|
||||
"abilities": [ [ "NON_LIVING", 0, 0, 0 ] ], //magic elementals shouldn't get morale
|
||||
"ability_remove": [ "DOUBLE_WIDE" ],
|
||||
"abilities":
|
||||
{
|
||||
"nonLiving" :
|
||||
{
|
||||
"type" : "NON_LIVING"
|
||||
}
|
||||
},
|
||||
"doubleWide" : false,
|
||||
"upgrades": ["magicElemental"],
|
||||
"graphics" :
|
||||
{
|
||||
@ -175,9 +275,19 @@
|
||||
"id": 121,
|
||||
"level": 6,
|
||||
"faction": "conflux",
|
||||
"abilities": [ [ "NON_LIVING", 0, 0, 0 ], //ice elementals shouldn't get morale
|
||||
[ "LEVEL_SPELL_IMMUNITY", 5, 0, 0 ] ], //magic elementals are immune to all spells
|
||||
"ability_remove": [ "DOUBLE_WIDE" ],
|
||||
"abilities":
|
||||
{
|
||||
"nonLiving" :
|
||||
{
|
||||
"type" : "NON_LIVING"
|
||||
},
|
||||
"magicImmunity" :
|
||||
{
|
||||
"type" : "LEVEL_SPELL_IMMUNITY",
|
||||
"val" : 5
|
||||
}
|
||||
},
|
||||
"doubleWide" : false,
|
||||
"graphics" :
|
||||
{
|
||||
"animation": "CMAGEL.DEF"
|
||||
@ -196,18 +306,36 @@
|
||||
"id": 123,
|
||||
"level": 3,
|
||||
"faction": "conflux",
|
||||
"abilities": [ [ "NON_LIVING", 0, 0, 0 ],
|
||||
[ "DOUBLE_WIDE", 0, 0, 0 ], //ice elemental should be treated as double-wide
|
||||
[ "CREATURE_ENCHANT_POWER", 6, 0, 0 ],
|
||||
[ "CASTS", 3, 0, 0 ],
|
||||
[ "SPELLCASTER", 2, "spell.protectWater", 0 ]],
|
||||
"abilities":
|
||||
{
|
||||
"nonLiving" :
|
||||
{
|
||||
"type" : "NON_LIVING"
|
||||
},
|
||||
"spellPower" :
|
||||
{
|
||||
"type" : "CREATURE_ENCHANT_POWER",
|
||||
"val" : 6
|
||||
},
|
||||
"spellPoints" :
|
||||
{
|
||||
"type" : "CASTS",
|
||||
"val" : 3
|
||||
},
|
||||
"spellcaster":
|
||||
{
|
||||
"type" : "SPELLCASTER",
|
||||
"subtype" : "spell.protectWater",
|
||||
"val" : 2
|
||||
}
|
||||
},
|
||||
"doubleWide" : true,
|
||||
"graphics" :
|
||||
{
|
||||
"animation": "CICEE.DEF",
|
||||
"missile" :
|
||||
{
|
||||
"projectile": "PICEE.DEF",
|
||||
"spinning": false
|
||||
"projectile": "PICEE.DEF"
|
||||
}
|
||||
},
|
||||
"sound" :
|
||||
@ -225,10 +353,29 @@
|
||||
"id": 125,
|
||||
"level": 5,
|
||||
"faction": "conflux",
|
||||
"abilities": [ [ "NON_LIVING", 0, 0, 0 ], //magma elementals shouldn't get morale
|
||||
[ "CREATURE_ENCHANT_POWER", 6, 0, 0 ],
|
||||
[ "CASTS", 3, 0, 0 ],
|
||||
[ "SPELLCASTER", 2, "spell.protectEarth", 0 ]],
|
||||
"abilities":
|
||||
{
|
||||
"nonLiving" :
|
||||
{
|
||||
"type" : "NON_LIVING"
|
||||
},
|
||||
"spellPower" :
|
||||
{
|
||||
"type" : "CREATURE_ENCHANT_POWER",
|
||||
"val" : 6
|
||||
},
|
||||
"spellPoints" :
|
||||
{
|
||||
"type" : "CASTS",
|
||||
"val" : 3
|
||||
},
|
||||
"spellcaster":
|
||||
{
|
||||
"type" : "SPELLCASTER",
|
||||
"subtype" : "spell.protectEarth",
|
||||
"val" : 2
|
||||
}
|
||||
},
|
||||
"graphics" :
|
||||
{
|
||||
"animation": "CSTONE.DEF"
|
||||
@ -247,17 +394,35 @@
|
||||
"id": 127,
|
||||
"level": 2,
|
||||
"faction": "conflux",
|
||||
"abilities": [ [ "NON_LIVING", 0, 0, 0 ], //storm elementals shouldn't get morale
|
||||
[ "CREATURE_ENCHANT_POWER", 6, 0, 0 ],
|
||||
[ "CASTS", 3, 0, 0 ],
|
||||
[ "SPELLCASTER", 2, "spell.protectAir", 0 ]],
|
||||
"abilities":
|
||||
{
|
||||
"nonLiving" :
|
||||
{
|
||||
"type" : "NON_LIVING"
|
||||
},
|
||||
"spellPower" :
|
||||
{
|
||||
"type" : "CREATURE_ENCHANT_POWER",
|
||||
"val" : 6
|
||||
},
|
||||
"spellPoints" :
|
||||
{
|
||||
"type" : "CASTS",
|
||||
"val" : 3
|
||||
},
|
||||
"spellcaster":
|
||||
{
|
||||
"type" : "SPELLCASTER",
|
||||
"subtype" : "spell.protectAir",
|
||||
"val" : 2
|
||||
}
|
||||
},
|
||||
"graphics" :
|
||||
{
|
||||
"animation": "CSTORM.DEF",
|
||||
"missile" :
|
||||
{
|
||||
"projectile": "CPRGTIX.DEF",
|
||||
"spinning": false
|
||||
"projectile": "CPRGTIX.DEF"
|
||||
}
|
||||
},
|
||||
"sound" :
|
||||
@ -275,10 +440,29 @@
|
||||
"id": 129,
|
||||
"level": 4,
|
||||
"faction": "conflux",
|
||||
"abilities": [ [ "NON_LIVING", 0, 0, 0 ] , //energy elementals shouldn't get morale
|
||||
[ "CREATURE_ENCHANT_POWER", 6, 0, 0 ],
|
||||
[ "CASTS", 3, 0, 0 ],
|
||||
[ "SPELLCASTER", 2, "spell.protectFire", 0 ]],
|
||||
"abilities":
|
||||
{
|
||||
"nonLiving" :
|
||||
{
|
||||
"type" : "NON_LIVING"
|
||||
},
|
||||
"spellPower" :
|
||||
{
|
||||
"type" : "CREATURE_ENCHANT_POWER",
|
||||
"val" : 6
|
||||
},
|
||||
"spellPoints" :
|
||||
{
|
||||
"type" : "CASTS",
|
||||
"val" : 3
|
||||
},
|
||||
"spellcaster":
|
||||
{
|
||||
"type" : "SPELLCASTER",
|
||||
"subtype" : "spell.protectFire",
|
||||
"val" : 2
|
||||
}
|
||||
},
|
||||
"graphics" :
|
||||
{
|
||||
"animation": "CNRG.DEF"
|
||||
@ -298,7 +482,13 @@
|
||||
"level": 7,
|
||||
"faction": "conflux",
|
||||
"upgrades": ["phoenix"],
|
||||
"abilities": [ ["FIRE_IMMUNITY", 0, 0, 0] ],
|
||||
"abilities":
|
||||
{
|
||||
"immuneToFire" :
|
||||
{
|
||||
"type" : "FIRE_IMMUNITY"
|
||||
},
|
||||
},
|
||||
"graphics" :
|
||||
{
|
||||
"animation": "CFBIRD.DEF"
|
||||
@ -317,9 +507,23 @@
|
||||
"id": 131,
|
||||
"level": 7,
|
||||
"faction": "conflux",
|
||||
"abilities": [ [ "CASTS", 1, 0, 0 ], //Phoenix rebirths once
|
||||
["FIRE_IMMUNITY", 0, 0, 0],
|
||||
[ "REBIRTH", 20, 0, 0 ] ], //20% of stack is resurrected
|
||||
"abilities":
|
||||
{
|
||||
"rebirthOnce" :
|
||||
{
|
||||
"type" : "CASTS",
|
||||
"val" : 1
|
||||
},
|
||||
"immuneToFire" :
|
||||
{
|
||||
"type" : "FIRE_IMMUNITY"
|
||||
},
|
||||
"rebirth" :
|
||||
{
|
||||
"type" : "REBIRTH",
|
||||
"val" : 20
|
||||
}
|
||||
},
|
||||
"graphics" :
|
||||
{
|
||||
"animation": "CPHX.DEF"
|
||||
|
@ -4,7 +4,14 @@
|
||||
"id": 70,
|
||||
"level": 1,
|
||||
"faction": "dungeon",
|
||||
"abilities": [ [ "SPELL_IMMUNITY", 0, "spell.blind", 0 ] ], //troglodytes are immune to blind
|
||||
"abilities":
|
||||
{
|
||||
"blindImmunity" :
|
||||
{
|
||||
"type" : "SPELL_IMMUNITY",
|
||||
"subtype" : "spell.blind"
|
||||
}
|
||||
},
|
||||
"upgrades": ["infernalTroglodyte"],
|
||||
"hasDoubleWeek": true,
|
||||
"graphics" :
|
||||
@ -25,7 +32,14 @@
|
||||
"id": 71,
|
||||
"level": 1,
|
||||
"faction": "dungeon",
|
||||
"abilities": [ [ "SPELL_IMMUNITY", 0, "spell.blind", 0 ] ], //infernal troglodytes are immune to blind
|
||||
"abilities":
|
||||
{
|
||||
"blindImmunity" :
|
||||
{
|
||||
"type" : "SPELL_IMMUNITY",
|
||||
"subtype" : "spell.blind"
|
||||
}
|
||||
},
|
||||
"graphics" :
|
||||
{
|
||||
"animation": "CITROG.DEF"
|
||||
@ -44,7 +58,13 @@
|
||||
"id": 72,
|
||||
"level": 2,
|
||||
"faction": "dungeon",
|
||||
"abilities": [ [ "RETURN_AFTER_STRIKE", 0, 0, 0 ] ], //Harpies return after attack
|
||||
"abilities":
|
||||
{
|
||||
"strikeAndReturn" :
|
||||
{
|
||||
"type" : "RETURN_AFTER_STRIKE"
|
||||
}
|
||||
},
|
||||
"upgrades": ["harpyHag"],
|
||||
"hasDoubleWeek": true,
|
||||
"graphics" :
|
||||
@ -66,8 +86,17 @@
|
||||
"id": 73,
|
||||
"level": 2,
|
||||
"faction": "dungeon",
|
||||
"abilities": [ [ "RETURN_AFTER_STRIKE", 0, 0, 0 ], //Harpy Hags return after attack
|
||||
[ "BLOCKS_RETALIATION", 0, 0, 0 ] ], //Harpy Hags
|
||||
"abilities":
|
||||
{
|
||||
"strikeAndReturn" :
|
||||
{
|
||||
"type" : "RETURN_AFTER_STRIKE"
|
||||
},
|
||||
"noRetaliation" :
|
||||
{
|
||||
"type" : "BLOCKS_RETALIATION"
|
||||
}
|
||||
},
|
||||
"graphics" :
|
||||
{
|
||||
"animation": "CHARPH.DEF"
|
||||
@ -93,8 +122,7 @@
|
||||
"animation": "CBEHOL.DEF",
|
||||
"missile" :
|
||||
{
|
||||
"projectile": "SMBALX.DEF",
|
||||
"spinning": false
|
||||
"projectile": "SMBALX.DEF"
|
||||
}
|
||||
},
|
||||
"sound" :
|
||||
@ -104,8 +132,7 @@
|
||||
"killed": "BHDRKILL.wav",
|
||||
"move": "BHDRMOVE.wav",
|
||||
"shoot": "BHDRSHOT.wav",
|
||||
"wince": "BHDRWNCE.wav",
|
||||
"ext1": "BHDRDETH.wav"
|
||||
"wince": "BHDRWNCE.wav"
|
||||
}
|
||||
},
|
||||
"evilEye" :
|
||||
@ -118,8 +145,7 @@
|
||||
"animation": "CEVEYE.DEF",
|
||||
"missile" :
|
||||
{
|
||||
"projectile": "SMBALX.DEF",
|
||||
"spinning": false
|
||||
"projectile": "SMBALX.DEF"
|
||||
}
|
||||
},
|
||||
"sound" :
|
||||
@ -129,8 +155,7 @@
|
||||
"killed": "EVLIKILL.wav",
|
||||
"move": "EVLIMOVE.wav",
|
||||
"shoot": "EVLISHOT.wav",
|
||||
"wince": "EVLIWNCE.wav",
|
||||
"ext1": "EVLIDETH.wav"
|
||||
"wince": "EVLIWNCE.wav"
|
||||
}
|
||||
},
|
||||
"medusa" :
|
||||
@ -138,15 +163,23 @@
|
||||
"id": 76,
|
||||
"level": 4,
|
||||
"faction": "dungeon",
|
||||
"abilities": [ [ "SPELL_AFTER_ATTACK", 20, "spell.stoneGaze", 2000 ] ],
|
||||
"abilities":
|
||||
{
|
||||
"petrification" :
|
||||
{
|
||||
"type" : "SPELL_AFTER_ATTACK",
|
||||
"subtype" : "spell.stoneGaze",
|
||||
"val" : 20,
|
||||
"addInfo" : 2000 // FIXME: replace with range field?
|
||||
}
|
||||
},
|
||||
"upgrades": ["medusaQueen"],
|
||||
"graphics" :
|
||||
{
|
||||
"animation": "CMEDUS.DEF",
|
||||
"missile" :
|
||||
{
|
||||
"projectile": "PMEDUSX.DEF",
|
||||
"spinning": false
|
||||
"projectile": "PMEDUSX.DEF"
|
||||
}
|
||||
},
|
||||
"sound" :
|
||||
@ -164,14 +197,22 @@
|
||||
"id": 77,
|
||||
"level": 4,
|
||||
"faction": "dungeon",
|
||||
"abilities": [ [ "SPELL_AFTER_ATTACK", 20, "spell.stoneGaze", 2000 ] ],
|
||||
"abilities":
|
||||
{
|
||||
"petrification" :
|
||||
{
|
||||
"type" : "SPELL_AFTER_ATTACK",
|
||||
"subtype" : "spell.stoneGaze",
|
||||
"val" : 20,
|
||||
"addInfo" : 2000 // FIXME: replace with range?
|
||||
}
|
||||
},
|
||||
"graphics" :
|
||||
{
|
||||
"animation": "CMEDUQ.DEF",
|
||||
"missile" :
|
||||
{
|
||||
"projectile": "PMEDUSX.DEF",
|
||||
"spinning": false
|
||||
"projectile": "PMEDUSX.DEF"
|
||||
}
|
||||
},
|
||||
"sound" :
|
||||
@ -189,7 +230,13 @@
|
||||
"id": 78,
|
||||
"level": 5,
|
||||
"faction": "dungeon",
|
||||
"abilities": [ [ "SELF_MORALE", 0, 0, 0 ] ],
|
||||
"abilities":
|
||||
{
|
||||
"fearless" :
|
||||
{
|
||||
"type" : "SELF_MORALE"
|
||||
}
|
||||
},
|
||||
"upgrades": ["minotaurKing"],
|
||||
"graphics" :
|
||||
{
|
||||
@ -209,7 +256,13 @@
|
||||
"id": 79,
|
||||
"level": 5,
|
||||
"faction": "dungeon",
|
||||
"abilities": [ [ "SELF_MORALE", 0, 0, 0 ] ],
|
||||
"abilities":
|
||||
{
|
||||
"fearless" :
|
||||
{
|
||||
"type" : "SELF_MORALE"
|
||||
}
|
||||
},
|
||||
"graphics" :
|
||||
{
|
||||
"animation": "CMINOK.DEF"
|
||||
@ -249,7 +302,15 @@
|
||||
"id": 81,
|
||||
"level": 6,
|
||||
"faction": "dungeon",
|
||||
"abilities": [ [ "SPELL_AFTER_ATTACK", 20, "spell.paralyze", 0 ] ],
|
||||
"abilities":
|
||||
{
|
||||
"paralize" :
|
||||
{
|
||||
"type" : "SPELL_AFTER_ATTACK",
|
||||
"subtype" : "spell.paralyze",
|
||||
"val" : 20
|
||||
}
|
||||
},
|
||||
"graphics" :
|
||||
{
|
||||
"animation": "CCMCOR.DEF"
|
||||
@ -269,9 +330,22 @@
|
||||
"id": 82,
|
||||
"level": 7,
|
||||
"faction": "dungeon",
|
||||
"abilities": [ [ "DRAGON_NATURE", 0, 0, 0 ], //red dragon is a dragon
|
||||
[ "TWO_HEX_ATTACK_BREATH", 0, 0, 0 ], //Red Dragon has breath attack
|
||||
[ "LEVEL_SPELL_IMMUNITY", 3, 0, 0 ] ], //red dragon's spell immunity
|
||||
"abilities":
|
||||
{
|
||||
"dragon" :
|
||||
{
|
||||
"type" : "DRAGON_NATURE"
|
||||
},
|
||||
"fireBreath" :
|
||||
{
|
||||
"type" : "TWO_HEX_ATTACK_BREATH"
|
||||
},
|
||||
"spellImmunity" :
|
||||
{
|
||||
"type" : "LEVEL_SPELL_IMMUNITY",
|
||||
"val" : 3
|
||||
}
|
||||
},
|
||||
"upgrades": ["blackDragon"],
|
||||
"graphics" :
|
||||
{
|
||||
@ -291,11 +365,34 @@
|
||||
"id": 83,
|
||||
"level": 7,
|
||||
"faction": "dungeon",
|
||||
"abilities": [ [ "DRAGON_NATURE", 0, 0, 0 ], //black dragon is a dragon
|
||||
[ "TWO_HEX_ATTACK_BREATH", 0, 0, 0 ], //Black Dragon has breath attack
|
||||
[ "HATE", 50, "creature.titan", 0 ], //Hate Titans
|
||||
[ "HATE", 50, "creature.giant", 0 ], //Hate Giants
|
||||
[ "LEVEL_SPELL_IMMUNITY", 5, 0, 0 ] ], //black dragon's spell immunity
|
||||
"abilities":
|
||||
{
|
||||
"dragon" :
|
||||
{
|
||||
"type" : "DRAGON_NATURE"
|
||||
},
|
||||
"fireBreath" :
|
||||
{
|
||||
"type" : "TWO_HEX_ATTACK_BREATH"
|
||||
},
|
||||
"spellImmunity" :
|
||||
{
|
||||
"type" : "LEVEL_SPELL_IMMUNITY",
|
||||
"val" : 5
|
||||
},
|
||||
"hateGiants" :
|
||||
{
|
||||
"type" : "HATE",
|
||||
"subtype" : "creature.giant",
|
||||
"val" : 50
|
||||
},
|
||||
"hateTitans" :
|
||||
{
|
||||
"type" : "HATE",
|
||||
"subtype" : "creature.titan",
|
||||
"val" : 50
|
||||
}
|
||||
},
|
||||
"graphics" :
|
||||
{
|
||||
"animation": "CBDRGN.DEF"
|
||||
|
@ -49,8 +49,7 @@
|
||||
"animation": "CPLIZA.DEF",
|
||||
"missile" :
|
||||
{
|
||||
"projectile": "PPLIZAX.DEF",
|
||||
"spinning": false
|
||||
"projectile": "PPLIZAX.DEF"
|
||||
}
|
||||
},
|
||||
"sound" :
|
||||
@ -73,8 +72,7 @@
|
||||
"animation": "CALIZA.DEF",
|
||||
"missile" :
|
||||
{
|
||||
"projectile": "PPLIZAX.DEF",
|
||||
"spinning": false
|
||||
"projectile": "PPLIZAX.DEF"
|
||||
}
|
||||
},
|
||||
"sound" :
|
||||
@ -111,7 +109,14 @@
|
||||
"id": 103,
|
||||
"level": 5,
|
||||
"faction": "fortress",
|
||||
"abilities": [ [ "DEATH_STARE", 10, 0, 0 ] ], //mighty gorgons
|
||||
"abilities":
|
||||
{
|
||||
"deathStare" :
|
||||
{
|
||||
"type" : "DEATH_STARE",
|
||||
"val" : 10
|
||||
}
|
||||
},
|
||||
"graphics" :
|
||||
{
|
||||
"animation": "CBGOG.DEF"
|
||||
@ -131,7 +136,15 @@
|
||||
"level": 3,
|
||||
"extraNames": [ "dragonFly" ],
|
||||
"faction": "fortress",
|
||||
"abilities": [ [ "SPELL_AFTER_ATTACK", 100, "spell.dispelHelpful", 0 ] ],
|
||||
"abilities":
|
||||
{
|
||||
"dispellHelpful" :
|
||||
{
|
||||
"type" : "SPELL_AFTER_ATTACK",
|
||||
"subtype" : "spell.dispelHelpful",
|
||||
"val" : 100
|
||||
}
|
||||
},
|
||||
"upgrades": ["fireDragonFly"],
|
||||
"hasDoubleWeek": true,
|
||||
"graphics" :
|
||||
@ -152,8 +165,21 @@
|
||||
"id": 105,
|
||||
"level": 3,
|
||||
"faction": "fortress",
|
||||
"abilities": [ [ "SPELL_AFTER_ATTACK", 100, "spell.dispelHelpful", 0 ],
|
||||
[ "SPELL_AFTER_ATTACK", 100, "spell.weakness", 0 ] ],
|
||||
"abilities":
|
||||
{
|
||||
"dispellHelpful" :
|
||||
{
|
||||
"type" : "SPELL_AFTER_ATTACK",
|
||||
"subtype" : "spell.dispelHelpful",
|
||||
"val" : 100
|
||||
},
|
||||
"castWeakness" :
|
||||
{
|
||||
"type" : "SPELL_AFTER_ATTACK",
|
||||
"subtype" : "spell.weakness",
|
||||
"val" : 100
|
||||
}
|
||||
},
|
||||
"graphics" :
|
||||
{
|
||||
"animation": "CDRFIR.DEF"
|
||||
@ -173,7 +199,15 @@
|
||||
"id": 106,
|
||||
"level": 4,
|
||||
"faction": "fortress",
|
||||
"abilities": [ [ "SPELL_AFTER_ATTACK", 20, "spell.stoneGaze", 0 ] ],
|
||||
"abilities":
|
||||
{
|
||||
"petrify" :
|
||||
{
|
||||
"type" : "SPELL_AFTER_ATTACK",
|
||||
"subtype" : "spell.stoneGaze",
|
||||
"val" : 20
|
||||
}
|
||||
},
|
||||
"upgrades": ["greaterBasilisk"],
|
||||
"graphics" :
|
||||
{
|
||||
@ -193,7 +227,15 @@
|
||||
"id": 107,
|
||||
"level": 4,
|
||||
"faction": "fortress",
|
||||
"abilities": [ [ "SPELL_AFTER_ATTACK", 20, "spell.stoneGaze", 0 ] ],
|
||||
"abilities":
|
||||
{
|
||||
"petrify" :
|
||||
{
|
||||
"type" : "SPELL_AFTER_ATTACK",
|
||||
"subtype" : "spell.stoneGaze",
|
||||
"val" : 20
|
||||
}
|
||||
},
|
||||
"graphics" :
|
||||
{
|
||||
"animation": "CGBASI.DEF"
|
||||
@ -231,7 +273,15 @@
|
||||
"id": 109,
|
||||
"level": 6,
|
||||
"faction": "fortress",
|
||||
"abilities": [ [ "SPELL_AFTER_ATTACK", 50, "spell.poison", 0 ] ], //50% probability (from FizMiG)
|
||||
"abilities":
|
||||
{
|
||||
"petrify" :
|
||||
{
|
||||
"type" : "SPELL_AFTER_ATTACK",
|
||||
"subtype" : "spell.stoneGaze",
|
||||
"val" : 50
|
||||
}
|
||||
},
|
||||
"graphics" :
|
||||
{
|
||||
"animation": "CWYVMN.DEF"
|
||||
@ -250,8 +300,17 @@
|
||||
"id": 110,
|
||||
"level": 7,
|
||||
"faction": "fortress",
|
||||
"abilities": [ [ "BLOCKS_RETALIATION", 0, 0, 0 ],
|
||||
[ "ATTACKS_ALL_ADJACENT", 0, 0, 0 ] ],
|
||||
"abilities":
|
||||
{
|
||||
"noRetaliate" :
|
||||
{
|
||||
"type" : "BLOCKS_RETALIATION"
|
||||
},
|
||||
"attackAll" :
|
||||
{
|
||||
"type" : "ATTACKS_ALL_ADJACENT"
|
||||
}
|
||||
},
|
||||
"upgrades": ["chaosHydra"],
|
||||
"graphics" :
|
||||
{
|
||||
@ -271,8 +330,17 @@
|
||||
"id": 111,
|
||||
"level": 7,
|
||||
"faction": "fortress",
|
||||
"abilities": [ [ "BLOCKS_RETALIATION", 0, 0, 0 ],
|
||||
[ "ATTACKS_ALL_ADJACENT", 0, 0, 0 ] ],
|
||||
"abilities":
|
||||
{
|
||||
"noRetaliate" :
|
||||
{
|
||||
"type" : "BLOCKS_RETALIATION"
|
||||
},
|
||||
"attackAll" :
|
||||
{
|
||||
"type" : "ATTACKS_ALL_ADJACENT"
|
||||
}
|
||||
},
|
||||
"graphics" :
|
||||
{
|
||||
"animation": "CCHYDR.DEF"
|
||||
|
@ -23,7 +23,14 @@
|
||||
"id": 43,
|
||||
"level": 1,
|
||||
"faction": "inferno",
|
||||
"abilities": [ [ "MANA_CHANNELING", 20, 0, 0 ] ], //familiars
|
||||
"abilities":
|
||||
{
|
||||
"manaChannel" :
|
||||
{
|
||||
"type" : "MANA_CHANNELING",
|
||||
"val" : 20
|
||||
}
|
||||
},
|
||||
"graphics" :
|
||||
{
|
||||
"animation": "CFAMIL.DEF"
|
||||
@ -49,8 +56,7 @@
|
||||
"animation": "CGOG.DEF",
|
||||
"missile" :
|
||||
{
|
||||
"projectile": "CPRGOGX.DEF",
|
||||
"spinning": false
|
||||
"projectile": "CPRGOGX.DEF"
|
||||
}
|
||||
},
|
||||
"sound" :
|
||||
@ -60,8 +66,7 @@
|
||||
"killed": "GOGGKILL.wav",
|
||||
"move": "GOGGMOVE.wav",
|
||||
"shoot": "GOGGSHOT.wav",
|
||||
"wince": "GOGGWNCE.wav",
|
||||
"ext1": "GOGFLAME.wav"
|
||||
"wince": "GOGGWNCE.wav"
|
||||
}
|
||||
},
|
||||
"magog" :
|
||||
@ -69,14 +74,20 @@
|
||||
"id": 45,
|
||||
"level": 2,
|
||||
"faction": "inferno",
|
||||
"abilities": [ [ "SPELL_LIKE_ATTACK", 0, 21, 0 ] ], //magogs fire with fireballs
|
||||
"abilities":
|
||||
{
|
||||
"fireball" :
|
||||
{
|
||||
"type" : "SPELL_LIKE_ATTACK",
|
||||
"subtype" : "spell.fireball"
|
||||
}
|
||||
},
|
||||
"graphics" :
|
||||
{
|
||||
"animation": "CMAGOG.DEF",
|
||||
"missile" :
|
||||
{
|
||||
"projectile": "CPRGOGX.DEF",
|
||||
"spinning": false
|
||||
"projectile": "CPRGOGX.DEF"
|
||||
}
|
||||
},
|
||||
"sound" :
|
||||
@ -86,8 +97,7 @@
|
||||
"killed": "MGOGKILL.wav",
|
||||
"move": "MGOGMOVE.wav",
|
||||
"shoot": "MGOGSHOT.wav",
|
||||
"wince": "MGOGWNCE.wav",
|
||||
"ext1": "GOGFLAME.wav"
|
||||
"wince": "MGOGWNCE.wav"
|
||||
}
|
||||
},
|
||||
"hellHound" :
|
||||
@ -96,7 +106,10 @@
|
||||
"level": 3,
|
||||
"faction": "inferno",
|
||||
"upgrades": ["cerberus"],
|
||||
"ability_remove": [ "FLYING" ], //hell hound doesn't fly
|
||||
"abilities":
|
||||
{
|
||||
"FLYING_ARMY" : null //hell hound doesn't fly
|
||||
},
|
||||
"graphics" :
|
||||
{
|
||||
"animation": "CHHOUN.DEF"
|
||||
@ -115,9 +128,18 @@
|
||||
"id": 47,
|
||||
"level": 3,
|
||||
"faction": "inferno",
|
||||
"abilities": [ [ "THREE_HEADED_ATTACK", 0, 0, 0 ],
|
||||
[ "BLOCKS_RETALIATION", 0, 0, 0 ] ],
|
||||
"ability_remove": [ "FLYING" ], //cerberus doesn't fly
|
||||
"abilities":
|
||||
{
|
||||
"threeHeads" :
|
||||
{
|
||||
"type" : "THREE_HEADED_ATTACK"
|
||||
},
|
||||
"noRetaliation" :
|
||||
{
|
||||
"type" : "BLOCKS_RETALIATION"
|
||||
},
|
||||
"FLYING_ARMY" : null //cerberus doesn't fly
|
||||
},
|
||||
"graphics" :
|
||||
{
|
||||
"animation": "CCERBU.DEF"
|
||||
@ -192,8 +214,20 @@
|
||||
"id": 51,
|
||||
"level": 5,
|
||||
"faction": "inferno",
|
||||
"abilities": [ [ "DAEMON_SUMMONING", 50, 48, 0 ],
|
||||
[ "CASTS", 1, 0, 0] ], //pit lord
|
||||
"abilities":
|
||||
{
|
||||
"demonSummon" :
|
||||
{
|
||||
"type" : "DAEMON_SUMMONING",
|
||||
"subtype" : "creature.demon",
|
||||
"val" : 50
|
||||
},
|
||||
"castsAmount" :
|
||||
{
|
||||
"type" : "CASTS",
|
||||
"val" : 1
|
||||
}
|
||||
},
|
||||
"graphics" :
|
||||
{
|
||||
"animation": "CPFOE.DEF"
|
||||
@ -211,11 +245,30 @@
|
||||
{
|
||||
"id": 52,
|
||||
"level": 6,
|
||||
"faction": "inferno",
|
||||
"abilities": [ [ "HATE", 50, 37, 0 ],
|
||||
[ "HATE", 50, 36, 0 ],
|
||||
[ "FLYING", 0, 0, 0 ], //efreeti hate master genies
|
||||
[ "FIRE_IMMUNITY", 0, 0, 0 ] ], //efreeti hate genies
|
||||
"faction": "inferno",
|
||||
"abilities":
|
||||
{
|
||||
"hateGenies" :
|
||||
{
|
||||
"type" : "HATE",
|
||||
"subtype" : "creature.genie",
|
||||
"val" : 50
|
||||
},
|
||||
"hateMasterGenies" :
|
||||
{
|
||||
"type" : "HATE",
|
||||
"subtype" : "creature.masterGenie",
|
||||
"val" : 50
|
||||
},
|
||||
"canFly" :
|
||||
{
|
||||
"type" : "FLYING"
|
||||
},
|
||||
"immuneToFire" :
|
||||
{
|
||||
"type" : "FIRE_IMMUNITY"
|
||||
}
|
||||
},
|
||||
"upgrades": ["efreetSultan"],
|
||||
"graphics" :
|
||||
{
|
||||
@ -235,11 +288,34 @@
|
||||
"id": 53,
|
||||
"level": 6,
|
||||
"faction": "inferno",
|
||||
"abilities": [ [ "HATE", 50, 37, 0 ],
|
||||
[ "HATE", 50, 36, 0 ],
|
||||
[ "FLYING", 0, 0, 0 ], //efreet sultans hate master genies
|
||||
[ "FIRE_SHIELD", 0, 36, 0 ], //efreet sultans hate genies
|
||||
[ "FIRE_IMMUNITY", 0, 0, 0 ] ], //efreet sultan //Efreet Sultan
|
||||
"abilities":
|
||||
{
|
||||
"hateGenies" :
|
||||
{
|
||||
"type" : "HATE",
|
||||
"subtype" : "creature.genie",
|
||||
"val" : 50
|
||||
},
|
||||
"hateMasterGenies" :
|
||||
{
|
||||
"type" : "HATE",
|
||||
"subtype" : "creature.masterGenie",
|
||||
"val" : 50
|
||||
},
|
||||
"canFly" :
|
||||
{
|
||||
"type" : "FLYING"
|
||||
},
|
||||
"immuneToFire" :
|
||||
{
|
||||
"type" : "FIRE_IMMUNITY"
|
||||
},
|
||||
"fireShield" :
|
||||
{
|
||||
"type" : "FIRE_SHIELD",
|
||||
"subtype" : 36 //FIXME: what is this magic number for?
|
||||
}
|
||||
},
|
||||
"graphics" :
|
||||
{
|
||||
"animation": "CEFRES.DEF"
|
||||
@ -259,12 +335,36 @@
|
||||
"id": 54,
|
||||
"level": 7,
|
||||
"faction": "inferno",
|
||||
"ability_remove": [ "FLYING" ], //use teleport instead
|
||||
"abilities": [ [ "HATE", 50, 13, 0 ],
|
||||
[ "FLYING", 0, 1, 0], //teleport
|
||||
[ "HATE", 50, 12, 0 ],
|
||||
[ "ENEMY_LUCK_DECREASING", 1, 0, 0 ], //devils //devils hate archangles
|
||||
[ "BLOCKS_RETALIATION", 0, 0, 0 ] ], //devils //devils hate angels
|
||||
"abilities":
|
||||
{
|
||||
"hateAngels" :
|
||||
{
|
||||
"type" : "HATE",
|
||||
"subtype" : "creature.angel",
|
||||
"val" : 50
|
||||
},
|
||||
"hateArchAngels" :
|
||||
{
|
||||
"type" : "HATE",
|
||||
"subtype" : "creature.angel",
|
||||
"val" : 50
|
||||
},
|
||||
"FLYING_ARMY" :
|
||||
{
|
||||
// type loaded from crtraits
|
||||
"subtype" : 1 // teleports
|
||||
},
|
||||
"descreaseLuck" :
|
||||
{
|
||||
"type" : "LUCK",
|
||||
"effectRange" : "ONLY_ENEMY_ARMY",
|
||||
"val" : -1
|
||||
},
|
||||
"blockRetaliation" :
|
||||
{
|
||||
"type" : "BLOCKS_RETALIATION"
|
||||
}
|
||||
},
|
||||
"upgrades": ["archDevil"],
|
||||
"graphics" :
|
||||
{
|
||||
@ -277,8 +377,8 @@
|
||||
"killed": "DEVLKILL.wav",
|
||||
"move": "DEVLMOVE.wav",
|
||||
"wince": "DEVLWNCE.wav",
|
||||
"ext1": "DEVLEXT1.wav",
|
||||
"ext2": "DEVLEXT2.wav"
|
||||
"startMoving": "DEVLEXT1.wav",
|
||||
"endMoving": "DEVLEXT2.wav"
|
||||
}
|
||||
},
|
||||
"archDevil" :
|
||||
@ -286,14 +386,39 @@
|
||||
"id": 55,
|
||||
"level": 7,
|
||||
"faction": "inferno",
|
||||
"ability_remove": [ "FLYING" ], //use teleport instead
|
||||
"abilities": [ [ "HATE", 50, 13, 0 ],
|
||||
[ "HATE", 50, 12, 0 ],
|
||||
[ "FLYING", 0, 1, 0],
|
||||
[ "ENEMY_LUCK_DECREASING", 1, 0, 0 ], //archdevils //archdevils hate archangles
|
||||
[ "BLOCKS_RETALIATION", 0, 0, 0 ] ], //archdevils //archdevils hate angels
|
||||
"abilities" :
|
||||
{
|
||||
"hateAngels" :
|
||||
{
|
||||
"type" : "HATE",
|
||||
"subtype" : "creature.angel",
|
||||
"val" : 50
|
||||
},
|
||||
"hateArchAngels" :
|
||||
{
|
||||
"type" : "HATE",
|
||||
"subtype" : "creature.angel",
|
||||
"val" : 50
|
||||
},
|
||||
"FLYING_ARMY" :
|
||||
{
|
||||
// type loaded from crtraits
|
||||
"subtype" : 1 // teleports
|
||||
},
|
||||
"descreaseLuck" :
|
||||
{
|
||||
"type" : "LUCK",
|
||||
"effectRange" : "ONLY_ENEMY_ARMY",
|
||||
"val" : -1
|
||||
},
|
||||
"blockRetaliation" :
|
||||
{
|
||||
"type" : "BLOCKS_RETALIATION"
|
||||
}
|
||||
},
|
||||
"graphics" :
|
||||
{
|
||||
"missile" : null,
|
||||
"animation": "CADEVL.DEF"
|
||||
},
|
||||
"sound" :
|
||||
@ -304,7 +429,7 @@
|
||||
"move": "ADVLMOVE.wav",
|
||||
"wince": "ADVLWNCE.wav",
|
||||
"startMoving": "ADVLEXT1.wav",
|
||||
"stopMoving": "ADVLEXT2.wav"
|
||||
"endMoving": "ADVLEXT2.wav"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -79,7 +79,14 @@
|
||||
"id": 60,
|
||||
"level": 3,
|
||||
"faction": "necropolis",
|
||||
"abilities": [ [ "FULL_HP_REGENERATION", 0, 1, 0 ] ],
|
||||
"abilities":
|
||||
{
|
||||
"regenerate" :
|
||||
{
|
||||
"type" : "FULL_HP_REGENERATION",
|
||||
"subtype" : 1
|
||||
}
|
||||
},
|
||||
"upgrades": ["wraith"],
|
||||
"hasDoubleWeek": true,
|
||||
"graphics" :
|
||||
@ -100,8 +107,19 @@
|
||||
"id": 61,
|
||||
"level": 3,
|
||||
"faction": "necropolis",
|
||||
"abilities": [ [ "FULL_HP_REGENERATION", 0, 1, 0 ],
|
||||
[ "MANA_DRAIN", 2, 0, 0 ] ],
|
||||
"abilities":
|
||||
{
|
||||
"regenerate" :
|
||||
{
|
||||
"type" : "FULL_HP_REGENERATION",
|
||||
"subtype" : 1
|
||||
},
|
||||
"drainsMana" :
|
||||
{
|
||||
"type" : "MANA_DRAIN",
|
||||
"val" : 2
|
||||
}
|
||||
},
|
||||
"graphics" :
|
||||
{
|
||||
"animation": "CWRAIT.DEF"
|
||||
@ -120,7 +138,14 @@
|
||||
"id": 62,
|
||||
"level": 4,
|
||||
"faction": "necropolis",
|
||||
"abilities": [ [ "BLOCKS_RETALIATION", 0, 0, 0 ] ],
|
||||
"abilities":
|
||||
{
|
||||
"noRetalitation" :
|
||||
{
|
||||
"type" : "BLOCKS_RETALIATION",
|
||||
"subtype" : 1
|
||||
}
|
||||
},
|
||||
"upgrades": ["vampireLord"],
|
||||
"graphics" :
|
||||
{
|
||||
@ -134,7 +159,7 @@
|
||||
"move": "VAMPMOVE.wav",
|
||||
"wince": "VAMPWNCE.wav",
|
||||
"startMoving": "VAMPEXT1.wav",
|
||||
"stopMoving": "VAMPEXT2.wav"
|
||||
"endMoving": "VAMPEXT2.wav"
|
||||
}
|
||||
},
|
||||
"vampireLord" :
|
||||
@ -142,8 +167,19 @@
|
||||
"id": 63,
|
||||
"level": 4,
|
||||
"faction": "necropolis",
|
||||
"abilities": [ [ "LIFE_DRAIN", 100, 0, 0 ], //drain 100% of damage dealt
|
||||
[ "BLOCKS_RETALIATION", 0, 0, 0 ] ],
|
||||
"abilities":
|
||||
{
|
||||
"noRetalitation" :
|
||||
{
|
||||
"type" : "BLOCKS_RETALIATION",
|
||||
"subtype" : 1
|
||||
},
|
||||
"drainsLife" :
|
||||
{
|
||||
"type" : "LIFE_DRAIN",
|
||||
"val" : 100
|
||||
}
|
||||
},
|
||||
"graphics" :
|
||||
{
|
||||
"animation": "CNOSFE.DEF"
|
||||
@ -156,8 +192,8 @@
|
||||
"move": "NOSFMOVE.wav",
|
||||
"shoot": "NOSFSHOT.wav",
|
||||
"wince": "NOSFWNCE.wav",
|
||||
"ext1": "NOSFEXT1.wav",
|
||||
"ext2": "NOSFEXT2.wav"
|
||||
"startMoving": "NOSFEXT1.wav",
|
||||
"endMoving": "NOSFEXT2.wav"
|
||||
}
|
||||
},
|
||||
"lich" :
|
||||
@ -165,15 +201,21 @@
|
||||
"id": 64,
|
||||
"level": 5,
|
||||
"faction": "necropolis",
|
||||
"abilities": [ [ "SPELL_LIKE_ATTACK", 0, "spell.deathCloud", 0 ] ],
|
||||
"abilities":
|
||||
{
|
||||
"deathCloud" :
|
||||
{
|
||||
"type" : "SPELL_LIKE_ATTACK",
|
||||
"subtype" : "spell.deathCloud"
|
||||
}
|
||||
},
|
||||
"upgrades": ["powerLich"],
|
||||
"graphics" :
|
||||
{
|
||||
"animation": "CLICH.DEF",
|
||||
"missile" :
|
||||
{
|
||||
"projectile": "PLICH.DEF",
|
||||
"spinning": false
|
||||
"projectile": "PLICH.DEF"
|
||||
}
|
||||
},
|
||||
"sound" :
|
||||
@ -183,8 +225,7 @@
|
||||
"killed": "LICHKILL.wav",
|
||||
"move": "LICHMOVE.wav",
|
||||
"shoot": "LICHSHOT.wav",
|
||||
"wince": "LICHWNCE.wav",
|
||||
"ext1": "LICHATK2.wav"
|
||||
"wince": "LICHWNCE.wav"
|
||||
}
|
||||
},
|
||||
"powerLich" :
|
||||
@ -192,14 +233,20 @@
|
||||
"id": 65,
|
||||
"level": 5,
|
||||
"faction": "necropolis",
|
||||
"abilities": [ [ "SPELL_LIKE_ATTACK", 0, "spell.deathCloud", 0 ] ], //power liches
|
||||
"abilities":
|
||||
{
|
||||
"deathCloud" :
|
||||
{
|
||||
"type" : "SPELL_LIKE_ATTACK",
|
||||
"subtype" : "spell.deathCloud"
|
||||
}
|
||||
},
|
||||
"graphics" :
|
||||
{
|
||||
"animation": "CPLICH.DEF",
|
||||
"missile" :
|
||||
{
|
||||
"projectile": "PLICH.DEF",
|
||||
"spinning": false
|
||||
"projectile": "PLICH.DEF"
|
||||
}
|
||||
},
|
||||
"sound" :
|
||||
@ -217,7 +264,15 @@
|
||||
"id": 66,
|
||||
"level": 6,
|
||||
"faction": "necropolis",
|
||||
"abilities": [ [ "SPELL_AFTER_ATTACK", 20, "spell.curse", 0 ] ],
|
||||
"abilities":
|
||||
{
|
||||
"curses" :
|
||||
{
|
||||
"type" : "SPELL_AFTER_ATTACK",
|
||||
"subtype" : "spell.curse",
|
||||
"val" : 20
|
||||
}
|
||||
},
|
||||
"upgrades": ["dreadKnight"],
|
||||
"graphics" :
|
||||
{
|
||||
@ -237,8 +292,20 @@
|
||||
"id": 67,
|
||||
"level": 6,
|
||||
"faction": "necropolis",
|
||||
"abilities": [ [ "SPELL_AFTER_ATTACK", 20, "spell.curse", 0 ],
|
||||
[ "DOUBLE_DAMAGE_CHANCE", 20, 0, 0 ] ],
|
||||
"abilities":
|
||||
{
|
||||
"curses" :
|
||||
{
|
||||
"type" : "SPELL_AFTER_ATTACK",
|
||||
"subtype" : "spell.curse",
|
||||
"val" : 20
|
||||
},
|
||||
"deathStrike" :
|
||||
{
|
||||
"type" : "DOUBLE_DAMAGE_CHANCE",
|
||||
"val" : 20
|
||||
}
|
||||
},
|
||||
"graphics" :
|
||||
{
|
||||
"animation": "CBLORD.DEF"
|
||||
@ -257,7 +324,13 @@
|
||||
"id": 68,
|
||||
"level": 7,
|
||||
"faction": "necropolis",
|
||||
"abilities": [ [ "DRAGON_NATURE", 0, 0, 0 ] ], //bone dragon is a dragon
|
||||
"abilities" :
|
||||
{
|
||||
"dragon" :
|
||||
{
|
||||
"type" : "DRAGON_NATURE"
|
||||
}
|
||||
},
|
||||
"upgrades": ["ghostDragon"],
|
||||
"graphics" :
|
||||
{
|
||||
@ -277,8 +350,19 @@
|
||||
"id": 69,
|
||||
"level": 7,
|
||||
"faction": "necropolis",
|
||||
"abilities": [ [ "DRAGON_NATURE", 0, 0, 0 ], //ghost dragon is a dragon
|
||||
[ "SPELL_AFTER_ATTACK", 20, "spell.age", 0 ] ],
|
||||
"abilities":
|
||||
{
|
||||
"dragon" :
|
||||
{
|
||||
"type" : "DRAGON_NATURE"
|
||||
},
|
||||
"age" :
|
||||
{
|
||||
"type" : "SPELL_AFTER_ATTACK",
|
||||
"subtype" : "spell.age",
|
||||
"val" : 20
|
||||
}
|
||||
},
|
||||
"graphics" :
|
||||
{
|
||||
"animation": "CHDRGN.DEF"
|
||||
|
@ -5,8 +5,19 @@
|
||||
"id": 116,
|
||||
"level": 4,
|
||||
"faction": "neutral",
|
||||
"abilities": [ [ "SPELL_DAMAGE_REDUCTION", 85, -1, 0 ], //gold golems reduce dmg from spells
|
||||
[ "NON_LIVING", 0, 0, 0 ] ], //diamond golems are non-living
|
||||
"abilities":
|
||||
{
|
||||
"magicResistance" :
|
||||
{
|
||||
"type" : "SPELL_DAMAGE_REDUCTION",
|
||||
"subtype" : -1,
|
||||
"val" : 85
|
||||
},
|
||||
"nonliving" :
|
||||
{
|
||||
"type" : "NON_LIVING"
|
||||
}
|
||||
},
|
||||
"graphics" :
|
||||
{
|
||||
"animation": "CGGOLE.DEF"
|
||||
@ -25,8 +36,19 @@
|
||||
"id": 117,
|
||||
"level": 5,
|
||||
"faction": "neutral",
|
||||
"abilities": [ [ "SPELL_DAMAGE_REDUCTION", 95, -1, 0 ], //diamond golems reduce dmg from spells
|
||||
[ "NON_LIVING", 0, 0, 0 ] ],
|
||||
"abilities":
|
||||
{
|
||||
"magicResistance" :
|
||||
{
|
||||
"type" : "SPELL_DAMAGE_REDUCTION",
|
||||
"subtype" : -1,
|
||||
"val" : 95
|
||||
},
|
||||
"nonliving" :
|
||||
{
|
||||
"type" : "NON_LIVING"
|
||||
}
|
||||
},
|
||||
"graphics" :
|
||||
{
|
||||
"animation": "CDGOLE.DEF"
|
||||
@ -46,11 +68,30 @@
|
||||
"id": 132,
|
||||
"level": 10,
|
||||
"faction": "neutral",
|
||||
"abilities": [ [ "DRAGON_NATURE", 0, 0, 0 ],
|
||||
[ "TWO_HEX_ATTACK_BREATH", 0, 0, 0 ], //azure dragon's breath
|
||||
[ "FEARLESS", 0, 0, 0 ], //azure dragon is immune to fear
|
||||
[ "LEVEL_SPELL_IMMUNITY", 3, 0, 0 ], //immunity spell levels 1-3
|
||||
[ "FEAR", 0, 0, 0]], //azure dragon is a dragon
|
||||
"abilities":
|
||||
{
|
||||
"dragon" :
|
||||
{
|
||||
"type" : "DRAGON_NATURE"
|
||||
},
|
||||
"fireBreath" :
|
||||
{
|
||||
"type" : "TWO_HEX_ATTACK_BREATH"
|
||||
},
|
||||
"spellImmunity" :
|
||||
{
|
||||
"type" : "LEVEL_SPELL_IMMUNITY",
|
||||
"val" : 3
|
||||
},
|
||||
"fearless" :
|
||||
{
|
||||
"type" : "FEARLESS"
|
||||
},
|
||||
"fear" :
|
||||
{
|
||||
"type" : "FEAR"
|
||||
}
|
||||
},
|
||||
"graphics" :
|
||||
{
|
||||
"animation": "CADRGN.DEF"
|
||||
@ -70,8 +111,14 @@
|
||||
"id": 133,
|
||||
"level": 10,
|
||||
"faction": "neutral",
|
||||
"abilities": [ [ "DRAGON_NATURE", 0, 0, 0 ] ], //crystal dragon is a dragon
|
||||
"ability_remove": [ "FLYING" ], //Crystal Dragons do not fly
|
||||
"abilities":
|
||||
{
|
||||
"dragon" :
|
||||
{
|
||||
"type" : "DRAGON_NATURE"
|
||||
},
|
||||
"FLYING" : null
|
||||
},
|
||||
"graphics" :
|
||||
{
|
||||
"animation": "CCDRGN.DEF"
|
||||
@ -91,18 +138,84 @@
|
||||
"id": 134,
|
||||
"level": 8,
|
||||
"faction": "neutral",
|
||||
"abilities": [ [ "DRAGON_NATURE", 0, 0, 0 ], //faerie dragon is a dragon
|
||||
[ "MAGIC_MIRROR", 30, 0, 0 ],
|
||||
[ "CASTS", 5, 0, 0 ],
|
||||
[ "CREATURE_SPELL_POWER", 500, 0, 0], //5 spell power per dragon
|
||||
[ "SPELLCASTER", 2, "spell.magicArrow", 10 ],
|
||||
[ "SPELLCASTER", 2, "spell.iceBolt", 22 ],
|
||||
[ "SPELLCASTER", 2, "spell.lightningBolt", 22 ],
|
||||
[ "SPELLCASTER", 2, "spell.chainLightning", 5 ],
|
||||
[ "SPELLCASTER", 2, "spell.frostRing", 10 ],
|
||||
[ "SPELLCASTER", 2, "spell.fireball", 21 ],
|
||||
[ "SPELLCASTER", 2, "spell.inferno", 5 ],
|
||||
[ "SPELLCASTER", 2, "spell.meteorShower", 5 ]],
|
||||
"abilities":
|
||||
{
|
||||
"dragon" :
|
||||
{
|
||||
"type" : "DRAGON_NATURE",
|
||||
},
|
||||
"mirror" :
|
||||
{
|
||||
"type" : "MAGIC_MIRROR",
|
||||
"val" : 30
|
||||
},
|
||||
"casts" :
|
||||
{
|
||||
"type" : "CASTS",
|
||||
"val" : 5
|
||||
},
|
||||
"spellpower" :
|
||||
{
|
||||
"type" : "CREATURE_SPELL_POWER",
|
||||
"val" : 500
|
||||
},
|
||||
"castsMagicArrow" :
|
||||
{
|
||||
"type" : "SPELLCASTER",
|
||||
"subtype" : "spell.magicArrow",
|
||||
"addInfo" : 22,
|
||||
"val" : 2
|
||||
},
|
||||
"castsIceBolt" :
|
||||
{
|
||||
"type" : "SPELLCASTER",
|
||||
"subtype" : "spell.iceBolt",
|
||||
"addInfo" : 22,
|
||||
"val" : 2
|
||||
},
|
||||
"castsLightningBolt" :
|
||||
{
|
||||
"type" : "SPELLCASTER",
|
||||
"subtype" : "spell.lightningBolt",
|
||||
"addInfo" : 22,
|
||||
"val" : 2
|
||||
},
|
||||
"castsChainLightning" :
|
||||
{
|
||||
"type" : "SPELLCASTER",
|
||||
"subtype" : "spell.chainLightning",
|
||||
"addInfo" : 5,
|
||||
"val" : 2
|
||||
},
|
||||
"castsFrostRing" :
|
||||
{
|
||||
"type" : "SPELLCASTER",
|
||||
"subtype" : "spell.frostRing",
|
||||
"addInfo" : 10,
|
||||
"val" : 2
|
||||
},
|
||||
"castsFireball" :
|
||||
{
|
||||
"type" : "SPELLCASTER",
|
||||
"subtype" : "spell.fireball",
|
||||
"addInfo" : 21,
|
||||
"val" : 2
|
||||
},
|
||||
"castsInferno" :
|
||||
{
|
||||
"type" : "SPELLCASTER",
|
||||
"subtype" : "spell.inferno",
|
||||
"addInfo" : 5,
|
||||
"val" : 2
|
||||
},
|
||||
"castsMeteorShower" :
|
||||
{
|
||||
"type" : "SPELLCASTER",
|
||||
"subtype" : "spell.meteorShower",
|
||||
"addInfo" : 5,
|
||||
"val" : 2
|
||||
}
|
||||
},
|
||||
"graphics" :
|
||||
{
|
||||
"animation": "CFDRGN.DEF"
|
||||
@ -123,9 +236,25 @@
|
||||
"id": 135,
|
||||
"level": 10,
|
||||
"faction": "neutral",
|
||||
"abilities": [ [ "SPELL_AFTER_ATTACK", 100, 80, 0 ], //always reduce defense
|
||||
[ "ACID_BREATH", 25, 0, 20 ], //20% chance to do 25 damage
|
||||
[ "DRAGON_NATURE", 0, 0, 0 ] ], //rust dragon is a dragon
|
||||
"abilities":
|
||||
{
|
||||
"dragon" :
|
||||
{
|
||||
"type" : "DRAGON_NATURE"
|
||||
},
|
||||
"acidBreath" :
|
||||
{
|
||||
"type" : "ACID_BREATH",
|
||||
"val" : 25,
|
||||
"addInfo" : 20
|
||||
},
|
||||
"reduceDefence" :
|
||||
{
|
||||
"type" : "SPELL_AFTER_ATTACK",
|
||||
"subtype" : "spell.acidBreath",
|
||||
"val" : 100
|
||||
}
|
||||
},
|
||||
"graphics" :
|
||||
{
|
||||
"animation": "CRSDGN.DEF"
|
||||
@ -146,21 +275,67 @@
|
||||
"level": 6,
|
||||
"extraNames": [ "enchanters" ],
|
||||
"faction": "neutral",
|
||||
"abilities": [ [ "NO_WALL_PENALTY", 0, 0, 0 ],
|
||||
[ "ENCHANTER", 3, "spell.airShield", 3],
|
||||
[ "ENCHANTER", 3, "spell.bless", 3],
|
||||
[ "ENCHANTER", 3, "spell.weakness", 3],
|
||||
[ "ENCHANTER", 3, "spell.stoneSkin", 3],
|
||||
[ "ENCHANTER", 3, "spell.slow", 3],
|
||||
[ "ENCHANTER", 3, "spell.haste", 3],
|
||||
[ "CASTS", 5, 0, 0]],
|
||||
"abilities":
|
||||
{
|
||||
"noPenalty" :
|
||||
{
|
||||
"type" : "NO_WALL_PENALTY"
|
||||
},
|
||||
"casts" :
|
||||
{
|
||||
"type" : "CASTS",
|
||||
"val" : 5
|
||||
},
|
||||
"castsAirShield" :
|
||||
{
|
||||
"type" : "ENCHANTER",
|
||||
"subtype" : "spell.airShield",
|
||||
"val" : 3,
|
||||
"addInfo" : 3
|
||||
},
|
||||
"castsBless" :
|
||||
{
|
||||
"type" : "ENCHANTER",
|
||||
"subtype" : "spell.bless",
|
||||
"val" : 3,
|
||||
"addInfo" : 3
|
||||
},
|
||||
"castsWeakness" :
|
||||
{
|
||||
"type" : "ENCHANTER",
|
||||
"subtype" : "spell.weakness",
|
||||
"val" : 3,
|
||||
"addInfo" : 3
|
||||
},
|
||||
"castsStoneSkin" :
|
||||
{
|
||||
"type" : "ENCHANTER",
|
||||
"subtype" : "spell.stoneSkin",
|
||||
"val" : 3,
|
||||
"addInfo" : 3
|
||||
},
|
||||
"castsSlow" :
|
||||
{
|
||||
"type" : "ENCHANTER",
|
||||
"subtype" : "spell.slow",
|
||||
"val" : 3,
|
||||
"addInfo" : 3
|
||||
},
|
||||
"castsHaste" :
|
||||
{
|
||||
"type" : "ENCHANTER",
|
||||
"subtype" : "spell.haste",
|
||||
"val" : 3,
|
||||
"addInfo" : 3
|
||||
}
|
||||
|
||||
},
|
||||
"graphics" :
|
||||
{
|
||||
"animation": "CENCH.DEF",
|
||||
"animation": "CGTITA.DEF",
|
||||
"missile" :
|
||||
{
|
||||
"projectile": "CPRZEAX.DEF",
|
||||
"spinning": false
|
||||
"projectile": "CPRZEAX.DEF"
|
||||
}
|
||||
},
|
||||
"sound" :
|
||||
@ -180,15 +355,23 @@
|
||||
"level": 4,
|
||||
"extraNames": [ "sharpshooters" ],
|
||||
"faction": "neutral",
|
||||
"abilities": [ [ "NO_WALL_PENALTY", 0, 0, 0 ],
|
||||
[ "NO_DISTANCE_PENALTY", 0, 0, 0 ] ],
|
||||
"abilities":
|
||||
{
|
||||
"noPenalty" :
|
||||
{
|
||||
"type" : "NO_WALL_PENALTY"
|
||||
},
|
||||
"noDistancePenalty" :
|
||||
{
|
||||
"type" : "NO_DISTANCE_PENALTY"
|
||||
}
|
||||
},
|
||||
"graphics" :
|
||||
{
|
||||
"animation": "CSHARP.DEF",
|
||||
"missile" :
|
||||
{
|
||||
"projectile": "PELFX.DEF",
|
||||
"spinning": false
|
||||
"projectile": "PELFX.DEF"
|
||||
}
|
||||
},
|
||||
"sound" :
|
||||
@ -211,8 +394,7 @@
|
||||
"animation": "CHALF.DEF",
|
||||
"missile" :
|
||||
{
|
||||
"projectile": "PHALF.DEF",
|
||||
"spinning": true
|
||||
"projectile": "PHALF.DEF"
|
||||
}
|
||||
},
|
||||
"sound" :
|
||||
@ -248,7 +430,7 @@
|
||||
"id": 140,
|
||||
"level": 2,
|
||||
"faction": "neutral",
|
||||
"abilities": [ [ "DOUBLE_WIDE", 0, 0, 0 ] ], //boar should be treated as double-wide
|
||||
"doubleWide" : true,
|
||||
"graphics" :
|
||||
{
|
||||
"animation": "CBOAR.DEF"
|
||||
@ -267,7 +449,13 @@
|
||||
"id": 141,
|
||||
"level": 3,
|
||||
"faction": "neutral",
|
||||
"abilities": [ [ "UNDEAD", 0, 0, 0 ] ],
|
||||
"abilities":
|
||||
{
|
||||
"undead" :
|
||||
{
|
||||
"type" : "UNDEAD"
|
||||
}
|
||||
},
|
||||
"graphics" :
|
||||
{
|
||||
"animation": "CMUMMY.DEF"
|
||||
@ -286,7 +474,7 @@
|
||||
"id": 142,
|
||||
"level": 3,
|
||||
"faction": "neutral",
|
||||
"abilities": [ [ "DOUBLE_WIDE", 0, 0, 0 ] ], //nomads should be treated as double-wide
|
||||
"doubleWide" : true,
|
||||
"graphics" :
|
||||
{
|
||||
"animation": "CNOMAD.DEF"
|
||||
@ -323,7 +511,13 @@
|
||||
"id": 144,
|
||||
"level": 5,
|
||||
"faction": "neutral",
|
||||
"abilities": [ [ "FULL_HP_REGENERATION", 0, 0, 0 ] ],
|
||||
"abilities":
|
||||
{
|
||||
"regenerates" :
|
||||
{
|
||||
"type" : "FULL_HP_REGENERATION"
|
||||
}
|
||||
},
|
||||
"graphics" :
|
||||
{
|
||||
"animation": "CTROLL.DEF"
|
||||
|
@ -8,6 +8,7 @@
|
||||
"hasDoubleWeek": true,
|
||||
"graphics" :
|
||||
{
|
||||
"missile" : null,
|
||||
"animation": "CCENTR.DEF"
|
||||
},
|
||||
"sound" :
|
||||
@ -27,6 +28,7 @@
|
||||
"faction": "rampart",
|
||||
"graphics" :
|
||||
{
|
||||
"missile" : null,
|
||||
"animation": "CECENT.DEF"
|
||||
},
|
||||
"sound" :
|
||||
@ -43,7 +45,14 @@
|
||||
"id": 16,
|
||||
"level": 2,
|
||||
"faction": "rampart",
|
||||
"abilities": [ [ "MAGIC_RESISTANCE", 20, 0, 0 ] ], //dwarf's magic resistance 20%
|
||||
"abilities":
|
||||
{
|
||||
"magicResistance" :
|
||||
{
|
||||
"type" : "MAGIC_RESISTANCE",
|
||||
"val" : 20
|
||||
}
|
||||
},
|
||||
"upgrades": ["battleDwarf"],
|
||||
"graphics" :
|
||||
{
|
||||
@ -63,7 +72,14 @@
|
||||
"id": 17,
|
||||
"level": 2,
|
||||
"faction": "rampart",
|
||||
"abilities": [ [ "MAGIC_RESISTANCE", 40, 0, 0 ] ], //battle dwarf's magic resistance 40%
|
||||
"abilities":
|
||||
{
|
||||
"magicResistance" :
|
||||
{
|
||||
"type" : "MAGIC_RESISTANCE",
|
||||
"val" : 40
|
||||
}
|
||||
},
|
||||
"graphics" :
|
||||
{
|
||||
"animation": "CBDWAR.DEF"
|
||||
@ -88,8 +104,7 @@
|
||||
"animation": "CELF.DEF",
|
||||
"missile" :
|
||||
{
|
||||
"projectile": "PELFX.DEF",
|
||||
"spinning": false
|
||||
"projectile": "PELFX.DEF"
|
||||
}
|
||||
},
|
||||
"sound" :
|
||||
@ -107,20 +122,21 @@
|
||||
"id": 19,
|
||||
"level": 3,
|
||||
"faction": "rampart",
|
||||
"abilities": [
|
||||
{
|
||||
"type": "ADDITIONAL_ATTACK",
|
||||
"val" : 1,
|
||||
"effectRange": "ONLY_DISTANCE_FIGHT"
|
||||
}
|
||||
],
|
||||
"abilities":
|
||||
{
|
||||
"doubleShot" :
|
||||
{
|
||||
"type": "ADDITIONAL_ATTACK",
|
||||
"val" : 1,
|
||||
"effectRange": "ONLY_DISTANCE_FIGHT"
|
||||
}
|
||||
},
|
||||
"graphics" :
|
||||
{
|
||||
"animation": "CGRELF.DEF",
|
||||
"missile" :
|
||||
{
|
||||
"projectile": "PELFX.DEF",
|
||||
"spinning": false
|
||||
"projectile": "PELFX.DEF"
|
||||
}
|
||||
},
|
||||
"sound" :
|
||||
@ -138,7 +154,14 @@
|
||||
"id": 20,
|
||||
"level": 4,
|
||||
"faction": "rampart",
|
||||
"abilities": [ [ "CHANGES_SPELL_COST_FOR_ENEMY", 2, 0, 0 ] ], //pegasus makes spell cost higher for enemy mage
|
||||
"abilities":
|
||||
{
|
||||
"increaseManaCost" :
|
||||
{
|
||||
"type" : "CHANGES_SPELL_COST_FOR_ENEMY",
|
||||
"val" : 2
|
||||
}
|
||||
},
|
||||
"upgrades": ["silverPegasus"],
|
||||
"hasDoubleWeek": true,
|
||||
"graphics" :
|
||||
@ -159,7 +182,14 @@
|
||||
"id": 21,
|
||||
"level": 4,
|
||||
"faction": "rampart",
|
||||
"abilities": [ [ "CHANGES_SPELL_COST_FOR_ENEMY", 2, 0, 0 ] ], //silver pegasus makes spell cost higher for enemy mage
|
||||
"abilities":
|
||||
{
|
||||
"increaseManaCost" :
|
||||
{
|
||||
"type" : "CHANGES_SPELL_COST_FOR_ENEMY",
|
||||
"val" : 2
|
||||
}
|
||||
},
|
||||
"graphics" :
|
||||
{
|
||||
"animation": "CAPEGS.DEF"
|
||||
@ -178,7 +208,15 @@
|
||||
"id": 22,
|
||||
"level": 5,
|
||||
"faction": "rampart",
|
||||
"abilities": [ [ "SPELL_AFTER_ATTACK", 100, "spell.bind", 0 ] ], //dendroids cast bind
|
||||
"abilities":
|
||||
{
|
||||
"binds" :
|
||||
{
|
||||
"type" : "SPELL_AFTER_ATTACK",
|
||||
"subtype" : "spell.bind",
|
||||
"val" : 100
|
||||
}
|
||||
},
|
||||
"upgrades": ["dendroidSoldier"],
|
||||
"graphics" :
|
||||
{
|
||||
@ -198,7 +236,15 @@
|
||||
"id": 23,
|
||||
"level": 5,
|
||||
"faction": "rampart",
|
||||
"abilities": [ [ "SPELL_AFTER_ATTACK", 100, "spell.bind", 0 ] ], //dendroid guards cast bind
|
||||
"abilities":
|
||||
{
|
||||
"binds" :
|
||||
{
|
||||
"type" : "SPELL_AFTER_ATTACK",
|
||||
"subtype" : "spell.bind",
|
||||
"val" : 100
|
||||
}
|
||||
},
|
||||
"graphics" :
|
||||
{
|
||||
"animation": "CBTREE.DEF"
|
||||
@ -217,8 +263,20 @@
|
||||
"id": 24,
|
||||
"level": 6,
|
||||
"faction": "rampart",
|
||||
"abilities": [ [ "SPELL_RESISTANCE_AURA", 0, 55, 0 ], //unicorn
|
||||
[ "SPELL_AFTER_ATTACK", 20, "spell.blind", 0 ] ], //unicorns cast blind with 20% probability
|
||||
"abilities":
|
||||
{
|
||||
"spellResistAura" :
|
||||
{
|
||||
"type" : "SPELL_RESISTANCE_AURA",
|
||||
"val" : 20
|
||||
},
|
||||
"blinds" :
|
||||
{
|
||||
"type" : "SPELL_AFTER_ATTACK",
|
||||
"subtype" : "spell.blind",
|
||||
"val" : 20
|
||||
}
|
||||
},
|
||||
"upgrades": ["warUnicorn"],
|
||||
"graphics" :
|
||||
{
|
||||
@ -238,8 +296,20 @@
|
||||
"id": 25,
|
||||
"level": 6,
|
||||
"faction": "rampart",
|
||||
"abilities": [ [ "SPELL_RESISTANCE_AURA", 20, 55, 0 ], //war unicorn
|
||||
[ "SPELL_AFTER_ATTACK", 20, "spell.blind", 0 ] ], //war unicorns cast blind with 20% probability
|
||||
"abilities":
|
||||
{
|
||||
"spellResistAura" :
|
||||
{
|
||||
"type" : "SPELL_RESISTANCE_AURA",
|
||||
"val" : 20
|
||||
},
|
||||
"blinds" :
|
||||
{
|
||||
"type" : "SPELL_AFTER_ATTACK",
|
||||
"subtype" : "spell.blind",
|
||||
"val" : 20
|
||||
}
|
||||
},
|
||||
"graphics" :
|
||||
{
|
||||
"animation": "CWUNIC.DEF"
|
||||
@ -259,9 +329,22 @@
|
||||
"id": 26,
|
||||
"level": 7,
|
||||
"faction": "rampart",
|
||||
"abilities": [ [ "DRAGON_NATURE", 0, 0, 0 ], //green dragon is a dragon
|
||||
[ "TWO_HEX_ATTACK_BREATH", 0, 0, 0 ], //green dragon's breath
|
||||
[ "LEVEL_SPELL_IMMUNITY", 3, 0, 0 ] ], //green dragon's spell immunity
|
||||
"abilities":
|
||||
{
|
||||
"dragon" :
|
||||
{
|
||||
"type" : "DRAGON_NATURE"
|
||||
},
|
||||
"fireBreath" :
|
||||
{
|
||||
"type" : "TWO_HEX_ATTACK_BREATH"
|
||||
},
|
||||
"spellImmunity" :
|
||||
{
|
||||
"type" : "LEVEL_SPELL_IMMUNITY",
|
||||
"val" : 3
|
||||
}
|
||||
},
|
||||
"upgrades": ["goldDragon"],
|
||||
"graphics" :
|
||||
{
|
||||
@ -281,9 +364,22 @@
|
||||
"id": 27,
|
||||
"level": 7,
|
||||
"faction": "rampart",
|
||||
"abilities": [ [ "DRAGON_NATURE", 0, 0, 0 ], //gold dragon is a dragon
|
||||
[ "TWO_HEX_ATTACK_BREATH", 0, 0, 0 ], //gold dragon's breath
|
||||
[ "LEVEL_SPELL_IMMUNITY", 4, 0, 0 ] ], //gold dragon's spell immunity
|
||||
"abilities":
|
||||
{
|
||||
"dragon" :
|
||||
{
|
||||
"type" : "DRAGON_NATURE"
|
||||
},
|
||||
"fireBreath" :
|
||||
{
|
||||
"type" : "TWO_HEX_ATTACK_BREATH"
|
||||
},
|
||||
"spellImmunity" :
|
||||
{
|
||||
"type" : "LEVEL_SPELL_IMMUNITY",
|
||||
"val" : 4
|
||||
}
|
||||
},
|
||||
"graphics" :
|
||||
{
|
||||
"animation": "CDDRAG.DEF"
|
||||
|
@ -4,25 +4,29 @@
|
||||
"unused122" :
|
||||
{
|
||||
"faction": "neutral",
|
||||
"special" : true,
|
||||
"disabled" : true,
|
||||
"graphics" : null,
|
||||
"id" : 122
|
||||
},
|
||||
"unused124" :
|
||||
{
|
||||
"faction": "neutral",
|
||||
"special" : true,
|
||||
"disabled" : true,
|
||||
"graphics" : null,
|
||||
"id" : 124
|
||||
},
|
||||
"unused126" :
|
||||
{
|
||||
"faction": "neutral",
|
||||
"special" : true,
|
||||
"disabled" : true,
|
||||
"graphics" : null,
|
||||
"id" : 126
|
||||
},
|
||||
"unused128" :
|
||||
{
|
||||
"faction": "neutral",
|
||||
"special" : true,
|
||||
"disabled" : true,
|
||||
"graphics" : null,
|
||||
"id" : 128
|
||||
},
|
||||
|
||||
@ -37,8 +41,7 @@
|
||||
"animation": "SMCATA.DEF",
|
||||
"missile" :
|
||||
{
|
||||
"projectile": "SMCATX.DEF",
|
||||
"spinning": true
|
||||
"projectile": "SMCATX.DEF"
|
||||
}
|
||||
},
|
||||
"sound" :
|
||||
@ -59,8 +62,7 @@
|
||||
"animation": "SMBAL.DEF",
|
||||
"missile" :
|
||||
{
|
||||
"projectile": "SMBALX.DEF",
|
||||
"spinning": false
|
||||
"projectile": "SMBALX.DEF"
|
||||
}
|
||||
},
|
||||
"sound" :
|
||||
@ -76,7 +78,7 @@
|
||||
"id": 147,
|
||||
"level": 0,
|
||||
"faction": "neutral",
|
||||
"abilities": [ [ "HEALER", 0, 0, 0 ] ],
|
||||
"abilities": { "heals" : { "type" : "HEALER" } },
|
||||
"graphics" :
|
||||
{
|
||||
"animation": "SMTENT.DEF"
|
||||
@ -93,7 +95,7 @@
|
||||
"id": 148,
|
||||
"level": 0,
|
||||
"faction": "neutral",
|
||||
"abilities": [ [ "NOT_ACTIVE", 0, 0, 0 ] ],
|
||||
"abilities": { "inactive" : { "type" : "NOT_ACTIVE" } },
|
||||
"graphics" :
|
||||
{
|
||||
"animation": "SMCART.DEF"
|
||||
@ -110,13 +112,11 @@
|
||||
"id": 149,
|
||||
"level": 0,
|
||||
"faction": "neutral",
|
||||
"abilities": [ [ "SHOOTER", 0, 0, 0 ] ],
|
||||
"abilities": { "shooter" : { "type" : "SHOOTER" } },
|
||||
"graphics" :
|
||||
{
|
||||
"missile" :
|
||||
{
|
||||
"projectile": "SMBALX.DEF", //workaround for crash
|
||||
}
|
||||
}
|
||||
"animation" : "This should never be used"
|
||||
},
|
||||
"sound": {}
|
||||
}
|
||||
}
|
||||
|
@ -63,7 +63,14 @@
|
||||
"id": 87,
|
||||
"level": 2,
|
||||
"faction": "stronghold",
|
||||
"abilities": [ [ "ADDITIONAL_ATTACK", 1, 0, 0 ] ],
|
||||
"abilities":
|
||||
{
|
||||
"extraAttack" :
|
||||
{
|
||||
"type" : "ADDITIONAL_ATTACK",
|
||||
"val" : 1
|
||||
}
|
||||
},
|
||||
"graphics" :
|
||||
{
|
||||
"animation": "CUWLFR.DEF"
|
||||
@ -88,8 +95,7 @@
|
||||
"animation": "CORC.DEF",
|
||||
"missile" :
|
||||
{
|
||||
"projectile": "PORCHX.DEF",
|
||||
"spinning": true
|
||||
"projectile": "PORCHX.DEF"
|
||||
}
|
||||
},
|
||||
"sound" :
|
||||
@ -112,8 +118,7 @@
|
||||
"animation": "CORCCH.DEF",
|
||||
"missile" :
|
||||
{
|
||||
"projectile": "PORCHX.DEF",
|
||||
"spinning": true
|
||||
"projectile": "PORCHX.DEF"
|
||||
}
|
||||
},
|
||||
"sound" :
|
||||
@ -150,9 +155,25 @@
|
||||
"id": 91,
|
||||
"level": 4,
|
||||
"faction": "stronghold",
|
||||
"abilities": [ [ "SPELLCASTER", 2, "spell.bloodlust", 0 ],
|
||||
[ "CASTS", 3, 0, 0],
|
||||
[ "CREATURE_ENCHANT_POWER", 3, 0, 0]],
|
||||
"abilities":
|
||||
{
|
||||
"castsBloodlust" :
|
||||
{
|
||||
"type" : "SPELLCASTER",
|
||||
"subtype" : "spell.bloodlust",
|
||||
"val" : 2
|
||||
},
|
||||
"castsCount" :
|
||||
{
|
||||
"type" : "CASTS",
|
||||
"val" : 3
|
||||
},
|
||||
"castLength" :
|
||||
{
|
||||
"type" : "CREATURE_ENCHANT_POWER",
|
||||
"val" : 3
|
||||
}
|
||||
},
|
||||
"graphics" :
|
||||
{
|
||||
"animation": "COGMAG.DEF"
|
||||
@ -191,8 +212,21 @@
|
||||
"id": 93,
|
||||
"level": 5,
|
||||
"faction": "stronghold",
|
||||
"abilities": [ [ "SPECIFIC_SPELL_POWER", 10, "spell.thunderbolt", 0 ], //10 damage per unit
|
||||
[ "SPELL_AFTER_ATTACK", 20, "spell.thunderbolt", 0 ] ],
|
||||
"abilities":
|
||||
{
|
||||
"thunderStrength" :
|
||||
{
|
||||
"type" : "SPECIFIC_SPELL_POWER",
|
||||
"subtype" : "spell.thunderbolt",
|
||||
"val" : 10
|
||||
},
|
||||
"thunderOnAttack" :
|
||||
{
|
||||
"type" : "SPELL_AFTER_ATTACK",
|
||||
"subtype" : "spell.thunderbolt",
|
||||
"val" : 20
|
||||
}
|
||||
},
|
||||
"graphics" :
|
||||
{
|
||||
"animation": "CTBIRD.DEF"
|
||||
@ -217,8 +251,7 @@
|
||||
"animation": "CCYCLR.DEF",
|
||||
"missile" :
|
||||
{
|
||||
"projectile": "PCYCLBX.DEF",
|
||||
"spinning": true
|
||||
"projectile": "PCYCLBX.DEF"
|
||||
}
|
||||
},
|
||||
"sound" :
|
||||
@ -241,8 +274,7 @@
|
||||
"animation": "CCYCLLOR.DEF",
|
||||
"missile" :
|
||||
{
|
||||
"projectile": "PCYCLBX.DEF",
|
||||
"spinning": true
|
||||
"projectile": "PCYCLBX.DEF"
|
||||
}
|
||||
},
|
||||
"sound" :
|
||||
@ -260,7 +292,14 @@
|
||||
"id": 96,
|
||||
"level": 7,
|
||||
"faction": "stronghold",
|
||||
"abilities": [ [ "ENEMY_DEFENCE_REDUCTION", 40, 0, 0 ] ],
|
||||
"abilities":
|
||||
{
|
||||
"reduceDefence" :
|
||||
{
|
||||
"type" : "ENEMY_DEFENCE_REDUCTION",
|
||||
"val" : 40
|
||||
}
|
||||
},
|
||||
"upgrades": ["ancientBehemoth"],
|
||||
"graphics" :
|
||||
{
|
||||
@ -280,7 +319,14 @@
|
||||
"id": 97,
|
||||
"level": 7,
|
||||
"faction": "stronghold",
|
||||
"abilities": [ [ "ENEMY_DEFENCE_REDUCTION", 80, 0, 0 ] ],
|
||||
"abilities":
|
||||
{
|
||||
"reduceDefence" :
|
||||
{
|
||||
"type" : "ENEMY_DEFENCE_REDUCTION",
|
||||
"val" : 80
|
||||
}
|
||||
},
|
||||
"graphics" :
|
||||
{
|
||||
"animation": "CABEHE.DEF"
|
||||
|
@ -31,8 +31,7 @@
|
||||
"animation": "CGREMM.DEF",
|
||||
"missile" :
|
||||
{
|
||||
"projectile": "CPRGRE.DEF",
|
||||
"spinning": false
|
||||
"projectile": "CPRGRE.DEF"
|
||||
}
|
||||
},
|
||||
"sound" :
|
||||
@ -50,7 +49,13 @@
|
||||
"id": 30,
|
||||
"level": 2,
|
||||
"faction": "tower",
|
||||
"abilities": [ [ "NON_LIVING", 0, 0, 0 ] ], //stone gargoyles are non-living
|
||||
"abilities":
|
||||
{
|
||||
"nonliving" :
|
||||
{
|
||||
"type" : "NON_LIVING"
|
||||
}
|
||||
},
|
||||
"upgrades": ["obsidianGargoyle"],
|
||||
"graphics" :
|
||||
{
|
||||
@ -70,7 +75,13 @@
|
||||
"id": 31,
|
||||
"level": 2,
|
||||
"faction": "tower",
|
||||
"abilities": [ [ "NON_LIVING", 0, 0, 0 ] ], //obsidian gargoyles are non-living
|
||||
"abilities":
|
||||
{
|
||||
"nonliving" :
|
||||
{
|
||||
"type" : "NON_LIVING"
|
||||
}
|
||||
},
|
||||
"graphics" :
|
||||
{
|
||||
"animation": "COGARG.DEF"
|
||||
@ -89,8 +100,19 @@
|
||||
"id": 32,
|
||||
"level": 3,
|
||||
"faction": "tower",
|
||||
"abilities": [ [ "SPELL_DAMAGE_REDUCTION", 50, -1, 0 ], //stone golems reduce dmg from spells
|
||||
[ "NON_LIVING", 0, 0, 0 ] ], //stone golems are non-living
|
||||
"abilities":
|
||||
{
|
||||
"magicResistance" :
|
||||
{
|
||||
"type" : "SPELL_DAMAGE_REDUCTION",
|
||||
"subtype" : -1,
|
||||
"val" : 50
|
||||
},
|
||||
"nonliving" :
|
||||
{
|
||||
"type" : "NON_LIVING"
|
||||
}
|
||||
},
|
||||
"upgrades": ["stoneGolem"],
|
||||
"graphics" :
|
||||
{
|
||||
@ -110,8 +132,19 @@
|
||||
"id": 33,
|
||||
"level": 3,
|
||||
"faction": "tower",
|
||||
"abilities": [ [ "SPELL_DAMAGE_REDUCTION", 75, -1, 0 ], //iron golems reduce dmg from spells
|
||||
[ "NON_LIVING", 0, 0, 0 ] ], //iron golems are non-living
|
||||
"abilities" :
|
||||
{
|
||||
"magicResistance" :
|
||||
{
|
||||
"type" : "SPELL_DAMAGE_REDUCTION",
|
||||
"subtype" : -1,
|
||||
"val" : 75
|
||||
},
|
||||
"nonliving" :
|
||||
{
|
||||
"type" : "NON_LIVING"
|
||||
}
|
||||
},
|
||||
"graphics" :
|
||||
{
|
||||
"animation": "CIGOLE.DEF"
|
||||
@ -130,15 +163,21 @@
|
||||
"id": 34,
|
||||
"level": 4,
|
||||
"faction": "tower",
|
||||
"abilities": [ [ "CHANGES_SPELL_COST_FOR_ALLY", 2, 0, 0 ] ], //mages reduce spell cost
|
||||
"abilities":
|
||||
{
|
||||
"reduceSpellCost" :
|
||||
{
|
||||
"type" : "CHANGES_SPELL_COST_FOR_ALLY",
|
||||
"val" : 2
|
||||
}
|
||||
},
|
||||
"upgrades": ["archMage"],
|
||||
"graphics" :
|
||||
{
|
||||
"animation": "CMAGE.DEF",
|
||||
"missile" :
|
||||
{
|
||||
"projectile": "PMAGEX.DEF",
|
||||
"spinning": false
|
||||
"projectile": "PMAGEX.DEF"
|
||||
}
|
||||
},
|
||||
"sound" :
|
||||
@ -156,14 +195,20 @@
|
||||
"id": 35,
|
||||
"level": 4,
|
||||
"faction": "tower",
|
||||
"abilities": [ [ "CHANGES_SPELL_COST_FOR_ALLY", 2, 0, 0 ]], //archmages reduce spell cost
|
||||
"abilities":
|
||||
{
|
||||
"reduceSpellCost" :
|
||||
{
|
||||
"type" : "CHANGES_SPELL_COST_FOR_ALLY",
|
||||
"val" : 2
|
||||
}
|
||||
},
|
||||
"graphics" :
|
||||
{
|
||||
"animation": "CAMAGE.DEF",
|
||||
"missile" :
|
||||
{
|
||||
"projectile": "PMAGEX.DEF",
|
||||
"spinning": false
|
||||
"projectile": "PMAGEX.DEF"
|
||||
}
|
||||
},
|
||||
"sound" :
|
||||
@ -181,8 +226,21 @@
|
||||
"id": 36,
|
||||
"level": 5,
|
||||
"faction": "tower",
|
||||
"abilities": [ [ "HATE", 50, 53, 0 ], //master genies hate efreets
|
||||
[ "HATE", 50, 52, 0 ] ], //genies hate efreet sultans
|
||||
"abilities":
|
||||
{
|
||||
"hateAngels" :
|
||||
{
|
||||
"type" : "HATE",
|
||||
"subtype" : "creature.efreet",
|
||||
"val" : 50
|
||||
},
|
||||
"hateArchAngels" :
|
||||
{
|
||||
"type" : "HATE",
|
||||
"subtype" : "creature.efreetSultan",
|
||||
"val" : 50
|
||||
}
|
||||
},
|
||||
"upgrades": ["masterGenie"],
|
||||
"graphics" :
|
||||
{
|
||||
@ -202,11 +260,36 @@
|
||||
"id": 37,
|
||||
"level": 5,
|
||||
"faction": "tower",
|
||||
"abilities": [ [ "CREATURE_ENCHANT_POWER", 5, 0, 0 ], //spells last 5 turns
|
||||
[ "RANDOM_SPELLCASTER", 2, 0, 0 ], //master genies cast spells on advanced level
|
||||
[ "CASTS", 3, 0, 0],
|
||||
[ "HATE", 50, 53, 0 ],
|
||||
[ "HATE", 50, 52, 0 ] ], //master genies hate efreet sultans
|
||||
"abilities":
|
||||
{
|
||||
"hateAngels" :
|
||||
{
|
||||
"type" : "HATE",
|
||||
"subtype" : "creature.efreet",
|
||||
"val" : 50
|
||||
},
|
||||
"hateArchAngels" :
|
||||
{
|
||||
"type" : "HATE",
|
||||
"subtype" : "creature.efreetSultan",
|
||||
"val" : 50
|
||||
},
|
||||
"spellsLength" :
|
||||
{
|
||||
"type" : "CREATURE_ENCHANT_POWER",
|
||||
"val" : 5
|
||||
},
|
||||
"randomSpellcaster" :
|
||||
{
|
||||
"type" : "RANDOM_SPELLCASTER",
|
||||
"val" : 2
|
||||
},
|
||||
"casts" :
|
||||
{
|
||||
"type" : "CASTS",
|
||||
"val" : 3
|
||||
}
|
||||
},
|
||||
"graphics" :
|
||||
{
|
||||
"animation": "CSULTA.DEF"
|
||||
@ -226,7 +309,13 @@
|
||||
"id": 38,
|
||||
"level": 6,
|
||||
"faction": "tower",
|
||||
"abilities": [ [ "BLOCKS_RETALIATION", 0, 0, 0 ] ], //nagas block retaliation
|
||||
"abilities" :
|
||||
{
|
||||
"noRetaliation" :
|
||||
{
|
||||
"type" : "BLOCKS_RETALIATION"
|
||||
}
|
||||
},
|
||||
"upgrades": ["nagaQueen"],
|
||||
"graphics" :
|
||||
{
|
||||
@ -246,7 +335,13 @@
|
||||
"id": 39,
|
||||
"level": 6,
|
||||
"faction": "tower",
|
||||
"abilities": [ [ "BLOCKS_RETALIATION", 0, 0, 0 ] ], //naga queens block retaliation
|
||||
"abilities" :
|
||||
{
|
||||
"noRetaliation" :
|
||||
{
|
||||
"type" : "BLOCKS_RETALIATION"
|
||||
}
|
||||
},
|
||||
"graphics" :
|
||||
{
|
||||
"animation": "CNAGAG.DEF"
|
||||
@ -265,7 +360,13 @@
|
||||
"id": 40,
|
||||
"level": 7,
|
||||
"faction": "tower",
|
||||
"abilities": [ ["MIND_IMMUNITY", 0, 0, 0] ], //giants are immune to mind spells
|
||||
"abilities" :
|
||||
{
|
||||
"immuneToMind" :
|
||||
{
|
||||
"type" : "MIND_IMMUNITY"
|
||||
}
|
||||
},
|
||||
"upgrades": ["titan"],
|
||||
"graphics" :
|
||||
{
|
||||
@ -285,15 +386,25 @@
|
||||
"id": 41,
|
||||
"level": 7,
|
||||
"faction": "tower",
|
||||
"abilities": [ ["MIND_IMMUNITY", 0, 0, 0], //Titans are immune to mind spells
|
||||
[ "HATE", 50, "creature.blackDragon", 0 ] ], //titans hate black dragons
|
||||
"abilities" :
|
||||
{
|
||||
"immuneToMind" :
|
||||
{
|
||||
"type" : "MIND_IMMUNITY"
|
||||
},
|
||||
"hateArchAngels" :
|
||||
{
|
||||
"type" : "HATE",
|
||||
"subtype" : "creature.blackDragon",
|
||||
"val" : 50
|
||||
}
|
||||
},
|
||||
"graphics" :
|
||||
{
|
||||
"animation": "CGTITA.DEF",
|
||||
"missile" :
|
||||
{
|
||||
"projectile": "CPRGTIX.DEF",
|
||||
"spinning": false
|
||||
"projectile": "CPRGTIX.DEF"
|
||||
}
|
||||
},
|
||||
"sound" :
|
||||
|
@ -22,7 +22,13 @@
|
||||
"id": 151,
|
||||
"level": 8,
|
||||
"faction": "rampart",
|
||||
"abilities": [ [ "DRAGON_NATURE", 0, 0, 0 ] ], //diamond dragon is a dragon
|
||||
"abilities":
|
||||
{
|
||||
"dragon" :
|
||||
{
|
||||
"type" : "DRAGON_NATURE"
|
||||
}
|
||||
},
|
||||
"graphics" :
|
||||
{
|
||||
"animation": "ZM151Z.DEF"
|
||||
@ -46,8 +52,7 @@
|
||||
"animation": "ZM152Z.DEF",
|
||||
"missile" :
|
||||
{
|
||||
"projectile": "CPRGTIX.DEF",
|
||||
"spinning": false
|
||||
"projectile": "CPRGTIX.DEF"
|
||||
}
|
||||
},
|
||||
"sound" :
|
||||
@ -65,9 +70,17 @@
|
||||
"id": 153,
|
||||
"level": 8,
|
||||
"faction": "inferno",
|
||||
"abilities": [ [ "FLYING", 0, 1, 0 ] ],
|
||||
"abilities":
|
||||
{
|
||||
"teleport" :
|
||||
{
|
||||
"type" : "FLYING",
|
||||
"subtype" : 1
|
||||
}
|
||||
},
|
||||
"graphics" :
|
||||
{
|
||||
"missile" : null,
|
||||
"animation": "ZM153Z.DEF"
|
||||
},
|
||||
"sound" :
|
||||
@ -78,7 +91,7 @@
|
||||
"move": "ADVLMOVE.wav",
|
||||
"wince": "ADVLWNCE.wav",
|
||||
"startMoving": "ADVLEXT1.wav",
|
||||
"stopMoving": "ADVLEXT2.wav"
|
||||
"endMoving": "ADVLEXT2.wav"
|
||||
}
|
||||
},
|
||||
"bloodDragon" :
|
||||
@ -86,8 +99,18 @@
|
||||
"id": 154,
|
||||
"level": 8,
|
||||
"faction": "necropolis",
|
||||
"abilities": [ [ "LIFE_DRAIN", 40, 0, 0 ], //40%
|
||||
[ "DRAGON_NATURE", 0, 0, 0 ] ], //blood dragon is a dragon
|
||||
"abilities":
|
||||
{
|
||||
"drainsLife" :
|
||||
{
|
||||
"type" : "LIFE_DRAIN",
|
||||
"val" : 40
|
||||
},
|
||||
"dragon" :
|
||||
{
|
||||
"type" : "DRAGON_NATURE"
|
||||
}
|
||||
},
|
||||
"graphics" :
|
||||
{
|
||||
"animation": "ZM154Z.DEF"
|
||||
@ -106,7 +129,13 @@
|
||||
"id": 155,
|
||||
"level": 8,
|
||||
"faction": "dungeon",
|
||||
"abilities": [ [ "DRAGON_NATURE", 0, 0, 0 ] ], //darkness dragon is a dragon
|
||||
"abilities":
|
||||
{
|
||||
"dragon" :
|
||||
{
|
||||
"type" : "DRAGON_NATURE"
|
||||
}
|
||||
},
|
||||
"graphics" :
|
||||
{
|
||||
"animation": "ZM155Z.DEF"
|
||||
@ -143,7 +172,10 @@
|
||||
"id": 157,
|
||||
"level": 8,
|
||||
"faction": "fortress",
|
||||
"ability_remove": [ "SHOOTER" ], //Hell Hydra certainly does not shoot
|
||||
"abilities" :
|
||||
{
|
||||
"SHOOTER" : null
|
||||
},
|
||||
"graphics" :
|
||||
{
|
||||
"animation": "ZM157Z.DEF"
|
||||
@ -195,7 +227,7 @@
|
||||
},
|
||||
"godWar" :
|
||||
{
|
||||
"special" : true,
|
||||
"disabled" : true,
|
||||
"id": 160,
|
||||
"level": 0,
|
||||
"faction": "neutral",
|
||||
@ -206,7 +238,7 @@
|
||||
},
|
||||
"godPeace" :
|
||||
{
|
||||
"special" : true,
|
||||
"disabled" : true,
|
||||
"id": 161,
|
||||
"level": 0,
|
||||
"faction": "neutral",
|
||||
@ -217,7 +249,7 @@
|
||||
},
|
||||
"godMana" :
|
||||
{
|
||||
"special" : true,
|
||||
"disabled" : true,
|
||||
"id": 162,
|
||||
"level": 0,
|
||||
"faction": "neutral",
|
||||
@ -228,7 +260,7 @@
|
||||
},
|
||||
"godLore" :
|
||||
{
|
||||
"special" : true,
|
||||
"disabled" : true,
|
||||
"id": 163,
|
||||
"level": 0,
|
||||
"faction": "neutral",
|
||||
@ -314,7 +346,13 @@
|
||||
"id": 168,
|
||||
"level": 0,
|
||||
"faction": "neutral",
|
||||
"abilities": [ [ "FLYING", 0, 0, 0 ] ], //Gorynyches fly
|
||||
"abilities":
|
||||
{
|
||||
"canFly" :
|
||||
{
|
||||
"type" : "FLYING"
|
||||
}
|
||||
},
|
||||
"graphics" :
|
||||
{
|
||||
"animation": "ZM168DG.DEF"
|
||||
@ -338,8 +376,7 @@
|
||||
"animation": "ZM169ZL.DEF",
|
||||
"missile" :
|
||||
{
|
||||
"projectile": "CPRZEAX.DEF",
|
||||
"spinning": false
|
||||
"projectile": "CPRZEAX.DEF"
|
||||
}
|
||||
},
|
||||
"sound" :
|
||||
@ -362,8 +399,7 @@
|
||||
"animation": "ZM170SW.DEF",
|
||||
"missile" :
|
||||
{
|
||||
"projectile": "PLCBOWX.DEF",
|
||||
"spinning": false
|
||||
"projectile": "PLCBOWX.DEF"
|
||||
}
|
||||
},
|
||||
"sound" :
|
||||
@ -386,8 +422,7 @@
|
||||
"animation": "ZM171SR.DEF",
|
||||
"missile" :
|
||||
{
|
||||
"projectile": "PLCBOWX.DEF",
|
||||
"spinning": false
|
||||
"projectile": "PLCBOWX.DEF"
|
||||
}
|
||||
},
|
||||
"sound" :
|
||||
@ -425,12 +460,11 @@
|
||||
"faction": "neutral",
|
||||
"graphics" :
|
||||
{
|
||||
"animation": "ZM173M.DEF",
|
||||
"missile" :
|
||||
{
|
||||
"projectile": "CPRGRE.DEF",
|
||||
"spinning": true
|
||||
}
|
||||
"animation": "ZM173M.DEF"
|
||||
//"missile" :
|
||||
//{
|
||||
// "projectile": "CPRGRE.DEF"
|
||||
//}
|
||||
},
|
||||
"sound" :
|
||||
{
|
||||
@ -460,7 +494,7 @@
|
||||
"projectile": "PLCBOWX.DEF"
|
||||
}
|
||||
},
|
||||
"sounds" :
|
||||
"sound" :
|
||||
{
|
||||
"attack": "CRUSATTK.wav",
|
||||
"defend": "CRUSDFND.wav",
|
||||
@ -475,11 +509,35 @@
|
||||
"id": 175,
|
||||
"level": 0,
|
||||
"faction": "neutral",
|
||||
"abilities": [ [ "MAGIC_RESISTANCE", 5, 0, 0 ],
|
||||
[ "CASTS", 1, 0, 0 ] ,
|
||||
[ "CREATURE_ENCHANT_POWER", 1, 0, 0 ] ,
|
||||
[ "CREATURE_SPELL_POWER", 100, 0, 0 ] ,
|
||||
[ "SPELLCASTER", 3, "spell.shield", 0 ] ], //expert shield
|
||||
"abilities":
|
||||
{
|
||||
"magicResistance" :
|
||||
{
|
||||
"type" : "MAGIC_RESISTANCE",
|
||||
"val" : 5
|
||||
},
|
||||
"castsAmount" :
|
||||
{
|
||||
"type" : "CASTS",
|
||||
"val" : 1
|
||||
},
|
||||
"enchant" :
|
||||
{
|
||||
"type" : "CREATURE_ENCHANT_POWER",
|
||||
"val" : 1
|
||||
},
|
||||
"spellpower" :
|
||||
{
|
||||
"type" : "CREATURE_SPELL_POWER",
|
||||
"val" : 100
|
||||
},
|
||||
"canCast" :
|
||||
{
|
||||
"type" : "SPELLCASTER",
|
||||
"subtype" : "spell.shield",
|
||||
"val" : 3
|
||||
}
|
||||
},
|
||||
"graphics" :
|
||||
{
|
||||
"animation": "ZM175NPC.DEF",
|
||||
@ -488,7 +546,7 @@
|
||||
"projectile": "CPRZEAX.DEF"
|
||||
}
|
||||
},
|
||||
"sounds" :
|
||||
"sound" :
|
||||
{
|
||||
"attack": "MONKATTK.wav",
|
||||
"defend": "MONKDFND.wav",
|
||||
@ -504,11 +562,35 @@
|
||||
"id": 176,
|
||||
"level": 0,
|
||||
"faction": "neutral",
|
||||
"abilities": [ [ "MAGIC_RESISTANCE", 5, 0, 0 ],
|
||||
[ "CASTS", 1, 0, 0 ] ,
|
||||
[ "CREATURE_ENCHANT_POWER", 1, 0, 0 ] ,
|
||||
[ "CREATURE_SPELL_POWER", 100, 0, 0 ] ,
|
||||
[ "SPELLCASTER", 3, "spell.precision", 0 ] ], //expert precision
|
||||
"abilities":
|
||||
{
|
||||
"magicResistance" :
|
||||
{
|
||||
"type" : "MAGIC_RESISTANCE",
|
||||
"val" : 5
|
||||
},
|
||||
"castsAmount" :
|
||||
{
|
||||
"type" : "CASTS",
|
||||
"val" : 1
|
||||
},
|
||||
"enchant" :
|
||||
{
|
||||
"type" : "CREATURE_ENCHANT_POWER",
|
||||
"val" : 1
|
||||
},
|
||||
"spellpower" :
|
||||
{
|
||||
"type" : "CREATURE_SPELL_POWER",
|
||||
"val" : 100
|
||||
},
|
||||
"canCast" :
|
||||
{
|
||||
"type" : "SPELLCASTER",
|
||||
"subtype" : "spell.precision",
|
||||
"val" : 3
|
||||
}
|
||||
},
|
||||
"graphics" :
|
||||
{
|
||||
"animation": "ZM176NPC.DEF",
|
||||
@ -517,15 +599,14 @@
|
||||
"projectile": "PLCBOWX.DEF"
|
||||
}
|
||||
},
|
||||
"sounds" :
|
||||
"sound" :
|
||||
{
|
||||
"attack": "LICHATTK.wav",
|
||||
"defend": "LICHDFND.wav",
|
||||
"killed": "LICHKILL.wav",
|
||||
"move": "LICHMOVE.wav",
|
||||
"shoot": "LICHSHOT.wav",
|
||||
"wince": "LICHWNCE.wav",
|
||||
"ext1": "LICHATK2.wav"
|
||||
"wince": "LICHWNCE.wav"
|
||||
}
|
||||
},
|
||||
"succubus1" :
|
||||
@ -534,11 +615,35 @@
|
||||
"id": 177,
|
||||
"level": 0,
|
||||
"faction": "neutral",
|
||||
"abilities": [ [ "MAGIC_RESISTANCE", 5, 0, 0 ],
|
||||
[ "CASTS", 1, 0, 0 ] ,
|
||||
[ "CREATURE_ENCHANT_POWER", 1, 0, 0 ] ,
|
||||
[ "CREATURE_SPELL_POWER", 100, 0, 0 ] ,
|
||||
[ "SPELLCASTER", 3, "spell.fireShield", 0 ] ], //expert fire shield
|
||||
"abilities":
|
||||
{
|
||||
"magicResistance" :
|
||||
{
|
||||
"type" : "MAGIC_RESISTANCE",
|
||||
"val" : 5
|
||||
},
|
||||
"castsAmount" :
|
||||
{
|
||||
"type" : "CASTS",
|
||||
"val" : 1
|
||||
},
|
||||
"enchant" :
|
||||
{
|
||||
"type" : "CREATURE_ENCHANT_POWER",
|
||||
"val" : 1
|
||||
},
|
||||
"spellpower" :
|
||||
{
|
||||
"type" : "CREATURE_SPELL_POWER",
|
||||
"val" : 100
|
||||
},
|
||||
"canCast" :
|
||||
{
|
||||
"type" : "SPELLCASTER",
|
||||
"subtype" : "spell.fireShield",
|
||||
"val" : 3
|
||||
}
|
||||
},
|
||||
"graphics" :
|
||||
{
|
||||
"animation": "ZM177NPC.DEF",
|
||||
@ -547,7 +652,7 @@
|
||||
"projectile": "PLCBOWX.DEF"
|
||||
}
|
||||
},
|
||||
"sounds" :
|
||||
"sound" :
|
||||
{
|
||||
"attack": "SGRGATTK.wav",
|
||||
"defend": "SGRGDFND.wav",
|
||||
@ -562,11 +667,35 @@
|
||||
"id": 178,
|
||||
"level": 0,
|
||||
"faction": "neutral",
|
||||
"abilities": [ [ "MAGIC_RESISTANCE", 5, 0, 0 ],
|
||||
[ "CASTS", 1, 0, 0 ] ,
|
||||
[ "CREATURE_ENCHANT_POWER", 1, 0, 0 ] ,
|
||||
[ "CREATURE_SPELL_POWER", 100, 0, 0 ] ,
|
||||
[ "SPELLCASTER", 3, "spell.animateDead", 0 ] ], //expert animate dead
|
||||
"abilities":
|
||||
{
|
||||
"magicResistance" :
|
||||
{
|
||||
"type" : "MAGIC_RESISTANCE",
|
||||
"val" : 5
|
||||
},
|
||||
"castsAmount" :
|
||||
{
|
||||
"type" : "CASTS",
|
||||
"val" : 1
|
||||
},
|
||||
"enchant" :
|
||||
{
|
||||
"type" : "CREATURE_ENCHANT_POWER",
|
||||
"val" : 1
|
||||
},
|
||||
"spellpower" :
|
||||
{
|
||||
"type" : "CREATURE_SPELL_POWER",
|
||||
"val" : 100
|
||||
},
|
||||
"canCast" :
|
||||
{
|
||||
"type" : "SPELLCASTER",
|
||||
"subtype" : "spell.animateDead",
|
||||
"val" : 3
|
||||
}
|
||||
},
|
||||
"graphics" :
|
||||
{
|
||||
"animation": "ZM178NPC.DEF",
|
||||
@ -575,7 +704,7 @@
|
||||
"projectile": "PLCBOWX.DEF"
|
||||
}
|
||||
},
|
||||
"sounds" :
|
||||
"sound" :
|
||||
{
|
||||
"attack": "GNOLATTK.wav",
|
||||
"defend": "GNOLDFND.wav",
|
||||
@ -590,11 +719,35 @@
|
||||
"id": 179,
|
||||
"level": 0,
|
||||
"faction": "neutral",
|
||||
"abilities": [ [ "MAGIC_RESISTANCE", 5, 0, 0 ],
|
||||
[ "CASTS", 1, 0, 0 ] ,
|
||||
[ "CREATURE_ENCHANT_POWER", 1, 0, 0 ] ,
|
||||
[ "CREATURE_SPELL_POWER", 100, 0, 0 ] ,
|
||||
[ "SPELLCASTER", 3, "spell.stoneSkin", 0 ] ], //expert stone skin
|
||||
"abilities":
|
||||
{
|
||||
"magicResistance" :
|
||||
{
|
||||
"type" : "MAGIC_RESISTANCE",
|
||||
"val" : 5
|
||||
},
|
||||
"castsAmount" :
|
||||
{
|
||||
"type" : "CASTS",
|
||||
"val" : 1
|
||||
},
|
||||
"enchant" :
|
||||
{
|
||||
"type" : "CREATURE_ENCHANT_POWER",
|
||||
"val" : 1
|
||||
},
|
||||
"spellpower" :
|
||||
{
|
||||
"type" : "CREATURE_SPELL_POWER",
|
||||
"val" : 100
|
||||
},
|
||||
"canCast" :
|
||||
{
|
||||
"type" : "SPELLCASTER",
|
||||
"subtype" : "spell.stoneSkin",
|
||||
"val" : 3
|
||||
}
|
||||
},
|
||||
"graphics" :
|
||||
{
|
||||
"animation": "ZM179NPC.DEF",
|
||||
@ -603,7 +756,7 @@
|
||||
"projectile": "PLCBOWX.DEF"
|
||||
}
|
||||
},
|
||||
"sounds" :
|
||||
"sound" :
|
||||
{
|
||||
"attack": "PFOEATTK.wav",
|
||||
"defend": "PFOEDFND.wav",
|
||||
@ -618,11 +771,35 @@
|
||||
"id": 180,
|
||||
"level": 0,
|
||||
"faction": "neutral",
|
||||
"abilities": [ [ "MAGIC_RESISTANCE", 5, 0, 0 ],
|
||||
[ "CASTS", 1, 0, 0 ] ,
|
||||
[ "CREATURE_ENCHANT_POWER", 1, 0, 0 ] ,
|
||||
[ "CREATURE_SPELL_POWER", 100, 0, 0 ] ,
|
||||
[ "SPELLCASTER", 3, "spell.cure", 0 ] ], //expert cure
|
||||
"abilities":
|
||||
{
|
||||
"magicResistance" :
|
||||
{
|
||||
"type" : "MAGIC_RESISTANCE",
|
||||
"val" : 5
|
||||
},
|
||||
"castsAmount" :
|
||||
{
|
||||
"type" : "CASTS",
|
||||
"val" : 1
|
||||
},
|
||||
"enchant" :
|
||||
{
|
||||
"type" : "CREATURE_ENCHANT_POWER",
|
||||
"val" : 1
|
||||
},
|
||||
"spellpower" :
|
||||
{
|
||||
"type" : "CREATURE_SPELL_POWER",
|
||||
"val" : 100
|
||||
},
|
||||
"canCast" :
|
||||
{
|
||||
"type" : "SPELLCASTER",
|
||||
"subtype" : "spell.cure",
|
||||
"val" : 3
|
||||
}
|
||||
},
|
||||
"graphics" :
|
||||
{
|
||||
"animation": "ZM180NPC.DEF",
|
||||
@ -631,7 +808,7 @@
|
||||
"projectile": "PLCBOWX.DEF"
|
||||
}
|
||||
},
|
||||
"sounds" :
|
||||
"sound" :
|
||||
{
|
||||
"attack": "TRLLATTK.wav",
|
||||
"defend": "TRLLDFND.wav",
|
||||
@ -646,11 +823,35 @@
|
||||
"id": 181,
|
||||
"level": 0,
|
||||
"faction": "neutral",
|
||||
"abilities": [ [ "MAGIC_RESISTANCE", 5, 0, 0 ],
|
||||
[ "CASTS", 1, 0, 0 ] ,
|
||||
[ "CREATURE_ENCHANT_POWER", 1, 0, 0 ] ,
|
||||
[ "CREATURE_SPELL_POWER", 100, 0, 0 ] ,
|
||||
[ "SPELLCASTER", 3, "spell.haste", 0 ] ], //expert haste
|
||||
"abilities":
|
||||
{
|
||||
"magicResistance" :
|
||||
{
|
||||
"type" : "MAGIC_RESISTANCE",
|
||||
"val" : 5
|
||||
},
|
||||
"castsAmount" :
|
||||
{
|
||||
"type" : "CASTS",
|
||||
"val" : 1
|
||||
},
|
||||
"enchant" :
|
||||
{
|
||||
"type" : "CREATURE_ENCHANT_POWER",
|
||||
"val" : 1
|
||||
},
|
||||
"spellpower" :
|
||||
{
|
||||
"type" : "CREATURE_SPELL_POWER",
|
||||
"val" : 100
|
||||
},
|
||||
"canCast" :
|
||||
{
|
||||
"type" : "SPELLCASTER",
|
||||
"subtype" : "spell.haste",
|
||||
"val" : 3
|
||||
}
|
||||
},
|
||||
"graphics" :
|
||||
{
|
||||
"animation": "ZM181NPC.DEF",
|
||||
@ -659,7 +860,7 @@
|
||||
"projectile": "PLCBOWX.DEF"
|
||||
}
|
||||
},
|
||||
"sounds" :
|
||||
"sound" :
|
||||
{
|
||||
"attack": "AMAGATTK.wav",
|
||||
"defend": "AMAGDFND.wav",
|
||||
@ -675,11 +876,35 @@
|
||||
"id": 182,
|
||||
"level": 0,
|
||||
"faction": "neutral",
|
||||
"abilities": [ [ "MAGIC_RESISTANCE", 5, 0, 0 ],
|
||||
[ "CASTS", 1, 0, 0 ] ,
|
||||
[ "CREATURE_ENCHANT_POWER", 1, 0, 0 ] ,
|
||||
[ "CREATURE_SPELL_POWER", 100, 0, 0 ] ,
|
||||
[ "SPELLCASTER", 3, "spell.counterstrike", 0 ] ], //expert counterstrike
|
||||
"abilities":
|
||||
{
|
||||
"magicResistance" :
|
||||
{
|
||||
"type" : "MAGIC_RESISTANCE",
|
||||
"val" : 5
|
||||
},
|
||||
"castsAmount" :
|
||||
{
|
||||
"type" : "CASTS",
|
||||
"val" : 1
|
||||
},
|
||||
"enchant" :
|
||||
{
|
||||
"type" : "CREATURE_ENCHANT_POWER",
|
||||
"val" : 1
|
||||
},
|
||||
"spellpower" :
|
||||
{
|
||||
"type" : "CREATURE_SPELL_POWER",
|
||||
"val" : 100
|
||||
},
|
||||
"canCast" :
|
||||
{
|
||||
"type" : "SPELLCASTER",
|
||||
"subtype" : "spell.counterstrike",
|
||||
"val" : 3
|
||||
}
|
||||
},
|
||||
"graphics" :
|
||||
{
|
||||
"animation": "ZM182NPC.DEF",
|
||||
@ -688,7 +913,7 @@
|
||||
"projectile": "PLCBOWX.DEF"
|
||||
}
|
||||
},
|
||||
"sounds" :
|
||||
"sound" :
|
||||
{
|
||||
"attack": "GENIATTK.wav",
|
||||
"defend": "GENIDFND.wav",
|
||||
@ -705,95 +930,139 @@
|
||||
"faction": "neutral",
|
||||
"graphics" :
|
||||
{
|
||||
"animation": "ZM174NPC.DEF"
|
||||
"animation": "ZM174NPC.DEF",
|
||||
"missile" :
|
||||
{
|
||||
"projectile": "PLCBOWX.DEF"
|
||||
}
|
||||
}
|
||||
},
|
||||
"hierophant2" :
|
||||
{
|
||||
"special" : true,
|
||||
"disabled" : true,
|
||||
"id": 184,
|
||||
"level": 0,
|
||||
"faction": "neutral",
|
||||
"graphics" :
|
||||
{
|
||||
"animation": "ZM175NPC.DEF"
|
||||
"animation": "ZM175NPC.DEF",
|
||||
"missile" :
|
||||
{
|
||||
"projectile": "CPRZEAX.DEF"
|
||||
}
|
||||
}
|
||||
},
|
||||
"templeGuardian2" :
|
||||
{
|
||||
"special" : true,
|
||||
"disabled" : true,
|
||||
"id": 185,
|
||||
"level": 0,
|
||||
"faction": "neutral",
|
||||
"graphics" :
|
||||
{
|
||||
"animation": "ZM176NPC.DEF"
|
||||
"animation": "ZM176NPC.DEF",
|
||||
"missile" :
|
||||
{
|
||||
"projectile": "PLCBOWX.DEF"
|
||||
}
|
||||
}
|
||||
},
|
||||
"succubus2" :
|
||||
{
|
||||
"special" : true,
|
||||
"disabled" : true,
|
||||
"id": 186,
|
||||
"level": 0,
|
||||
"faction": "neutral",
|
||||
"graphics" :
|
||||
{
|
||||
"animation": "ZM177NPC.DEF"
|
||||
"animation": "ZM177NPC.DEF",
|
||||
"missile" :
|
||||
{
|
||||
"projectile": "PLCBOWX.DEF"
|
||||
}
|
||||
}
|
||||
},
|
||||
"soulEater2" :
|
||||
{
|
||||
"special" : true,
|
||||
"disabled" : true,
|
||||
"id": 187,
|
||||
"level": 0,
|
||||
"faction": "neutral",
|
||||
"graphics" :
|
||||
{
|
||||
"animation": "ZM178NPC.DEF"
|
||||
"animation": "ZM178NPC.DEF",
|
||||
"missile" :
|
||||
{
|
||||
"projectile": "PLCBOWX.DEF"
|
||||
}
|
||||
}
|
||||
},
|
||||
"brute2" :
|
||||
{
|
||||
"special" : true,
|
||||
"disabled" : true,
|
||||
"id": 188,
|
||||
"level": 0,
|
||||
"faction": "neutral",
|
||||
"graphics" :
|
||||
{
|
||||
"animation": "ZM179NPC.DEF"
|
||||
"animation": "ZM179NPC.DEF",
|
||||
"missile" :
|
||||
{
|
||||
"projectile": "PLCBOWX.DEF"
|
||||
}
|
||||
}
|
||||
},
|
||||
"ogreLeader2" :
|
||||
{
|
||||
"special" : true,
|
||||
"disabled" : true,
|
||||
"id": 189,
|
||||
"level": 0,
|
||||
"faction": "neutral",
|
||||
"graphics" :
|
||||
{
|
||||
"animation": "ZM180NPC.DEF"
|
||||
"animation": "ZM180NPC.DEF",
|
||||
"missile" :
|
||||
{
|
||||
"projectile": "PLCBOWX.DEF"
|
||||
}
|
||||
}
|
||||
},
|
||||
"shaman2" :
|
||||
{
|
||||
"special" : true,
|
||||
"disabled" : true,
|
||||
"id": 190,
|
||||
"level": 0,
|
||||
"faction": "neutral",
|
||||
"graphics" :
|
||||
{
|
||||
"animation": "ZM181NPC.DEF"
|
||||
"animation": "ZM181NPC.DEF",
|
||||
"missile" :
|
||||
{
|
||||
"projectile": "PLCBOWX.DEF"
|
||||
}
|
||||
}
|
||||
},
|
||||
"astralSpirit2" :
|
||||
{
|
||||
"special" : true,
|
||||
"disabled" : true,
|
||||
"id": 191,
|
||||
"level": 0,
|
||||
"faction": "neutral",
|
||||
"graphics" :
|
||||
{
|
||||
"animation": "ZM182NPC.DEF"
|
||||
"animation": "ZM182NPC.DEF",
|
||||
"missile" :
|
||||
{
|
||||
"projectile": "PLCBOWX.DEF"
|
||||
}
|
||||
}
|
||||
},
|
||||
"sylvanCentaur" :
|
||||
@ -806,8 +1075,7 @@
|
||||
"animation": "ZM192Z.DEF",
|
||||
"missile" :
|
||||
{
|
||||
"projectile": "PELFX.DEF",
|
||||
"spinning": true
|
||||
"projectile": "PELFX.DEF"
|
||||
}
|
||||
},
|
||||
"sound" :
|
||||
@ -830,8 +1098,7 @@
|
||||
"animation": "ZM193Z.DEF",
|
||||
"missile" :
|
||||
{
|
||||
"projectile": "CPRZEAX.DEF",
|
||||
"spinning": false
|
||||
"projectile": "CPRZEAX.DEF"
|
||||
}
|
||||
},
|
||||
"sound" :
|
||||
@ -878,20 +1145,40 @@
|
||||
"id": 196,
|
||||
"level": 10,
|
||||
"faction": "neutral",
|
||||
"abilities": [ [ "DRAGON_NATURE", 0, 0, 0 ],
|
||||
[ "TWO_HEX_ATTACK_BREATH", 0, 0, 0 ],
|
||||
[ "DRAGON_NATURE", 0, 0, 0 ],
|
||||
[ "UNDEAD", 0, 0, 0 ],
|
||||
[ "FLYING", 0, 0, 0 ],
|
||||
[ "SPELL_LIKE_ATTACK", 0, "spell.deathCloud", 0 ],
|
||||
[ "SHOOTER", 0, 0, 0 ] ],
|
||||
"abilities":
|
||||
{
|
||||
"dragon" :
|
||||
{
|
||||
"type" : "DRAGON_NATURE",
|
||||
},
|
||||
"dragonBreath" :
|
||||
{
|
||||
"type" : "TWO_HEX_ATTACK_BREATH"
|
||||
},
|
||||
"undead" :
|
||||
{
|
||||
"type" : "UNDEAD"
|
||||
},
|
||||
"canFly" :
|
||||
{
|
||||
"type" : "FLYING"
|
||||
},
|
||||
"deathCloud" :
|
||||
{
|
||||
"type" : "SPELL_LIKE_ATTACK",
|
||||
"subtype" : "spell.deathCloud"
|
||||
},
|
||||
"canShoot" :
|
||||
{
|
||||
"type" : "SHOOTER"
|
||||
}
|
||||
},
|
||||
"graphics" :
|
||||
{
|
||||
"animation": "ZM196Z.DEF",
|
||||
"missile" :
|
||||
{
|
||||
"projectile": "ZSHOT195.DEF",
|
||||
"spinning": false
|
||||
"projectile": "ZSHOT195.DEF"
|
||||
}
|
||||
},
|
||||
"sound" :
|
||||
|
@ -1,6 +1,7 @@
|
||||
{
|
||||
"neutral" :
|
||||
{
|
||||
"name" : "Neutral",
|
||||
"index" : 9,
|
||||
"alignment" : "neutral",
|
||||
"creatureBackground" :
|
||||
|
@ -4,6 +4,24 @@
|
||||
"title" : "VCMI artifact format",
|
||||
"description" : "Format used to define new artifacts in VCMI",
|
||||
"required" : [ "class", "graphics", "text", "type", "value" ],
|
||||
|
||||
"definitions" : {
|
||||
"growingBonusList" : {
|
||||
"type" : "array",
|
||||
"items" : {
|
||||
"type" : "object",
|
||||
"additionalProperties" : false,
|
||||
"properties" : {
|
||||
"level" : {
|
||||
"type" : "number"
|
||||
},
|
||||
"bonus" : { "$ref" : "vcmi:bonus" }
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
"additionalProperties" : false,
|
||||
"properties":{
|
||||
"bonuses": {
|
||||
"type":"array",
|
||||
@ -15,6 +33,10 @@
|
||||
"enum" : [ "SPECIAL", "TREASURE", "MINOR", "MAJOR", "RELIC" ],
|
||||
"description": "Artifact class, treasure, minor, major or relic"
|
||||
},
|
||||
"id" : {
|
||||
"type" : "number",
|
||||
"description" : "Private field to break things, do not use."
|
||||
},
|
||||
"components": {
|
||||
"type":"array",
|
||||
"description": "Optional, list of components for combinational artifacts",
|
||||
@ -22,8 +44,10 @@
|
||||
},
|
||||
"graphics": {
|
||||
"type":"object",
|
||||
"additionalProperties" : false,
|
||||
"description": "Graphical files associated with the artifact",
|
||||
"required" : [ "iconIndex", "image", "map" ],
|
||||
//"required" : [ "iconIndex", "image", "map" ],
|
||||
"required" : [ "iconIndex" ],
|
||||
"properties":{
|
||||
"iconIndex": {
|
||||
"type":"number",
|
||||
@ -43,12 +67,30 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"growing" : {
|
||||
"type" : "object",
|
||||
"additionalProperties" : false,
|
||||
"properties" : {
|
||||
"bonusesPerLevel" : { "$ref" : "#/definitions/growingBonusList"},
|
||||
"thresholdBonuses" : { "$ref" : "#/definitions/growingBonusList"}
|
||||
}
|
||||
},
|
||||
"slot": {
|
||||
"type":"string",
|
||||
"description": "Slot to which this artifact can be put, if applicable"
|
||||
"description": "Slot to which this artifact can be put, if applicable",
|
||||
"oneOf" : [
|
||||
{
|
||||
"type":"string"
|
||||
},
|
||||
{
|
||||
"type" : "array",
|
||||
"minItems" : 1,
|
||||
"additionalItems" : { "type" : "string" }
|
||||
}
|
||||
]
|
||||
},
|
||||
"text": {
|
||||
"type":"object",
|
||||
"additionalProperties" : false,
|
||||
"description": "Texts associated with artifact",
|
||||
"required" : [ "description", "event", "name" ],
|
||||
"properties":{
|
||||
|
@ -4,6 +4,8 @@
|
||||
"title" : "VCMI bonus system format",
|
||||
"description" : "Subsection of several formats, used to add generic bonuses to objects",
|
||||
"required": ["type"],
|
||||
|
||||
"additionalProperties" : false,
|
||||
"properties":{
|
||||
"addInfo": {
|
||||
"anyOf" : [
|
||||
@ -28,18 +30,26 @@
|
||||
"type":"array",
|
||||
"description": "limiters",
|
||||
"items": {
|
||||
"type":"object",
|
||||
"properties" : {
|
||||
"parameters": {
|
||||
"type":"array",
|
||||
"description" : "parameters",
|
||||
"additionalItems": true
|
||||
"oneOf" : [
|
||||
{
|
||||
"type":"object",
|
||||
"additionalProperties" : false,
|
||||
"properties" : {
|
||||
"parameters": {
|
||||
"type":"array",
|
||||
"description" : "parameters",
|
||||
"additionalItems": true
|
||||
},
|
||||
"type": {
|
||||
"type":"string",
|
||||
"description": "type",
|
||||
}
|
||||
}
|
||||
},
|
||||
"type": {
|
||||
"type":"string",
|
||||
"description": "type",
|
||||
{
|
||||
"type" : "string"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"propagator": {
|
||||
|
@ -3,14 +3,25 @@
|
||||
"$schema": "http://json-schema.org/draft-04/schema",
|
||||
"title" : "VCMI creature format",
|
||||
"description": "Json format for defining new creatures in VCMI",
|
||||
"required" : [
|
||||
"name", "faction", "cost", "level", "fightValue", "aiValue",
|
||||
"attack", "defense", "hitPoints", "speed", "damage", "advMapAmount",
|
||||
"graphics", "sound"
|
||||
"required" : [ "faction" ],
|
||||
"anyOf" : [
|
||||
{
|
||||
"disabled" : { "enum" : [ true ] }
|
||||
},
|
||||
{
|
||||
"required" : [
|
||||
"name", "cost", "level", "fightValue", "aiValue",
|
||||
"attack", "defense", "hitPoints", "speed", "damage", "advMapAmount",
|
||||
"graphics", "sound"
|
||||
]
|
||||
}
|
||||
],
|
||||
|
||||
"additionalProperties" : false,
|
||||
"properties":{
|
||||
"name": {
|
||||
"type":"object",
|
||||
"additionalProperties" : false,
|
||||
"description": "Translatable names for this creature",
|
||||
"required" : [ "singular", "plural" ],
|
||||
"properties":{
|
||||
@ -24,12 +35,26 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"abilityText" : {
|
||||
"type" : "string",
|
||||
"description" : "Text version of creature abilities. Used only with original creature window"
|
||||
},
|
||||
"id" : {
|
||||
"type" : "number",
|
||||
"description" : "Private field to break things, do not use."
|
||||
},
|
||||
"extraNames" : {
|
||||
"type" : "array",
|
||||
"items" : { "type" : "string" },
|
||||
"description" : "Private field to break things, do not use."
|
||||
},
|
||||
"faction": {
|
||||
"type":"string",
|
||||
"description": "Faction this creature belongs to. Examples: castle, rampart"
|
||||
},
|
||||
"cost": {
|
||||
"type":"object",
|
||||
"additionalProperties" : false,
|
||||
"description": "Cost to recruit this creature",
|
||||
"properties":{
|
||||
"wood": { "type":"number"},
|
||||
@ -45,6 +70,10 @@
|
||||
"type":"boolean",
|
||||
"description": "Marks this object as special and not available by default"
|
||||
},
|
||||
"disabled": {
|
||||
"type":"boolean",
|
||||
"description": "Object is competely disabled and may not be even loaded in-game"
|
||||
},
|
||||
"level": { "type":"number"},
|
||||
"fightValue": {
|
||||
"type":"number",
|
||||
@ -70,6 +99,7 @@
|
||||
|
||||
"damage": {
|
||||
"type":"object",
|
||||
"additionalProperties" : false,
|
||||
"properties":{
|
||||
"max": { "type":"number" },
|
||||
"min": { "type":"number" }
|
||||
@ -81,6 +111,7 @@
|
||||
},
|
||||
"advMapAmount": {
|
||||
"type":"object",
|
||||
"additionalProperties" : false,
|
||||
"description" : "Initial size of random stacks on adventure map",
|
||||
"properties":{
|
||||
"min": { "type":"number" },
|
||||
@ -101,15 +132,18 @@
|
||||
"description": "creature may receive \"week of\" events"
|
||||
},
|
||||
"abilities": {
|
||||
"type":"array",
|
||||
"description": "Creature abilities described using Bonus system",
|
||||
"items": { "$ref" : "vcmi:bonus" }
|
||||
"type":"object",
|
||||
"additionalProperties": {
|
||||
"$ref" : "vcmi:bonus"
|
||||
}
|
||||
},
|
||||
"stackExperience": {
|
||||
"type":"array",
|
||||
"description": "Stack experience, using bonus system",
|
||||
"items":{
|
||||
"type":"object",
|
||||
"additionalProperties" : false,
|
||||
"required" : [ "bonus", "values" ],
|
||||
"description": "0",
|
||||
"properties":{
|
||||
@ -119,7 +153,6 @@
|
||||
"minItems" : 10,
|
||||
"maxItems" : 10,
|
||||
"description": "Strength of the bonus",
|
||||
"additionalItems" : true,
|
||||
"anyof" : [
|
||||
{ "items": { "type" : "number" } },
|
||||
{ "items": { "type" : "boolean" } }
|
||||
@ -130,14 +163,16 @@
|
||||
},
|
||||
"graphics": {
|
||||
"type":"object",
|
||||
"additionalProperties" : false,
|
||||
"description": "Describes how this creature looks like during battles",
|
||||
"required" : [
|
||||
"animationTime", "iconLarge", "iconSmall", "iconIndex",
|
||||
"map", "animation", "attackClimaxFrame", "timeBetweenFidgets"
|
||||
"animationTime", "iconIndex",
|
||||
"map", "animation", "timeBetweenFidgets"
|
||||
],
|
||||
"properties":{
|
||||
"animationTime": {
|
||||
"type":"object",
|
||||
"additionalProperties" : false,
|
||||
"required" : [ "attack", "flight", "walk" ],
|
||||
"description": "Length of several animations",
|
||||
"properties":{
|
||||
@ -176,13 +211,10 @@
|
||||
"type":"string",
|
||||
"description": ".def file with animation of this creature in battles"
|
||||
},
|
||||
"attackClimaxFrame": {
|
||||
"type":"number",
|
||||
"description": "Frame from attack animation during which creature deals damage"
|
||||
},
|
||||
"missile": {
|
||||
"type":"object",
|
||||
"required" : [ "projectile", "frameAngles", "offset" ],
|
||||
"additionalProperties" : false,
|
||||
"required" : [ "projectile", "frameAngles", "offset", "attackClimaxFrame" ],
|
||||
"description": "Missile description for archers",
|
||||
"properties":{
|
||||
"projectile": {
|
||||
@ -201,6 +233,7 @@
|
||||
},
|
||||
"offset": {
|
||||
"type":"object",
|
||||
"additionalProperties" : false,
|
||||
"required" : [ "lowerX", "lowerY", "middleX", "middleY", "upperX", "upperY" ],
|
||||
"description": "Position where projectile image appears during shooting in specific direction",
|
||||
"properties":{
|
||||
@ -211,6 +244,10 @@
|
||||
"upperX": { "type":"number" },
|
||||
"upperY": { "type":"number" }
|
||||
}
|
||||
},
|
||||
"attackClimaxFrame": {
|
||||
"type":"number",
|
||||
"description": "Frame from attack animation during which creature deals damage"
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -226,18 +263,17 @@
|
||||
},
|
||||
"sound": {
|
||||
"type":"object",
|
||||
"additionalProperties" : false,
|
||||
"description": "Various sound files associated with this creature",
|
||||
"properties":{
|
||||
"attack": { "type":"string" },
|
||||
"defend": { "type":"string" },
|
||||
"killed": { "type":"string" },
|
||||
"moveEnd": { "type":"string" },
|
||||
"moveStart": { "type":"string" },
|
||||
"move": { "type":"string" },
|
||||
"shoot": { "type":"string" },
|
||||
"wince": { "type":"string" },
|
||||
"ext1": { "type":"string" },
|
||||
"ext2": { "type":"string" }
|
||||
"attack": { "type":"string" },
|
||||
"defend": { "type":"string" },
|
||||
"killed": { "type":"string" },
|
||||
"startMoving": { "type":"string" },
|
||||
"endMoving": { "type":"string" },
|
||||
"move": { "type":"string" },
|
||||
"shoot": { "type":"string" },
|
||||
"wince": { "type":"string" }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -7,11 +7,17 @@
|
||||
"dependencies" : {
|
||||
"town" : [ "puzzleMap", "commander" ]
|
||||
},
|
||||
|
||||
"additionalProperties" : false,
|
||||
"properties":{
|
||||
"name" : {
|
||||
"type" : "string",
|
||||
"description" : "Translatable name of town"
|
||||
},
|
||||
"index" : {
|
||||
"type" : "number",
|
||||
"description" : "Private field to break things, do not use."
|
||||
},
|
||||
"alignment": {
|
||||
"type":"string",
|
||||
"enum" : [ "good", "neutral", "evil" ],
|
||||
@ -23,6 +29,7 @@
|
||||
},
|
||||
"creatureBackground": {
|
||||
"type":"object",
|
||||
"additionalProperties" : false,
|
||||
"required" : [ "120px", "130px" ],
|
||||
"description": "Backgrounds for creature info card",
|
||||
"properties":{
|
||||
@ -42,6 +49,7 @@
|
||||
},
|
||||
"puzzleMap": {
|
||||
"type":"object",
|
||||
"additionalProperties" : false,
|
||||
"required" : [ "prefix", "pieces" ],
|
||||
"description": "Puzzle map from obelisks for this town. Must contain 48 pieces",
|
||||
"properties":{
|
||||
@ -52,6 +60,7 @@
|
||||
"maxItems" : 48,
|
||||
"items": {
|
||||
"type":"object",
|
||||
"additionalProperties" : false,
|
||||
"properties":{
|
||||
"index": { "type":"number", "description" : "Order in which images will be opened" },
|
||||
"x": { "type":"number", "description" : "X coordinate on screen" },
|
||||
@ -67,15 +76,17 @@
|
||||
},
|
||||
"town": {
|
||||
"type":"object",
|
||||
"additionalProperties" : false,
|
||||
"required" : [
|
||||
"adventureMap", "buildingsIcons", "buildings", "creatures", "guildWindow", "names",
|
||||
"hallBackground", "hallSlots", "horde", "icons", "mageGuild", "moatDamage",
|
||||
"musicTheme", "siege", "structures", "townBackground", "warMachine", "primaryResource"
|
||||
"musicTheme", "siege", "structures", "townBackground", "warMachine"
|
||||
],
|
||||
"description": "town",
|
||||
"properties":{
|
||||
"adventureMap": {
|
||||
"type":"object",
|
||||
"additionalProperties" : false,
|
||||
"description": "Paths to images of object on adventure map",
|
||||
"required" : [ "capitol", "castle", "village" ],
|
||||
"properties":{
|
||||
@ -96,6 +107,7 @@
|
||||
"description" : "Dwellings on adventure map",
|
||||
"items" : {
|
||||
"type" : "object",
|
||||
"additionalProperties" : false,
|
||||
"properties" : {
|
||||
"name": { "type":"string" },
|
||||
"graphics": { "type":"string" }
|
||||
@ -176,11 +188,13 @@
|
||||
},
|
||||
"icons": {
|
||||
"type":"object",
|
||||
"additionalProperties" : false,
|
||||
"description": "Town icons",
|
||||
"required" : [ "fort", "village" ],
|
||||
"properties":{
|
||||
"fort": {
|
||||
"type":"object",
|
||||
"additionalProperties" : false,
|
||||
"required" : [ "normal", "built" ],
|
||||
"description": "Icons for town with built fort",
|
||||
"properties":{
|
||||
@ -196,6 +210,7 @@
|
||||
},
|
||||
"village": {
|
||||
"type":"object",
|
||||
"additionalProperties" : false,
|
||||
"required" : [ "normal", "built" ],
|
||||
"description": "Icons for town without fort",
|
||||
"properties":{
|
||||
|
@ -4,6 +4,8 @@
|
||||
"title" : "VCMI hero format",
|
||||
"description" : "Format used to define new heroes in VCMI",
|
||||
"required": [ "army", "class", "images", "skills", "texts" ],
|
||||
|
||||
"additionalProperties" : false,
|
||||
"properties":{
|
||||
"army": {
|
||||
"type":"array",
|
||||
@ -12,6 +14,7 @@
|
||||
"maxItems" : 3,
|
||||
"items": {
|
||||
"type":"object",
|
||||
"additionalProperties" : false,
|
||||
"required" : [ "creature", "min", "max" ],
|
||||
"properties":{
|
||||
"creature": {
|
||||
@ -29,10 +32,14 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"id" : {
|
||||
"type" : "number",
|
||||
"description" : "Private field to break things, do not use."
|
||||
},
|
||||
"special": {
|
||||
"type":"boolean",
|
||||
"description": "Marks this object as special and not available by default"
|
||||
},
|
||||
},
|
||||
"class": {
|
||||
"type":"string",
|
||||
"description": "Hero class, e.g. knight or battleMage"
|
||||
@ -43,8 +50,9 @@
|
||||
},
|
||||
"images": {
|
||||
"type":"object",
|
||||
"additionalProperties" : false,
|
||||
"description": "images",
|
||||
"required": [ "index", "large", "small", "specialtyLarge", "specialtySmall" ],
|
||||
"required": [ "index" ],
|
||||
"properties":{
|
||||
"index": {
|
||||
"type":"number",
|
||||
@ -74,6 +82,7 @@
|
||||
"maxItems" : 8,
|
||||
"items": {
|
||||
"type":"object",
|
||||
"additionalProperties" : false,
|
||||
"required" : [ "level", "skill" ],
|
||||
"properties":{
|
||||
"level": {
|
||||
@ -88,11 +97,18 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"specialties" :
|
||||
{
|
||||
"type" : "array",
|
||||
"description" : "Specialty format used for OH3 heroes. Use \"specialty\" instead",
|
||||
"additionalItems" : true
|
||||
},
|
||||
"specialty": {
|
||||
"type":"array",
|
||||
"description": "Description of hero specialty using bonus system",
|
||||
"items": {
|
||||
"type":"object",
|
||||
"additionalProperties" : false,
|
||||
"required" : [ "bonuses" ],
|
||||
"properties":{
|
||||
"growsWithLevel" : {
|
||||
@ -114,6 +130,7 @@
|
||||
},
|
||||
"texts": {
|
||||
"type":"object",
|
||||
"additionalProperties" : false,
|
||||
"description": "All translatable texts related to hero",
|
||||
"required" : [ "biography", "name", "specialty" ],
|
||||
"properties":{
|
||||
@ -127,6 +144,7 @@
|
||||
},
|
||||
"specialty": {
|
||||
"type":"object",
|
||||
"additionalProperties" : false,
|
||||
"description": "Hero specialty information",
|
||||
"required" : [ "description", "name", "tooltip" ],
|
||||
"properties":{
|
||||
|
@ -7,14 +7,18 @@
|
||||
"animation", "faction", "highLevelChance", "lowLevelChance",
|
||||
"name", "primarySkills", "secondarySkills", "tavern"
|
||||
],
|
||||
|
||||
"additionalProperties" : false,
|
||||
"properties":{
|
||||
"animation": {
|
||||
"type":"object",
|
||||
"additionalProperties" : false,
|
||||
"description": "Files related to hero animation",
|
||||
"required": [ "battle", "map" ],
|
||||
"properties":{
|
||||
"battle": {
|
||||
"type":"object",
|
||||
"additionalProperties" : false,
|
||||
"description": "Hero animations for battle",
|
||||
"required": [ "female", "male" ],
|
||||
"properties":{
|
||||
@ -30,6 +34,7 @@
|
||||
},
|
||||
"map": {
|
||||
"type":"object",
|
||||
"additionalProperties" : false,
|
||||
"description": "Hero animations for adventure map",
|
||||
"required": [ "female", "male" ],
|
||||
"properties":{
|
||||
@ -45,6 +50,10 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"id" : {
|
||||
"type" : "number",
|
||||
"description" : "Private field to break things, do not use."
|
||||
},
|
||||
"faction": {
|
||||
"type":"string",
|
||||
"description": "Faction this hero class belongs to"
|
||||
|
@ -4,8 +4,9 @@
|
||||
"title" : "VCMI mod file format",
|
||||
"description" : "Format used to define main mod file (mod.json) in VCMI",
|
||||
"required" : [ "name", "description" ],
|
||||
"properties":{
|
||||
|
||||
"additionalProperties" : false,
|
||||
"properties":{
|
||||
"name": {
|
||||
"type":"string",
|
||||
"description": "Short name of your mod. No more than 2-3 words"
|
||||
@ -60,6 +61,7 @@
|
||||
"description" : "list of data sources attached to this mount point",
|
||||
"items": {
|
||||
"type":"object",
|
||||
"additionalProperties" : false,
|
||||
"properties":{
|
||||
"path": {
|
||||
"type":"string",
|
||||
|
@ -9,12 +9,14 @@
|
||||
"type" : "string",
|
||||
"enum" : [ "trace", "debug", "info", "warn", "error" ]
|
||||
}
|
||||
},
|
||||
},
|
||||
"additionalProperties" : false,
|
||||
"properties":
|
||||
{
|
||||
"general" : {
|
||||
"type" : "object",
|
||||
"default": {},
|
||||
"additionalProperties" : false,
|
||||
"required" : [ "classicCreatureWindow", "playerName", "showfps", "music", "sound" ],
|
||||
"properties" : {
|
||||
"classicCreatureWindow" : {
|
||||
@ -41,11 +43,13 @@
|
||||
},
|
||||
"video" : {
|
||||
"type" : "object",
|
||||
"additionalProperties" : false,
|
||||
"default": {},
|
||||
"required" : [ "screenRes", "bitsPerPixel", "fullscreen" ],
|
||||
"properties" : {
|
||||
"screenRes" : {
|
||||
"type" : "object",
|
||||
"additionalProperties" : false,
|
||||
"required" : [ "width", "height" ],
|
||||
"properties" : {
|
||||
"width" : { "type" : "number" },
|
||||
@ -65,6 +69,7 @@
|
||||
},
|
||||
"adventure" : {
|
||||
"type" : "object",
|
||||
"additionalProperties" : false,
|
||||
"default": {},
|
||||
"required" : [ "heroSpeed", "enemySpeed", "scrollSpeed", "heroReminder" ],
|
||||
"properties" : {
|
||||
@ -88,6 +93,7 @@
|
||||
},
|
||||
"battle" : {
|
||||
"type" : "object",
|
||||
"additionalProperties" : false,
|
||||
"default": {},
|
||||
"required" : [ "animationSpeed", "mouseShadow", "cellBorders", "stackRange", "showQueue" ],
|
||||
"properties" : {
|
||||
@ -115,6 +121,7 @@
|
||||
},
|
||||
"server" : {
|
||||
"type" : "object",
|
||||
"additionalProperties" : false,
|
||||
"default": {},
|
||||
"required" : [ "server", "port", "localInformation", "playerAI", "neutralAI" ],
|
||||
"properties" : {
|
||||
@ -142,6 +149,7 @@
|
||||
},
|
||||
"logging" : {
|
||||
"type" : "object",
|
||||
"additionalProperties" : false,
|
||||
"default" : {},
|
||||
"required" : [ "console", "file", "loggers" ],
|
||||
"properties" : {
|
||||
@ -152,7 +160,7 @@
|
||||
"properties" : {
|
||||
"format" : {
|
||||
"type" : "string",
|
||||
"default" : "%l %n [%t] - %m"
|
||||
"default" : "%m"
|
||||
},
|
||||
"threshold" : {
|
||||
"$ref" : "#/definitions/logLevelEnum",
|
||||
@ -173,6 +181,7 @@
|
||||
],
|
||||
"items" : {
|
||||
"type" : "object",
|
||||
"additionalProperties" : false,
|
||||
"default" : {},
|
||||
"required" : [ "domain", "level", "color" ],
|
||||
"properties" : {
|
||||
@ -186,6 +195,7 @@
|
||||
},
|
||||
"file" : {
|
||||
"type" : "object",
|
||||
"additionalProperties" : false,
|
||||
"default" : {},
|
||||
"required" : [ "format" ],
|
||||
"properties" : {
|
||||
@ -200,6 +210,7 @@
|
||||
"default" : [ { "domain" : "global", "level" : "info" } ],
|
||||
"items" : {
|
||||
"type" : "object",
|
||||
"additionalProperties" : false,
|
||||
"required" : [ "level", "domain" ],
|
||||
"properties" : {
|
||||
"domain" : { "type" : "string" },
|
||||
|
@ -1,5 +1,6 @@
|
||||
{
|
||||
"type":"object",
|
||||
"additionalProperties" : false,
|
||||
"$schema": "http://json-schema.org/draft-04/schema",
|
||||
"title" : "VCMI town building format",
|
||||
"description" : "Format used to define town buildings in VCMI",
|
||||
@ -35,6 +36,7 @@
|
||||
},
|
||||
"cost": {
|
||||
"type":"object",
|
||||
"additionalProperties" : false,
|
||||
"description": "Cost to build this building",
|
||||
"properties":{
|
||||
"wood": { "type":"number"},
|
||||
|
@ -1,5 +1,6 @@
|
||||
{
|
||||
"type":"object",
|
||||
"additionalProperties" : false,
|
||||
"$schema": "http://json-schema.org/draft-04/schema",
|
||||
"title" : "VCMI siege screen format",
|
||||
"description" : "Format used to define town siege screen in VCMI",
|
||||
@ -12,6 +13,7 @@
|
||||
{
|
||||
"point" : {
|
||||
"type" : "object",
|
||||
"additionalProperties" : false,
|
||||
"required" : [ "x", "y" ],
|
||||
"properties":{
|
||||
"x": { "type":"number" },
|
||||
@ -20,6 +22,7 @@
|
||||
},
|
||||
"tower" : {
|
||||
"type" : "object",
|
||||
"additionalProperties" : false,
|
||||
"required" : [ "battlement", "creature", "tower" ],
|
||||
"properties":{
|
||||
"battlement": {
|
||||
@ -41,6 +44,7 @@
|
||||
"properties":{
|
||||
"gate": {
|
||||
"type":"object",
|
||||
"additionalProperties" : false,
|
||||
"description" : "Town gates",
|
||||
"properties":{
|
||||
"arch": {
|
||||
@ -59,6 +63,7 @@
|
||||
},
|
||||
"moat": {
|
||||
"type":"object",
|
||||
"additionalProperties" : false,
|
||||
"description" : "Castle moat description",
|
||||
"properties":{
|
||||
"bank": {
|
||||
@ -81,6 +86,7 @@
|
||||
},
|
||||
"static": {
|
||||
"type":"object",
|
||||
"additionalProperties" : false,
|
||||
"description" : "Static sections of walls",
|
||||
"properties":{
|
||||
"background": {
|
||||
@ -99,6 +105,7 @@
|
||||
},
|
||||
"towers": {
|
||||
"type":"object",
|
||||
"additionalProperties" : false,
|
||||
"description" : "Decription of towers",
|
||||
"properties":{
|
||||
"bottom": { "$ref" : "#/definitions/tower", "description" : "Bottom tower" },
|
||||
@ -108,6 +115,7 @@
|
||||
},
|
||||
"walls": {
|
||||
"type":"object",
|
||||
"additionalProperties" : false,
|
||||
"description" : "Destructible sections of the walls",
|
||||
"properties":{
|
||||
"bottomMid": {
|
||||
|
@ -4,6 +4,7 @@
|
||||
"title" : "VCMI town structures format",
|
||||
"description" : "Format used to define structures visible on town screen in VCMI",
|
||||
"required": [ "animation", "x", "y"],
|
||||
"additionalProperties" : false,
|
||||
"properties":{
|
||||
"animation": {
|
||||
"type":"string",
|
||||
|
@ -205,6 +205,7 @@ void CArtHandler::load(bool onlyTxt)
|
||||
JsonNode & artData = h3Data[numeric];
|
||||
JsonUtils::merge(artData, node.second);
|
||||
|
||||
//JsonUtils::validate(artData, "vcmi:artifact", node.first);
|
||||
artifacts[numeric] = loadArtifact(artData);
|
||||
artifacts[numeric]->id = ArtifactID(numeric);
|
||||
|
||||
@ -386,11 +387,11 @@ void CArtHandler::loadGrowingArt(CGrowingArtifact * art, const JsonNode & node)
|
||||
{
|
||||
BOOST_FOREACH (auto b, node["growing"]["bonusesPerLevel"].Vector())
|
||||
{
|
||||
art->bonusesPerLevel.push_back (std::pair <ui16, Bonus> (b["level"].Float(), *JsonUtils::parseBonus (b["bonus"].Vector())));
|
||||
art->bonusesPerLevel.push_back (std::pair <ui16, Bonus> (b["level"].Float(), *JsonUtils::parseBonus (b["bonus"])));
|
||||
}
|
||||
BOOST_FOREACH (auto b, node["growing"]["thresholdBonuses"].Vector())
|
||||
{
|
||||
art->thresholdBonuses.push_back (std::pair <ui16, Bonus> (b["level"].Float(), *JsonUtils::parseBonus (b["bonus"].Vector())));
|
||||
art->thresholdBonuses.push_back (std::pair <ui16, Bonus> (b["level"].Float(), *JsonUtils::parseBonus (b["bonus"])));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -7,6 +7,7 @@
|
||||
#include "CGameState.h"
|
||||
#include "CTownHandler.h"
|
||||
#include "CModHandler.h"
|
||||
#include "StringConstants.h"
|
||||
|
||||
using namespace boost::assign;
|
||||
|
||||
@ -19,24 +20,6 @@ using namespace boost::assign;
|
||||
* Full text of license available in license.txt file, in main folder
|
||||
*
|
||||
*/
|
||||
|
||||
static inline void registerCreature(const std::string &name, const si32 id)
|
||||
{
|
||||
const std::string fullname = "creature." + name;
|
||||
VLC->modh->identifiers.registerObject(fullname,id);
|
||||
}
|
||||
|
||||
///CCreatureHandler
|
||||
|
||||
CCreatureHandler::CCreatureHandler()
|
||||
{
|
||||
VLC->creh = this;
|
||||
|
||||
allCreatures.setDescription("All creatures");
|
||||
creaturesOfLevel[0].setDescription("Creatures of unnormalized tier");
|
||||
for(int i = 1; i < ARRAY_COUNT(creaturesOfLevel); i++)
|
||||
creaturesOfLevel[i].setDescription("Creatures of tier " + boost::lexical_cast<std::string>(i));
|
||||
}
|
||||
|
||||
int CCreature::getQuantityID(const int & quantity)
|
||||
{
|
||||
@ -182,78 +165,108 @@ static void AddAbility(CCreature *cre, const JsonVector &ability_vec)
|
||||
cre->addNewBonus(nsf);
|
||||
}
|
||||
|
||||
static void RemoveAbility(CCreature *cre, const JsonNode &ability)
|
||||
CCreatureHandler::CCreatureHandler()
|
||||
{
|
||||
const std::string type = ability.String();
|
||||
VLC->creh = this;
|
||||
|
||||
auto it = bonusNameMap.find(type);
|
||||
allCreatures.setDescription("All creatures");
|
||||
creaturesOfLevel[0].setDescription("Creatures of unnormalized tier");
|
||||
for(int i = 1; i < ARRAY_COUNT(creaturesOfLevel); i++)
|
||||
creaturesOfLevel[i].setDescription("Creatures of tier " + boost::lexical_cast<std::string>(i));
|
||||
|
||||
if (it == bonusNameMap.end()) {
|
||||
if (type == "DOUBLE_WIDE")
|
||||
cre->doubleWide = false;
|
||||
else
|
||||
logGlobal->errorStream() << "Error: invalid ability type " << type << " in creatures config";
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
const int typeNo = it->second;
|
||||
|
||||
Bonus::BonusType ecf = static_cast<Bonus::BonusType>(typeNo);
|
||||
|
||||
Bonus *b = cre->getBonusLocalFirst(Selector::type(ecf));
|
||||
cre->removeBonus(b);
|
||||
loadCommanders();
|
||||
}
|
||||
|
||||
void CCreatureHandler::loadBonuses(CCreature & ncre, std::string bonuses)
|
||||
void CCreatureHandler::loadCommanders()
|
||||
{
|
||||
static const std::map<std::string,Bonus::BonusType> abilityMap =
|
||||
const JsonNode config(ResourceID("config/commanders.json"));
|
||||
|
||||
BOOST_FOREACH (auto bonus, config["bonusPerLevel"].Vector())
|
||||
{
|
||||
commanderLevelPremy.push_back(JsonUtils::parseBonus (bonus.Vector()));
|
||||
}
|
||||
|
||||
int i = 0;
|
||||
BOOST_FOREACH (auto skill, config["skillLevels"].Vector())
|
||||
{
|
||||
skillLevels.push_back (std::vector<ui8>());
|
||||
BOOST_FOREACH (auto skillLevel, skill["levels"].Vector())
|
||||
{
|
||||
skillLevels[i].push_back (skillLevel.Float());
|
||||
}
|
||||
++i;
|
||||
}
|
||||
|
||||
BOOST_FOREACH (auto ability, config["abilityRequirements"].Vector())
|
||||
{
|
||||
std::pair <Bonus, std::pair <ui8, ui8> > a;
|
||||
a.first = *JsonUtils::parseBonus (ability["ability"].Vector());
|
||||
a.second.first = ability["skills"].Vector()[0].Float();
|
||||
a.second.second = ability["skills"].Vector()[1].Float();
|
||||
skillRequirements.push_back (a);
|
||||
}
|
||||
}
|
||||
|
||||
void CCreatureHandler::loadBonuses(JsonNode & creature, std::string bonuses)
|
||||
{
|
||||
auto makeBonusNode = [&](std::string type) -> JsonNode
|
||||
{
|
||||
JsonNode ret;
|
||||
ret["type"].String() = type;
|
||||
return ret;
|
||||
};
|
||||
|
||||
static const std::map<std::string, JsonNode> abilityMap =
|
||||
boost::assign::map_list_of
|
||||
("FLYING_ARMY", Bonus::FLYING)
|
||||
("SHOOTING_ARMY", Bonus::SHOOTER)
|
||||
("SIEGE_WEAPON", Bonus::SIEGE_WEAPON)
|
||||
("const_free_attack", Bonus::BLOCKS_RETALIATION)
|
||||
("IS_UNDEAD", Bonus::UNDEAD)
|
||||
("const_no_melee_penalty",Bonus::NO_MELEE_PENALTY)
|
||||
("const_jousting",Bonus::JOUSTING)
|
||||
("KING_1",Bonus::KING1)
|
||||
("KING_2",Bonus::KING2)
|
||||
("KING_3",Bonus::KING3)
|
||||
("const_no_wall_penalty",Bonus::NO_WALL_PENALTY)
|
||||
("CATAPULT",Bonus::CATAPULT)
|
||||
("MULTI_HEADED",Bonus::ATTACKS_ALL_ADJACENT)
|
||||
("IMMUNE_TO_MIND_SPELLS",Bonus::MIND_IMMUNITY)
|
||||
("HAS_EXTENDED_ATTACK",Bonus::TWO_HEX_ATTACK_BREATH);
|
||||
("FLYING_ARMY", makeBonusNode("FLYING"))
|
||||
("SHOOTING_ARMY", makeBonusNode("SHOOTER"))
|
||||
("SIEGE_WEAPON", makeBonusNode("SIEGE_WEAPON"))
|
||||
("const_free_attack", makeBonusNode("BLOCKS_RETALIATION"))
|
||||
("IS_UNDEAD", makeBonusNode("UNDEAD"))
|
||||
("const_no_melee_penalty", makeBonusNode("NO_MELEE_PENALTY"))
|
||||
("const_jousting", makeBonusNode("JOUSTING"))
|
||||
("KING_1", makeBonusNode("KING1"))
|
||||
("KING_2", makeBonusNode("KING2"))
|
||||
("KING_3", makeBonusNode("KING3"))
|
||||
("const_no_wall_penalty", makeBonusNode("NO_WALL_PENALTY"))
|
||||
("CATAPULT", makeBonusNode("CATAPULT"))
|
||||
("MULTI_HEADED", makeBonusNode("ATTACKS_ALL_ADJACENT"))
|
||||
("IMMUNE_TO_MIND_SPELLS", makeBonusNode("MIND_IMMUNITY"))
|
||||
("HAS_EXTENDED_ATTACK", makeBonusNode("TWO_HEX_ATTACK_BREATH"));
|
||||
|
||||
auto hasAbility = [&](const std::string name) -> bool
|
||||
{
|
||||
return boost::algorithm::find_first(bonuses, name);
|
||||
};
|
||||
|
||||
BOOST_FOREACH(auto a, abilityMap)
|
||||
{
|
||||
if(hasAbility(a.first))
|
||||
ncre.addBonus(0, a.second);
|
||||
creature["abilities"][a.first] = a.second;
|
||||
}
|
||||
if(hasAbility("DOUBLE_WIDE"))
|
||||
ncre.doubleWide = true;
|
||||
creature["doubleWide"].Bool() = true;
|
||||
|
||||
if(hasAbility("const_raises_morale"))
|
||||
{
|
||||
ncre.addBonus(+1, Bonus::MORALE);;
|
||||
ncre.getBonusList().back()->addPropagator(make_shared<CPropagatorNodeType>(CBonusSystemNode::HERO));
|
||||
JsonNode node = makeBonusNode("MORALE");
|
||||
node["val"].Float() = 1;
|
||||
node["propagator"].String() = "HERO";
|
||||
creature["abilities"]["const_raises_morale"] = node;
|
||||
}
|
||||
if(hasAbility("const_lowers_morale"))
|
||||
{
|
||||
ncre.addBonus(-1, Bonus::MORALE);;
|
||||
ncre.getBonusList().back()->effectRange = Bonus::ONLY_ENEMY_ARMY;
|
||||
JsonNode node = makeBonusNode("MORALE");
|
||||
node["val"].Float() = 1;
|
||||
node["effectRange"].String() = "ONLY_ENEMY_ARMY";
|
||||
creature["abilities"]["const_lowers_morale"] = node;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CCreatureHandler::load()
|
||||
{
|
||||
logGlobal->traceStream() << "\t\tReading ZCRTRAIT.TXT";
|
||||
std::vector<JsonNode> h3Data;
|
||||
|
||||
////////////reading ZCRTRAIT.TXT ///////////////////
|
||||
CLegacyConfigParser parser("DATA/ZCRTRAIT.TXT");
|
||||
|
||||
parser.endLine(); // header
|
||||
@ -265,70 +278,80 @@ void CCreatureHandler::load()
|
||||
while (parser.isNextEntryEmpty())
|
||||
parser.endLine();
|
||||
|
||||
CCreature &ncre = *new CCreature;
|
||||
ncre.idNumber = CreatureID(creatures.size());
|
||||
ncre.cost.resize(GameConstants::RESOURCE_QUANTITY);
|
||||
ncre.level=0;
|
||||
ncre.iconIndex = ncre.idNumber + 2; // +2 for empty\selection images
|
||||
JsonNode data;
|
||||
|
||||
ncre.nameSing = parser.readString();
|
||||
ncre.namePl = parser.readString();
|
||||
data["graphics"]["iconIndex"].Float() = h3Data.size() + 2; // +2 for empty\selection images
|
||||
|
||||
data["name"]["singular"].String() = parser.readString();
|
||||
data["name"]["plural"].String() = parser.readString();
|
||||
|
||||
for(int v=0; v<7; ++v)
|
||||
{
|
||||
ncre.cost[v] = parser.readNumber();
|
||||
}
|
||||
ncre.fightValue = parser.readNumber();
|
||||
ncre.AIValue = parser.readNumber();
|
||||
ncre.growth = parser.readNumber();
|
||||
ncre.hordeGrowth = parser.readNumber();
|
||||
data["cost"][GameConstants::RESOURCE_NAMES[v]].Float() = parser.readNumber();
|
||||
|
||||
ncre.addBonus(parser.readNumber(), Bonus::STACK_HEALTH);
|
||||
ncre.addBonus(parser.readNumber(), Bonus::STACKS_SPEED);
|
||||
ncre.addBonus(parser.readNumber(), Bonus::PRIMARY_SKILL, PrimarySkill::ATTACK);
|
||||
ncre.addBonus(parser.readNumber(), Bonus::PRIMARY_SKILL, PrimarySkill::DEFENSE);
|
||||
ncre.addBonus(parser.readNumber(), Bonus::CREATURE_DAMAGE, 1);
|
||||
ncre.addBonus(parser.readNumber(), Bonus::CREATURE_DAMAGE, 2);
|
||||
ncre.addBonus(parser.readNumber(), Bonus::SHOTS);
|
||||
data["fightValue"].Float() = parser.readNumber();
|
||||
data["aiValue"].Float() = parser.readNumber();
|
||||
data["growth"].Float() = parser.readNumber();
|
||||
data["horde"].Float() = parser.readNumber();
|
||||
|
||||
//spells - not used?
|
||||
parser.readNumber();
|
||||
ncre.ammMin = parser.readNumber();
|
||||
ncre.ammMax = parser.readNumber();
|
||||
|
||||
ncre.abilityText = parser.readString();
|
||||
loadBonuses(ncre, parser.readString()); //Attributes
|
||||
data["hitPoints"].Float() = parser.readNumber();
|
||||
data["speed"].Float() = parser.readNumber();
|
||||
data["attack"].Float() = parser.readNumber();
|
||||
data["defense"].Float() = parser.readNumber();
|
||||
data["damage"]["min"].Float() = parser.readNumber();
|
||||
data["damage"]["max"].Float() = parser.readNumber();
|
||||
|
||||
creatures.push_back(&ncre);
|
||||
if (float shots = parser.readNumber())
|
||||
data["shots"].Float() = shots;
|
||||
|
||||
if (float spells = parser.readNumber())
|
||||
data["spellPoints"].Float() = spells;
|
||||
|
||||
data["advMapAmount"]["min"].Float() = parser.readNumber();
|
||||
data["advMapAmount"]["max"].Float() = parser.readNumber();
|
||||
|
||||
data["abilityText"].String() = parser.readString();
|
||||
loadBonuses(data, parser.readString()); //Attributes
|
||||
|
||||
h3Data.push_back(data);
|
||||
}
|
||||
while (parser.endLine());
|
||||
|
||||
// loading creatures properties
|
||||
logGlobal->traceStream() << "\t\tReading creatures json configs";
|
||||
loadAnimationInfo(h3Data);
|
||||
|
||||
const JsonNode gameConf(ResourceID("config/gameConfig.json"));
|
||||
const JsonNode config(JsonUtils::assembleFromFiles(gameConf["creatures"].convertTo<std::vector<std::string> >()));
|
||||
JsonNode config(JsonUtils::assembleFromFiles(gameConf["creatures"].convertTo<std::vector<std::string> >()));
|
||||
|
||||
creatures.resize(GameConstants::CREATURES_COUNT);
|
||||
|
||||
BOOST_FOREACH(auto & node, config.Struct())
|
||||
{
|
||||
int creatureID = node.second["id"].Float();
|
||||
CCreature *c = creatures[creatureID];
|
||||
int numeric = node.second["id"].Float();
|
||||
|
||||
loadCreatureJson(c, node.second);
|
||||
JsonUtils::merge(h3Data[numeric], node.second);
|
||||
|
||||
// Main reference name, e.g. royalGriffin
|
||||
c->nameRef = node.first;
|
||||
registerCreature(node.first, c->idNumber);
|
||||
//JsonUtils::validate(h3Data[numeric], "vcmi:creature", node.first);
|
||||
|
||||
creatures[numeric] = loadCreature(h3Data[numeric]);
|
||||
creatures[numeric]->idNumber = CreatureID(numeric);
|
||||
|
||||
VLC->modh->identifiers.registerObject ("creature." + node.first, numeric);
|
||||
|
||||
// Alternative names, if any
|
||||
BOOST_FOREACH(const JsonNode &name, node.second["extraNames"].Vector())
|
||||
{
|
||||
registerCreature(name.String(), c->idNumber);
|
||||
}
|
||||
BOOST_FOREACH(const JsonNode &name, h3Data[numeric]["extraNames"].Vector())
|
||||
VLC->modh->identifiers.registerObject ("creature." + name.String(), numeric);
|
||||
}
|
||||
|
||||
loadAnimationInfo();
|
||||
for (size_t i=0; i < creatures.size(); i++)
|
||||
{
|
||||
if (creatures[i] == nullptr)
|
||||
logGlobal->warnStream() << "Warning: creature with id " << i << " is missing!";
|
||||
}
|
||||
|
||||
loadCrExpBon();
|
||||
}
|
||||
|
||||
void CCreatureHandler::loadCrExpBon()
|
||||
{
|
||||
if (VLC->modh->modules.STACK_EXP) //reading default stack experience bonuses
|
||||
{
|
||||
CLegacyConfigParser parser("DATA/CREXPBON.TXT");
|
||||
@ -429,76 +452,60 @@ void CCreatureHandler::load()
|
||||
maxExpPerBattle[0] = maxExpPerBattle[7];
|
||||
|
||||
}//end of Stack Experience
|
||||
|
||||
logGlobal->traceStream() << "\t\tReading config/commanders.json";
|
||||
const JsonNode config3(ResourceID("config/commanders.json"));
|
||||
|
||||
BOOST_FOREACH (auto bonus, config3["bonusPerLevel"].Vector())
|
||||
{
|
||||
commanderLevelPremy.push_back(JsonUtils::parseBonus (bonus.Vector()));
|
||||
}
|
||||
|
||||
int i = 0;
|
||||
BOOST_FOREACH (auto skill, config3["skillLevels"].Vector())
|
||||
{
|
||||
skillLevels.push_back (std::vector<ui8>());
|
||||
BOOST_FOREACH (auto skillLevel, skill["levels"].Vector())
|
||||
{
|
||||
skillLevels[i].push_back (skillLevel.Float());
|
||||
}
|
||||
++i;
|
||||
}
|
||||
|
||||
BOOST_FOREACH (auto ability, config3["abilityRequirements"].Vector())
|
||||
{
|
||||
std::pair <Bonus, std::pair <ui8, ui8> > a;
|
||||
a.first = *JsonUtils::parseBonus (ability["ability"].Vector());
|
||||
a.second.first = ability["skills"].Vector()[0].Float();
|
||||
a.second.second = ability["skills"].Vector()[1].Float();
|
||||
skillRequirements.push_back (a);
|
||||
}
|
||||
}
|
||||
|
||||
void CCreatureHandler::loadAnimationInfo()
|
||||
void CCreatureHandler::loadAnimationInfo(std::vector<JsonNode> &h3Data)
|
||||
{
|
||||
CLegacyConfigParser parser("DATA/CRANIM.TXT");
|
||||
|
||||
parser.endLine(); // header
|
||||
parser.endLine();
|
||||
|
||||
for(int dd=0; dd<creatures.size(); ++dd)
|
||||
for(int dd=0; dd<GameConstants::CREATURES_COUNT; ++dd)
|
||||
{
|
||||
while (parser.isNextEntryEmpty() && parser.endLine()) // skip empty lines
|
||||
;
|
||||
|
||||
loadUnitAnimInfo(*creatures[dd], parser);
|
||||
loadUnitAnimInfo(h3Data[dd]["graphics"], parser);
|
||||
parser.endLine();
|
||||
}
|
||||
}
|
||||
|
||||
void CCreatureHandler::loadUnitAnimInfo(CCreature & unit, CLegacyConfigParser & parser)
|
||||
void CCreatureHandler::loadUnitAnimInfo(JsonNode & graphics, CLegacyConfigParser & parser)
|
||||
{
|
||||
unit.animation.timeBetweenFidgets = parser.readNumber();
|
||||
unit.animation.walkAnimationTime = parser.readNumber();
|
||||
unit.animation.attackAnimationTime = parser.readNumber();
|
||||
unit.animation.flightAnimationDistance = parser.readNumber();
|
||||
///////////////////////
|
||||
graphics["map"].String(); //create empty string. Real value will be loaded from H3 txt's
|
||||
graphics["timeBetweenFidgets"].Float() = parser.readNumber();
|
||||
|
||||
unit.animation.upperRightMissleOffsetX = parser.readNumber();
|
||||
unit.animation.upperRightMissleOffsetY = parser.readNumber();
|
||||
unit.animation.rightMissleOffsetX = parser.readNumber();
|
||||
unit.animation.rightMissleOffsetY = parser.readNumber();
|
||||
unit.animation.lowerRightMissleOffsetX = parser.readNumber();
|
||||
unit.animation.lowerRightMissleOffsetY = parser.readNumber();
|
||||
JsonNode & animationTime = graphics["animationTime"];
|
||||
animationTime["walk"].Float() = parser.readNumber();
|
||||
animationTime["attack"].Float() = parser.readNumber();
|
||||
animationTime["flight"].Float() = parser.readNumber();
|
||||
|
||||
///////////////////////
|
||||
JsonNode & missile = graphics["missile"];
|
||||
JsonNode & offsets = missile["offset"];
|
||||
|
||||
for(int jjj=0; jjj<12; ++jjj)
|
||||
unit.animation.missleFrameAngles.push_back(parser.readNumber());
|
||||
offsets["upperX"].Float() = parser.readNumber();
|
||||
offsets["upperY"].Float() = parser.readNumber();
|
||||
offsets["middleX"].Float() = parser.readNumber();
|
||||
offsets["middleY"].Float() = parser.readNumber();
|
||||
offsets["lowerX"].Float() = parser.readNumber();
|
||||
offsets["lowerY"].Float() = parser.readNumber();
|
||||
|
||||
unit.animation.troopCountLocationOffset= parser.readNumber();
|
||||
unit.animation.attackClimaxFrame = parser.readNumber();
|
||||
for(int i=0; i<12; i++)
|
||||
{
|
||||
JsonNode entry;
|
||||
entry.Float() = parser.readNumber();
|
||||
missile["frameAngles"].Vector().push_back(entry);
|
||||
}
|
||||
|
||||
parser.endLine();
|
||||
graphics["troopCountLocationOffset"].Float() = parser.readNumber();
|
||||
|
||||
missile["attackClimaxFrame"].Float() = parser.readNumber();
|
||||
|
||||
// assume that creature is not a shooter and should not have whole missile field
|
||||
if (missile["frameAngles"].Vector()[0].Float() == 0 &&
|
||||
missile["attackClimaxFrame"].Float() == 0)
|
||||
graphics.Struct().erase("missile");
|
||||
}
|
||||
|
||||
void CCreatureHandler::load(std::string creatureID, const JsonNode & node)
|
||||
@ -509,7 +516,8 @@ void CCreatureHandler::load(std::string creatureID, const JsonNode & node)
|
||||
|
||||
creatures.push_back(creature);
|
||||
logGlobal->traceStream() << "Added creature: " << creatureID;
|
||||
registerCreature(creature->nameRef, creature->idNumber);
|
||||
|
||||
VLC->modh->identifiers.registerObject ("creature." + creature->nameRef, creature->idNumber);
|
||||
}
|
||||
|
||||
CCreature * CCreatureHandler::loadCreature(const JsonNode & node)
|
||||
@ -531,13 +539,12 @@ CCreature * CCreatureHandler::loadCreature(const JsonNode & node)
|
||||
cre->addBonus(node["speed"].Float(), Bonus::STACKS_SPEED);
|
||||
cre->addBonus(node["attack"].Float(), Bonus::PRIMARY_SKILL, PrimarySkill::ATTACK);
|
||||
cre->addBonus(node["defense"].Float(), Bonus::PRIMARY_SKILL, PrimarySkill::DEFENSE);
|
||||
const JsonNode & vec = node["damage"];
|
||||
cre->addBonus(vec["min"].Float(), Bonus::CREATURE_DAMAGE, 1);
|
||||
cre->addBonus(vec["max"].Float(), Bonus::CREATURE_DAMAGE, 2);
|
||||
cre->addBonus(node["damage"]["min"].Float(), Bonus::CREATURE_DAMAGE, 1);
|
||||
cre->addBonus(node["damage"]["max"].Float(), Bonus::CREATURE_DAMAGE, 2);
|
||||
|
||||
auto & amounts = node ["advMapAmount"];
|
||||
cre->ammMin = amounts["min"].Float();
|
||||
cre->ammMax = amounts["max"].Float();
|
||||
cre->ammMin = node["advMapAmount"]["min"].Float();
|
||||
cre->ammMax = node["advMapAmount"]["max"].Float();
|
||||
assert(cre->ammMin <= cre->ammMax);
|
||||
|
||||
if (!node["shots"].isNull())
|
||||
cre->addBonus(node["shots"].Float(), Bonus::SHOTS);
|
||||
@ -547,13 +554,16 @@ CCreature * CCreatureHandler::loadCreature(const JsonNode & node)
|
||||
|
||||
cre->doubleWide = node["doubleWide"].Bool();
|
||||
|
||||
//graphics
|
||||
loadStackExperience(cre, node["stackExperience"]);
|
||||
loadJsonAnimation(cre, node["graphics"]);
|
||||
loadCreatureJson(cre, node);
|
||||
return cre;
|
||||
}
|
||||
|
||||
const JsonNode & graphics = node["graphics"];
|
||||
void CCreatureHandler::loadJsonAnimation(CCreature * cre, const JsonNode & graphics)
|
||||
{
|
||||
cre->animation.timeBetweenFidgets = graphics["timeBetweenFidgets"].Float();
|
||||
cre->animation.troopCountLocationOffset = graphics["troopCountLocationOffset"].Float();
|
||||
cre->animation.attackClimaxFrame = graphics["attackClimaxFrame"].Float();
|
||||
|
||||
const JsonNode & animationTime = graphics["animationTime"];
|
||||
cre->animation.walkAnimationTime = animationTime["walk"].Float();
|
||||
@ -569,13 +579,11 @@ CCreature * CCreatureHandler::loadCreature(const JsonNode & node)
|
||||
cre->animation.lowerRightMissleOffsetX = offsets["lowerX"].Float();
|
||||
cre->animation.lowerRightMissleOffsetY = offsets["lowerY"].Float();
|
||||
|
||||
cre->animation.missleFrameAngles = missile["frameAngles"].convertTo<std::vector<double>>();
|
||||
cre->animation.attackClimaxFrame = missile["attackClimaxFrame"].Float();
|
||||
cre->animation.missleFrameAngles = missile["frameAngles"].convertTo<std::vector<double> >();
|
||||
|
||||
cre->advMapDef = graphics["map"].String();
|
||||
cre->iconIndex = graphics["iconIndex"].Float();
|
||||
|
||||
loadCreatureJson(cre, node);
|
||||
return cre;
|
||||
}
|
||||
|
||||
void CCreatureHandler::loadCreatureJson(CCreature * creature, const JsonNode & config)
|
||||
@ -583,21 +591,32 @@ void CCreatureHandler::loadCreatureJson(CCreature * creature, const JsonNode & c
|
||||
creature->level = config["level"].Float();
|
||||
creature->animDefName = config["graphics"]["animation"].String();
|
||||
|
||||
BOOST_FOREACH(const JsonNode &ability, config["ability_remove"].Vector())
|
||||
if (config["abilities"].getType() == JsonNode::DATA_STRUCT)
|
||||
{
|
||||
RemoveAbility(creature, ability);
|
||||
}
|
||||
|
||||
BOOST_FOREACH(const JsonNode &ability, config["abilities"].Vector())
|
||||
{
|
||||
if (ability.getType() == JsonNode::DATA_VECTOR)
|
||||
AddAbility(creature, ability.Vector()); // used only for H3 creatures
|
||||
else
|
||||
BOOST_FOREACH(auto &ability, config["abilities"].Struct())
|
||||
{
|
||||
auto b = JsonUtils::parseBonus(ability);
|
||||
b->source = Bonus::CREATURE_ABILITY;
|
||||
b->duration = Bonus::PERMANENT;
|
||||
creature->addNewBonus(b);
|
||||
if (!ability.second.isNull())
|
||||
{
|
||||
auto b = JsonUtils::parseBonus(ability.second);
|
||||
b->source = Bonus::CREATURE_ABILITY;
|
||||
b->duration = Bonus::PERMANENT;
|
||||
creature->addNewBonus(b);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
BOOST_FOREACH(const JsonNode &ability, config["abilities"].Vector())
|
||||
{
|
||||
if (ability.getType() == JsonNode::DATA_VECTOR)
|
||||
AddAbility(creature, ability.Vector()); // used only for H3 creatures
|
||||
else
|
||||
{
|
||||
auto b = JsonUtils::parseBonus(ability);
|
||||
b->source = Bonus::CREATURE_ABILITY;
|
||||
b->duration = Bonus::PERMANENT;
|
||||
creature->addNewBonus(b);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -618,9 +637,8 @@ void CCreatureHandler::loadCreatureJson(CCreature * creature, const JsonNode & c
|
||||
doubledCreatures.insert(creature->idNumber);
|
||||
|
||||
creature->animation.projectileImageName = config["graphics"]["missile"]["projectile"].String();
|
||||
//creature->animation.projectileSpin = config["graphics"]["missile"]["spinning"].Bool();
|
||||
|
||||
creature->special = config["special"].Bool();
|
||||
creature->special = config["special"].Bool() || config["disabled"].Bool();
|
||||
|
||||
const JsonNode & sounds = config["sound"];
|
||||
|
||||
@ -631,8 +649,6 @@ void CCreatureHandler::loadCreatureJson(CCreature * creature, const JsonNode & c
|
||||
GET_SOUND_VALUE(move);
|
||||
GET_SOUND_VALUE(shoot);
|
||||
GET_SOUND_VALUE(wince);
|
||||
GET_SOUND_VALUE(ext1);
|
||||
GET_SOUND_VALUE(ext2);
|
||||
GET_SOUND_VALUE(startMoving);
|
||||
GET_SOUND_VALUE(endMoving);
|
||||
#undef GET_SOUND_VALUE
|
||||
|
@ -79,14 +79,12 @@ public:
|
||||
std::string move;
|
||||
std::string shoot; // range attack
|
||||
std::string wince; // attacked but did not die
|
||||
std::string ext1; // creature specific extension
|
||||
std::string ext2; // creature specific extension
|
||||
std::string startMoving; // usually same as ext1
|
||||
std::string endMoving; // usually same as ext2
|
||||
std::string startMoving;
|
||||
std::string endMoving;
|
||||
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{
|
||||
h & attack & defend & killed & move & shoot & wince & ext1 & ext2 & startMoving & endMoving;
|
||||
h & attack & defend & killed & move & shoot & wince & startMoving & endMoving;
|
||||
}
|
||||
} sounds;
|
||||
|
||||
@ -140,6 +138,7 @@ private:
|
||||
CBonusSystemNode allCreatures;
|
||||
CBonusSystemNode creaturesOfLevel[GameConstants::CREATURES_PER_TOWN + 1];//index 0 is used for creatures of unknown tier or outside <1-7> range
|
||||
|
||||
void loadJsonAnimation(CCreature * creature, const JsonNode & graphics);
|
||||
void loadStackExperience(CCreature * creature, const JsonNode &input);
|
||||
void loadCreatureJson(CCreature * creature, const JsonNode & config);
|
||||
public:
|
||||
@ -159,9 +158,10 @@ public:
|
||||
/// loading functions
|
||||
|
||||
/// adding abilities from ZCRTRAIT.TXT
|
||||
void loadBonuses(CCreature & creature, std::string bonuses);
|
||||
void loadBonuses(JsonNode & creature, std::string bonuses);
|
||||
/// load all creatures from H3 files
|
||||
void load();
|
||||
void loadCommanders();
|
||||
/// load creature from json structure
|
||||
void load(std::string creatureID, const JsonNode & node);
|
||||
/// load one creature from json config
|
||||
@ -169,9 +169,11 @@ public:
|
||||
/// generates tier-specific bonus tree entries
|
||||
void buildBonusTreeForTiers();
|
||||
/// read cranim.txt file from H3
|
||||
void loadAnimationInfo();
|
||||
void loadAnimationInfo(std::vector<JsonNode> & h3Data);
|
||||
/// read one line from cranim.txt
|
||||
void loadUnitAnimInfo(CCreature & unit, CLegacyConfigParser &parser);
|
||||
void loadUnitAnimInfo(JsonNode & unit, CLegacyConfigParser &parser);
|
||||
/// load all creatures from H3 files
|
||||
void loadCrExpBon();
|
||||
/// parse crexpbon.txt file from H3
|
||||
void loadStackExp(Bonus & b, BonusList & bl, CLegacyConfigParser &parser);
|
||||
/// help function for parsing CREXPBON.txt
|
||||
|
@ -123,6 +123,7 @@ void CHeroClassHandler::load()
|
||||
JsonNode & classData = h3Data[numeric];
|
||||
JsonUtils::merge(classData, node.second);
|
||||
|
||||
//JsonUtils::validate(classData, "vcmi:heroClass", node.first);
|
||||
heroClasses[numeric] = loadClass(classData);
|
||||
heroClasses[numeric]->id = numeric;
|
||||
|
||||
@ -457,6 +458,8 @@ void CHeroHandler::loadHeroes()
|
||||
{
|
||||
ui32 identifier = entry.second["id"].Float();
|
||||
JsonUtils::merge(h3Data[identifier], entry.second);
|
||||
|
||||
//JsonUtils::validate(h3Data[identifier], "vcmi:hero", entry.first);
|
||||
CHero * hero = loadHero(h3Data[identifier]);
|
||||
hero->ID = identifier;
|
||||
heroes[identifier] = hero;
|
||||
|
@ -70,6 +70,8 @@ JsonNode readBuilding(CLegacyConfigParser & parser)
|
||||
BOOST_FOREACH(const std::string & resID, GameConstants::RESOURCE_NAMES)
|
||||
cost[resID].Float() = parser.readNumber();
|
||||
|
||||
cost.Struct().erase("mithril"); // erase mithril to avoid confusing validator
|
||||
|
||||
parser.endLine();
|
||||
return ret;
|
||||
}
|
||||
@ -588,6 +590,7 @@ void CTownHandler::load()
|
||||
}
|
||||
BOOST_FOREACH(auto & entry, buildingsConf.Struct())
|
||||
{
|
||||
//JsonUtils::validate(entry.second, "vcmi:faction", entry.first);
|
||||
load(entry.first, entry.second);
|
||||
}
|
||||
}
|
||||
|
@ -66,7 +66,8 @@ const bmap<std::string, TLimiterPtr> bonusLimiterMap = boost::assign::map_list_o
|
||||
const bmap<std::string, TPropagatorPtr> bonusPropagatorMap = boost::assign::map_list_of
|
||||
("BATTLE_WIDE", make_shared<CPropagatorNodeType>(CBonusSystemNode::BATTLE))
|
||||
("VISITED_TOWN_AND_VISITOR", make_shared<CPropagatorNodeType>(CBonusSystemNode::TOWN_AND_VISITOR))
|
||||
("PLAYER_PROPAGATOR", make_shared<CPropagatorNodeType>(CBonusSystemNode::PLAYER));
|
||||
("PLAYER_PROPAGATOR", make_shared<CPropagatorNodeType>(CBonusSystemNode::PLAYER))
|
||||
("HERO", make_shared<CPropagatorNodeType>(CBonusSystemNode::HERO));
|
||||
|
||||
|
||||
#define BONUS_LOG_LINE(x) logBonus->traceStream() << x
|
||||
|
@ -755,18 +755,23 @@ std::string JsonValidator::validateEnum(const JsonNode &node, const JsonVector &
|
||||
|
||||
std::string JsonValidator::validatesSchemaList(const JsonNode &node, const JsonNode &schemas, std::string errorMsg, std::function<bool(size_t)> isValid)
|
||||
{
|
||||
std::string errors;
|
||||
if (!schemas.isNull())
|
||||
{
|
||||
std::string errors = "<tested schemas>\n";
|
||||
size_t result = 0;
|
||||
|
||||
BOOST_FOREACH(auto & schema, schemas.Vector())
|
||||
{
|
||||
std::string error = validateNode(node, schema);
|
||||
if (error.empty())
|
||||
{
|
||||
result++;
|
||||
}
|
||||
else
|
||||
errors += fail(error);
|
||||
{
|
||||
errors += error;
|
||||
errors += "<end of schema>\n";
|
||||
}
|
||||
}
|
||||
if (isValid(result))
|
||||
{
|
||||
@ -794,7 +799,7 @@ std::string JsonValidator::validateNodeType(const JsonNode &node, const JsonNode
|
||||
});
|
||||
|
||||
// data must be valid against one and only one schema
|
||||
errors += validatesSchemaList(node, schema["oneOf"], "Failed to pass only one and only one schema", [&](size_t count)
|
||||
errors += validatesSchemaList(node, schema["oneOf"], "Failed to pass one and only one schema", [&](size_t count)
|
||||
{
|
||||
return count == 1;
|
||||
});
|
||||
@ -805,13 +810,6 @@ std::string JsonValidator::validateNodeType(const JsonNode &node, const JsonNode
|
||||
if (validateNode(node, schema["not"]).empty())
|
||||
errors += fail("Successful validation against negative check");
|
||||
}
|
||||
// basic schema check
|
||||
if (!schema["type"].isNull())
|
||||
{
|
||||
JsonNode::JsonType type = stringToType.find(schema["type"].String())->second;
|
||||
if(type != node.getType())
|
||||
errors += fail("Type mismatch!");
|
||||
}
|
||||
return errors;
|
||||
}
|
||||
|
||||
@ -822,6 +820,9 @@ std::string JsonValidator::validateNode(const JsonNode &node, const JsonNode &sc
|
||||
|
||||
assert(!schema.isNull()); // can this error be triggered?
|
||||
|
||||
if (node.isNull())
|
||||
return ""; // node not present. consider to be "valid"
|
||||
|
||||
if (!schema["$ref"].isNull())
|
||||
{
|
||||
std::string URI = schema["$ref"].String();
|
||||
@ -833,6 +834,14 @@ std::string JsonValidator::validateNode(const JsonNode &node, const JsonNode &sc
|
||||
return validateRoot(node, URI);
|
||||
}
|
||||
|
||||
// basic schema check
|
||||
if (!schema["type"].isNull())
|
||||
{
|
||||
JsonNode::JsonType type = stringToType.find(schema["type"].String())->second;
|
||||
if(type != node.getType())
|
||||
return errors + fail("Type mismatch!"); // different type. Any other checks are useless
|
||||
}
|
||||
|
||||
errors += validateNodeType(node, schema);
|
||||
|
||||
// enumeration - data must be equeal to one of items in list
|
||||
@ -876,10 +885,10 @@ std::string JsonValidator::validateVectorItem(const JsonVector items, const Json
|
||||
return validateNode(items[index], additional);
|
||||
|
||||
// or, additionalItems field can be bool which indicates if such items are allowed
|
||||
// default = false, so case if additionalItems is not present will be handled as well
|
||||
if (!additional.Bool())
|
||||
if (!additional.isNull() && additional.Bool() == false) // present and set to false - error
|
||||
return fail("Unknown entry found");
|
||||
|
||||
// by default - additional items are allowed
|
||||
return "";
|
||||
}
|
||||
|
||||
@ -930,9 +939,11 @@ std::string JsonValidator::validateStructItem(const JsonNode &node, const JsonNo
|
||||
if (additional.getType() == JsonNode::DATA_STRUCT)
|
||||
return validateNode(node, additional);
|
||||
|
||||
if (!additional.Bool())
|
||||
// or, additionalItems field can be bool which indicates if such items are allowed
|
||||
if (!additional.isNull() && additional.Bool() == false) // present and set to false - error
|
||||
return fail("Unknown entry found: " + nodeName);
|
||||
|
||||
// by default - additional items are allowed
|
||||
return "";
|
||||
}
|
||||
|
||||
@ -947,7 +958,7 @@ std::string JsonValidator::validateStruct(const JsonNode &node, const JsonNode &
|
||||
|
||||
BOOST_FOREACH(auto & required, schema["required"].Vector())
|
||||
{
|
||||
if (!vstd::contains(map, required.String()))
|
||||
if (node[required.String()].isNull())
|
||||
errors += fail("Required entry " + required.String() + " is missing");
|
||||
}
|
||||
|
||||
|
@ -174,9 +174,6 @@ void CResourceLoader::addLoader(std::string mountPoint, shared_ptr<ISimpleResour
|
||||
ResourceID ident(mountPoint, entry.first.getName(), entry.first.getType());
|
||||
ResourceLocator locator(loader.get(), entry.second);
|
||||
|
||||
if (ident.getType() == EResType::OTHER)
|
||||
logGlobal->warnStream() << "Warning: unknown file type: " << entry.second;
|
||||
|
||||
resources[ident].push_back(locator);
|
||||
}
|
||||
}
|
||||
|
@ -266,9 +266,9 @@ CLogFormatter::CLogFormatter() : pattern("%m")
|
||||
|
||||
}
|
||||
|
||||
CLogFormatter::CLogFormatter(const std::string & pattern) : pattern(pattern)
|
||||
CLogFormatter::CLogFormatter(const std::string & pattern)
|
||||
{
|
||||
|
||||
setPattern(pattern);
|
||||
}
|
||||
|
||||
std::string CLogFormatter::format(const LogRecord & record) const
|
||||
@ -370,7 +370,10 @@ EConsoleTextColor::EConsoleTextColor CColorMapping::getColorFor(const CLoggerDom
|
||||
|
||||
CLogConsoleTarget::CLogConsoleTarget(CConsoleHandler * console) : console(console), threshold(ELogLevel::INFO), coloredOutputEnabled(true)
|
||||
{
|
||||
formatter.setPattern("%l %n [%t] - %m");
|
||||
// more verbose version:
|
||||
//formatter.setPattern("%l %n [%t] - %m");
|
||||
|
||||
formatter.setPattern("%m");
|
||||
}
|
||||
|
||||
void CLogConsoleTarget::write(const LogRecord & record)
|
||||
|
Loading…
Reference in New Issue
Block a user