mirror of
https://github.com/sudoxnym/habitica.git
synced 2026-08-05 12:02:13 +00:00
Implement new "flat" and "classbased" automatic allocation modes
This commit is contained in:
parent
82afe6e796
commit
6997cd9821
2 changed files with 88 additions and 22 deletions
79
dist/habitrpg-shared.js
vendored
79
dist/habitrpg-shared.js
vendored
|
|
@ -63,7 +63,7 @@ process.chdir = function (dir) {
|
||||||
};
|
};
|
||||||
|
|
||||||
},{}],3:[function(require,module,exports){
|
},{}],3:[function(require,module,exports){
|
||||||
var global=self;/**
|
var global=typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {};/**
|
||||||
* @license
|
* @license
|
||||||
* Lo-Dash 2.4.1 (Custom Build) <http://lodash.com/>
|
* Lo-Dash 2.4.1 (Custom Build) <http://lodash.com/>
|
||||||
* Build: `lodash modern -o ./dist/lodash.js`
|
* Build: `lodash modern -o ./dist/lodash.js`
|
||||||
|
|
@ -11937,7 +11937,7 @@ var process=require("__browserify_process");(function() {
|
||||||
*/
|
*/
|
||||||
|
|
||||||
updateStats: function(stats) {
|
updateStats: function(stats) {
|
||||||
var suggested, tallies, tnl;
|
var diff, ideal, lowest, preference, suggested, tallies, tnl;
|
||||||
if (stats.hp <= 0) {
|
if (stats.hp <= 0) {
|
||||||
return user.stats.hp = 0;
|
return user.stats.hp = 0;
|
||||||
}
|
}
|
||||||
|
|
@ -11956,23 +11956,64 @@ var process=require("__browserify_process");(function() {
|
||||||
user.stats.lvl++;
|
user.stats.lvl++;
|
||||||
tnl = api.tnl(user.stats.lvl);
|
tnl = api.tnl(user.stats.lvl);
|
||||||
if (user.preferences.automaticAllocation) {
|
if (user.preferences.automaticAllocation) {
|
||||||
tallies = _.reduce(user.tasks, (function(m, v) {
|
switch (user.preferences.allocationMode) {
|
||||||
m[v.attribute || 'str'] += v.value;
|
case "flat":
|
||||||
return m;
|
lowest = Math.min(user.stats.str, user.stats.int, user.stats.con, user.stats.per);
|
||||||
}), {
|
if (user.stats.int === lowest) {
|
||||||
str: 0,
|
user.stats.int++;
|
||||||
int: 0,
|
} else if (user.stats.per === lowest) {
|
||||||
con: 0,
|
user.stats.per++;
|
||||||
per: 0
|
} else if (user.stats.str === lowest) {
|
||||||
});
|
user.stats.str++;
|
||||||
suggested = _.reduce(tallies, (function(m, v, k) {
|
} else {
|
||||||
if (v > tallies[m]) {
|
user.stats.con++;
|
||||||
return k;
|
}
|
||||||
} else {
|
break;
|
||||||
return m;
|
case "classbased":
|
||||||
}
|
ideal = [user.stats.lvl / 7, user.stats.lvl / 7, user.stats.lvl / 7 * 2, user.stats.lvl / 7 * 3];
|
||||||
}), 'str');
|
if (user.stats["class"] === "wizard") {
|
||||||
user.stats[suggested]++;
|
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 {
|
} else {
|
||||||
user.stats.points = user.stats.lvl - (user.stats.con + user.stats.str + user.stats.per + user.stats.int);
|
user.stats.points = user.stats.lvl - (user.stats.con + user.stats.str + user.stats.per + user.stats.int);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -962,9 +962,34 @@ api.wrap = (user) ->
|
||||||
|
|
||||||
# Auto-allocate a point, or give them a new manual point
|
# Auto-allocate a point, or give them a new manual point
|
||||||
if user.preferences.automaticAllocation
|
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}
|
switch user.preferences.allocationMode
|
||||||
suggested = _.reduce tallies, ((m,v,k)-> if v>tallies[m] then k else m), 'str'
|
when "flat"
|
||||||
user.stats[suggested]++
|
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
|
else
|
||||||
# add new allocatable points. We could do user.stats.points++, but this does a fail-safe just in case
|
# 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);
|
user.stats.points = user.stats.lvl - (user.stats.con + user.stats.str + user.stats.per + user.stats.int);
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue