2.0.3 update (#260)

* Mage atree changes

* Bump version to 2.0.3.1

just tree for now

* Warrior tree

🙏

* Shaman tree

WIP some things are too jank to stay

* Fixes to bamboozle behavior

also echo was -60% instead of -65% in the file??? wtf

* Shurikens damage boost by echo

meme

* Fix description text in echo, update old version atree file

* Fix shaman tree

thanks spegg!

* Spegg atree changes

assassin tree
fixed many of my shaman mistakes
and other changes we missed over the months somehow?

* Updated archer ability tree

Thanks @mr_me! All credit to them.

* Fixes to spegg's fixes

implement beast lore

* Change how Chant of the Lunatic is calculated

coursing restraints ingame is 15% damage bonus

* Updated ingredients manually

thanks @watermelon (snownlite)!

* Forgor to bump ing db version

* Fix ingredient display jank

* 2.0.3 items (#259)

* API update

also add new IDs to a bunch of places... tech debt whyyy

* Forgot to update ingreds...

* Change heal power ID name to stack with tree abils, fix multi totem effect on totemic shatter

and req for mana traps

* Forgot to bump item db version

* Implement major IDs

not implemented: Gentle Glow, and Forest's Blessing damage increase (since I don't know the exact numbers)

and radiance boost is not implemented (radiance is currently handled way too jank)

might wait for buffs rework to handle radiance.

* patch item searcher

TODO: make this not disgusting... build_encode_decode file has gotten too big

---------

Co-authored-by: hppeng <hppeng>
Co-authored-by: RawFish69 <108964215+RawFish69@users.noreply.github.com>
This commit is contained in:
hppeng-wynn 2023-07-14 18:34:30 -07:00 committed by GitHub
parent 1a5ad19ef5
commit 479af33a81
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
42 changed files with 47215 additions and 41980 deletions

60433
clean.json

File diff suppressed because it is too large Load diff

File diff suppressed because one or more lines are too long

1
data/2.0.1.1/majid.json Normal file
View file

@ -0,0 +1 @@
{"MAGNET":{"displayName":"Magnet","description":"Pulls items within an 8 block radius towards you","abilities":[]},"PLAGUE":{"displayName":"Plague","description":"Poisoned mobs spread their poison to nearby mobs","abilities":[]},"HAWKEYE":{"displayName":"Hawkeye","description":"Condense Arrow Storm into a tight beam. Arrows deal ✤10%, ✦1%, and ❋1%","abilities":[{"class":"Archer","base_abil":7,"effects":[{"type":"add_spell_prop","base_spell":1,"target_part":"Single Stream","behavior":"overwrite","hits":{"Single Arrow":5}},{"type":"add_spell_prop","base_spell":1,"target_part":"Single Arrow","behavior":"overwrite","multipliers":[10,0,1,0,0,1]},{"type":"add_spell_prop","base_spell":1,"target_part":"Total Damage","behavior":"modify","hits":{"Single Stream":4}}]}]},"GREED":{"displayName":"Greed","description":"Picking up emeralds heals you and nearby players for 15% max health","abilities":[]},"CAVALRYMAN":{"displayName":"Cavalryman","description":"You may cast spells and attack with a 70% damage penalty while on a horse","abilities":[]},"GUARDIAN":{"displayName":"Guardian","description":"20% of the damage taken by nearby allies is redirected to you","abilities":[]},"HERO":{"displayName":"Saviours Sacrifice","description":"While under 50% maximum health, nearby allies gain 30% bonus damage and defense","abilities":[]},"ALTRUISM":{"displayName":"Heart of the Pack","description":"Nearby players gain 35% of the health you naturally regenerate","abilities":[]},"ARCANES":{"displayName":"Transcendence","description":"30% chance for spells to cost no mana when casted","abilities":[]},"ENTROPY":{"displayName":"Entropy","description":"Meteor falls three times faster","abilities":[]},"ROVINGASSASSIN":{"displayName":"Roving Assassin","description":"Vanish no longer drains mana while invisible","abilities":[]},"MADNESS":{"displayName":"Madness","description":"Cast a random ability every 3 seconds","abilities":[]},"LIGHTWEIGHT":{"displayName":"Lightweight","description":"You no longer take fall damage","abilities":[]},"SORCERY":{"displayName":"Sorcery","description":"30% chance for spells and attacks to cast a second time at no additional cost","abilities":[]},"TAUNT":{"displayName":"Taunt","description":"Mobs within 12 blocks target you upon casting War Scream","abilities":[]},"RALLY":{"displayName":"Rally","description":"Charge heals you by 10% and nearby allies by 15% on impact, but becomes harmless","abilities":[{"class":"Warrior","base_abil":4,"effects":[{"type":"add_spell_prop","base_spell":2,"display":"Rally Self Heal","target_part":"Rally Self Heal","power":0.1},{"type":"add_spell_prop","base_spell":2,"target_part":"Rally Ally Heal","power":0.15},{"type":"raw_stat","bonuses":[{"type":"stat","name":"damMult.Rally:2.Flying Kick","value":-100},{"type":"stat","name":"damMult.Rally:2.Collide","value":-100},{"type":"stat","name":"damMult.Rally:2.Heavy Impact","value":-100},{"type":"stat","name":"damMult.Rally:2.Flyby Jab","value":-100}]}]}]},"CHERRY_BOMBS":{"displayName":"Cherry Bombs","description":"Your Smoke Bombs explode instantly, and increase their Neutral Damage by +90%","abilities":[{"class":"Assassin","base_abil":7,"effects":[{"type":"add_spell_prop","base_spell":4,"target_part":"Per Tick","multipliers":[90,0,0,0,0,0]},{"type":"add_spell_prop","base_spell":4,"target_part":"Per Bomb","hits":{"Per Tick":-9}}]}]},"FREERUNNER":{"displayName":"Freerunner","description":"Double your sprint speed when your sprint bar is under 30%","abilities":[]},"PEACEFUL_EFFIGY":{"displayName":"Peaceful Effigy","description":"Your totem will last twice as long","abilities":[]},"FURIOUS_EFFIGY":{"displayName":"Furious Effigy","description":"Totem effects are twice as fast, but duration is halved","abilities":[{"class":"Shaman","base_abil":0,"properties":{"rate":-0.2,"totem_mul":2.5},"effects":[]}]},"FLASHFREEZE":{"displayName":"Flashfreeze","description":"Ice Snake is instant but has a reduced range","abilities":[]},"GRAVITYWELL":{"displayName":"Gravity Well","description":"Meteor has increased blast radius and pulls enemies instead","abilities":[]},"DESC_SNOWYSTEPS":{"displayName":"Snowy Steps","description":"Leaves a trail of snow behind you","abilities":[]},"GEOCENTRISM":{"displayName":"Geocentrism","description":"Aura radiates from you instead of your totem and can be cast anytime","abilities":[]},"DESC_FESTIVESPIRIT":{"displayName":"Festive Spirits","description":"Plays wintery tunes","abilities":[]}}

File diff suppressed because one or more lines are too long

1
data/2.0.1.2/majid.json Normal file
View file

@ -0,0 +1 @@
{"MAGNET":{"displayName":"Magnet","description":"Pulls items within an 8 block radius towards you","abilities":[]},"PLAGUE":{"displayName":"Plague","description":"Poisoned mobs spread their poison to nearby mobs","abilities":[]},"HAWKEYE":{"displayName":"Hawkeye","description":"Condense Arrow Storm into a tight beam. Arrows deal ✤10%, ✦1%, and ❋1%","abilities":[{"class":"Archer","base_abil":7,"effects":[{"type":"add_spell_prop","base_spell":1,"target_part":"Single Stream","behavior":"overwrite","hits":{"Single Arrow":5}},{"type":"add_spell_prop","base_spell":1,"target_part":"Single Arrow","behavior":"overwrite","multipliers":[10,0,1,0,0,1]},{"type":"add_spell_prop","base_spell":1,"target_part":"Total Damage","behavior":"modify","hits":{"Single Stream":4}}]}]},"GREED":{"displayName":"Greed","description":"Picking up emeralds heals you and nearby players for 15% max health","abilities":[]},"CAVALRYMAN":{"displayName":"Cavalryman","description":"You may cast spells and attack with a 70% damage penalty while on a horse","abilities":[]},"GUARDIAN":{"displayName":"Guardian","description":"20% of the damage taken by nearby allies is redirected to you","abilities":[]},"HERO":{"displayName":"Saviours Sacrifice","description":"While under 50% maximum health, nearby allies gain 30% bonus damage and defense","abilities":[]},"ALTRUISM":{"displayName":"Heart of the Pack","description":"Nearby players gain 35% of the health you naturally regenerate","abilities":[]},"ARCANES":{"displayName":"Transcendence","description":"30% chance for spells to cost no mana when casted","abilities":[]},"ENTROPY":{"displayName":"Entropy","description":"Meteor falls three times faster","abilities":[]},"ROVINGASSASSIN":{"displayName":"Roving Assassin","description":"Vanish no longer drains mana while invisible","abilities":[]},"MADNESS":{"displayName":"Madness","description":"Cast a random ability every 3 seconds","abilities":[]},"LIGHTWEIGHT":{"displayName":"Lightweight","description":"You no longer take fall damage","abilities":[]},"SORCERY":{"displayName":"Sorcery","description":"30% chance for spells and attacks to cast a second time at no additional cost","abilities":[]},"TAUNT":{"displayName":"Taunt","description":"Mobs within 12 blocks target you upon casting War Scream","abilities":[]},"RALLY":{"displayName":"Rally","description":"Charge heals you by 10% and nearby allies by 15% on impact, but becomes harmless","abilities":[{"class":"Warrior","base_abil":4,"effects":[{"type":"add_spell_prop","base_spell":2,"display":"Rally Self Heal","target_part":"Rally Self Heal","power":0.1},{"type":"add_spell_prop","base_spell":2,"target_part":"Rally Ally Heal","power":0.15},{"type":"raw_stat","bonuses":[{"type":"stat","name":"damMult.Rally:2.Flying Kick","value":-100},{"type":"stat","name":"damMult.Rally:2.Collide","value":-100},{"type":"stat","name":"damMult.Rally:2.Heavy Impact","value":-100},{"type":"stat","name":"damMult.Rally:2.Flyby Jab","value":-100}]}]}]},"CHERRY_BOMBS":{"displayName":"Cherry Bombs","description":"Your Smoke Bombs explode instantly, and increase their Neutral Damage by +90%","abilities":[{"class":"Assassin","base_abil":7,"effects":[{"type":"add_spell_prop","base_spell":4,"target_part":"Per Tick","multipliers":[90,0,0,0,0,0]},{"type":"add_spell_prop","base_spell":4,"target_part":"Per Bomb","hits":{"Per Tick":-9}}]}]},"FREERUNNER":{"displayName":"Freerunner","description":"Double your sprint speed when your sprint bar is under 30%","abilities":[]},"PEACEFUL_EFFIGY":{"displayName":"Peaceful Effigy","description":"Your totem will last twice as long","abilities":[]},"FURIOUS_EFFIGY":{"displayName":"Furious Effigy","description":"Totem effects are twice as fast, but duration is halved","abilities":[{"class":"Shaman","base_abil":0,"properties":{"rate":-0.2,"totem_mul":2.5},"effects":[]}]},"FLASHFREEZE":{"displayName":"Flashfreeze","description":"Ice Snake is instant but has a reduced range","abilities":[]},"GRAVITYWELL":{"displayName":"Gravity Well","description":"Meteor has increased blast radius and pulls enemies instead","abilities":[]},"DESC_SNOWYSTEPS":{"displayName":"Snowy Steps","description":"Leaves a trail of snow behind you","abilities":[]},"GEOCENTRISM":{"displayName":"Geocentrism","description":"Aura radiates from you instead of your totem and can be cast anytime","abilities":[]},"DESC_FESTIVESPIRIT":{"displayName":"Festive Spirits","description":"Plays wintery tunes","abilities":[]}}

File diff suppressed because one or more lines are too long

1
data/2.0.2.1/majid.json Normal file
View file

@ -0,0 +1 @@
{"MAGNET":{"displayName":"Magnet","description":"Pulls items within an 8 block radius towards you","abilities":[]},"PLAGUE":{"displayName":"Plague","description":"Poisoned mobs spread their poison to nearby mobs","abilities":[]},"HAWKEYE":{"displayName":"Hawkeye","description":"Condense Arrow Storm into a tight beam. Arrows deal ✤10%, ✦1%, and ❋1%","abilities":[{"class":"Archer","base_abil":7,"effects":[{"type":"add_spell_prop","base_spell":1,"target_part":"Single Stream","behavior":"overwrite","hits":{"Single Arrow":5}},{"type":"add_spell_prop","base_spell":1,"target_part":"Single Arrow","behavior":"overwrite","multipliers":[10,0,1,0,0,1]},{"type":"add_spell_prop","base_spell":1,"target_part":"Total Damage","behavior":"modify","hits":{"Single Stream":4}}]}]},"GREED":{"displayName":"Greed","description":"Picking up emeralds heals you and nearby players for 15% max health","abilities":[]},"CAVALRYMAN":{"displayName":"Cavalryman","description":"You may cast spells and attack with a 70% damage penalty while on a horse","abilities":[]},"GUARDIAN":{"displayName":"Guardian","description":"20% of the damage taken by nearby allies is redirected to you","abilities":[]},"HERO":{"displayName":"Saviours Sacrifice","description":"While under 50% maximum health, nearby allies gain 30% bonus damage and defense","abilities":[]},"ALTRUISM":{"displayName":"Heart of the Pack","description":"Nearby players gain 35% of the health you naturally regenerate","abilities":[]},"ARCANES":{"displayName":"Transcendence","description":"30% chance for spells to cost no mana when casted","abilities":[]},"ENTROPY":{"displayName":"Entropy","description":"Meteor falls three times faster","abilities":[]},"ROVINGASSASSIN":{"displayName":"Roving Assassin","description":"Vanish no longer drains mana while invisible","abilities":[]},"MADNESS":{"displayName":"Madness","description":"Cast a random ability every 3 seconds","abilities":[]},"LIGHTWEIGHT":{"displayName":"Lightweight","description":"You no longer take fall damage","abilities":[]},"SORCERY":{"displayName":"Sorcery","description":"30% chance for spells and attacks to cast a second time at no additional cost","abilities":[]},"TAUNT":{"displayName":"Taunt","description":"Mobs within 12 blocks target you upon casting War Scream","abilities":[]},"RALLY":{"displayName":"Rally","description":"Charge heals you by 10% and nearby allies by 15% on impact, but becomes harmless","abilities":[{"class":"Warrior","base_abil":4,"effects":[{"type":"add_spell_prop","base_spell":2,"display":"Rally Self Heal","target_part":"Rally Self Heal","power":0.1},{"type":"add_spell_prop","base_spell":2,"target_part":"Rally Ally Heal","power":0.15},{"type":"raw_stat","bonuses":[{"type":"stat","name":"damMult.Rally:2.Flying Kick","value":-100},{"type":"stat","name":"damMult.Rally:2.Collide","value":-100},{"type":"stat","name":"damMult.Rally:2.Heavy Impact","value":-100},{"type":"stat","name":"damMult.Rally:2.Flyby Jab","value":-100}]}]}]},"CHERRY_BOMBS":{"displayName":"Cherry Bombs","description":"Your Smoke Bombs explode instantly, and increase their Neutral Damage by +90%","abilities":[{"class":"Assassin","base_abil":7,"effects":[{"type":"add_spell_prop","base_spell":4,"target_part":"Per Tick","multipliers":[90,0,0,0,0,0]},{"type":"add_spell_prop","base_spell":4,"target_part":"Per Bomb","hits":{"Per Tick":-9}}]}]},"FREERUNNER":{"displayName":"Freerunner","description":"Double your sprint speed when your sprint bar is under 30%","abilities":[]},"PEACEFUL_EFFIGY":{"displayName":"Peaceful Effigy","description":"Your totem will last twice as long","abilities":[]},"FURIOUS_EFFIGY":{"displayName":"Furious Effigy","description":"Totem effects are twice as fast, but duration is halved","abilities":[{"class":"Shaman","base_abil":0,"properties":{"rate":-0.2,"totem_mul":2.5},"effects":[]}]},"FLASHFREEZE":{"displayName":"Flashfreeze","description":"Ice Snake is instant but has a reduced range","abilities":[]},"GRAVITYWELL":{"displayName":"Gravity Well","description":"Meteor has increased blast radius and pulls enemies instead","abilities":[]},"DESC_SNOWYSTEPS":{"displayName":"Snowy Steps","description":"Leaves a trail of snow behind you","abilities":[]},"GEOCENTRISM":{"displayName":"Geocentrism","description":"Aura radiates from you instead of your totem and can be cast anytime","abilities":[]},"DESC_FESTIVESPIRIT":{"displayName":"Festive Spirits","description":"Plays wintery tunes","abilities":[]}}

File diff suppressed because one or more lines are too long

1
data/2.0.2.3/majid.json Normal file
View file

@ -0,0 +1 @@
{"MAGNET":{"displayName":"Magnet","description":"Pulls items within an 8 block radius towards you","abilities":[]},"PLAGUE":{"displayName":"Plague","description":"Poisoned mobs spread their poison to nearby mobs","abilities":[]},"HAWKEYE":{"displayName":"Hawkeye","description":"Condense Arrow Storm into a tight beam. Arrows deal ✤10%, ✦1%, and ❋1%","abilities":[{"class":"Archer","base_abil":7,"effects":[{"type":"add_spell_prop","base_spell":1,"target_part":"Single Stream","behavior":"overwrite","hits":{"Single Arrow":5}},{"type":"add_spell_prop","base_spell":1,"target_part":"Single Arrow","behavior":"overwrite","multipliers":[10,0,1,0,0,1]},{"type":"add_spell_prop","base_spell":1,"target_part":"Total Damage","behavior":"modify","hits":{"Single Stream":4}}]}]},"GREED":{"displayName":"Greed","description":"Picking up emeralds heals you and nearby players for 15% max health","abilities":[]},"CAVALRYMAN":{"displayName":"Cavalryman","description":"You may cast spells and attack with a 70% damage penalty while on a horse","abilities":[]},"GUARDIAN":{"displayName":"Guardian","description":"20% of the damage taken by nearby allies is redirected to you","abilities":[]},"HERO":{"displayName":"Saviours Sacrifice","description":"While under 50% maximum health, nearby allies gain 30% bonus damage and defense","abilities":[]},"ALTRUISM":{"displayName":"Heart of the Pack","description":"Nearby players gain 35% of the health you naturally regenerate","abilities":[]},"ARCANES":{"displayName":"Transcendence","description":"30% chance for spells to cost no mana when casted","abilities":[]},"ENTROPY":{"displayName":"Entropy","description":"Meteor falls three times faster","abilities":[]},"ROVINGASSASSIN":{"displayName":"Roving Assassin","description":"Vanish no longer drains mana while invisible","abilities":[]},"MADNESS":{"displayName":"Madness","description":"Cast a random ability every 3 seconds","abilities":[]},"LIGHTWEIGHT":{"displayName":"Lightweight","description":"You no longer take fall damage","abilities":[]},"SORCERY":{"displayName":"Sorcery","description":"30% chance for spells and attacks to cast a second time at no additional cost","abilities":[]},"TAUNT":{"displayName":"Taunt","description":"Mobs within 12 blocks target you upon casting War Scream","abilities":[]},"RALLY":{"displayName":"Rally","description":"Charge heals you by 10% and nearby allies by 15% on impact, but becomes harmless","abilities":[{"class":"Warrior","base_abil":4,"effects":[{"type":"add_spell_prop","base_spell":2,"display":"Rally Self Heal","target_part":"Rally Self Heal","power":0.1},{"type":"add_spell_prop","base_spell":2,"target_part":"Rally Ally Heal","power":0.15},{"type":"raw_stat","bonuses":[{"type":"stat","name":"damMult.Rally:2.Flying Kick","value":-100},{"type":"stat","name":"damMult.Rally:2.Collide","value":-100},{"type":"stat","name":"damMult.Rally:2.Heavy Impact","value":-100},{"type":"stat","name":"damMult.Rally:2.Flyby Jab","value":-100}]}]}]},"CHERRY_BOMBS":{"displayName":"Cherry Bombs","description":"Your Smoke Bombs explode instantly, and increase their Neutral Damage by +90%","abilities":[{"class":"Assassin","base_abil":7,"effects":[{"type":"add_spell_prop","base_spell":4,"target_part":"Per Tick","multipliers":[90,0,0,0,0,0]},{"type":"add_spell_prop","base_spell":4,"target_part":"Per Bomb","hits":{"Per Tick":-9}}]}]},"FREERUNNER":{"displayName":"Freerunner","description":"Double your sprint speed when your sprint bar is under 30%","abilities":[]},"PEACEFUL_EFFIGY":{"displayName":"Peaceful Effigy","description":"Your totem will last twice as long","abilities":[]},"FURIOUS_EFFIGY":{"displayName":"Furious Effigy","description":"Totem effects are twice as fast, but duration is halved","abilities":[{"class":"Shaman","base_abil":0,"properties":{"rate":-0.2,"totem_mul":2.5},"effects":[]}]},"FLASHFREEZE":{"displayName":"Flashfreeze","description":"Ice Snake is instant but has a reduced range","abilities":[]},"GRAVITYWELL":{"displayName":"Gravity Well","description":"Meteor has increased blast radius and pulls enemies instead","abilities":[]},"DESC_SNOWYSTEPS":{"displayName":"Snowy Steps","description":"Leaves a trail of snow behind you","abilities":[]},"GEOCENTRISM":{"displayName":"Geocentrism","description":"Aura radiates from you instead of your totem and can be cast anytime","abilities":[]},"DESC_FESTIVESPIRIT":{"displayName":"Festive Spirits","description":"Plays wintery tunes","abilities":[]}}

File diff suppressed because one or more lines are too long

1
data/2.0.3.1/atree.json Normal file

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

1
data/2.0.3.1/items.json Normal file

File diff suppressed because one or more lines are too long

1
data/2.0.3.1/majid.json Executable file

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

1069
data/2.0.3.1/tomes.json Normal file

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because one or more lines are too long

View file

@ -165,18 +165,19 @@
</div> </div>
</div> </div>
<script src="/thirdparty/autoComplete.min.js"></script> <script src="/thirdparty/autoComplete.min.js"></script>
<script type="text/javascript" src="../js/drag_drop_touch.js"></script> <script type="text/javascript" src="/js/drag_drop_touch.js"></script>
<script type="text/javascript" src="../js/utils.js"></script> <script type="text/javascript" src="/js/utils.js"></script>
<script type="text/javascript" src="../js/build_utils.js"></script> <script type="text/javascript" src="/js/build_utils.js"></script>
<script type="text/javascript" src="../js/icons.js"></script> <script type="text/javascript" src="/js/builder/build_encode_decode.js"></script>
<script type="text/javascript" src="../js/damage_calc.js"></script> <script type="text/javascript" src="/js/icons.js"></script>
<script type="text/javascript" src="../js/display_constants.js"></script> <script type="text/javascript" src="/js/damage_calc.js"></script>
<script type="text/javascript" src="../js/display.js"></script> <script type="text/javascript" src="/js/display_constants.js"></script>
<script type="text/javascript" src="../js/query.js"></script> <script type="text/javascript" src="/js/display.js"></script>
<script type="text/javascript" src="../js/expr_parser.js"></script> <script type="text/javascript" src="/js/query.js"></script>
<script type="text/javascript" src="../js/load.js"></script> <script type="text/javascript" src="/js/expr_parser.js"></script>
<script type="text/javascript" src="../js/search.js"></script> <script type="text/javascript" src="/js/load.js"></script>
<script type="text/javascript" src="../js/items.js"></script> <script type="text/javascript" src="/js/search.js"></script>
<script type="text/javascript" src="../js/powders.js"></script> <script type="text/javascript" src="/js/powders.js"></script>
<script type="text/javascript" src="/js/items.js"></script>
</body> </body>
</html> </html>

View file

@ -76,6 +76,7 @@
<script type="text/javascript" src="/js/utils.js"></script> <script type="text/javascript" src="/js/utils.js"></script>
<script type="text/javascript" src="/js/build_utils.js"></script> <script type="text/javascript" src="/js/build_utils.js"></script>
<script type="text/javascript" src="/js/builder/build_encode_decode.js"></script>
<script type="text/javascript" src="/js/icons.js"></script> <script type="text/javascript" src="/js/icons.js"></script>
<script type="text/javascript" src="/js/powders.js"></script> <script type="text/javascript" src="/js/powders.js"></script>
<script type="text/javascript" src="/js/damage_calc.js"></script> <script type="text/javascript" src="/js/damage_calc.js"></script>

View file

@ -75,7 +75,10 @@ let item_types = armorTypes.concat(accessoryTypes).concat(weaponTypes).concat(to
let elementIcons = ["\u2724","\u2726", "\u2749", "\u2739", "\u274b" ]; let elementIcons = ["\u2724","\u2726", "\u2749", "\u2739", "\u274b" ];
let skpReqs = skp_order.map(x => x + "Req"); let skpReqs = skp_order.map(x => x + "Req");
let item_fields = [ "name", "displayName", "lore", "color", "tier", "set", "slots", "type", "material", "drop", "quest", "restrict", "nDam", "fDam", "wDam", "aDam", "tDam", "eDam", "atkSpd", "hp", "fDef", "wDef", "aDef", "tDef", "eDef", "lvl", "classReq", "strReq", "dexReq", "intReq", "defReq", "agiReq", "hprPct", "mr", "sdPct", "mdPct", "ls", "ms", "xpb", "lb", "ref", "str", "dex", "int", "agi", "def", "thorns", "expd", "spd", "atkTier", "poison", "hpBonus", "spRegen", "eSteal", "hprRaw", "sdRaw", "mdRaw", "fDamPct", "wDamPct", "aDamPct", "tDamPct", "eDamPct", "fDefPct", "wDefPct", "aDefPct", "tDefPct", "eDefPct", "fixID", "category", "spPct1", "spRaw1", "spPct2", "spRaw2", "spPct3", "spRaw3", "spPct4", "spRaw4", "rSdRaw", "sprint", "sprintReg", "jh", "lq", "gXp", "gSpd", "id", "majorIds", "damMobs", "defMobs", let item_fields = [ "name", "displayName", "lore", "color", "tier", "set", "slots", "type", "material", "drop", "quest", "restrict", "nDam", "fDam", "wDam", "aDam", "tDam", "eDam", "atkSpd", "hp", "fDef", "wDef", "aDef", "tDef", "eDef", "lvl", "classReq", "strReq", "dexReq", "intReq", "defReq", "agiReq", "hprPct", "mr", "sdPct", "mdPct", "ls", "ms", "xpb", "lb", "ref", "str", "dex", "int", "agi", "def", "thorns", "expd", "spd", "atkTier", "poison", "hpBonus", "spRegen", "eSteal", "hprRaw", "sdRaw", "mdRaw",
"fDamPct", "wDamPct", "aDamPct", "tDamPct", "eDamPct",
"fDefPct", "wDefPct", "aDefPct", "tDefPct", "eDefPct",
"fixID", "category", "spPct1", "spRaw1", "spPct2", "spRaw2", "spPct3", "spRaw3", "spPct4", "spRaw4", "rSdRaw", "sprint", "sprintReg", "jh", "lq", "gXp", "gSpd", "id", "majorIds", "damMobs", "defMobs",
// wynn2 damages. // wynn2 damages.
"eMdPct","eMdRaw","eSdPct","eSdRaw",/*"eDamPct,"*/"eDamRaw","eDamAddMin","eDamAddMax", "eMdPct","eMdRaw","eSdPct","eSdRaw",/*"eDamPct,"*/"eDamRaw","eDamAddMin","eDamAddMax",
@ -87,14 +90,15 @@ let item_fields = [ "name", "displayName", "lore", "color", "tier", "set", "slot
/*"mdPct","mdRaw","sdPct","sdRaw",*/"damPct","damRaw","damAddMin","damAddMax", // These are the old ids. Become proportional. /*"mdPct","mdRaw","sdPct","sdRaw",*/"damPct","damRaw","damAddMin","damAddMax", // These are the old ids. Become proportional.
"rMdPct","rMdRaw","rSdPct",/*"rSdRaw",*/"rDamPct","rDamRaw","rDamAddMin","rDamAddMax", // rainbow (the "element" of all minus neutral). rSdRaw is rainraw "rMdPct","rMdRaw","rSdPct",/*"rSdRaw",*/"rDamPct","rDamRaw","rDamAddMin","rDamAddMax", // rainbow (the "element" of all minus neutral). rSdRaw is rainraw
"critDamPct", "critDamPct",
"spPct1Final", "spPct2Final", "spPct3Final", "spPct4Final" "spPct1Final", "spPct2Final", "spPct3Final", "spPct4Final",
"healPct", "kb", "weakenEnemy", "slowEnemy", "rDefPct"
]; ];
// Extra fake IDs (reserved for use in spell damage calculation) : damMult, defMult, poisonPct, activeMajorIDs // Extra fake IDs (reserved for use in spell damage calculation) : damMult, defMult, poisonPct, activeMajorIDs
let str_item_fields = [ "name", "displayName", "lore", "color", "tier", "set", "type", "material", "drop", "quest", "restrict", "category", "atkSpd" ] let str_item_fields = [ "name", "displayName", "lore", "color", "tier", "set", "type", "material", "drop", "quest", "restrict", "category", "atkSpd" ]
//File reading for ID translations for JSON purposes //File reading for ID translations for JSON purposes
let reversetranslations = new Map(); let reversetranslations = new Map();
let _translations_list = [["name", "name"],["displayName", "displayName"],["tier", "tier"],["set", "set"],["sockets", "slots"],["type", "type"],["armorColor", "color"],["addedLore", "lore"],["dropType", "drop"],["quest", "quest"],["restrictions", "restrict"],["damage", "nDam"],["fireDamage", "fDam"],["waterDamage", "wDam"],["airDamage", "aDam"],["thunderDamage", "tDam"],["earthDamage", "eDam"],["attackSpeed", "atkSpd"],["health", "hp"],["fireDefense", "fDef"],["waterDefense", "wDef"],["airDefense", "aDef"],["thunderDefense", "tDef"],["earthDefense", "eDef"],["level", "lvl"],["classRequirement", "classReq"],["strength", "strReq"],["dexterity", "dexReq"],["intelligence", "intReq"],["agility", "agiReq"],["defense", "defReq"],["healthRegen", "hprPct"],["manaRegen", "mr"],["spellDamageBonus", "sdPct"],["spellElementalDamageBonus", "rSdPct"],["spellNeutralDamageBonus", "nSdPct"],["spellFireDamageBonus", "fSdPct"],["spellWaterDamageBonus", "wSdPct"],["spellAirDamageBonus", "aSdPct"],["spellThunderDamageBonus", "tSdPct"],["spellEarthDamageBonus", "eSdPct"],["mainAttackDamageBonus", "mdPct"],["mainAttackElementalDamageBonus", "rMdPct"],["mainAttackNeutralDamageBonus", "nMdPct"],["mainAttackFireDamageBonus", "fMdPct"],["mainAttackWaterDamageBonus", "wMdPct"],["mainAttackAirDamageBonus", "aMdPct"],["mainAttackThunderDamageBonus", "tMdPct"],["mainAttackEarthDamageBonus", "eMdPct"],["lifeSteal", "ls"],["manaSteal", "ms"],["xpBonus", "xpb"],["lootBonus", "lb"],["reflection", "ref"],["strengthPoints", "str"],["dexterityPoints", "dex"],["intelligencePoints", "int"],["agilityPoints", "agi"],["defensePoints", "def"],["thorns", "thorns"],["exploding", "expd"],["speed", "spd"],["attackSpeedBonus", "atkTier"],["poison", "poison"],["healthBonus", "hpBonus"],["soulPoints", "spRegen"],["emeraldStealing", "eSteal"],["healthRegenRaw", "hprRaw"],["spellDamageBonusRaw", "sdRaw"],["spellElementalDamageBonusRaw", "rSdRaw"],["spellNeutralDamageBonusRaw", "nSdRaw"],["spellFireDamageBonusRaw", "fSdRaw"],["spellWaterDamageBonusRaw", "wSdRaw"],["spellAirDamageBonusRaw", "aSdRaw"],["spellThunderDamageBonusRaw", "tSdRaw"],["spellEarthDamageBonusRaw", "eSdRaw"],["mainAttackDamageBonusRaw", "mdRaw"],["mainAttackElementalDamageBonusRaw", "rMdRaw"],["mainAttackNeutralDamageBonusRaw", "nMdRaw"],["mainAttackFireDamageBonusRaw", "fMdRaw"],["mainAttackWaterDamageBonusRaw", "wMdRaw"],["mainAttackAirDamageBonusRaw", "aMdRaw"],["mainAttackThunderDamageBonusRaw", "tMdRaw"],["mainAttackEarthDamageBonusRaw", "eMdRaw"],["fireDamageBonus", "fDamPct"],["waterDamageBonus", "wDamPct"],["airDamageBonus", "aDamPct"],["thunderDamageBonus", "tDamPct"],["earthDamageBonus", "eDamPct"],["bonusFireDefense", "fDefPct"],["bonusWaterDefense", "wDefPct"],["bonusAirDefense", "aDefPct"],["bonusThunderDefense", "tDefPct"],["bonusEarthDefense", "eDefPct"],["accessoryType", "type"],["identified", "fixID"],["skin", "skin"],["category", "category"],["spellCostPct1", "spPct1"],["spellCostRaw1", "spRaw1"],["spellCostPct2", "spPct2"],["spellCostRaw2", "spRaw2"],["spellCostPct3", "spPct3"],["spellCostRaw3", "spRaw3"],["spellCostPct4", "spPct4"],["spellCostRaw4", "spRaw4"],["sprint", "sprint"],["sprintRegen", "sprintReg"],["jumpHeight", "jh"],["lootQuality", "lq"],["gatherXpBonus", "gXp"],["gatherSpeed", "gSpd"]]; let _translations_list = [["name", "name"],["displayName", "displayName"],["tier", "tier"],["set", "set"],["sockets", "slots"],["type", "type"],["armorColor", "color"],["addedLore", "lore"],["dropType", "drop"],["quest", "quest"],["restrictions", "restrict"],["damage", "nDam"],["fireDamage", "fDam"],["waterDamage", "wDam"],["airDamage", "aDam"],["thunderDamage", "tDam"],["earthDamage", "eDam"],["attackSpeed", "atkSpd"],["health", "hp"],["fireDefense", "fDef"],["waterDefense", "wDef"],["airDefense", "aDef"],["thunderDefense", "tDef"],["earthDefense", "eDef"],["level", "lvl"],["classRequirement", "classReq"],["strength", "strReq"],["dexterity", "dexReq"],["intelligence", "intReq"],["agility", "agiReq"],["defense", "defReq"],["healthRegen", "hprPct"],["manaRegen", "mr"],["spellDamageBonus", "sdPct"],["spellElementalDamageBonus", "rSdPct"],["spellNeutralDamageBonus", "nSdPct"],["spellFireDamageBonus", "fSdPct"],["spellWaterDamageBonus", "wSdPct"],["spellAirDamageBonus", "aSdPct"],["spellThunderDamageBonus", "tSdPct"],["spellEarthDamageBonus", "eSdPct"],["mainAttackDamageBonus", "mdPct"],["mainAttackElementalDamageBonus", "rMdPct"],["mainAttackNeutralDamageBonus", "nMdPct"],["mainAttackFireDamageBonus", "fMdPct"],["mainAttackWaterDamageBonus", "wMdPct"],["mainAttackAirDamageBonus", "aMdPct"],["mainAttackThunderDamageBonus", "tMdPct"],["mainAttackEarthDamageBonus", "eMdPct"],["lifeSteal", "ls"],["manaSteal", "ms"],["xpBonus", "xpb"],["lootBonus", "lb"],["reflection", "ref"],["strengthPoints", "str"],["dexterityPoints", "dex"],["intelligencePoints", "int"],["agilityPoints", "agi"],["defensePoints", "def"],["thorns", "thorns"],["exploding", "expd"],["speed", "spd"],["attackSpeedBonus", "atkTier"],["poison", "poison"],["healthBonus", "hpBonus"],["soulPoints", "spRegen"],["emeraldStealing", "eSteal"],["healthRegenRaw", "hprRaw"],["spellDamageBonusRaw", "sdRaw"],["spellElementalDamageBonusRaw", "rSdRaw"],["spellNeutralDamageBonusRaw", "nSdRaw"],["spellFireDamageBonusRaw", "fSdRaw"],["spellWaterDamageBonusRaw", "wSdRaw"],["spellAirDamageBonusRaw", "aSdRaw"],["spellThunderDamageBonusRaw", "tSdRaw"],["spellEarthDamageBonusRaw", "eSdRaw"],["mainAttackDamageBonusRaw", "mdRaw"],["mainAttackElementalDamageBonusRaw", "rMdRaw"],["mainAttackNeutralDamageBonusRaw", "nMdRaw"],["mainAttackFireDamageBonusRaw", "fMdRaw"],["mainAttackWaterDamageBonusRaw", "wMdRaw"],["mainAttackAirDamageBonusRaw", "aMdRaw"],["mainAttackThunderDamageBonusRaw", "tMdRaw"],["mainAttackEarthDamageBonusRaw", "eMdRaw"],["fireDamageBonus", "fDamPct"],["waterDamageBonus", "wDamPct"],["airDamageBonus", "aDamPct"],["thunderDamageBonus", "tDamPct"],["earthDamageBonus", "eDamPct"],["bonusFireDefense", "fDefPct"],["bonusWaterDefense", "wDefPct"],["bonusAirDefense", "aDefPct"],["bonusThunderDefense", "tDefPct"],["bonusEarthDefense", "eDefPct"],["accessoryType", "type"],["identified", "fixID"],["skin", "skin"],["category", "category"],["spellCostPct1", "spPct1"],["spellCostRaw1", "spRaw1"],["spellCostPct2", "spPct2"],["spellCostRaw2", "spRaw2"],["spellCostPct3", "spPct3"],["spellCostRaw3", "spRaw3"],["spellCostPct4", "spPct4"],["spellCostRaw4", "spRaw4"],["sprint", "sprint"],["sprintRegen", "sprintReg"],["jumpHeight", "jh"],["lootQuality", "lq"],["gatherXpBonus", "gXp"],["gatherSpeed", "gSpd"],["healingEfficiency", "healPct"], ["knockback", "kb"], ["weakenEnemy", "weakenEnemy"], ["slowEnemy", "slowEnemy"], ["elementalDefense", "rDefPct"]];
let translations = new Map(_translations_list); let translations = new Map(_translations_list);
//does not include damMobs (wep tomes) and defMobs (armor tomes) //does not include damMobs (wep tomes) and defMobs (armor tomes)
@ -176,11 +180,12 @@ let rolledIDs = [
"nMdPct","nMdRaw","nSdPct","nSdRaw","nDamPct","nDamRaw","nDamAddMin","nDamAddMax", // neutral which is now an element "nMdPct","nMdRaw","nSdPct","nSdRaw","nDamPct","nDamRaw","nDamAddMin","nDamAddMax", // neutral which is now an element
/*"mdPct","mdRaw","sdPct","sdRaw",*/"damPct","damRaw","damAddMin","damAddMax", // These are the old ids. Become proportional. /*"mdPct","mdRaw","sdPct","sdRaw",*/"damPct","damRaw","damAddMin","damAddMax", // These are the old ids. Become proportional.
"rMdPct","rMdRaw","rSdPct",/*"rSdRaw",*/"rDamPct","rDamRaw","rDamAddMin","rDamAddMax", // rainbow (the "element" of all minus neutral). rSdRaw is rainraw "rMdPct","rMdRaw","rSdPct",/*"rSdRaw",*/"rDamPct","rDamRaw","rDamAddMin","rDamAddMax", // rainbow (the "element" of all minus neutral). rSdRaw is rainraw
"spPct1Final", "spPct2Final", "spPct3Final", "spPct4Final" "spPct1Final", "spPct2Final", "spPct3Final", "spPct4Final",
"healPct", "kb", "weakenEnemy", "slowEnemy", "rDefPct"
]; ];
let reversedIDs = [ "spPct1", "spRaw1", "spPct2", "spRaw2", "spPct3", "spRaw3", "spPct4", "spRaw4" ]; let reversedIDs = [ "spPct1", "spRaw1", "spPct2", "spRaw2", "spPct3", "spRaw3", "spPct4", "spRaw4" ];
let ingFields = ["fDefPct", "wDefPct", "aDefPct", "tDefPct", "eDefPct", "hprPct", "mr", "sdPct", "mdPct", "ls", "ms", "xpb", "lb", "lq", "ref", "str", "dex", "int", "agi", "def", "thorns", "expd", "spd", "atkTier", "poison", "hpBonus", "spRegen", "eSteal", "hprRaw", "sdRaw", "mdRaw", "fDamPct", "wDamPct", "aDamPct", "tDamPct", "eDamPct", "spPct1", "spRaw1", "spPct2", "spRaw2", "spPct3", "spRaw3", "spPct4", "spRaw4", "jh", "sprint", "sprintReg", "gXp", "gSpd"]; let ingFields = rolledIDs.concat(["str", "dex", "int", "def", "agi"]);
/** /**
* Take an item with id list and turn it into a set of minrolls and maxrolls. * Take an item with id list and turn it into a set of minrolls and maxrolls.

View file

@ -45,9 +45,10 @@ add_spell_prop: {
base_spell: int // spell identifier base_spell: int // spell identifier
target_part: Optional[str] // Part of the spell to modify. Can be not present/empty for ex. cost modifier. target_part: Optional[str] // Part of the spell to modify. Can be not present/empty for ex. cost modifier.
// If target part does not exist, a new part is created. // If target part does not exist, a new part is created.
behavior: Optional[str] // One of: "merge", "modify". default: merge behavior: Optional[str] // One of: "merge", "modify", "overwrite". default: merge
// merge: add if exist, make new part if not exist // merge: add if exist, make new part if not exist
// modify: increment existing part. do nothing if not exist // modify: increment existing part. do nothing if not exist
// overwrite: set part. do nothing if not exist
cost: Optional[int] // change to spellcost. If the spell is not spell 1-4, this must be left empty. cost: Optional[int] // change to spellcost. If the spell is not spell 1-4, this must be left empty.
multipliers: Optional[array[float, 6]] // Additive changes to spellmult (for damage spell) multipliers: Optional[array[float, 6]] // Additive changes to spellmult (for damage spell)
power: Optional[float] // Additive change to healing power (for heal spell) power: Optional[float] // Additive change to healing power (for heal spell)
@ -421,6 +422,7 @@ const atree_merge = new (class extends ComputeNode {
const [hard_error, errors] = input_map.get('atree-errors'); const [hard_error, errors] = input_map.get('atree-errors');
if (hard_error) { return null; } if (hard_error) { return null; }
const player_class = input_map.get('player-class'); const player_class = input_map.get('player-class');
const build = input_map.get('build');
const atree_state = input_map.get('atree-state'); const atree_state = input_map.get('atree-state');
const atree_order = input_map.get('atree'); const atree_order = input_map.get('atree');
@ -433,26 +435,20 @@ const atree_merge = new (class extends ComputeNode {
else if (!Array.isArray(tmp_abil.desc)) { else if (!Array.isArray(tmp_abil.desc)) {
tmp_abil.desc = [tmp_abil.desc]; tmp_abil.desc = [tmp_abil.desc];
} }
tmp_abil.subparts = [abil.id];
abils_merged.set(abil.id, tmp_abil); abils_merged.set(abil.id, tmp_abil);
} }
for (const node of atree_order) { function merge_abil(abil) {
const abil_id = node.ability.id;
if (!atree_state.get(abil_id).active) {
continue;
}
const abil = node.ability;
if ('base_abil' in abil) { if ('base_abil' in abil) {
if (abils_merged.has(abil.base_abil)) { if (abils_merged.has(abil.base_abil)) {
// Merge abilities. // Merge abilities.
// TODO: What if there is more than one base abil? // TODO: What if there is more than one base abil?
let base_abil = abils_merged.get(abil.base_abil); let base_abil = abils_merged.get(abil.base_abil);
if (Array.isArray(abil.desc)) { base_abil.desc = base_abil.desc.concat(abil.desc); } if (abil.desc) {
else { base_abil.desc.push(abil.desc); } if (Array.isArray(abil.desc)) { base_abil.desc = base_abil.desc.concat(abil.desc); }
else { base_abil.desc.push(abil.desc); }
}
base_abil.subparts.push(abil.id);
base_abil.effects = base_abil.effects.concat(abil.effects); base_abil.effects = base_abil.effects.concat(abil.effects);
for (let propname in abil.properties) { for (let propname in abil.properties) {
if (propname in base_abil.properties) { if (propname in base_abil.properties) {
@ -468,8 +464,24 @@ const atree_merge = new (class extends ComputeNode {
if (!Array.isArray(tmp_abil.desc)) { if (!Array.isArray(tmp_abil.desc)) {
tmp_abil.desc = [tmp_abil.desc]; tmp_abil.desc = [tmp_abil.desc];
} }
tmp_abil.subparts = [abil.id]; abils_merged.set(abil.id, tmp_abil);
abils_merged.set(abil_id, tmp_abil); }
}
for (const node of atree_order) {
const abil_id = node.ability.id;
if (!atree_state.get(abil_id).active) {
continue;
}
merge_abil(node.ability);
}
const build_class = wep_to_class.get(build.weapon.statMap.get("type"));
for (const major_id_name of build.statMap.get("activeMajorIDs")) {
if (major_id_name in major_ids) {
for (const abil of major_ids[major_id_name].abilities) {
if (abil["class"] === build_class) { merge_abil(abil); }
}
} }
} }
return abils_merged; return abils_merged;
@ -539,7 +551,6 @@ const atree_make_interactives = new (class extends ComputeNode {
} }
} }
else if (behavior === 'merge') { else if (behavior === 'merge') {
console.log(effect);
slider_map.set(slider_name, { slider_map.set(slider_name, {
label_name: slider_name+' ('+ability.display_name+')', label_name: slider_name+' ('+ability.display_name+')',
max: slider_max, max: slider_max,
@ -867,17 +878,22 @@ const atree_collect_spells = new (class extends ComputeNode {
// we found the part. merge or modify it! // we found the part. merge or modify it!
if ('multipliers' in effect) { if ('multipliers' in effect) {
for (const [idx, v] of effect.multipliers.entries()) { // python: enumerate() for (const [idx, v] of effect.multipliers.entries()) { // python: enumerate()
part.multipliers[idx] += v; if (behavior === 'overwrite') { part.multipliers[idx] = v; }
else { part.multipliers[idx] += v; }
} }
} }
else if ('power' in effect) { else if ('power' in effect) {
part.power += effect.power; if (behavior === 'overwrite') { part.power = effect.power; }
else { part.power += effect.power; }
} }
else if ('hits' in effect) { else if ('hits' in effect) {
for (const [idx, _v] of Object.entries(effect.hits)) { // looks kinda similar to multipliers case... hmm... can we unify all of these three? (make healpower a list) for (const [idx, _v] of Object.entries(effect.hits)) { // looks kinda similar to multipliers case... hmm... can we unify all of these three? (make healpower a list)
let v = translate(_v); let v = translate(_v);
if (idx in part.hits) { part.hits[idx] += v; } if (behavior === 'overwrite') { part.hits[idx] = v; }
else { part.hits[idx] = v; } else {
if (idx in part.hits) { part.hits[idx] += v; }
else { part.hits[idx] = v; }
}
} }
} }
else { else {
@ -901,6 +917,7 @@ const atree_collect_spells = new (class extends ComputeNode {
} }
continue; continue;
} }
// NOTE: Legacy support
case 'convert_spell_conv': case 'convert_spell_conv':
const { base_spell, target_part, conversion } = effect; const { base_spell, target_part, conversion } = effect;
const ret_spell = ret_spells.get(base_spell); const ret_spell = ret_spells.get(base_spell);
@ -1001,13 +1018,9 @@ class AbilityTreeEnsureNodesNode extends ComputeNode {
// TODO shortcut update path for sliders // TODO shortcut update path for sliders
for (const [spell_id, spell] of new Map([...spell_map].sort((a, b) => a[0] - b[0])).entries()) { for (const [spell_id, spell] of new Map([...spell_map].sort((a, b) => a[0] - b[0])).entries()) {
let spell_node = new SpellSelectNode(spell) let calc_node = new SpellDamageCalcNode(spell)
.link_to(build_node, 'build');
let calc_node = new SpellDamageCalcNode(spell.base_spell)
.link_to(build_node, 'build') .link_to(build_node, 'build')
.link_to(stat_agg_node, 'stats') .link_to(stat_agg_node, 'stats');
.link_to(spell_node, 'spell-info');
this.spelldmg_nodes.push(calc_node); this.spelldmg_nodes.push(calc_node);
let display_elem = make_elem('div', ["col", "pe-0"]); let display_elem = make_elem('div', ["col", "pe-0"]);
@ -1019,9 +1032,8 @@ class AbilityTreeEnsureNodesNode extends ComputeNode {
display_elem.append(spell_summary, spell_detail); display_elem.append(spell_summary, spell_detail);
let display_node = new SpellDisplayNode(spell.base_spell) let display_node = new SpellDisplayNode(spell)
.link_to(stat_agg_node, 'stats') .link_to(stat_agg_node, 'stats')
.link_to(spell_node, 'spell-info')
.link_to(calc_node, 'spell-damage'); .link_to(calc_node, 'spell-damage');
this.spell_display_elem.appendChild(display_elem); this.spell_display_elem.appendChild(display_elem);

File diff suppressed because it is too large Load diff

File diff suppressed because one or more lines are too long

View file

@ -10,7 +10,7 @@ const classDefenseMultipliers = new Map([ ["relik",0.60], ["bow",0.70], ["wand",
/* /*
* Class that represents a wynn player's build. * Class that represents a wynn player's build.
*/ */
class Build{ class Build {
/** /**
* @description Construct a build. * @description Construct a build.
@ -79,7 +79,8 @@ class Build{
"aMdPct","aMdRaw","aSdPct","aSdRaw","aDamPct","aDamRaw","aDamAddMin","aDamAddMax", "aMdPct","aMdRaw","aSdPct","aSdRaw","aDamPct","aDamRaw","aDamAddMin","aDamAddMax",
"nMdPct","nMdRaw","nSdPct","nSdRaw","nDamPct","nDamRaw","nDamAddMin","nDamAddMax", // neutral which is now an element "nMdPct","nMdRaw","nSdPct","nSdRaw","nDamPct","nDamRaw","nDamAddMin","nDamAddMax", // neutral which is now an element
"mdPct","mdRaw","sdPct","sdRaw","damPct","damRaw","damAddMin","damAddMax", // These are the old ids. Become proportional. "mdPct","mdRaw","sdPct","sdRaw","damPct","damRaw","damAddMin","damAddMax", // These are the old ids. Become proportional.
"rMdPct","rMdRaw","rSdPct","rSdRaw","rDamPct","rDamRaw","rDamAddMin","rDamAddMax" // rainbow (the "element" of all minus neutral). rSdRaw is rainraw "rMdPct","rMdRaw","rSdPct","rSdRaw","rDamPct","rDamRaw","rDamAddMin","rDamAddMax", // rainbow (the "element" of all minus neutral). rSdRaw is rainraw
"healPct",
] ]
//Create a map of this build's stats //Create a map of this build's stats
@ -131,7 +132,7 @@ class Build{
} }
statMap.set("poisonPct", 0); statMap.set("poisonPct", 0);
statMap.set("critDamPct", 0); statMap.set("critDamPct", 0);
statMap.set("healPct", 0); statMap.set("healMult", 0);
// The stuff relevant for damage calculation!!! @ferricles // The stuff relevant for damage calculation!!! @ferricles
statMap.set("atkSpd", this.weapon.statMap.get("atkSpd")); statMap.set("atkSpd", this.weapon.statMap.get("atkSpd"));

View file

@ -31,20 +31,33 @@ const wynn_version_names = [
'2.0.1.1', '2.0.1.1',
'2.0.1.2', '2.0.1.2',
'2.0.2.1', '2.0.2.1',
'2.0.2.3' '2.0.2.3',
'2.0.3.1'
]; ];
const WYNN_VERSION_LATEST = wynn_version_names.length - 1; const WYNN_VERSION_LATEST = wynn_version_names.length - 1;
// Default to the newest version. // Default to the newest version.
let wynn_version_id = WYNN_VERSION_LATEST; let wynn_version_id = WYNN_VERSION_LATEST;
let major_ids = null;
let major_id_load_complete = false;
async function load_major_id_data(version_str) {
let getUrl = window.location;
let baseUrl = `${getUrl.protocol}//${getUrl.host}/`;
// No random string -- we want to use caching
let url = `${baseUrl}/data/${version_str}/majid.json`;
major_ids = await (await fetch(url)).json();
major_id_load_complete = true;
}
/* /*
* Populate fields based on url, and calculate build. * Populate fields based on url, and calculate build.
* TODO: THIS CODE IS GOD AWFUL result of being lazy * TODO: THIS CODE IS GOD AWFUL result of being lazy
* fix all the slice() and break into functions or do something about it... its inefficient, ugly and error prone * fix all the slice() and break into functions or do something about it... its inefficient, ugly and error prone
*/ */
async function parse_hash(url_tag) { async function parse_hash(url_tag) {
const default_load_promises = [ load_atree_data(wynn_version_names[WYNN_VERSION_LATEST]), let latest_ver_name = wynn_version_names[WYNN_VERSION_LATEST];
load_init(), load_ing_init(), load_tome_init() ]; const default_load_promises = [ load_atree_data(latest_ver_name), load_major_id_data(latest_ver_name),
load_init(), load_ing_init(), load_tome_init()];
if (!url_tag) { if (!url_tag) {
await Promise.all(default_load_promises); await Promise.all(default_load_promises);
return; return;
@ -98,6 +111,7 @@ async function parse_hash(url_tag) {
else { else {
version_name = wynn_version_names[wynn_version_id]; version_name = wynn_version_names[wynn_version_id];
const load_promises = [ load_atree_data(version_name), const load_promises = [ load_atree_data(version_name),
load_major_id_data(version_name),
load_old_version(version_name), load_old_version(version_name),
load_ings_old_version(version_name), load_ings_old_version(version_name),
load_tome_old_version(version_name) ]; load_tome_old_version(version_name) ];

View file

@ -500,28 +500,6 @@ class PowderInputNode extends InputNode {
} }
} }
/**
* Select a spell+spell "variation" based on a build / spell idx.
* Right now this isn't much logic and is only used to abstract away major id interactions
* but will become significantly more complex in wynn2.
*
* Signature: SpellSelectNode<int>(build: Build) => [Spell, SpellParts]
*/
class SpellSelectNode extends ComputeNode {
constructor(spell) {
super("builder-spell"+spell.base_spell+"-select");
this.spell = spell;
}
compute_func(input_map) {
const build = input_map.get('build');
let stats = build.statMap;
// TODO: apply major ids... DOOM.....
return [this.spell, this.spell.parts];
}
}
/* /*
* Get all defensive stats for this build. * Get all defensive stats for this build.
*/ */
@ -576,15 +554,15 @@ function getDefenseStats(stats) {
* spell-info: [Spell, SpellParts]) => List[SpellDamage] * spell-info: [Spell, SpellParts]) => List[SpellDamage]
*/ */
class SpellDamageCalcNode extends ComputeNode { class SpellDamageCalcNode extends ComputeNode {
constructor(spell_num) { constructor(spell) {
super("builder-spell"+spell_num+"-calc"); super("builder-spell"+spell.base_spell+"-calc");
this.spell = spell;
} }
compute_func(input_map) { compute_func(input_map) {
const weapon = input_map.get('build').weapon.statMap; const weapon = input_map.get('build').weapon.statMap;
const spell_info = input_map.get('spell-info'); const spell = this.spell;
const spell = spell_info[0]; const spell_parts = spell.parts;
const spell_parts = spell_info[1];
const stats = input_map.get('stats'); const stats = input_map.get('stats');
const skillpoints = [ const skillpoints = [
stats.get('str'), stats.get('str'),
@ -593,7 +571,7 @@ class SpellDamageCalcNode extends ComputeNode {
stats.get('def'), stats.get('def'),
stats.get('agi') stats.get('agi')
]; ];
let spell_results = [] let display_spell_results = []
let spell_result_map = new Map(); let spell_result_map = new Map();
const use_speed = (('use_atkspd' in spell) ? spell.use_atkspd : true); const use_speed = (('use_atkspd' in spell) ? spell.use_atkspd : true);
const use_spell = (('scaling' in spell) ? spell.scaling === 'spell' : true); const use_spell = (('scaling' in spell) ? spell.scaling === 'spell' : true);
@ -615,10 +593,12 @@ class SpellDamageCalcNode extends ComputeNode {
} }
} else if ('power' in part) { } else if ('power' in part) {
// TODO: wynn2 formula // TODO: wynn2 formula
let _heal_amount = (part.power * getDefenseStats(stats)[0] * (1+stats.get('healPct')/100)); let heal_additive = stats.get('healPct');
if (stats.has('healPct:'+part_id)) { if (stats.has('healPct:'+part_id)) {
_heal_amount *= 1+(stats.get('healPct:'+part_id)/100); heal_additive += stats.get('healPct:'+part_id);
} }
let heal_mult = 1+(stats.get('healMult') / 100)
let _heal_amount = part.power * getDefenseStats(stats)[0] * (1 + (heal_additive/100)) * heal_mult;
spell_result = { spell_result = {
type: "heal", type: "heal",
heal_amount: _heal_amount heal_amount: _heal_amount
@ -630,7 +610,7 @@ class SpellDamageCalcNode extends ComputeNode {
const {name, display = true} = part; const {name, display = true} = part;
spell_result.name = name; spell_result.name = name;
spell_result.display = display; spell_result.display = display;
spell_results.push(spell_result); display_spell_results.push(spell_result);
spell_result_map.set(name, spell_result); spell_result_map.set(name, spell_result);
} }
for (const part of spell_parts) { for (const part of spell_parts) {
@ -670,10 +650,10 @@ class SpellDamageCalcNode extends ComputeNode {
const {name, display = true} = part; const {name, display = true} = part;
spell_result.name = name; spell_result.name = name;
spell_result.display = display; spell_result.display = display;
spell_results.push(spell_result); display_spell_results.push(spell_result);
spell_result_map.set(name, spell_result); spell_result_map.set(name, spell_result);
} }
return spell_results; return display_spell_results;
} }
} }
@ -687,18 +667,17 @@ class SpellDamageCalcNode extends ComputeNode {
* spell-damage: List[SpellDamage]) => null * spell-damage: List[SpellDamage]) => null
*/ */
class SpellDisplayNode extends ComputeNode { class SpellDisplayNode extends ComputeNode {
constructor(spell_num) { constructor(spell) {
super("builder-spell"+spell_num+"-display"); super("builder-spell"+spell.base_spell+"-display");
this.spell_idx = spell_num; this.spell = spell;
} }
compute_func(input_map) { compute_func(input_map) {
const stats = input_map.get('stats'); const stats = input_map.get('stats');
const spell_info = input_map.get('spell-info');
const damages = input_map.get('spell-damage'); const damages = input_map.get('spell-damage');
const spell = spell_info[0]; const spell = this.spell;
const i = this.spell_idx; const i = this.spell.base_spell;
let parent_elem = document.getElementById("spell"+i+"-info"); let parent_elem = document.getElementById("spell"+i+"-info");
let overallparent_elem = document.getElementById("spell"+i+"-infoAvg"); let overallparent_elem = document.getElementById("spell"+i+"-infoAvg");
displaySpellDamage(parent_elem, overallparent_elem, stats, spell, i, damages); displaySpellDamage(parent_elem, overallparent_elem, stats, spell, i, damages);
@ -862,7 +841,8 @@ let radiance_affected = [ /*"hp"*/, "fDef", "wDef", "aDef", "tDef", "eDef", "hpr
/*"mdPct","mdRaw","sdPct","sdRaw",*/"damPct","damRaw",//"damAddMin","damAddMax", // These are the old ids. Become proportional. /*"mdPct","mdRaw","sdPct","sdRaw",*/"damPct","damRaw",//"damAddMin","damAddMax", // These are the old ids. Become proportional.
"rMdPct","rMdRaw","rSdPct",/*"rSdRaw",*/"rDamPct","rDamRaw",//"rDamAddMin","rDamAddMax", // rainbow (the "element" of all minus neutral). rSdRaw is rainraw "rMdPct","rMdRaw","rSdPct",/*"rSdRaw",*/"rDamPct","rDamRaw",//"rDamAddMin","rDamAddMax", // rainbow (the "element" of all minus neutral). rSdRaw is rainraw
"critDamPct", "critDamPct",
//"spPct1Final", "spPct2Final", "spPct3Final", "spPct4Final" //"spPct1Final", "spPct2Final", "spPct3Final", "spPct4Final",
"healPct", "kb", "weakenEnemy", "slowEnemy", "rDefPct"
]; ];
/** /**
* Scale stats if radiance is enabled. * Scale stats if radiance is enabled.
@ -1057,6 +1037,8 @@ function builder_graph_init(save_skp) {
// "Build" now only refers to equipment and level (no powders). Powders are injected before damage calculation / stat display. // "Build" now only refers to equipment and level (no powders). Powders are injected before damage calculation / stat display.
build_node = new BuildAssembleNode(); build_node = new BuildAssembleNode();
build_node.link_to(level_input); build_node.link_to(level_input);
atree_merge.link_to(build_node, "build");
let build_encode_node = new BuildEncodeNode(); let build_encode_node = new BuildEncodeNode();
build_encode_node.link_to(build_node, 'build'); build_encode_node.link_to(build_node, 'build');

View file

@ -214,14 +214,18 @@ function displayExpandedItem(item, parent_id){
parent_div.appendChild(make_elem("div", ["col"], { textContent: "Set: " + item.get(id).toString() })); parent_div.appendChild(make_elem("div", ["col"], { textContent: "Set: " + item.get(id).toString() }));
} else if (id === "majorIds") { } else if (id === "majorIds") {
//console.log(item.get(id)); //console.log(item.get(id));
for (let majorID of item.get(id)) { for (let major_id_str of item.get(id)) {
if (major_id_str in major_ids) {
let major_id_info = major_ids[major_id_str];
major_id_str = `+${major_id_info.displayName}: ${major_id_info.description}`;
}
let p_elem = make_elem("div", ['col']); let p_elem = make_elem("div", ['col']);
let title_elem = make_elem("b"); let title_elem = make_elem("b");
let b_elem = make_elem("b"); let b_elem = make_elem("b");
if (majorID.includes(":")) { if (major_id_str.includes(":")) {
let name = majorID.substring(0, majorID.indexOf(":")+1); let name = major_id_str.substring(0, major_id_str.indexOf(":")+1);
let mid = majorID.substring(majorID.indexOf(":")+1); let mid = major_id_str.substring(major_id_str.indexOf(":")+1);
if (name.charAt(0) !== "+") {name = "+" + name} if (name.charAt(0) !== "+") {name = "+" + name}
title_elem.classList.add("Legendary"); title_elem.classList.add("Legendary");
title_elem.textContent = name; title_elem.textContent = name;
@ -230,10 +234,9 @@ function displayExpandedItem(item, parent_id){
p_elem.appendChild(title_elem); p_elem.appendChild(title_elem);
p_elem.appendChild(b_elem); p_elem.appendChild(b_elem);
} else { } else {
let name = item.get(id).toString() if (major_id_str.charAt(0) !== "+") {major_id_str = "+" + major_id_str}
if (name.charAt(0) !== "+") {name = "+" + name}
b_elem.classList.add("Legendary"); b_elem.classList.add("Legendary");
b_elem.textContent = name; b_elem.textContent = major_id_str;
p_elem.appendChild(b_elem); p_elem.appendChild(b_elem);
} }
parent_div.appendChild(p_elem); parent_div.appendChild(p_elem);
@ -1180,7 +1183,7 @@ function displayDefenseStats(parent_elem, statMap, insertSummary){
boost.classList.add("text-end"); boost.classList.add("text-end");
let defRaw = statMap.get(skp_elements[i]+"Def"); let defRaw = statMap.get(skp_elements[i]+"Def");
let defPct = statMap.get(skp_elements[i]+"DefPct")/100; let defPct = (statMap.get(skp_elements[i]+"DefPct") + statMap.get('rDefPct'))/100;
if (defRaw < 0) { if (defRaw < 0) {
defPct >= 0 ? defPct = "- " + defPct: defPct = "+ " + defPct; defPct >= 0 ? defPct = "- " + defPct: defPct = "+ " + defPct;
} else { } else {

View file

@ -40,6 +40,7 @@ let idPrefixes = {"displayName": "",
"hpBonus":"Health Bonus: ", "hpBonus":"Health Bonus: ",
"hprRaw":"Raw Health Regen: ", "hprRaw":"Raw Health Regen: ",
"hprPct":"Health Regen %: ", "hprPct":"Health Regen %: ",
"healPct":"Healing Effectiveness %",
"sdRaw":"Spell Damage Raw: ", "sdRaw":"Spell Damage Raw: ",
"rSdRaw":"Elem. Spell Damage Raw: ", "rSdRaw":"Elem. Spell Damage Raw: ",
"nSdRaw":"Neut. Spell Damage Raw: ", "nSdRaw":"Neut. Spell Damage Raw: ",
@ -102,6 +103,7 @@ let idPrefixes = {"displayName": "",
"wDefPct":"Water Defense %: ", "wDefPct":"Water Defense %: ",
"fDefPct":"Fire Defense %: ", "fDefPct":"Fire Defense %: ",
"aDefPct":"Air Defense %: ", "aDefPct":"Air Defense %: ",
"rDefPct":"Elemental Defense %: ",
"spPct1":"1st Spell Cost %: ", "spPct1":"1st Spell Cost %: ",
"spRaw1":"1st Spell Cost Raw: ", "spRaw1":"1st Spell Cost Raw: ",
"spPct2":"2nd Spell Cost %: ", "spPct2":"2nd Spell Cost %: ",
@ -120,6 +122,9 @@ let idPrefixes = {"displayName": "",
"eSteal":"Stealing: ", "eSteal":"Stealing: ",
"gXp":"Gathering XP Bonus: ", "gXp":"Gathering XP Bonus: ",
"gSpd":"Gathering Speed Bonus: ", "gSpd":"Gathering Speed Bonus: ",
"kb":"Knockback: ",
"weakenEnemy":"Weaken Enemy: ",
"slowEnemy":"Slow Enemy: ",
"slots":"Powder Slots: ", "slots":"Powder Slots: ",
"set":"Set: ", "set":"Set: ",
"quest":"Quest Req: ", "quest":"Quest Req: ",
@ -155,6 +160,7 @@ let idSuffixes = {"displayName": "",
"hpBonus":"", "hpBonus":"",
"hprRaw":"", "hprRaw":"",
"hprPct":"%", "hprPct":"%",
"healPct":"%",
"sdRaw":"", "sdRaw":"",
"rSdRaw":"", "rSdRaw":"",
"nSdRaw":"", "nSdRaw":"",
@ -217,6 +223,7 @@ let idSuffixes = {"displayName": "",
"wDefPct":"%", "wDefPct":"%",
"fDefPct":"%", "fDefPct":"%",
"aDefPct":"%", "aDefPct":"%",
"rDefPct":"%",
"spPct1":"%", "spPct1":"%",
"spRaw1":"", "spRaw1":"",
"spPct2":"%", "spPct2":"%",
@ -235,11 +242,14 @@ let idSuffixes = {"displayName": "",
"eSteal":"%", "eSteal":"%",
"gXp":"%", "gXp":"%",
"gSpd":"%", "gSpd":"%",
"kb": "%",
"weakenEnemy": "%",
"slowEnemy": "%",
"slots":"", "slots":"",
"set":" set.", "set":" set.",
"quest":"", "quest":"",
"restrict":"", "restrict":"",
"lore": "" "lore": "",
}; };
//Used for item IDs and ingredient id field IDs //Used for item IDs and ingredient id field IDs
@ -302,6 +312,7 @@ let build_overall_display_commands = [
"spRegen", "spRegen",
"eSteal", "eSteal",
"gXp", "gSpd", "gXp", "gSpd",
"kb", "weakenEnemy", "slowEnemy",
]; ];
let build_detailed_display_commands = [ let build_detailed_display_commands = [
@ -309,7 +320,7 @@ let build_detailed_display_commands = [
"str", "dex", "int", "def", "agi", "str", "dex", "int", "def", "agi",
"!spacer", "!spacer",
"mr", "ms", "mr", "ms",
"hprRaw", "hprPct", "hprRaw", "hprPct", "healPct",
"ls", "ls",
"sdRaw", "nSdRaw", "rSdRaw", "sdRaw", "nSdRaw", "rSdRaw",
"sdPct", "nSdPct", "rSdPct", "sdPct", "nSdPct", "rSdPct",
@ -338,6 +349,7 @@ let build_detailed_display_commands = [
"spRegen", "spRegen",
"eSteal", "eSteal",
"gXp", "gSpd", "gXp", "gSpd",
"kb", "weakenEnemy", "slowEnemy",
]; ];
// full // full
@ -394,7 +406,7 @@ let sq2_item_display_commands = [
"!spacer", "!spacer",
"str", "dex", "int", "def", "agi", "str", "dex", "int", "def", "agi",
"hpBonus", "hpBonus",
"hprRaw", "hprPct", "hprRaw", "hprPct", "healPct",
"mr", "ms", "mr", "ms",
"ref", "thorns", "ref", "thorns",
"ls", "ls",
@ -424,6 +436,7 @@ let sq2_item_display_commands = [
"spRegen", "spRegen",
"eSteal", "eSteal",
"gXp", "gSpd", "gXp", "gSpd",
"kb", "weakenEnemy", "slowEnemy",
"majorIds", "majorIds",
"!spacer", "!spacer",
"slots", "slots",
@ -431,7 +444,7 @@ let sq2_item_display_commands = [
"set", "set",
"lore", "lore",
"quest", "quest",
"restrict" "restrict",
]; ];
let sq2_ing_display_order = [ let sq2_ing_display_order = [

View file

@ -10,154 +10,200 @@
// "Raw Thunder Defense": "tDef", // "Raw Thunder Defense": "tDef",
// "Raw Earth Defense": "eDef", // "Raw Earth Defense": "eDef",
const translate_mappings = { const translate_mappings = {
"Durability": "durability", "Durability": "durability",
"Duration": "duration", "Duration": "duration",
"Charges": "charges", "Charges": "charges",
"Effectiveness Left": "left", "Effectiveness Left": "left",
"Effectiveness Right": "right", "Effectiveness Right": "right",
"Effectiveness Above": "above", "Effectiveness Above": "above",
"Effectiveness Under": "under", "Effectiveness Under": "under",
"Effectiveness Touching": "touching", "Effectiveness Touching": "touching",
"Effectiveness Not Touching": "nottouching", "Effectiveness Not Touching": "nottouching",
"Combat Level": "lvl", "Combat Level": "lvl",
"Req Strength": "strReq", "Req Strength": "strReq",
"Req Dexterity": "dexReq", "Req Dexterity": "dexReq",
"Req Intelligence": "intReq", "Req Intelligence": "intReq",
"Req Agility": "agiReq", "Req Agility": "agiReq",
"Req Defense": "defReq", "Req Defense": "defReq",
"% Health Regen": "hprPct", "% Health Regen": "hprPct",
"Mana Regen": "mr", "Mana Regen": "mr",
"% Spell Damage": "sdPct", "Life Steal": "ls",
"% Melee Damage": "mdPct", "Mana Steal": "ms",
"Life Steal": "ls", "XP Bonus": "xpb",
"Mana Steal": "ms", "Loot Bonus": "lb",
"XP Bonus": "xpb", "Reflection": "ref",
"Loot Bonus": "lb", "Strength": "str",
"Reflection": "ref", "Dexterity": "dex",
"Strength": "str", "Intelligence": "int",
"Dexterity": "dex", "Agility": "agi",
"Intelligence": "int", "Defense": "def",
"Agility": "agi", "Thorns": "thorns",
"Defense": "def", "Exploding": "expd",
"Thorns": "thorns", "Walk Speed": "spd",
"Exploding": "expd", "Attack Speed Bonus": "atkTier",
"Walk Speed": "spd", "Poison": "poison",
"Attack Speed Bonus": "atkTier", "Health Bonus": "hpBonus",
"Poison": "poison", "Soul Point Regen": "spRegen",
"Health Bonus": "hpBonus", "Stealing": "eSteal",
"Soul Point Regen": "spRegen", "Raw Health Regen": "hprRaw",
"Stealing": "eSteal", "Spell Damage Raw: ": "sdRaw",
"Raw Health Regen": "hprRaw", "Elem. Spell Damage Raw: ": "rSdRaw",
"Raw Spell": "sdRaw", "Neut. Spell Damage Raw: ": "nSdRaw",
"Raw Melee": "mdRaw", "Earth Spell Damage Raw: ": "eSdRaw",
"% Fire Damage": "fDamPct", "Thunder Spell Damage Raw: ": "tSdRaw",
"% Water Damage": "wDamPct", "Water Spell Damage Raw: ": "wSdRaw",
"% Air Damage": "aDamPct", "Fire Spell Damage Raw: ": "fSdRaw",
"% Thunder Damage": "tDamPct", "Air Spell Damage Raw: ": "aSdRaw",
"% Earth Damage": "eDamPct", "Spell Damage %: ": "sdPct",
"% Fire Defense": "fDefPct", "Elem. Spell Damage %: ": "rSdPct",
"% Water Defense": "wDefPct", "Neut. Spell Damage %: ": "nSdPct",
"% Air Defense": "aDefPct", "Earth Spell Damage %: ": "eSdPct",
"% Thunder Defense": "tDefPct", "Thunder Spell Damage %: ": "tSdPct",
"% Earth Defense": "eDefPct", "Water Spell Damage %: ": "wSdPct",
"1st Spell Cost %": "-spPct1", "Fire Spell Damage %: ": "fSdPct",
"1st Spell Cost Raw": "-spRaw1", "Air Spell Damage %: ": "aSdPct",
"2nd Spell Cost %": "-spPct2", "Melee Damage Raw: ": "mdRaw",
"2nd Spell Cost Raw": "-spRaw2", "Elem. Melee Damage Raw: ": "rMdRaw",
"3rd Spell Cost %": "-spPct3", "Neut. Melee Damage Raw: ": "nMdRaw",
"3rd Spell Cost Raw": "-spRaw3", "Earth Melee Damage Raw: ": "eMdRaw",
"4th Spell Cost %": "-spPct4", "Thunder Melee Damage Raw: ": "tMdRaw",
"4th Spell Cost Raw": "-spRaw4", "Water Melee Damage Raw: ": "wMdRaw",
"Rainbow Spell Damage Raw": "rainbowRaw", "Fire Melee Damage Raw: ": "fMdRaw",
"Sprint": "sprint", "Air Melee Damage Raw: ": "aMdRaw",
"Sprint Regen": "sprintReg", "Melee Damage %: ": "mdPct",
"Jump Height": "jh", "Elem. Melee Damage %: ": "rMdPct",
"Loot Quality": "lq", "Neut. Melee Damage %: ": "nMdPct",
"Gather XP Bonus": "gXp", "Earth Melee Damage %: ": "eMdPct",
"Gather Speed Bonus": "gSpd" "Thunder Melee Damage %: ": "tMdPct",
}; "Water Melee Damage %: ": "wMdPct",
"Fire Melee Damage %: ": "fMdPct",
const special_mappings = { "Air Melee Damage %: ": "aMdPct",
"Sum (skill points)": "str+dex+int+def+agi", "Damage Raw: ": "damRaw",
"Sum (Mana Sustain)": "mr+ms", "Elemental Damage Raw: ": "rDamRaw",
"Sum (Life Sustain)": "hpr+ls", "Neutral Damage Raw: ": "nDamRaw",
"Sum (Effectiveness)": "7/3 * touching + 8/3 * nottouching + 2/3 * (top + bottom) + 1/2 * (left + right)" "Earth Damage Raw: ": "eDamRaw",
}; "Thunder Damage Raw: ": "tDamRaw",
"Water Damage Raw: ": "wDamRaw",
for (let x in translate_mappings) { "Fire Damage Raw: ": "fDamRaw",
item_filters.push(x); "Air Damage Raw: ": "aDamRaw",
} "Damage %: ": "damPct",
for (let x in special_mappings) { "Elemental Damage %: ": "rDamPct",
item_filters.push(x); "Neutral Damage %: ": "nDamPct",
} "Earth Damage %: ": "eDamPct",
"Thunder Damage %: ": "tDamPct",
"Water Damage %: ": "wDamPct",
"Fire Damage %: ": "fDamPct",
"Air Damage %: ": "aDamPct",
types = {armouring: false, tailoring: false, weaponsmithing: false, woodworking: false, jeweling: false, cooking: false, alchemism: false, scribing: false}; "% Fire Defense": "fDefPct",
search_tiers = {zero: true, one: true, two: true, three: true}; "% Water Defense": "wDefPct",
"% Air Defense": "aDefPct",
function display(ing_copy) { "% Thunder Defense": "tDefPct",
let ing_parent = document.getElementById("search-results"); "% Earth Defense": "eDefPct",
for (let i in ing_copy) { "% Elemental Defense": "rDefPct",
if (i > 200) {break;}
let ing = ing_copy[i].itemExp;
let box = make_elem('div', ['ing-stats', 'col-lg-3', 'p-2', 'col-sm-6'], {id: 'ing'+i});
let bckgrdbox = make_elem('div', ["rounded", "g-0", "dark-7", "border", "border-dark", "dark-shadow", "p-3", "col-auto"], {id: 'ing'+i+'b'});
box.append(bckgrdbox);
ing_parent.appendChild(box);
displayExpandedIngredient(ing, bckgrdbox.id, true); "1st Spell Cost %": "-spPct1",
"1st Spell Cost Raw": "-spRaw1",
"2nd Spell Cost %": "-spPct2",
"2nd Spell Cost Raw": "-spRaw2",
"3rd Spell Cost %": "-spPct3",
"3rd Spell Cost Raw": "-spRaw3",
"4th Spell Cost %": "-spPct4",
"4th Spell Cost Raw": "-spRaw4",
"Rainbow Spell Damage Raw": "rainbowRaw",
"Sprint": "sprint",
"Sprint Regen": "sprintReg",
"Jump Height": "jh",
"Loot Quality": "lq",
"Gather XP Bonus": "gXp",
"Gather Speed Bonus": "gSpd",
"Healing Efficiency": "healPct",
"Knockback": "kb",
"Weaken Enemy": "weakenEnemy",
"Slow Enemy": "slowEnemy"
};
const special_mappings = {
"Sum (skill points)": "str+dex+int+def+agi",
"Sum (Mana Sustain)": "mr+ms",
"Sum (Life Sustain)": "hpr+ls",
"Sum (Effectiveness)": "7/3 * touching + 8/3 * nottouching + 2/3 * (top + bottom) + 1/2 * (left + right)"
};
for (let x in translate_mappings) {
item_filters.push(x);
}
for (let x in special_mappings) {
item_filters.push(x);
}
types = {armouring: false, tailoring: false, weaponsmithing: false, woodworking: false, jeweling: false, cooking: false, alchemism: false, scribing: false};
search_tiers = {zero: true, one: true, two: true, three: true};
function display(ing_copy) {
let ing_parent = document.getElementById("search-results");
for (let i in ing_copy) {
if (i > 200) {break;}
let ing = ing_copy[i].itemExp;
let box = make_elem('div', ['ing-stats', 'col-lg-3', 'p-2', 'col-sm-6'], {id: 'ing'+i});
let bckgrdbox = make_elem('div', ["rounded", "g-0", "dark-7", "border", "border-dark", "dark-shadow", "p-3", "col-auto"], {id: 'ing'+i+'b'});
box.append(bckgrdbox);
ing_parent.appendChild(box);
displayExpandedIngredient(ing, bckgrdbox.id, true);
}
}
function filter_types_tiers(queries) {
// type
let allTypes = true, noTypes = true;
let typeQuery = "f:("
for (const type of Object.keys(types)) {
if (types[type]) {
typeQuery += type + "|";
noTypes = false;
} else {
allTypes = false;
} }
} }
if (noTypes) {
function filter_types_tiers(queries) { document.getElementById("summary").innerHTML = "Error: Cannot search without at least 1 type selected";
// type return false;
let allTypes = true, noTypes = true; } else if (!allTypes) {
let typeQuery = "f:(" queries.push(typeQuery.substring(0, typeQuery.length - 1) + ")");
for (const type of Object.keys(types)) {
if (types[type]) {
typeQuery += type + "|";
noTypes = false;
} else {
allTypes = false;
}
}
if (noTypes) {
document.getElementById("summary").innerHTML = "Error: Cannot search without at least 1 type selected";
return false;
} else if (!allTypes) {
queries.push(typeQuery.substring(0, typeQuery.length - 1) + ")");
}
// stars
let allStars = true, noStars = true;
let starQuery = "f:("
for (const star of Object.keys(search_tiers)) {
if (search_tiers[star]) {
starQuery += "starsname=\"" + star + "\"|";
noStars = false;
} else {
allStars = false;
}
}
if (noStars) {
document.getElementById("summary").innerHTML = "Error: Cannot search without at least 1 star selected";
return false;
} else if (!allStars) {
queries.push(starQuery.substring(0, starQuery.length - 1) + ")");
}
return true;
} }
function init_values() { // stars
search_db = ings.filter( i => ! i.remapID ).map( i => [i, expandIngredient(i, [])] ); let allStars = true, noStars = true;
expr_parser = new ExprParser(ingredientQueryProps, queryFuncs); let starQuery = "f:("
for (const star of Object.keys(search_tiers)) {
if (search_tiers[star]) {
starQuery += "starsname=\"" + star + "\"|";
noStars = false;
} else {
allStars = false;
}
} }
if (noStars) {
(async function() { document.getElementById("summary").innerHTML = "Error: Cannot search without at least 1 star selected";
await Promise.resolve(load_ing_init()); return false;
init_search(); } else if (!allStars) {
})(); queries.push(starQuery.substring(0, starQuery.length - 1) + ")");
}
return true;
}
function init_values() {
search_db = ings.filter( i => ! i.remapID ).map( i => [i, expandIngredient(i, [])] );
expr_parser = new ExprParser(ingredientQueryProps, queryFuncs);
}
(async function() {
await Promise.resolve(load_ing_init());
init_search();
})();

View file

@ -56,18 +56,62 @@ const translate_mappings = {
"Soul Point Regen": "spRegen", "Soul Point Regen": "spRegen",
"Stealing": "eSteal", "Stealing": "eSteal",
"Raw Health Regen": "hprRaw", "Raw Health Regen": "hprRaw",
"Raw Spell": "sdRaw", "Spell Damage Raw: ": "sdRaw",
"Raw Melee": "mdRaw", "Elem. Spell Damage Raw: ": "rSdRaw",
"% Fire Damage": "fDamPct", "Neut. Spell Damage Raw: ": "nSdRaw",
"% Water Damage": "wDamPct", "Earth Spell Damage Raw: ": "eSdRaw",
"% Air Damage": "aDamPct", "Thunder Spell Damage Raw: ": "tSdRaw",
"% Thunder Damage": "tDamPct", "Water Spell Damage Raw: ": "wSdRaw",
"% Earth Damage": "eDamPct", "Fire Spell Damage Raw: ": "fSdRaw",
"Air Spell Damage Raw: ": "aSdRaw",
"Spell Damage %: ": "sdPct",
"Elem. Spell Damage %: ": "rSdPct",
"Neut. Spell Damage %: ": "nSdPct",
"Earth Spell Damage %: ": "eSdPct",
"Thunder Spell Damage %: ": "tSdPct",
"Water Spell Damage %: ": "wSdPct",
"Fire Spell Damage %: ": "fSdPct",
"Air Spell Damage %: ": "aSdPct",
"Melee Damage Raw: ": "mdRaw",
"Elem. Melee Damage Raw: ": "rMdRaw",
"Neut. Melee Damage Raw: ": "nMdRaw",
"Earth Melee Damage Raw: ": "eMdRaw",
"Thunder Melee Damage Raw: ": "tMdRaw",
"Water Melee Damage Raw: ": "wMdRaw",
"Fire Melee Damage Raw: ": "fMdRaw",
"Air Melee Damage Raw: ": "aMdRaw",
"Melee Damage %: ": "mdPct",
"Elem. Melee Damage %: ": "rMdPct",
"Neut. Melee Damage %: ": "nMdPct",
"Earth Melee Damage %: ": "eMdPct",
"Thunder Melee Damage %: ": "tMdPct",
"Water Melee Damage %: ": "wMdPct",
"Fire Melee Damage %: ": "fMdPct",
"Air Melee Damage %: ": "aMdPct",
"Damage Raw: ": "damRaw",
"Elemental Damage Raw: ": "rDamRaw",
"Neutral Damage Raw: ": "nDamRaw",
"Earth Damage Raw: ": "eDamRaw",
"Thunder Damage Raw: ": "tDamRaw",
"Water Damage Raw: ": "wDamRaw",
"Fire Damage Raw: ": "fDamRaw",
"Air Damage Raw: ": "aDamRaw",
"Damage %: ": "damPct",
"Elemental Damage %: ": "rDamPct",
"Neutral Damage %: ": "nDamPct",
"Earth Damage %: ": "eDamPct",
"Thunder Damage %: ": "tDamPct",
"Water Damage %: ": "wDamPct",
"Fire Damage %: ": "fDamPct",
"Air Damage %: ": "aDamPct",
"% Fire Defense": "fDefPct", "% Fire Defense": "fDefPct",
"% Water Defense": "wDefPct", "% Water Defense": "wDefPct",
"% Air Defense": "aDefPct", "% Air Defense": "aDefPct",
"% Thunder Defense": "tDefPct", "% Thunder Defense": "tDefPct",
"% Earth Defense": "eDefPct", "% Earth Defense": "eDefPct",
"% Elemental Defense": "rDefPct",
"1st Spell Cost %": "-spPct1", "1st Spell Cost %": "-spPct1",
"1st Spell Cost Raw": "-spRaw1", "1st Spell Cost Raw": "-spRaw1",
"2nd Spell Cost %": "-spPct2", "2nd Spell Cost %": "-spPct2",
@ -76,13 +120,16 @@ const translate_mappings = {
"3rd Spell Cost Raw": "-spRaw3", "3rd Spell Cost Raw": "-spRaw3",
"4th Spell Cost %": "-spPct4", "4th Spell Cost %": "-spPct4",
"4th Spell Cost Raw": "-spRaw4", "4th Spell Cost Raw": "-spRaw4",
"Rainbow Spell Damage Raw": "rainbowRaw",
"Sprint": "sprint", "Sprint": "sprint",
"Sprint Regen": "sprintReg", "Sprint Regen": "sprintReg",
"Jump Height": "jh", "Jump Height": "jh",
"Loot Quality": "lq", "Loot Quality": "lq",
"Gather XP Bonus": "gXp", "Gather XP Bonus": "gXp",
"Gather Speed Bonus": "gSpd" "Gather Speed Bonus": "gSpd",
"Healing Efficiency": "healPct",
"Knockback": "kb",
"Weaken Enemy": "weakenEnemy",
"Slow Enemy": "slowEnemy"
}; };
const special_mappings = { const special_mappings = {
@ -170,6 +217,6 @@ function init_values() {
} }
(async function() { (async function() {
await Promise.resolve(load_init()); await Promise.resolve(load_init(), load_major_id_data(wynn_version_names[WYNN_VERSION_LATEST]));
init_search(); init_search();
})(); })();

View file

@ -53,6 +53,6 @@ function display(itemExp, id) {
} }
(async function() { (async function() {
await Promise.resolve(load_init()); await Promise.resolve(load_init(), load_major_id_data(wynn_version_names[WYNN_VERSION_LATEST]));
init_items_adv(); init_items_adv();
})(); })();

View file

@ -1,4 +1,4 @@
const DB_VERSION = 126; const DB_VERSION = 128;
// @See https://github.com/mdn/learning-area/blob/master/javascript/apis/client-side-storage/indexeddb/video-store/index.jsA // @See https://github.com/mdn/learning-area/blob/master/javascript/apis/client-side-storage/indexeddb/video-store/index.jsA
let db; let db;

View file

@ -1,4 +1,4 @@
const ING_DB_VERSION = 22; const ING_DB_VERSION = 25;
// @See https://github.com/mdn/learning-area/blob/master/javascript/apis/client-side-storage/indexeddb/video-store/index.js // @See https://github.com/mdn/learning-area/blob/master/javascript/apis/client-side-storage/indexeddb/video-store/index.js
@ -71,7 +71,7 @@ async function load_ings_old_version(version_str) {
clean_ing(ings[id]); clean_ing(ings[id]);
} }
url = baseUrl + "/recipes_compress.json"; url = `${baseUrl}/data/${version_str}/recipes.json`;
result = await (await fetch(url)).json(); result = await (await fetch(url)).json();
recipes = result.recipes; recipes = result.recipes;

View file

@ -299,7 +299,8 @@ const ingredientQueryProps = (function() {
maxId(['waterdef%', 'wdef%', 'wdefpct'], 'wDefPct'); maxId(['waterdef%', 'wdef%', 'wdefpct'], 'wDefPct');
maxId(['firedef%', 'fdef%', 'fdefpct'], 'fDefPct'); maxId(['firedef%', 'fdef%', 'fdefpct'], 'fDefPct');
maxId(['airdef%', 'adef%', 'adefpct'], 'aDefPct'); maxId(['airdef%', 'adef%', 'adefpct'], 'aDefPct');
sum(['sumdef%', 'totaldef%', 'sumdefpct', 'totaldefpct'], props.edefpct, props.tdefpct, props.wdefpct, props.fdefpct, props.adefpct); maxId(['elementaldef%', 'rdef%', 'rdefpct'], 'rDefPct');
sum(['sumdef%', 'totaldef%', 'sumdefpct', 'totaldefpct'], props.edefpct, props.tdefpct, props.wdefpct, props.fdefpct, props.adefpct, props.rDefPct);
maxId(['bonushealth', 'healthid', 'bonushp', 'hpid', 'hpbonus'], 'hpBonus'); maxId(['bonushealth', 'healthid', 'bonushp', 'hpid', 'hpbonus'], 'hpBonus');
@ -335,7 +336,11 @@ const ingredientQueryProps = (function() {
maxId(['stealing', 'esteal'], 'eSteal'); maxId(['stealing', 'esteal'], 'eSteal');
maxId(['lq', 'quality'], 'lq'); maxId(['lq', 'quality'], 'lq');
maxId('gxp', 'gXp'); maxId('gxp', 'gXp');
maxId(['gspd'], 'gSpd'); maxId('gspd', 'gSpd');
maxId(['healeff', 'healpct'], 'healPct');
maxId('kb', 'kb');
maxId('weakenenemy', 'weakenEnemy');
maxId('slowenemy', 'slowEnemy');
return props; return props;
})(); })();

View file

@ -89,6 +89,16 @@ with open("atree_constants.js") as f:
translate_id(abilDict, data) translate_id(abilDict, data)
with open("major_ids_clean.json") as maj_id_file:
maj_id_dat = json.load(maj_id_file)
for k, v in maj_id_dat.items():
for abil in v['abilities']:
clazz = abil['class']
base_abil = abil['base_abil']
abil['base_abil'] = abilDict[clazz][base_abil]
with open("major_ids_min.json", "w", encoding='utf-8') as maj_id_out:
json.dump(maj_id_dat, maj_id_out, ensure_ascii=False, separators=(',', ':'))
data_str = json.dumps(data, ensure_ascii=False, separators=(',', ':')) data_str = json.dumps(data, ensure_ascii=False, separators=(',', ':'))
data_str = "const atrees=" + data_str data_str = "const atrees=" + data_str
with open('atree_constants_min.js', 'w', encoding='utf-8') as abil_dest: with open('atree_constants_min.js', 'w', encoding='utf-8') as abil_dest:

View file

@ -32,11 +32,13 @@ elif req.lower() == "ings":
for i in range(4): for i in range(4):
response['ings'].extend(requests.get("https://api.wynncraft.com/v2/ingredient/search/tier/" + str(i)).json()['data']) response['ings'].extend(requests.get("https://api.wynncraft.com/v2/ingredient/search/tier/" + str(i)).json()['data'])
elif req.lower() == "recipes": elif req.lower() == "recipes":
temp = requests.get("https://api.wynncraft.com/v2/recipe/list") import time
temp = requests.get("https://api.wynncraft.com/v2/recipe/list").json()
response = {"recipes":[]} response = {"recipes":[]}
for i in range(len(temp['data'])): for i in range(len(temp['data'])):
response["recipes"].extend(requests.get("https://api.wynncraft.com/v2/recipe/get/" + temp['data'][i]).json()['data']) response["recipes"].extend(requests.get("https://api.wynncraft.com/v2/recipe/get/" + temp['data'][i]).json()['data'])
print("" + str(i) + " / " + str(len(temp['data']))) print("" + str(i) + " / " + str(len(temp['data'])))
time.sleep(1)
elif req.lower() == "terrs": elif req.lower() == "terrs":
response = requests.get("https://api.wynncraft.com/public_api.php?action=territoryList").json()['territories'] response = requests.get("https://api.wynncraft.com/public_api.php?action=territoryList").json()['territories']
delkeys = ["territory","acquired","attacker"] delkeys = ["territory","acquired","attacker"]

View file

@ -3802,5 +3802,44 @@
"Eleventh Hour": 3800, "Eleventh Hour": 3800,
"Epilogue": 3801, "Epilogue": 3801,
"Prologue": 3802, "Prologue": 3802,
"Gleeman's Tale": 3803 "Gleeman's Tale": 3803,
"Elemental Training Dagger": 3804,
"Elemental Training Bow": 3805,
"Elemental Training Relik": 3806,
"Elemental Training Wand": 3807,
"Elemental Training Spear": 3808,
"Gladiator": 3809,
"Folklore": 3810,
"Mythos": 3811,
"Anti-Causality": 3812,
"Apex": 3813,
"Cinnamon": 3814,
"Azeotrope": 3815,
"Briars' Embrace": 3816,
"Cytotoxic Striders": 3817,
"Fluffwind": 3818,
"Keeper of Souls": 3819,
"Gnossis": 3820,
"Gravitron": 3821,
"Marionette": 3822,
"Payment Day": 3823,
"Resplendence": 3824,
"Tachyon": 3825,
"Empyreal Emberplate": 3826,
"Lazuli": 3827,
"Sourscratch": 3828,
"Pyrrhic Respite": 3829,
"Third Wish": 3830,
"Veritas": 3831,
"Ysengrim": 3832,
"Valence": 3833,
"Harmstick": 3834,
"Overreach": 3835,
"Apex Predator": 3836,
"Atavistic": 3837,
"Extinction": 3838,
"Symbiont": 3839,
"Roiling Ruckus": 3840,
"Zeer ID Test": 3841,
"Zeer ID Test2": 3842
} }

View file

@ -730,5 +730,36 @@
"Blazing Stimulants": 728, "Blazing Stimulants": 728,
"Icy Crampons": 729, "Icy Crampons": 729,
"Sanctified Sheep Soul": 730, "Sanctified Sheep Soul": 730,
"Solcrystal Horn": 731 "Solcrystal Horn": 731,
"Charcoal Lump": 732,
"Chunky Ash": 733,
"Cystic Lard": 734,
"Sunken Scales": 735,
"Twisted Coral": 736,
"Withered Root": 737,
"Angler's Light": 738,
"Deepborn Scavenger": 739,
"Essence of Dissolution": 740,
"Ice Silver": 741,
"Igneous Thread": 742,
"Impure Nullity": 743,
"Lactic Acid Crystal": 744,
"Obsidian Shards": 745,
"Warm Fleris": 746,
"Bioluminescent Blood": 747,
"Epipelagic Eye": 748,
"Flerisi Bark": 749,
"Giant Teratoma": 750,
"Hollow Psyche": 751,
"Peculiar Oddity": 752,
"Pluripotent Tissue": 753,
"Psionic Quill": 754,
"Subjoined Brain": 755,
"Amber-Encased Fleris": 756,
"Depurinated Genome": 757,
"Fathomflooded Flesh": 758,
"Rejected Geode": 759,
"Remnant of the Ruined": 760,
"Searing Heartwood": 761,
"Voidtossed Memory": 762
} }

View file

@ -128,6 +128,12 @@ translate_mappings = {
"gatherXpBonus": "gXp", "gatherXpBonus": "gXp",
"gatherSpeed": "gSpd", "gatherSpeed": "gSpd",
"healingEfficiency": "healPct",
"knockback": "kb",
"weakenEnemy": "weakenEnemy",
"slowEnemy": "slowEnemy",
"elementalDefense": "rDefPct",
} }
delete_keys = [ delete_keys = [

File diff suppressed because it is too large Load diff

File diff suppressed because one or more lines are too long