Reworked master modifiers; working sliders

This commit is contained in:
hppeng 2022-07-07 22:28:46 -07:00
parent a4eda17f4e
commit 70c117261d
7 changed files with 85 additions and 51 deletions

View file

@ -563,7 +563,7 @@ const atree_collect_spells = new (class extends ComputeNode {
/**
* Make interactive elements (sliders, buttons)
*
* Signature: AbilityActiveUINode(atree-merged: MergedATree) => List[ElemState]
* Signature: AbilityActiveUINode(atree-merged: MergedATree) => Map<str, slider_info>
*
* ElemState: {
* value: int // value for sliders; 0-1 for toggles
@ -578,12 +578,13 @@ const atree_make_interactives = new (class extends ComputeNode {
const atree_html = input_map.get('atree-elements');
/**
* slider_info {
* slider_info
* label_name: str,
* max: int,
* step: int,
* id: str,
* abil: atree_node
* slider: html element
* }
*/
// Map<str, slider_info>
@ -615,8 +616,10 @@ const atree_make_interactives = new (class extends ComputeNode {
for (const [slider_name, slider_info] of slider_map.entries()) {
let slider_container = gen_slider_labeled(slider_info);
atree_html.get(slider_info.abil.id).appendChild(slider_container);
slider_info.slider = document.getElementById(slider_info.id);
slider_info.slider.addEventListener("change", (e) => atree_stats.mark_dirty().update());
}
//return ret_states;
return slider_map;
}
})().link_to(atree_node, 'atree-order').link_to(atree_merge, 'atree-merged').link_to(atree_render_active, 'atree-elements');
@ -625,7 +628,7 @@ const atree_make_interactives = new (class extends ComputeNode {
* Collect stats from ability tree.
* Return StatMap of added stats (incl. cost modifications as raw cost)
*
* Signature: AbilityTreeStatsNode(atree-merged: MergedATree) => StatMap
* Signature: AbilityTreeStatsNode(atree-merged: MergedATree, build: Build, atree-interactive: Map<str, slider_info>) => StatMap
*/
const atree_stats = new (class extends ComputeNode {
constructor() { super('atree-stats-collector'); }
@ -633,6 +636,7 @@ const atree_stats = new (class extends ComputeNode {
compute_func(input_map) {
const atree_merged = input_map.get('atree-merged');
const item_stats = input_map.get('build').statMap;
const interactive_map = input_map.get('atree-interactive');
let ret_effects = new Map();
for (const [abil_id, abil] of atree_merged.entries()) {
@ -643,6 +647,20 @@ const atree_stats = new (class extends ComputeNode {
case 'stat_scaling':
if (effect.slider) {
// TODO: handle
const slider_val = interactive_map.get(effect.slider_name).slider.value;
const total = parseInt(slider_val) * effect.scaling[0];
if (Array.isArray(effect.output)) {
for (const output of effect.output) {
if (output.type === 'stat') {
merge_stat(ret_effects, output.name, total);
}
}
}
else {
if (effect.output.type === 'stat') {
merge_stat(ret_effects, effect.output.name, total);
}
}
}
else {
const cap = effect.max;
@ -691,11 +709,11 @@ const atree_stats = new (class extends ComputeNode {
}
}
if (ret_effects.has('baseResist')) {
merge_stat(ret_effects, "defMultiplier", 1 - (ret_effects.get('baseResist') / 100));
merge_stat(ret_effects, "defMult", 1 - (ret_effects.get('baseResist') / 100));
}
return ret_effects;
}
})().link_to(atree_merge, 'atree-merged');
})().link_to(atree_merge, 'atree-merged').link_to(atree_make_interactives, 'atree-interactive');
/**

View file

@ -1688,7 +1688,7 @@ const atrees = {
"slider_name": "Focus",
"output": {
"type": "stat",
"name": "damMult"
"name": "damMult.Focus"
},
"scaling": [40],
"slider_max": 3
@ -1717,7 +1717,7 @@ const atrees = {
"slider_max": 2,
"output": {
"type": "stat",
"name": "damMult"
"name": "damMult.Focus"
},
"scaling": [-5]
}]
@ -1745,7 +1745,7 @@ const atrees = {
"slider_max": 2,
"output": {
"type": "stat",
"name": "damMult"
"name": "damMult.Focus"
},
"scaling": [-5]
}]
@ -1803,7 +1803,7 @@ const atrees = {
"slider_max": 4,
"output": {
"type": "stat",
"name": "damMult:Basaltic Trap"
"name": "damMult.Basaltic:Basaltic Trap"
},
"slider_step": 1,
"scaling": [20]
@ -1967,7 +1967,7 @@ const atrees = {
"slider_max": 7,
"output": {
"type": "stat",
"name": "damMult:Single Arrow"
"name": "damMult.Decimator:Single Arrow"
},
"scaling": 10
}]
@ -2227,7 +2227,7 @@ const atrees = {
"bonuses": [
{
"type": "stat",
"name": "baseResist",
"name": "defMult.Base",
"value": 5
}
]
@ -2775,7 +2775,7 @@ const atrees = {
{
"type": "raw_stat",
"toggle": true,
"bonuses": [{ "type": "stat", "name": "defMultiplier", "value": 0.3}]
"bonuses": [{ "type": "stat", "name": "defMult.Mantle", "value": 70}]
}
]
},
@ -2986,7 +2986,7 @@ const atrees = {
"slider_name": "Corrupted",
"output": {
"type": "stat",
"name": "damMult"
"name": "damMult.Enraged"
},
"scaling": [3]
}
@ -3130,7 +3130,7 @@ const atrees = {
{
"type": "raw_stat",
"toggle": true,
"bonuses": [ {"type": "stat", "name": "damMult", "value": 30} ]
"bonuses": [ {"type": "stat", "name": "damMult.Ragnarokkr", "value": 30} ]
}
]
},
@ -3438,7 +3438,7 @@ const atrees = {
"bonuses": [
{
"type": "stat",
"name": "baseResist",
"name": "defMult.Base",
"value": 5
}
]
@ -3468,7 +3468,7 @@ const atrees = {
{
"type": "raw_stat",
"toggle": true,
"bonuses": [ {"type": "stat", "name": "damMult", "value": 30} ]
"bonuses": [ {"type": "stat", "name": "damMult.ArmorBreaker", "value": 30} ]
}
]
},
@ -3924,7 +3924,7 @@ const atrees = {
{
"type": "raw_stat",
"toggle": true,
"bonuses": [{ "type": "stat", "name": "defMultiplier", "value": 0.6}]
"bonuses": [{ "type": "stat", "name": "defMult.Brink", "value": 40}]
}
]
},

File diff suppressed because one or more lines are too long

View file

@ -83,7 +83,6 @@ class Build{
//Create a map of this build's stats
let statMap = new Map();
statMap.set("defMultiplier", 1);
for (const staticID of staticIDs) {
statMap.set(staticID, 0);
@ -113,8 +112,10 @@ class Build{
}
}
}
statMap.set('damageMultiplier', 1 + (statMap.get('damMobs') / 100));
statMap.set('defMultiplier', 1 - (statMap.get('defMobs') / 100));
statMap.set('damMult', new Map());
statMap.set('defMult', new Map());
statMap.get('damMult').set('tome', statMap.get('damMobs'))
statMap.get('defMult').set('tome', statMap.get('defMobs'))
statMap.set("activeMajorIDs", major_ids);
for (const [setName, count] of this.activeSetCounts) {
const bonus = sets.get(setName).bonuses[count-1];

View file

@ -74,17 +74,17 @@ 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",
// wynn2 damages.
"eMdPct","eMdRaw","eSdPct","eSdRaw",/*"eDamPct"*/,"eDamRaw","eDamAddMin","eDamAddMax",
"tMdPct","tMdRaw","tSdPct","tSdRaw",/*"tDamPct"*/,"tDamRaw","tDamAddMin","tDamAddMax",
"wMdPct","wMdRaw","wSdPct","wSdRaw",/*"wDamPct"*/,"wDamRaw","wDamAddMin","wDamAddMax",
"fMdPct","fMdRaw","fSdPct","fSdRaw",/*"fDamPct"*/,"fDamRaw","fDamAddMin","fDamAddMax",
"aMdPct","aMdRaw","aSdPct","aSdRaw",/*"aDamPct"*/,"aDamRaw","aDamAddMin","aDamAddMax",
"eMdPct","eMdRaw","eSdPct","eSdRaw",/*"eDamPct,"*/"eDamRaw","eDamAddMin","eDamAddMax",
"tMdPct","tMdRaw","tSdPct","tSdRaw",/*"tDamPct,"*/"tDamRaw","tDamAddMin","tDamAddMax",
"wMdPct","wMdRaw","wSdPct","wSdRaw",/*"wDamPct,"*/"wDamRaw","wDamAddMin","wDamAddMax",
"fMdPct","fMdRaw","fSdPct","fSdRaw",/*"fDamPct,"*/"fDamRaw","fDamAddMin","fDamAddMax",
"aMdPct","aMdRaw","aSdPct","aSdRaw",/*"aDamPct,"*/"aDamRaw","aDamAddMin","aDamAddMax",
"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.
"rMdPct","rMdRaw","rSdPct",/*"rSdRaw",*/"rDamPct","rDamRaw","rDamAddMin","rDamAddMax", // rainbow (the "element" of all minus neutral). rSdRaw is rainraw
"critDamPct"
];
// Extra fake IDs (reserved for use in spell damage calculation) : damageMultiplier, defMultiplier, 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" ]
//File reading for ID translations for JSON purposes
@ -169,11 +169,11 @@ let rolledIDs = [
"gXp",
"gSpd",
// wynn2 damages.
"eMdPct","eMdRaw","eSdPct","eSdRaw",/*"eDamPct"*/,"eDamRaw","eDamAddMin","eDamAddMax",
"tMdPct","tMdRaw","tSdPct","tSdRaw",/*"tDamPct"*/,"tDamRaw","tDamAddMin","tDamAddMax",
"wMdPct","wMdRaw","wSdPct","wSdRaw",/*"wDamPct"*/,"wDamRaw","wDamAddMin","wDamAddMax",
"fMdPct","fMdRaw","fSdPct","fSdRaw",/*"fDamPct"*/,"fDamRaw","fDamAddMin","fDamAddMax",
"aMdPct","aMdRaw","aSdPct","aSdRaw",/*"aDamPct"*/,"aDamRaw","aDamAddMin","aDamAddMax",
"eMdPct","eMdRaw","eSdPct","eSdRaw",/*"eDamPct,"*/"eDamRaw","eDamAddMin","eDamAddMax",
"tMdPct","tMdRaw","tSdPct","tSdRaw",/*"tDamPct,"*/"tDamRaw","tDamAddMin","tDamAddMax",
"wMdPct","wMdRaw","wSdPct","wSdRaw",/*"wDamPct,"*/"wDamRaw","wDamAddMin","wDamAddMax",
"fMdPct","fMdRaw","fSdPct","fSdRaw",/*"fDamPct,"*/"fDamRaw","fDamAddMin","fDamAddMax",
"aMdPct","aMdRaw","aSdPct","aSdRaw",/*"aDamPct,"*/"aDamRaw","aDamAddMin","aDamAddMax",
"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.
"rMdPct","rMdRaw","rSdPct",/*"rSdRaw",*/"rDamPct","rDamRaw","rDamAddMin","rDamAddMax" // rainbow (the "element" of all minus neutral). rSdRaw is rainraw
@ -305,11 +305,23 @@ function idRound(id){
* stupid stupid multiplicative stats
*/
function merge_stat(stats, name, value) {
if (stats.has(name)) {
if (name === 'damageMultiplier' || name === 'defMultiplier') {
stats.set(name, stats.get(name) * value);
const start = name.slice(0, 7);
if (start === 'damMult' || start === 'defMult') {
if (!stats.has(start)) {
stats.set(start, new Map());
}
else { stats.set(name, stats.get(name) + value); }
const map = stats.get(start);
if (value instanceof Map) {
for (const [k, v] of value.entries()) {
merge_stat(map, k, v);
}
return;
}
merge_stat(map, name.slice(8), value);
return;
}
if (stats.has(name)) {
stats.set(name, stats.get(name) + value);
}
else { stats.set(name, value); }
}

View file

@ -28,8 +28,8 @@ let boosts_node = new (class extends ComputeNode {
}
}
let res = new Map();
res.set('damageMultiplier', 1+damage_boost);
res.set('defMultiplier', 1-def_boost);
res.set('damMult.Potion', 100*damage_boost);
res.set('defMult.Potion', 100*def_boost);
return res;
}
})().update();
@ -489,7 +489,10 @@ function getDefenseStats(stats) {
defenseStats.push(totalHp);
//EHP
let ehp = [totalHp, totalHp];
let defMult = (2 - stats.get("classDef")) * stats.get("defMultiplier");
let defMult = (2 - stats.get("classDef"));
for (const [k, v] of stats.get("defMult").entries()) {
defMult *= (1 - v/100);
}
// newehp = oldehp / [0.1 * A(x) + (1 - A(x)) * (1 - D(x))]
ehp[0] = ehp[0] / (0.1*agi_pct + (1-agi_pct) * (1-def_pct));
ehp[0] /= defMult;
@ -536,7 +539,6 @@ class SpellDamageCalcNode extends ComputeNode {
const spell = spell_info[0];
const spell_parts = spell_info[1];
const stats = input_map.get('stats');
const damage_mult = stats.get('damageMultiplier');
const skillpoints = [
stats.get('str'),
stats.get('dex'),
@ -673,7 +675,7 @@ function getMeleeStats(stats, weapon) {
}
if (weapon_stats.get("type") === "relik") {
stats.set('damageMultiplier', 0.99); // CURSE YOU WYNNCRAFT
merge_stat(stats, 'damMult.ShamanMelee', 0.99); // CURSE YOU WYNNCRAFT
//One day we will create WynnWynn and no longer have shaman 99% melee injustice.
//In all seriousness 99% is because wynn uses 0.33 to estimate dividing the damage by 3 to split damage between 3 beams.
}
@ -841,13 +843,7 @@ class AggregateStatsNode extends ComputeNode {
const output_stats = new Map();
for (const [k, v] of input_map.entries()) {
for (const [k2, v2] of v.entries()) {
if (output_stats.has(k2)) {
// TODO: ugly AF
merge_stat(output_stats, k2, v2);
}
else {
output_stats.set(k2, v2);
}
merge_stat(output_stats, k2, v2);
}
}
return output_stats;

View file

@ -26,7 +26,7 @@ function get_base_dps(item) {
}
function calculateSpellDamage(stats, weapon, conversions, use_spell_damage, ignore_speed=false) {
function calculateSpellDamage(stats, weapon, conversions, use_spell_damage, ignore_speed=false, part=undefined) {
// TODO: Roll all the loops together maybe
// Array of neutral + ewtfa damages. Each entry is a pair (min, max).
@ -154,7 +154,14 @@ function calculateSpellDamage(stats, weapon, conversions, use_spell_damage, igno
let total_dam_norm = [0, 0];
let total_dam_crit = [0, 0];
let damages_results = [];
const damage_mult = stats.get("damageMultiplier");
const mult_map = stats.get("damMult");
console.log(mult_map);
let damage_mult = 1;
for (const [k, v] of mult_map.entries()) {
damage_mult *= (1 + v/100);
}
console.log(damage_mult);
for (const damage of damages) {
const res = [