commit
b07d4d2fa5
5 changed files with 46 additions and 42 deletions
|
@ -8,7 +8,7 @@ The game, of course
|
||||||
Additional Contributors, in no particular order:
|
Additional Contributors, in no particular order:
|
||||||
- Kiocifer (Icons!)
|
- Kiocifer (Icons!)
|
||||||
- IncinerateMe (helping transition to 1.20.3 / CI helper)
|
- IncinerateMe (helping transition to 1.20.3 / CI helper)
|
||||||
- puppy (wynn2 ability tree help)
|
- dog (wynn2 ability tree help)
|
||||||
- SockMower (ability tree encode/decode optimization)
|
- SockMower (ability tree encode/decode optimization)
|
||||||
- ITechnically (coding emotional support / misc)
|
- ITechnically (coding emotional support / misc)
|
||||||
- touhoku (best IM)
|
- touhoku (best IM)
|
||||||
|
|
27
js/atree.js
27
js/atree.js
|
@ -451,22 +451,24 @@ const atree_collect_spells = new (class extends ComputeNode {
|
||||||
let ret_spells = new Map();
|
let ret_spells = new Map();
|
||||||
for (const [abil_id, abil] of atree_merged.entries()) {
|
for (const [abil_id, abil] of atree_merged.entries()) {
|
||||||
// TODO: Possibly, make a better way for detecting "spell abilities"?
|
// TODO: Possibly, make a better way for detecting "spell abilities"?
|
||||||
if (abil.effects.length == 0) { continue; }
|
|
||||||
|
|
||||||
let ret_spell = deepcopy(abil.effects[0]); // NOTE: do not mutate results of previous steps!
|
|
||||||
let has_spell_def = false;
|
|
||||||
for (const effect of abil.effects) {
|
for (const effect of abil.effects) {
|
||||||
if (effect.type === 'replace_spell') {
|
if (effect.type === 'replace_spell') {
|
||||||
has_spell_def = true;
|
|
||||||
// replace_spell just replaces all (defined) aspects.
|
// replace_spell just replaces all (defined) aspects.
|
||||||
for (const key in effect) {
|
const ret_spell = ret_spells.get(effect.base_spell);
|
||||||
ret_spell[key] = deepcopy(effect[key]);
|
if (ret_spell) {
|
||||||
|
// NOTE: do not mutate results of previous steps!
|
||||||
|
for (const key in effect) {
|
||||||
|
ret_spell[key] = deepcopy(effect[key]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ret_spells.set(effect.base_spell, deepcopy(effect));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!has_spell_def) { continue; }
|
}
|
||||||
|
|
||||||
const base_spell_id = ret_spell.base_spell;
|
for (const [abil_id, abil] of atree_merged.entries()) {
|
||||||
for (const effect of abil.effects) {
|
for (const effect of abil.effects) {
|
||||||
switch (effect.type) {
|
switch (effect.type) {
|
||||||
case 'replace_spell':
|
case 'replace_spell':
|
||||||
|
@ -474,7 +476,7 @@ const atree_collect_spells = new (class extends ComputeNode {
|
||||||
continue;
|
continue;
|
||||||
case 'add_spell_prop': {
|
case 'add_spell_prop': {
|
||||||
const { base_spell, target_part = null, cost = 0, behavior = 'merge'} = effect;
|
const { base_spell, target_part = null, cost = 0, behavior = 'merge'} = effect;
|
||||||
if (base_spell !== base_spell_id) { continue; } // TODO: redundant? if we assume abils only affect one spell
|
const ret_spell = ret_spells.get(base_spell);
|
||||||
// TODO: unjankify this... if ('cost' in ret_spell) { ret_spell.cost += cost; }
|
// TODO: unjankify this... if ('cost' in ret_spell) { ret_spell.cost += cost; }
|
||||||
|
|
||||||
if (target_part === null) {
|
if (target_part === null) {
|
||||||
|
@ -496,7 +498,7 @@ const atree_collect_spells = new (class extends ComputeNode {
|
||||||
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)
|
||||||
if (idx in part.hits) { part.hits[idx] += v; }
|
if (idx in part.hits) { part.hits[idx] += v; }
|
||||||
else { part.hits[idx] = v; }
|
else { part.hits[idx] = v; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
throw "uhh invalid spell add effect";
|
throw "uhh invalid spell add effect";
|
||||||
|
@ -517,7 +519,7 @@ const atree_collect_spells = new (class extends ComputeNode {
|
||||||
}
|
}
|
||||||
case 'convert_spell_conv':
|
case 'convert_spell_conv':
|
||||||
const { base_spell, target_part, conversion } = effect;
|
const { base_spell, target_part, conversion } = effect;
|
||||||
if (base_spell !== base_spell_id) { continue; } // TODO: redundant? if we assume abils only affect one spell
|
const ret_spell = ret_spells.get(base_spell);
|
||||||
const elem_idx = damageClasses.indexOf(conversion);
|
const elem_idx = damageClasses.indexOf(conversion);
|
||||||
let filter = target_part === 'all';
|
let filter = target_part === 'all';
|
||||||
for (let part of ret_spell.parts) { // TODO: replace with Map? to avoid this linear search... idk prolly good since its not more verbose to type in json
|
for (let part of ret_spell.parts) { // TODO: replace with Map? to avoid this linear search... idk prolly good since its not more verbose to type in json
|
||||||
|
@ -536,7 +538,6 @@ const atree_collect_spells = new (class extends ComputeNode {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ret_spells.set(base_spell_id, ret_spell);
|
|
||||||
}
|
}
|
||||||
return ret_spells;
|
return ret_spells;
|
||||||
}
|
}
|
||||||
|
|
|
@ -341,7 +341,6 @@ const atrees = {
|
||||||
"desc": "When you hit the ground with Arrow Bomb, leave a Trap that damages enemies. (Max 2 Traps)",
|
"desc": "When you hit the ground with Arrow Bomb, leave a Trap that damages enemies. (Max 2 Traps)",
|
||||||
"archetype": "Trapper",
|
"archetype": "Trapper",
|
||||||
"archetype_req": 2,
|
"archetype_req": 2,
|
||||||
"base_abil": "Arrow Bomb",
|
|
||||||
"parents": ["Bryophyte Roots"],
|
"parents": ["Bryophyte Roots"],
|
||||||
"dependencies": [],
|
"dependencies": [],
|
||||||
"blockers": [],
|
"blockers": [],
|
||||||
|
@ -357,10 +356,17 @@ const atrees = {
|
||||||
},
|
},
|
||||||
"effects": [
|
"effects": [
|
||||||
{
|
{
|
||||||
"type": "add_spell_prop",
|
"type": "replace_spell",
|
||||||
"base_spell": 3,
|
"name": "Basaltic Trap",
|
||||||
"target_part": "Basaltic Trap",
|
"base_spell": 7,
|
||||||
"multipliers": [140, 30, 0, 0, 30, 0]
|
"display": "Trap Damage",
|
||||||
|
"parts": [
|
||||||
|
{
|
||||||
|
"name": "Trap Damage",
|
||||||
|
"type": "damage",
|
||||||
|
"multipliers": [140, 30, 0, 0, 30, 0]
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
@ -581,7 +587,7 @@ const atrees = {
|
||||||
"desc": "Your Traps will give you 2.85 Mana per second when you stay close to them.",
|
"desc": "Your Traps will give you 2.85 Mana per second when you stay close to them.",
|
||||||
"archetype": "Trapper",
|
"archetype": "Trapper",
|
||||||
"archetype_req": 5,
|
"archetype_req": 5,
|
||||||
"base_abil": "Arrow Bomb",
|
"base_abil": "Basaltic Trap",
|
||||||
"parents": ["More Traps", "Better Arrow Shield"],
|
"parents": ["More Traps", "Better Arrow Shield"],
|
||||||
"dependencies": [],
|
"dependencies": [],
|
||||||
"blockers": [],
|
"blockers": [],
|
||||||
|
@ -794,6 +800,7 @@ const atrees = {
|
||||||
"desc": "Your Traps will be connected by a rope that deals damage to enemies every 0.2s.",
|
"desc": "Your Traps will be connected by a rope that deals damage to enemies every 0.2s.",
|
||||||
"archetype": "Trapper",
|
"archetype": "Trapper",
|
||||||
"archetype_req": 0,
|
"archetype_req": 0,
|
||||||
|
"base_abil": "Basaltic Trap",
|
||||||
"parents": ["Grape Bomb"],
|
"parents": ["Grape Bomb"],
|
||||||
"dependencies": ["Basaltic Trap"],
|
"dependencies": ["Basaltic Trap"],
|
||||||
"blockers": [],
|
"blockers": [],
|
||||||
|
@ -804,20 +811,16 @@ const atrees = {
|
||||||
},
|
},
|
||||||
"effects": [
|
"effects": [
|
||||||
{
|
{
|
||||||
"type": "replace_spell",
|
"type": "add_spell_prop",
|
||||||
"name": "Tangled Traps",
|
"base_spell": 7,
|
||||||
"base_spell": 7,
|
"target_part": "Line Damage Tick",
|
||||||
"display": "DPS",
|
"multipliers": [20, 0, 0, 0, 0, 20]
|
||||||
"parts": [
|
},
|
||||||
{
|
{
|
||||||
"name": "Damage Tick",
|
"type": "add_spell_prop",
|
||||||
"multipliers": [20, 0, 0, 0, 0, 20]
|
"base_spell": 7,
|
||||||
},
|
"target_part": "DPS",
|
||||||
{
|
"hits": { "Line Damage Tick": 5 }
|
||||||
"name": "DPS",
|
|
||||||
"hits": { "Damage Tick": 5 }
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
@ -874,7 +877,7 @@ const atrees = {
|
||||||
"desc": "Allow you to place +6 Traps, but with reduced damage and range.",
|
"desc": "Allow you to place +6 Traps, but with reduced damage and range.",
|
||||||
"archetype": "Trapper",
|
"archetype": "Trapper",
|
||||||
"archetype_req": 10,
|
"archetype_req": 10,
|
||||||
"base_abil": "Arrow Bomb",
|
"base_abil": "Basaltic Trap",
|
||||||
"parents": ["Grape Bomb", "Cheaper Arrow Bomb (2)"],
|
"parents": ["Grape Bomb", "Cheaper Arrow Bomb (2)"],
|
||||||
"dependencies": ["Basaltic Trap"],
|
"dependencies": ["Basaltic Trap"],
|
||||||
"blockers": [],
|
"blockers": [],
|
||||||
|
@ -884,8 +887,8 @@ const atrees = {
|
||||||
"effects": [
|
"effects": [
|
||||||
{
|
{
|
||||||
"type": "add_spell_prop",
|
"type": "add_spell_prop",
|
||||||
"base_spell": 3,
|
"base_spell": 8,
|
||||||
"target_part": "Basaltic Trap",
|
"target_part": "Trap Damage",
|
||||||
"cost": 0,
|
"cost": 0,
|
||||||
"multipliers": [-80, 0, 0, 0, 0, 0]
|
"multipliers": [-80, 0, 0, 0, 0, 0]
|
||||||
},
|
},
|
||||||
|
@ -1262,7 +1265,7 @@ const atrees = {
|
||||||
"desc": "Increase the maximum amount of active Traps you can have by +2.",
|
"desc": "Increase the maximum amount of active Traps you can have by +2.",
|
||||||
"archetype": "Trapper",
|
"archetype": "Trapper",
|
||||||
"archetype_req": 0,
|
"archetype_req": 0,
|
||||||
"base_abil": "Arrow Bomb",
|
"base_abil": "Basaltic Trap",
|
||||||
"parents": ["Bouncing Bomb"],
|
"parents": ["Bouncing Bomb"],
|
||||||
"dependencies": ["Basaltic Trap"],
|
"dependencies": ["Basaltic Trap"],
|
||||||
"blockers": [],
|
"blockers": [],
|
||||||
|
@ -1781,7 +1784,7 @@ const atrees = {
|
||||||
"desc": "Your Traps will deal +20% more damage for every second they are active (Max +80%)",
|
"desc": "Your Traps will deal +20% more damage for every second they are active (Max +80%)",
|
||||||
"archetype": "Trapper",
|
"archetype": "Trapper",
|
||||||
"archetype_req": 0,
|
"archetype_req": 0,
|
||||||
"base_abil": "Arrow Bomb",
|
"base_abil": "Basaltic Trap",
|
||||||
"parents": ["More Shields"],
|
"parents": ["More Shields"],
|
||||||
"dependencies": ["Basaltic Trap"],
|
"dependencies": ["Basaltic Trap"],
|
||||||
"blockers": [],
|
"blockers": [],
|
||||||
|
@ -1812,7 +1815,7 @@ const atrees = {
|
||||||
"desc": "Add +80% Max Damage to Patient Hunter",
|
"desc": "Add +80% Max Damage to Patient Hunter",
|
||||||
"archetype": "Trapper",
|
"archetype": "Trapper",
|
||||||
"archetype_req": 0,
|
"archetype_req": 0,
|
||||||
"base_abil": "Arrow Bomb",
|
"base_abil": "Basaltic Trap",
|
||||||
"parents": ["Grape Bomb"],
|
"parents": ["Grape Bomb"],
|
||||||
"dependencies": ["Patient Hunter"],
|
"dependencies": ["Patient Hunter"],
|
||||||
"blockers": [],
|
"blockers": [],
|
||||||
|
|
File diff suppressed because one or more lines are too long
|
@ -976,7 +976,7 @@ class SkillPointSetterNode extends ComputeNode {
|
||||||
class SumNumberInputNode extends InputNode {
|
class SumNumberInputNode extends InputNode {
|
||||||
compute_func(input_map) {
|
compute_func(input_map) {
|
||||||
let value = this.input_field.value;
|
let value = this.input_field.value;
|
||||||
if (value === "") { value = 0; }
|
if (value === "") { value = "0"; }
|
||||||
|
|
||||||
let input_num = 0;
|
let input_num = 0;
|
||||||
if (value.includes("+")) {
|
if (value.includes("+")) {
|
||||||
|
|
Loading…
Reference in a new issue