From 6997cd9821449e286fffd4821b42ea9104e47a68 Mon Sep 17 00:00:00 2001 From: Sabe Jones Date: Sat, 28 Dec 2013 11:56:36 -0600 Subject: [PATCH 1/5] Implement new "flat" and "classbased" automatic allocation modes --- dist/habitrpg-shared.js | 79 +++++++++++++++++++++++++++++++---------- script/index.coffee | 31 ++++++++++++++-- 2 files changed, 88 insertions(+), 22 deletions(-) diff --git a/dist/habitrpg-shared.js b/dist/habitrpg-shared.js index b0ad765900..5c5f2fa0a8 100644 --- a/dist/habitrpg-shared.js +++ b/dist/habitrpg-shared.js @@ -63,7 +63,7 @@ process.chdir = function (dir) { }; },{}],3:[function(require,module,exports){ -var global=self;/** +var global=typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {};/** * @license * Lo-Dash 2.4.1 (Custom Build) * Build: `lodash modern -o ./dist/lodash.js` @@ -11937,7 +11937,7 @@ var process=require("__browserify_process");(function() { */ updateStats: function(stats) { - var suggested, tallies, tnl; + var diff, ideal, lowest, preference, suggested, tallies, tnl; if (stats.hp <= 0) { return user.stats.hp = 0; } @@ -11956,23 +11956,64 @@ var process=require("__browserify_process");(function() { user.stats.lvl++; tnl = api.tnl(user.stats.lvl); if (user.preferences.automaticAllocation) { - tallies = _.reduce(user.tasks, (function(m, v) { - m[v.attribute || 'str'] += v.value; - return m; - }), { - str: 0, - int: 0, - con: 0, - per: 0 - }); - suggested = _.reduce(tallies, (function(m, v, k) { - if (v > tallies[m]) { - return k; - } else { - return m; - } - }), 'str'); - user.stats[suggested]++; + switch (user.preferences.allocationMode) { + case "flat": + lowest = Math.min(user.stats.str, user.stats.int, user.stats.con, user.stats.per); + if (user.stats.int === lowest) { + user.stats.int++; + } else if (user.stats.per === lowest) { + user.stats.per++; + } else if (user.stats.str === lowest) { + user.stats.str++; + } else { + user.stats.con++; + } + break; + case "classbased": + ideal = [user.stats.lvl / 7, user.stats.lvl / 7, user.stats.lvl / 7 * 2, user.stats.lvl / 7 * 3]; + if (user.stats["class"] === "wizard") { + preference = ["con", "str", "per", "int"]; + } else if (user.stats["class"] === "rogue") { + preference = ["int", "con", "str", "per"]; + } else if (user.stats["class"] === "healer") { + preference = ["str", "per", "int", "con"]; + } else { + preference = ["per", "int", "con", "str"]; + } + diff = [user.stats[preference[0]] - ideal[0], user.stats[preference[1]] - ideal[1], user.stats[preference[2]] - ideal[2], user.stats[preference[3]] - ideal[3]]; + suggested = _.findIndex(diff, (function(val) { + if (val === _.min(diff)) { + return true; + } + })); + if (suggested === -1) { + user.stats.str++; + } else { + user.stats[preference[suggested]]++; + } + break; + case "taskbased": + tallies = _.reduce(user.tasks, (function(m, v) { + m[v.attribute || 'str'] += v.value; + return m; + }), { + str: 0, + int: 0, + con: 0, + per: 0 + }); + suggested = _.reduce(tallies, (function(m, v, k) { + if (v > tallies[m]) { + return k; + } else { + return m; + } + }), 'str'); + user.stats[suggested]++; + break; + default: + user.stats.str++; + } } else { user.stats.points = user.stats.lvl - (user.stats.con + user.stats.str + user.stats.per + user.stats.int); } diff --git a/script/index.coffee b/script/index.coffee index a9cccf5f8f..40ff23d45b 100644 --- a/script/index.coffee +++ b/script/index.coffee @@ -962,9 +962,34 @@ api.wrap = (user) -> # Auto-allocate a point, or give them a new manual point if user.preferences.automaticAllocation - tallies = _.reduce user.tasks, ((m,v)-> m[v.attribute or 'str'] += v.value;m), {str:0,int:0,con:0,per:0} - suggested = _.reduce tallies, ((m,v,k)-> if v>tallies[m] then k else m), 'str' - user.stats[suggested]++ + switch user.preferences.allocationMode + when "flat" + lowest = Math.min(user.stats.str, user.stats.int, user.stats.con, user.stats.per) + if user.stats.int is lowest # In case of ties, favor INT first, to get the next point sooner + user.stats.int++ + else if user.stats.per is lowest # Then favor PER, it's a god stat + user.stats.per++ + else if user.stats.str is lowest # Then favor STR, everyone loves crits + user.stats.str++ + else + user.stats.con++ # CON, the unsexiest of attributes + when "classbased" + # Attributes get 3:2:1:1 per 7 levels. But put dump stats up front so they're favored in ties ("building the foundation of the pyramid") + ideal = [(user.stats.lvl / 7), (user.stats.lvl / 7), (user.stats.lvl / 7 * 2), (user.stats.lvl / 7 * 3)] # Tertiary, quaternary, secondary, primary + # Primary, secondary etc. attributes aren't explicitly defined, so hardcode them. In order per above + if user.stats.class is "wizard" then preference = ["con", "str", "per", "int"] + else if user.stats.class is "rogue" then preference = ["int", "con", "str", "per"] + else if user.stats.class is "healer" then preference = ["str", "per", "int", "con"] + else preference = ["per", "int", "con", "str"] + # Get the difference between the ideal attribute spread according to level, and the user's current spread. + diff = [(user.stats[preference[0]]-ideal[0]),(user.stats[preference[1]]-ideal[1]),(user.stats[preference[2]]-ideal[2]),(user.stats[preference[3]]-ideal[3])] + suggested = _.findIndex(diff, ((val) -> if val is _.min(diff) then true)) # Returns the index of the first attribute that's furthest behind the ideal + if suggested is -1 then user.stats.str++ else user.stats[preference[suggested]]++ # If _findIndex failed, we'd get a -1... + when "taskbased" # old logic, temp + tallies = _.reduce user.tasks, ((m,v)-> m[v.attribute or 'str'] += v.value;m), {str:0,int:0,con:0,per:0} + suggested = _.reduce tallies, ((m,v,k)-> if v>tallies[m] then k else m), 'str' + user.stats[suggested]++ + else user.stats.str++ # if all else fails, dump into STR else # add new allocatable points. We could do user.stats.points++, but this does a fail-safe just in case user.stats.points = user.stats.lvl - (user.stats.con + user.stats.str + user.stats.per + user.stats.int); From 0478323efc564b5a74ce8a07572e28cd1963ada3 Mon Sep 17 00:00:00 2001 From: Sabe Jones Date: Sat, 28 Dec 2013 17:26:17 -0600 Subject: [PATCH 2/5] Change out one if chain for a switch, put stats in 3:2:1:1 order in code (@paglias) --- dist/habitrpg-shared.js | 32 ++++++++++++++++++-------------- script/index.coffee | 21 +++++++++++---------- 2 files changed, 29 insertions(+), 24 deletions(-) diff --git a/dist/habitrpg-shared.js b/dist/habitrpg-shared.js index 5c5f2fa0a8..9940e66987 100644 --- a/dist/habitrpg-shared.js +++ b/dist/habitrpg-shared.js @@ -11937,7 +11937,7 @@ var process=require("__browserify_process");(function() { */ updateStats: function(stats) { - var diff, ideal, lowest, preference, suggested, tallies, tnl; + var diff, ideal, preference, suggested, tallies, tnl; if (stats.hp <= 0) { return user.stats.hp = 0; } @@ -11958,27 +11958,31 @@ var process=require("__browserify_process");(function() { if (user.preferences.automaticAllocation) { switch (user.preferences.allocationMode) { case "flat": - lowest = Math.min(user.stats.str, user.stats.int, user.stats.con, user.stats.per); - if (user.stats.int === lowest) { + suggested = Math.min(user.stats.str, user.stats.int, user.stats.con, user.stats.per); + if (user.stats.int === suggested) { user.stats.int++; - } else if (user.stats.per === lowest) { + } else if (user.stats.per === suggested) { user.stats.per++; - } else if (user.stats.str === lowest) { + } else if (user.stats.str === suggested) { user.stats.str++; } else { user.stats.con++; } break; case "classbased": - ideal = [user.stats.lvl / 7, user.stats.lvl / 7, user.stats.lvl / 7 * 2, user.stats.lvl / 7 * 3]; - if (user.stats["class"] === "wizard") { - preference = ["con", "str", "per", "int"]; - } else if (user.stats["class"] === "rogue") { - preference = ["int", "con", "str", "per"]; - } else if (user.stats["class"] === "healer") { - preference = ["str", "per", "int", "con"]; - } else { - preference = ["per", "int", "con", "str"]; + ideal = [user.stats.lvl / 7 * 3, user.stats.lvl / 7 * 2, user.stats.lvl / 7, user.stats.lvl / 7]; + switch (user.stats["class"]) { + case "wizard": + preference = ["int", "per", "con", "str"]; + break; + case "rogue": + preference = ["per", "str", "int", "con"]; + break; + case "healer": + preference = ["con", "int", "str", "per"]; + break; + default: + preference = ["str", "con", "per", "int"]; } diff = [user.stats[preference[0]] - ideal[0], user.stats[preference[1]] - ideal[1], user.stats[preference[2]] - ideal[2], user.stats[preference[3]] - ideal[3]]; suggested = _.findIndex(diff, (function(val) { diff --git a/script/index.coffee b/script/index.coffee index 40ff23d45b..27e3e983f0 100644 --- a/script/index.coffee +++ b/script/index.coffee @@ -964,23 +964,24 @@ api.wrap = (user) -> if user.preferences.automaticAllocation switch user.preferences.allocationMode when "flat" - lowest = Math.min(user.stats.str, user.stats.int, user.stats.con, user.stats.per) - if user.stats.int is lowest # In case of ties, favor INT first, to get the next point sooner + suggested = Math.min(user.stats.str, user.stats.int, user.stats.con, user.stats.per) + if user.stats.int is suggested # In case of ties, favor INT first, to get the next point sooner user.stats.int++ - else if user.stats.per is lowest # Then favor PER, it's a god stat + else if user.stats.per is suggested # Then favor PER, it's a god stat user.stats.per++ - else if user.stats.str is lowest # Then favor STR, everyone loves crits + else if user.stats.str is suggested # Then favor STR, everyone loves crits user.stats.str++ else user.stats.con++ # CON, the unsexiest of attributes when "classbased" - # Attributes get 3:2:1:1 per 7 levels. But put dump stats up front so they're favored in ties ("building the foundation of the pyramid") - ideal = [(user.stats.lvl / 7), (user.stats.lvl / 7), (user.stats.lvl / 7 * 2), (user.stats.lvl / 7 * 3)] # Tertiary, quaternary, secondary, primary + # Attributes get 3:2:1:1 per 7 levels. + ideal = [(user.stats.lvl / 7 * 3), (user.stats.lvl / 7 * 2), (user.stats.lvl / 7), (user.stats.lvl / 7)] # Primary, secondary etc. attributes aren't explicitly defined, so hardcode them. In order per above - if user.stats.class is "wizard" then preference = ["con", "str", "per", "int"] - else if user.stats.class is "rogue" then preference = ["int", "con", "str", "per"] - else if user.stats.class is "healer" then preference = ["str", "per", "int", "con"] - else preference = ["per", "int", "con", "str"] + switch user.stats.class + when "wizard" then preference = ["int", "per", "con", "str"] + when "rogue" then preference = ["per", "str", "int", "con"] + when "healer" then preference = ["con", "int", "str", "per"] + else preference = ["str", "con", "per", "int"] # Get the difference between the ideal attribute spread according to level, and the user's current spread. diff = [(user.stats[preference[0]]-ideal[0]),(user.stats[preference[1]]-ideal[1]),(user.stats[preference[2]]-ideal[2]),(user.stats[preference[3]]-ideal[3])] suggested = _.findIndex(diff, ((val) -> if val is _.min(diff) then true)) # Returns the index of the first attribute that's furthest behind the ideal From 9f4efc31ed2c16c9a7a3cec8efc82617a3b7009d Mon Sep 17 00:00:00 2001 From: Sabe Jones Date: Mon, 30 Dec 2013 11:39:53 -0600 Subject: [PATCH 3/5] Break out autoAllocate to its own function --- dist/habitrpg-shared.js | 130 +++++++++++++++++++++------------------- script/index.coffee | 62 ++++++++++--------- 2 files changed, 100 insertions(+), 92 deletions(-) diff --git a/dist/habitrpg-shared.js b/dist/habitrpg-shared.js index 518e0b51f3..19b4142610 100644 --- a/dist/habitrpg-shared.js +++ b/dist/habitrpg-shared.js @@ -11962,8 +11962,72 @@ var process=require("__browserify_process");(function() { {update} if aggregated changes, pass in userObj as update. otherwise commits will be made immediately */ + autoAllocate: function() { + var diff, ideal, preference, suggested, tallies; + switch (user.preferences.allocationMode) { + case "flat": + suggested = Math.min(user.stats.str, user.stats.int, user.stats.con, user.stats.per); + if (user.stats.int === suggested) { + return "int"; + } else if (user.stats.per === suggested) { + return "per"; + } else if (user.stats.str === suggested) { + return "per"; + } else { + return "con"; + } + break; + case "classbased": + ideal = [user.stats.lvl / 7 * 3, user.stats.lvl / 7 * 2, user.stats.lvl / 7, user.stats.lvl / 7]; + switch (user.stats["class"]) { + case "wizard": + preference = ["int", "per", "con", "str"]; + break; + case "rogue": + preference = ["per", "str", "int", "con"]; + break; + case "healer": + preference = ["con", "int", "str", "per"]; + break; + default: + preference = ["str", "con", "per", "int"]; + } + diff = [user.stats[preference[0]] - ideal[0], user.stats[preference[1]] - ideal[1], user.stats[preference[2]] - ideal[2], user.stats[preference[3]] - ideal[3]]; + suggested = _.findIndex(diff, (function(val) { + if (val === _.min(diff)) { + return true; + } + })); + if (suggested === -1) { + return "str"; + } else { + return preference[suggested]; + } + break; + case "taskbased": + tallies = _.reduce(user.tasks, (function(m, v) { + m[v.attribute || 'str'] += v.value; + return m; + }), { + str: 0, + int: 0, + con: 0, + per: 0 + }); + suggested = _.reduce(tallies, (function(m, v, k) { + if (v > tallies[m]) { + return k; + } else { + return m; + } + }), 'str'); + return suggested; + default: + return "str"; + } + }, updateStats: function(stats) { - var diff, ideal, preference, suggested, tallies, tnl; + var suggested, tnl; if (stats.hp <= 0) { return user.stats.hp = 0; } @@ -11982,68 +12046,8 @@ var process=require("__browserify_process");(function() { user.stats.lvl++; tnl = api.tnl(user.stats.lvl); if (user.preferences.automaticAllocation) { - switch (user.preferences.allocationMode) { - case "flat": - suggested = Math.min(user.stats.str, user.stats.int, user.stats.con, user.stats.per); - if (user.stats.int === suggested) { - user.stats.int++; - } else if (user.stats.per === suggested) { - user.stats.per++; - } else if (user.stats.str === suggested) { - user.stats.str++; - } else { - user.stats.con++; - } - break; - case "classbased": - ideal = [user.stats.lvl / 7 * 3, user.stats.lvl / 7 * 2, user.stats.lvl / 7, user.stats.lvl / 7]; - switch (user.stats["class"]) { - case "wizard": - preference = ["int", "per", "con", "str"]; - break; - case "rogue": - preference = ["per", "str", "int", "con"]; - break; - case "healer": - preference = ["con", "int", "str", "per"]; - break; - default: - preference = ["str", "con", "per", "int"]; - } - diff = [user.stats[preference[0]] - ideal[0], user.stats[preference[1]] - ideal[1], user.stats[preference[2]] - ideal[2], user.stats[preference[3]] - ideal[3]]; - suggested = _.findIndex(diff, (function(val) { - if (val === _.min(diff)) { - return true; - } - })); - if (suggested === -1) { - user.stats.str++; - } else { - user.stats[preference[suggested]]++; - } - break; - case "taskbased": - tallies = _.reduce(user.tasks, (function(m, v) { - m[v.attribute || 'str'] += v.value; - return m; - }), { - str: 0, - int: 0, - con: 0, - per: 0 - }); - suggested = _.reduce(tallies, (function(m, v, k) { - if (v > tallies[m]) { - return k; - } else { - return m; - } - }), 'str'); - user.stats[suggested]++; - break; - default: - user.stats.str++; - } + suggested = user.fns.autoAllocate(); + user.stats[suggested]++; } else { user.stats.points = user.stats.lvl - (user.stats.con + user.stats.str + user.stats.per + user.stats.int); } diff --git a/script/index.coffee b/script/index.coffee index eb6d254a56..da65b9ac0f 100644 --- a/script/index.coffee +++ b/script/index.coffee @@ -941,6 +941,37 @@ api.wrap = (user) -> {stats} new stats {update} if aggregated changes, pass in userObj as update. otherwise commits will be made immediately ### + autoAllocate: -> + switch user.preferences.allocationMode + when "flat" + suggested = Math.min(user.stats.str, user.stats.int, user.stats.con, user.stats.per) + if user.stats.int is suggested # In case of ties, favor INT first, to get the next point sooner + return "int" + else if user.stats.per is suggested # Then favor PER, it's a god stat + return "per" + else if user.stats.str is suggested # Then favor STR, everyone loves crits + return "per" + else + return "con" # CON, the unsexiest of attributes + when "classbased" + # Attributes get 3:2:1:1 per 7 levels. + ideal = [(user.stats.lvl / 7 * 3), (user.stats.lvl / 7 * 2), (user.stats.lvl / 7), (user.stats.lvl / 7)] + # Primary, secondary etc. attributes aren't explicitly defined, so hardcode them. In order as above + switch user.stats.class + when "wizard" then preference = ["int", "per", "con", "str"] + when "rogue" then preference = ["per", "str", "int", "con"] + when "healer" then preference = ["con", "int", "str", "per"] + else preference = ["str", "con", "per", "int"] + # Get the difference between the ideal attribute spread according to level, and the user's current spread. + diff = [(user.stats[preference[0]]-ideal[0]),(user.stats[preference[1]]-ideal[1]),(user.stats[preference[2]]-ideal[2]),(user.stats[preference[3]]-ideal[3])] + suggested = _.findIndex(diff, ((val) -> if val is _.min(diff) then true)) # Returns the index of the first attribute that's furthest behind the ideal + if suggested is -1 then return "str" else return preference[suggested] # If _findIndex failed, we'd get a -1... + when "taskbased" # old logic, temp + tallies = _.reduce user.tasks, ((m,v)-> m[v.attribute or 'str'] += v.value;m), {str:0,int:0,con:0,per:0} + suggested = _.reduce tallies, ((m,v,k)-> if v>tallies[m] then k else m), 'str' + return suggested + else return "str" # if all else fails, dump into STR + updateStats: (stats) -> # Game Over return user.stats.hp=0 if stats.hp <= 0 @@ -966,35 +997,8 @@ api.wrap = (user) -> # Auto-allocate a point, or give them a new manual point if user.preferences.automaticAllocation - switch user.preferences.allocationMode - when "flat" - suggested = Math.min(user.stats.str, user.stats.int, user.stats.con, user.stats.per) - if user.stats.int is suggested # In case of ties, favor INT first, to get the next point sooner - user.stats.int++ - else if user.stats.per is suggested # Then favor PER, it's a god stat - user.stats.per++ - else if user.stats.str is suggested # Then favor STR, everyone loves crits - user.stats.str++ - else - user.stats.con++ # CON, the unsexiest of attributes - when "classbased" - # Attributes get 3:2:1:1 per 7 levels. - ideal = [(user.stats.lvl / 7 * 3), (user.stats.lvl / 7 * 2), (user.stats.lvl / 7), (user.stats.lvl / 7)] - # Primary, secondary etc. attributes aren't explicitly defined, so hardcode them. In order per above - switch user.stats.class - when "wizard" then preference = ["int", "per", "con", "str"] - when "rogue" then preference = ["per", "str", "int", "con"] - when "healer" then preference = ["con", "int", "str", "per"] - else preference = ["str", "con", "per", "int"] - # Get the difference between the ideal attribute spread according to level, and the user's current spread. - diff = [(user.stats[preference[0]]-ideal[0]),(user.stats[preference[1]]-ideal[1]),(user.stats[preference[2]]-ideal[2]),(user.stats[preference[3]]-ideal[3])] - suggested = _.findIndex(diff, ((val) -> if val is _.min(diff) then true)) # Returns the index of the first attribute that's furthest behind the ideal - if suggested is -1 then user.stats.str++ else user.stats[preference[suggested]]++ # If _findIndex failed, we'd get a -1... - when "taskbased" # old logic, temp - tallies = _.reduce user.tasks, ((m,v)-> m[v.attribute or 'str'] += v.value;m), {str:0,int:0,con:0,per:0} - suggested = _.reduce tallies, ((m,v,k)-> if v>tallies[m] then k else m), 'str' - user.stats[suggested]++ - else user.stats.str++ # if all else fails, dump into STR + suggested = user.fns.autoAllocate() + user.stats[suggested]++ else # add new allocatable points. We could do user.stats.points++, but this does a fail-safe just in case user.stats.points = user.stats.lvl - (user.stats.con + user.stats.str + user.stats.per + user.stats.int); From c4a82d4edd8accb37c496841b790c7257de7ea14 Mon Sep 17 00:00:00 2001 From: Sabe Jones Date: Mon, 30 Dec 2013 23:09:47 -0600 Subject: [PATCH 4/5] Daily derp! Don't return PER when STR is suggested --- dist/habitrpg-shared.js | 2 +- script/index.coffee | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/dist/habitrpg-shared.js b/dist/habitrpg-shared.js index 19b4142610..190d0db602 100644 --- a/dist/habitrpg-shared.js +++ b/dist/habitrpg-shared.js @@ -11972,7 +11972,7 @@ var process=require("__browserify_process");(function() { } else if (user.stats.per === suggested) { return "per"; } else if (user.stats.str === suggested) { - return "per"; + return "str"; } else { return "con"; } diff --git a/script/index.coffee b/script/index.coffee index da65b9ac0f..16b060629c 100644 --- a/script/index.coffee +++ b/script/index.coffee @@ -950,7 +950,7 @@ api.wrap = (user) -> else if user.stats.per is suggested # Then favor PER, it's a god stat return "per" else if user.stats.str is suggested # Then favor STR, everyone loves crits - return "per" + return "str" else return "con" # CON, the unsexiest of attributes when "classbased" From 4662fe151b18d22bc1b91094f642ca24ca69e7ee Mon Sep 17 00:00:00 2001 From: Sabe Jones Date: Tue, 31 Dec 2013 09:05:03 -0600 Subject: [PATCH 5/5] Implement "training" over the course of a level, for task-based attribute allocation --- dist/habitrpg-shared.js | 35 ++++++++++++++++++----------------- script/index.coffee | 17 ++++++++++++----- 2 files changed, 30 insertions(+), 22 deletions(-) diff --git a/dist/habitrpg-shared.js b/dist/habitrpg-shared.js index 190d0db602..1fdb40587a 100644 --- a/dist/habitrpg-shared.js +++ b/dist/habitrpg-shared.js @@ -11688,6 +11688,9 @@ var process=require("__browserify_process");(function() { currVal = task.value < -47.27 ? -47.27 : task.value > 21.27 ? 21.27 : task.value; nextDelta = Math.pow(0.9747, currVal) * (direction === 'down' ? -1 : 1); if (task.type !== 'reward') { + if (user.preferences.automaticAllocation === true && user.preferences.allocationMode === 'taskbased') { + user.stats.training[task.attribute] += nextDelta; + } adjustAmt = nextDelta; if (direction === 'up' && task.type !== 'reward' && !(task.type === 'habit' && !task.down)) { adjustAmt = nextDelta * (1 + user._statsComputed.str * .004); @@ -11963,7 +11966,7 @@ var process=require("__browserify_process");(function() { */ autoAllocate: function() { - var diff, ideal, preference, suggested, tallies; + var diff, ideal, preference, suggested; switch (user.preferences.allocationMode) { case "flat": suggested = Math.min(user.stats.str, user.stats.int, user.stats.con, user.stats.per); @@ -12005,23 +12008,21 @@ var process=require("__browserify_process");(function() { } break; case "taskbased": - tallies = _.reduce(user.tasks, (function(m, v) { - m[v.attribute || 'str'] += v.value; - return m; - }), { - str: 0, - int: 0, - con: 0, - per: 0 - }); - suggested = _.reduce(tallies, (function(m, v, k) { - if (v > tallies[m]) { - return k; - } else { - return m; + suggested = _.findKey(user.stats.training, (function(val) { + if (val === _.max(user.stats.training)) { + return val; } - }), 'str'); - return suggested; + })); + user.stats.training.str = 0; + user.stats.training.int = 0; + user.stats.training.con = 0; + user.stats.training.per = 0; + if (suggested === void 0) { + return "str"; + } else { + return suggested; + } + break; default: return "str"; } diff --git a/script/index.coffee b/script/index.coffee index 16b060629c..73e3f2ca25 100644 --- a/script/index.coffee +++ b/script/index.coffee @@ -687,6 +687,7 @@ api.wrap = (user) -> else task.value nextDelta = Math.pow(0.9747, currVal) * (if direction is 'down' then -1 else 1) unless task.type is 'reward' + if (user.preferences.automaticAllocation is true and user.preferences.allocationMode is 'taskbased') then user.stats.training[task.attribute] += nextDelta adjustAmt = nextDelta # ===== STRENGTH ===== # (Only for up-scoring, ignore up-onlies and rewards) @@ -965,11 +966,17 @@ api.wrap = (user) -> # Get the difference between the ideal attribute spread according to level, and the user's current spread. diff = [(user.stats[preference[0]]-ideal[0]),(user.stats[preference[1]]-ideal[1]),(user.stats[preference[2]]-ideal[2]),(user.stats[preference[3]]-ideal[3])] suggested = _.findIndex(diff, ((val) -> if val is _.min(diff) then true)) # Returns the index of the first attribute that's furthest behind the ideal - if suggested is -1 then return "str" else return preference[suggested] # If _findIndex failed, we'd get a -1... - when "taskbased" # old logic, temp - tallies = _.reduce user.tasks, ((m,v)-> m[v.attribute or 'str'] += v.value;m), {str:0,int:0,con:0,per:0} - suggested = _.reduce tallies, ((m,v,k)-> if v>tallies[m] then k else m), 'str' - return suggested + if suggested is -1 then return "str" else return preference[suggested] # If _.findIndex failed, we'd get a -1... + when "taskbased" + suggested = _.findKey(user.stats.training, ((val) -> if val is _.max(user.stats.training) then val)) # Returns the stat that's been trained up the most this level + # FIXME Reset training for this level. Tried _.each but couldn't get it to take. + user.stats.training.str = 0 + user.stats.training.int = 0 + user.stats.training.con = 0 + user.stats.training.per = 0 + if suggested is undefined then return "str" else return suggested # Failed _.findkey gives undefined + # tallies = _.reduce user.tasks, ((m,v)-> m[v.attribute or 'str'] += v.value;m), {str:0,int:0,con:0,per:0} + # suggested = _.reduce tallies, ((m,v,k)-> if v>tallies[m] then k else m), 'str' else return "str" # if all else fails, dump into STR updateStats: (stats) ->