mirror of
https://github.com/vcmi/vcmi.git
synced 2024-12-20 20:23:03 +02:00
02b5a5e830
Addresses several related problems: * Propagation / unpropagation of duplicate bonuses is inconsistent, causing bugs * Duplicate bonuses never stack, which is not always intended behaviour (e.g. multiple copies of resource generating artifacts) * Different bonuses always stack, which is not always intended behaviour (e.g. Angel + Archangel morale bonuses) This is addressed as follows: * Duplicate bonuses are never eliminated during propagation/inheritance. * Unpropagation eliminates only a single copy of duplicated bonus * Bonus receives a new field stacking that determines stacking behaviour: * * empty string = no stacking with duplicates (default) * * "ALWAYS" = stacks with duplicates & everything else * * some other value = no stacking with bonuses with same stacking value Also Morale/Luck window now hides non-stacking bonuses.
384 lines
6.0 KiB
JSON
384 lines
6.0 KiB
JSON
{
|
|
"pikeman" :
|
|
{
|
|
"index": 0,
|
|
"level": 1,
|
|
"faction": "castle",
|
|
"upgrades": ["halberdier"],
|
|
"abilities":
|
|
{
|
|
"cavalryChargeImmunity" :
|
|
{
|
|
"type" : "CHARGE_IMMUNITY"
|
|
}
|
|
},
|
|
"graphics" :
|
|
{
|
|
"animation": "CPKMAN.DEF"
|
|
},
|
|
"sound" :
|
|
{
|
|
"attack": "PIKEATTK.wav",
|
|
"defend": "PIKEDFND.wav",
|
|
"killed": "PIKEKILL.wav",
|
|
"move": "PIKEMOVE.wav",
|
|
"wince": "PIKEWNCE.wav"
|
|
}
|
|
},
|
|
"halberdier" :
|
|
{
|
|
"index": 1,
|
|
"level": 1,
|
|
"faction": "castle",
|
|
"abilities":
|
|
{
|
|
"cavalryChargeImmunity" :
|
|
{
|
|
"type" : "CHARGE_IMMUNITY"
|
|
}
|
|
},
|
|
"graphics" :
|
|
{
|
|
"animation": "CHALBD.DEF"
|
|
},
|
|
"sound" :
|
|
{
|
|
"attack": "HALBATTK.wav",
|
|
"defend": "HALBDFND.wav",
|
|
"killed": "HALBKILL.wav",
|
|
"move": "HALBMOVE.wav",
|
|
"wince": "HALBWNCE.wav"
|
|
}
|
|
},
|
|
"archer" :
|
|
{
|
|
"index": 2,
|
|
"level": 2,
|
|
"extraNames": [ "lightCrossbowman" ],
|
|
"faction": "castle",
|
|
"upgrades": ["marksman"],
|
|
"graphics" :
|
|
{
|
|
"animation": "CLCBOW.DEF",
|
|
"missile" :
|
|
{
|
|
"projectile": "PLCBOWX.DEF"
|
|
}
|
|
},
|
|
"sound" :
|
|
{
|
|
"attack": "LCRSATTK.wav",
|
|
"defend": "LCRSDFND.wav",
|
|
"killed": "LCRSKILL.wav",
|
|
"move": "LCRSMOVE.wav",
|
|
"shoot": "LCRSSHOT.wav",
|
|
"wince": "LCRSWNCE.wav"
|
|
}
|
|
},
|
|
"marksman" :
|
|
{
|
|
"index": 3,
|
|
"level": 2,
|
|
"faction": "castle",
|
|
"abilities": {
|
|
"extraAttack" :
|
|
{
|
|
"type": "ADDITIONAL_ATTACK",
|
|
"val" : 1,
|
|
"effectRange": "ONLY_DISTANCE_FIGHT"
|
|
}
|
|
},
|
|
"graphics" :
|
|
{
|
|
"animation": "CHCBOW.DEF",
|
|
"missile" :
|
|
{
|
|
"projectile": "PLCBOWX.DEF"
|
|
}
|
|
},
|
|
"sound" :
|
|
{
|
|
"attack": "HCRSATTK.wav",
|
|
"defend": "HCRSDFND.wav",
|
|
"killed": "HCRSKILL.wav",
|
|
"move": "HCRSMOVE.wav",
|
|
"shoot": "HCRSSHOT.wav",
|
|
"wince": "HCRSWNCE.wav"
|
|
}
|
|
},
|
|
"griffin" :
|
|
{
|
|
"index": 4,
|
|
"level": 3,
|
|
"faction": "castle",
|
|
"abilities":
|
|
{
|
|
"extraRetaliation" :
|
|
{
|
|
"type" : "ADDITIONAL_RETALIATION",
|
|
"val" : 1
|
|
}
|
|
},
|
|
"upgrades": ["royalGriffin"],
|
|
"hasDoubleWeek": true,
|
|
"graphics" :
|
|
{
|
|
"animation": "CGRIFF.DEF"
|
|
},
|
|
"sound" :
|
|
{
|
|
"attack": "GRIFATTK.wav",
|
|
"defend": "GRIFDFND.wav",
|
|
"killed": "GRIFKILL.wav",
|
|
"move": "GRIFMOVE.wav",
|
|
"wince": "GRIFWNCE.wav"
|
|
}
|
|
},
|
|
"royalGriffin" :
|
|
{
|
|
"index": 5,
|
|
"level": 3,
|
|
"faction": "castle",
|
|
"abilities":
|
|
{
|
|
"unlimitedRetaliation" :
|
|
{
|
|
"type" : "UNLIMITED_RETALIATIONS"
|
|
}
|
|
},
|
|
"graphics" :
|
|
{
|
|
"animation": "CRGRIF.DEF"
|
|
},
|
|
"sound" :
|
|
{
|
|
"attack": "RGRFATTK.wav",
|
|
"defend": "RGRFDFND.wav",
|
|
"killed": "RGRFKILL.wav",
|
|
"move": "RGRFMOVE.wav",
|
|
"wince": "RGRFWNCE.wav"
|
|
}
|
|
},
|
|
"swordsman" :
|
|
{
|
|
"index": 6,
|
|
"level": 4,
|
|
"faction": "castle",
|
|
"upgrades": ["crusader"],
|
|
"graphics" :
|
|
{
|
|
"animation": "CSWORD.DEF"
|
|
},
|
|
"sound" :
|
|
{
|
|
"attack": "SWRDATTK.wav",
|
|
"defend": "SWRDDFND.wav",
|
|
"killed": "SWRDKILL.wav",
|
|
"move": "SWRDMOVE.wav",
|
|
"wince": "SWRDWNCE.wav"
|
|
}
|
|
},
|
|
"crusader" :
|
|
{
|
|
"index": 7,
|
|
"level": 4,
|
|
"faction": "castle",
|
|
"abilities":
|
|
{
|
|
"extraAttack" :
|
|
{
|
|
"type" : "ADDITIONAL_ATTACK",
|
|
"val" : 1
|
|
}
|
|
},
|
|
"graphics" :
|
|
{
|
|
"animation": "CCRUSD.DEF"
|
|
},
|
|
"sound" :
|
|
{
|
|
"attack": "CRUSATTK.wav",
|
|
"defend": "CRUSDFND.wav",
|
|
"killed": "CRUSKILL.wav",
|
|
"move": "CRUSMOVE.wav",
|
|
"wince": "CRUSWNCE.wav"
|
|
}
|
|
},
|
|
"monk" :
|
|
{
|
|
"index": 8,
|
|
"level": 5,
|
|
"faction": "castle",
|
|
"upgrades": ["zealot"],
|
|
"graphics" :
|
|
{
|
|
"animation": "CMONKK.DEF",
|
|
"missile" :
|
|
{
|
|
"projectile": "CPRZEAX.DEF"
|
|
}
|
|
},
|
|
"sound" :
|
|
{
|
|
"attack": "MONKATTK.wav",
|
|
"defend": "MONKDFND.wav",
|
|
"killed": "MONKKILL.wav",
|
|
"move": "MONKMOVE.wav",
|
|
"shoot": "MONKSHOT.wav",
|
|
"wince": "MONKWNCE.wav"
|
|
}
|
|
},
|
|
"zealot" :
|
|
{
|
|
"index": 9,
|
|
"level": 5,
|
|
"faction": "castle",
|
|
"graphics" :
|
|
{
|
|
"animation": "CZEALT.DEF",
|
|
"missile" :
|
|
{
|
|
"projectile": "CPRZEAX.DEF"
|
|
}
|
|
},
|
|
"sound" :
|
|
{
|
|
"attack": "ZELTATTK.wav",
|
|
"defend": "ZELTDFND.wav",
|
|
"killed": "ZELTKILL.wav",
|
|
"move": "ZELTMOVE.wav",
|
|
"shoot": "ZELTSHOT.wav",
|
|
"wince": "ZELTWNCE.wav"
|
|
}
|
|
},
|
|
"cavalier" :
|
|
{
|
|
"index": 10,
|
|
"level": 6,
|
|
"faction": "castle",
|
|
"upgrades": ["champion"],
|
|
"graphics" :
|
|
{
|
|
"animation": "CCAVLR.DEF"
|
|
},
|
|
"sound" :
|
|
{
|
|
"attack": "CAVAATTK.wav",
|
|
"defend": "CAVADFND.wav",
|
|
"killed": "CAVAKILL.wav",
|
|
"move": "CAVAMOVE.wav",
|
|
"wince": "CAVAWNCE.wav"
|
|
}
|
|
},
|
|
"champion" :
|
|
{
|
|
"index": 11,
|
|
"level": 6,
|
|
"faction": "castle",
|
|
"graphics" :
|
|
{
|
|
"animation": "CCHAMP.DEF"
|
|
},
|
|
"sound" :
|
|
{
|
|
"attack": "CHMPATTK.wav",
|
|
"defend": "CHMPDFND.wav",
|
|
"killed": "CHMPKILL.wav",
|
|
"move": "CHMPMOVE.wav",
|
|
"wince": "CHMPWNCE.wav"
|
|
}
|
|
},
|
|
"angel" :
|
|
{
|
|
"index": 12,
|
|
"level": 7,
|
|
"faction": "castle",
|
|
"abilities":
|
|
{
|
|
"hateDevils" :
|
|
{
|
|
"type" : "HATE",
|
|
"subtype" : "creature.devil",
|
|
"val" : 50
|
|
},
|
|
"hateArchDevils" :
|
|
{
|
|
"type" : "HATE",
|
|
"subtype" : "creature.archDevil",
|
|
"val" : 50
|
|
},
|
|
"const_raises_morale" :
|
|
{
|
|
"stacking" : "Angels"
|
|
}
|
|
},
|
|
"upgrades": ["archangel"],
|
|
"graphics" :
|
|
{
|
|
"animation": "CANGEL.DEF"
|
|
},
|
|
"sound" :
|
|
{
|
|
"attack": "ANGLATTK.wav",
|
|
"defend": "ANGLDFND.wav",
|
|
"killed": "ANGLKILL.wav",
|
|
"move": "ANGLMOVE.wav",
|
|
"wince": "ANGLWNCE.wav"
|
|
}
|
|
},
|
|
"archangel" :
|
|
{
|
|
"index": 13,
|
|
"level": 7,
|
|
"faction": "castle",
|
|
"abilities":
|
|
{
|
|
"resurrection100hp" :
|
|
{
|
|
"type" : "SPECIFIC_SPELL_POWER",
|
|
"subtype" : "spell.resurrection",
|
|
"val" : 100
|
|
},
|
|
"resurrects" :
|
|
{
|
|
"type" : "SPELLCASTER",
|
|
"subtype" : "spell.resurrection",
|
|
"val" : 3
|
|
},
|
|
"spellpoints" :
|
|
{
|
|
"type" : "CASTS",
|
|
"val" : 1
|
|
},
|
|
"hateDevils" :
|
|
{
|
|
"type" : "HATE",
|
|
"subtype" : "creature.devil",
|
|
"val" : 50
|
|
},
|
|
"hateArchDevils" :
|
|
{
|
|
"type" : "HATE",
|
|
"subtype" : "creature.archDevil",
|
|
"val" : 50
|
|
},
|
|
"const_raises_morale" :
|
|
{
|
|
"stacking" : "Angels"
|
|
}
|
|
},
|
|
"graphics" :
|
|
{
|
|
"animation": "CRANGL.DEF"
|
|
},
|
|
"sound" :
|
|
{
|
|
"attack": "AAGLATTK.wav",
|
|
"defend": "AAGLDFND.wav",
|
|
"killed": "AAGLKILL.wav",
|
|
"move": "AAGLMOVE.wav",
|
|
"wince": "AAGLWNCE.wav"
|
|
}
|
|
}
|
|
}
|