mirror of
https://github.com/sudoxnym/habitica.git
synced 2026-05-21 05:08:51 +00:00
math-balancing WIP for passive stats & abilities
This commit is contained in:
parent
29e653cb4d
commit
6c8e2975b4
4 changed files with 183 additions and 146 deletions
106
dist/habitrpg-shared.js
vendored
106
dist/habitrpg-shared.js
vendored
|
|
@ -9167,7 +9167,7 @@ var global=self;/**
|
|||
|
||||
},{}],5:[function(require,module,exports){
|
||||
(function() {
|
||||
var api, crit, gear, moment, repeat, _;
|
||||
var api, gear, moment, repeat, _;
|
||||
|
||||
_ = require('lodash');
|
||||
|
||||
|
|
@ -10001,20 +10001,6 @@ var global=self;/**
|
|||
*/
|
||||
|
||||
|
||||
crit = function(user, stat, chance) {
|
||||
if (stat == null) {
|
||||
stat = 'per';
|
||||
}
|
||||
if (chance == null) {
|
||||
chance = .03;
|
||||
}
|
||||
if (user.fns.predictableRandom() <= chance) {
|
||||
return 1.5 + (.05 * user._statsComputed[stat]);
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
};
|
||||
|
||||
api.spells = {
|
||||
wizard: {
|
||||
fireball: {
|
||||
|
|
@ -10022,10 +10008,10 @@ var global=self;/**
|
|||
mana: 10,
|
||||
lvl: 6,
|
||||
target: 'task',
|
||||
notes: 'With a crack, flames burst from your staff, scorching a task. You deal much higher damage to the task and gain additional experience.',
|
||||
notes: 'With a crack, flames burst from your staff, scorching a task. You deal high damage to the task, and gain additional experience (more experience for greens).',
|
||||
cast: function(user, target) {
|
||||
target.value += user._statsComputed.int * .0075 * crit(user, 'per');
|
||||
return user.stats.exp += Math.abs(target.value);
|
||||
target.value += user._statsComputed.int * .0075 * user.fns.crit('per');
|
||||
return user.stats.exp += (target.value < 0 ? 1 : target.value + 1) * 2.5;
|
||||
}
|
||||
},
|
||||
mpheal: {
|
||||
|
|
@ -10037,7 +10023,7 @@ var global=self;/**
|
|||
cast: function(user, target) {
|
||||
return _.each(target, function(member) {
|
||||
var bonus;
|
||||
bonus = Math.ceil(user._statsComputed.int * .2 + 5);
|
||||
bonus = Math.ceil(user._statsComputed.int * .1);
|
||||
if (bonus > 25) {
|
||||
bonus = 25;
|
||||
}
|
||||
|
|
@ -10057,7 +10043,7 @@ var global=self;/**
|
|||
if ((_base = member.stats.buffs).int == null) {
|
||||
_base.int = 0;
|
||||
}
|
||||
return member.stats.buffs.int += user._statsComputed.int * .2;
|
||||
return member.stats.buffs.int += Math.ceil(user._statsComputed.int * .05);
|
||||
});
|
||||
}
|
||||
},
|
||||
|
|
@ -10080,7 +10066,7 @@ var global=self;/**
|
|||
target: 'task',
|
||||
notes: "You savagely hit a single task with all of your might, beating it into submission. The task's redness decreases.",
|
||||
cast: function(user, target) {
|
||||
return target.value += user._statsComputed.str * .01 * crit(user, 'per');
|
||||
return target.value += user._statsComputed.str * .01 * user.fns.crit('per');
|
||||
}
|
||||
},
|
||||
defensiveStance: {
|
||||
|
|
@ -10094,7 +10080,7 @@ var global=self;/**
|
|||
if ((_base = user.stats.buffs).con == null) {
|
||||
_base.con = 0;
|
||||
}
|
||||
return user.stats.buffs.con += user._statsComputed.con * .3;
|
||||
return user.stats.buffs.con += Math.ceil(user._statsComputed.con * .05);
|
||||
}
|
||||
},
|
||||
valorousPresence: {
|
||||
|
|
@ -10109,7 +10095,7 @@ var global=self;/**
|
|||
if ((_base = member.stats.buffs).str == null) {
|
||||
_base.str = 0;
|
||||
}
|
||||
return member.stats.buffs.str += user._statsComputed.str * .2;
|
||||
return member.stats.buffs.str += Math.ceil(user._statsComputed.str * .05);
|
||||
});
|
||||
}
|
||||
},
|
||||
|
|
@ -10125,7 +10111,7 @@ var global=self;/**
|
|||
if ((_base = member.stats.buffs).con == null) {
|
||||
_base.con = 0;
|
||||
}
|
||||
return member.stats.buffs.con += user._statsComputed.con * .2;
|
||||
return member.stats.buffs.con += Math.ceil(user._statsComputed.con * .03);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -10136,9 +10122,9 @@ var global=self;/**
|
|||
mana: 10,
|
||||
lvl: 6,
|
||||
target: 'task',
|
||||
notes: "Your nimble fingers run through the task's pockets and 'find' some treasures for yourself. You gain an increased gold bonus on the task and a higher chance of an item drop.",
|
||||
notes: "Your nimble fingers run through the task's pockets and find some treasures for yourself. You gain an increased gold bonus on the task, higher yet the 'fatter' (greener) your task.",
|
||||
cast: function(user, target) {
|
||||
return user.stats.gp += ((target.value < 0 ? 0 : target.value) + 1) + user._statsComputed.per * .3;
|
||||
return user.stats.gp += (target.value < 0 ? 1 : target.value + 1) + user._statsComputed.per * .075;
|
||||
}
|
||||
},
|
||||
backStab: {
|
||||
|
|
@ -10149,9 +10135,9 @@ var global=self;/**
|
|||
notes: "Without a sound, you sweep behind a task and stab it in the back. You deal higher damage to the task, with a higher chance of a critical hit.",
|
||||
cast: function(user, target) {
|
||||
var bonus, _crit;
|
||||
_crit = crit(user, 'per', .5);
|
||||
_crit = user.fns.crit('per', .3);
|
||||
target.value += _crit * .03;
|
||||
bonus = ((target.value < 0 ? 0 : target.value) + 1) * _crit;
|
||||
bonus = (target.value < 0 ? 1 : target.value + 1) * _crit;
|
||||
user.stats.exp += bonus;
|
||||
return user.stats.gp += bonus;
|
||||
}
|
||||
|
|
@ -10168,7 +10154,7 @@ var global=self;/**
|
|||
if ((_base = member.stats.buffs).per == null) {
|
||||
_base.per = 0;
|
||||
}
|
||||
return member.stats.buffs.per += user._statsComputed.per * .2;
|
||||
return member.stats.buffs.per += Math.ceil(user._statsComputed.per * .03);
|
||||
});
|
||||
}
|
||||
},
|
||||
|
|
@ -10195,7 +10181,7 @@ var global=self;/**
|
|||
target: 'self',
|
||||
notes: 'Light covers your body, healing your wounds. You gain a boost to your health.',
|
||||
cast: function(user, target) {
|
||||
user.stats.hp += (user._statsComputed.con + user._statsComputed.int + 10) * .5;
|
||||
user.stats.hp += (user._statsComputed.con + user._statsComputed.int + 5) * .075;
|
||||
if (user.stats.hp > 50) {
|
||||
return user.stats.hp = 50;
|
||||
}
|
||||
|
|
@ -10212,7 +10198,7 @@ var global=self;/**
|
|||
if (target.type === 'reward') {
|
||||
return;
|
||||
}
|
||||
return target.value += user._statsComputed.int * .075;
|
||||
return target.value += user._statsComputed.int * .006;
|
||||
});
|
||||
}
|
||||
},
|
||||
|
|
@ -10228,7 +10214,7 @@ var global=self;/**
|
|||
if ((_base = member.stats.buffs).con == null) {
|
||||
_base.con = 0;
|
||||
}
|
||||
return member.stats.buffs.con += user._statsComputed.con * .4;
|
||||
return member.stats.buffs.con += Math.ceil(user._statsComputed.con * .15);
|
||||
});
|
||||
}
|
||||
},
|
||||
|
|
@ -10240,7 +10226,7 @@ var global=self;/**
|
|||
notes: "Soothing light envelops your party and heals them of their injuries. Your party members gain a boost to their health.",
|
||||
cast: function(user, target) {
|
||||
return _.each(target, function(member) {
|
||||
member.stats.hp += (user._statsComputed.con + user._statsComputed.int + 10) * .3;
|
||||
member.stats.hp += (user._statsComputed.con + user._statsComputed.int + 5) * .04;
|
||||
if (member.stats.hp > 50) {
|
||||
return member.stats.hp = 50;
|
||||
}
|
||||
|
|
@ -10687,6 +10673,21 @@ var process=require("__browserify_process");(function() {
|
|||
}
|
||||
};
|
||||
|
||||
/*
|
||||
A hyperbola function that creates diminishing returns, so you can't go to infinite (eg, with Exp gain).
|
||||
{max} The asymptote
|
||||
{bonus} All the numbers combined for your point bonus (eg, task.value * user.stats.int * critChance, etc)
|
||||
{halfway} (optional) the point at which the graph starts bending
|
||||
*/
|
||||
|
||||
|
||||
api.diminishingReturns = function(bonus, max, halfway) {
|
||||
if (halfway == null) {
|
||||
halfway = bonus / 2;
|
||||
}
|
||||
return max * (bonus / (bonus + halfway));
|
||||
};
|
||||
|
||||
/*
|
||||
Preen history for users with > 7 history entries
|
||||
This takes an infinite array of single day entries [day day day day day...], and turns it into a condensed array
|
||||
|
|
@ -11600,28 +11601,28 @@ var process=require("__browserify_process");(function() {
|
|||
if (adjustvalue) {
|
||||
task.value += nextDelta;
|
||||
if (direction === 'up' && task.type !== 'reward' && !(task.type === 'habit' && !task.down)) {
|
||||
task.value += nextDelta * user._statsComputed.str * .005;
|
||||
task.value += nextDelta * user._statsComputed.str * .004;
|
||||
}
|
||||
}
|
||||
return delta += nextDelta;
|
||||
});
|
||||
};
|
||||
addPoints = function() {
|
||||
var afterStreak, crit, gpMod, intMod, streakBonus;
|
||||
crit = user.fns.predictableRandom() <= .03 ? 1.5 + (.05 * user._statsComputed.str) : 1;
|
||||
intMod = 1 + (user._statsComputed.int * .075);
|
||||
stats.exp += Math.round(delta * intMod * task.priority * crit * 6);
|
||||
gpMod = delta * task.priority * crit;
|
||||
gpMod *= 1 + user._statsComputed.per * .06;
|
||||
return stats.gp += task.streak ? (streakBonus = task.streak / 100 + 1, afterStreak = gpMod * streakBonus, gpMod > 0 ? user._tmp.streakBonus = afterStreak - gpMod : void 0, afterStreak) : gpMod;
|
||||
var afterStreak, gpMod, intBonus, perBonus, streakBonus, _crit;
|
||||
_crit = user.fns.crit();
|
||||
intBonus = 1 + (user._statsComputed.int * .025);
|
||||
stats.exp += Math.round(delta * intBonus * task.priority * _crit * 6);
|
||||
perBonus = 1 + user._statsComputed.per * .02;
|
||||
gpMod = delta * task.priority * _crit * perBonus;
|
||||
return gpMod *= stats.gp += task.streak ? (streakBonus = task.streak / 100 + 1, afterStreak = gpMod * streakBonus, gpMod > 0 ? user._tmp.streakBonus = afterStreak - gpMod : void 0, afterStreak) : gpMod;
|
||||
};
|
||||
subtractPoints = function() {
|
||||
var conMod, hpMod;
|
||||
conMod = 1 - (user._statsComputed.con / 250);
|
||||
if (conMod < .1) {
|
||||
conMod = 0.1;
|
||||
var conBonus, hpMod;
|
||||
conBonus = 1 - (user._statsComputed.con / 250);
|
||||
if (conBonus < .1) {
|
||||
conBonus = 0.1;
|
||||
}
|
||||
hpMod = delta * conMod * task.priority;
|
||||
hpMod = delta * conBonus * task.priority * 2;
|
||||
return stats.hp += Math.round(hpMod * 10) / 10;
|
||||
};
|
||||
switch (task.type) {
|
||||
|
|
@ -11745,6 +11746,19 @@ var process=require("__browserify_process");(function() {
|
|||
x = Math.sin(seed++) * 10000;
|
||||
return x - Math.floor(x);
|
||||
},
|
||||
crit: function(stat, chance) {
|
||||
if (stat == null) {
|
||||
stat = 'str';
|
||||
}
|
||||
if (chance == null) {
|
||||
chance = .03;
|
||||
}
|
||||
if (user.fns.predictableRandom() <= chance) {
|
||||
return 1.5 + (.02 * user._statsComputed[stat]);
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
},
|
||||
/*
|
||||
Get a random property from an object
|
||||
http://stackoverflow.com/questions/2532218/pick-random-property-from-a-javascript-object
|
||||
|
|
|
|||
|
|
@ -209,10 +209,6 @@ api.potion = type: 'potion', text: "Health Potion", notes: "Recover 15 Health (I
|
|||
Note, user.stats.mp is docked after automatically (it's appended to functions automatically down below in an _.each)
|
||||
###
|
||||
|
||||
crit = (user, stat='per', chance=.03) ->
|
||||
if user.fns.predictableRandom() <= chance then 1.5 + (.05*user._statsComputed[stat])
|
||||
else 1
|
||||
|
||||
api.spells =
|
||||
|
||||
wizard:
|
||||
|
|
@ -221,10 +217,10 @@ api.spells =
|
|||
mana: 10
|
||||
lvl: 6
|
||||
target: 'task'
|
||||
notes: 'With a crack, flames burst from your staff, scorching a task. You deal much higher damage to the task and gain additional experience.'
|
||||
notes: 'With a crack, flames burst from your staff, scorching a task. You deal high damage to the task, and gain additional experience (more experience for greens).'
|
||||
cast: (user, target) ->
|
||||
target.value += user._statsComputed.int * .0075 * crit(user, 'per')
|
||||
user.stats.exp += Math.abs(target.value)
|
||||
target.value += user._statsComputed.int * .0075 * user.fns.crit('per')
|
||||
user.stats.exp += (if target.value < 0 then 1 else target.value+1) * 2.5
|
||||
|
||||
mpheal:
|
||||
text: 'Ethereal Surge'
|
||||
|
|
@ -234,7 +230,7 @@ api.spells =
|
|||
notes: "A flow of magical energy rushes from your hands and recharges your party. Your party recovers MP.",
|
||||
cast: (user, target)->
|
||||
_.each target, (member) ->
|
||||
bonus = Math.ceil(user._statsComputed.int * .2 + 5)
|
||||
bonus = Math.ceil(user._statsComputed.int * .1)
|
||||
bonus = 25 if bonus > 25 #prevent ability to replenish own mp infinitely
|
||||
member.stats.mp += bonus
|
||||
|
||||
|
|
@ -247,7 +243,7 @@ api.spells =
|
|||
cast: (user, target) ->
|
||||
_.each target, (member) ->
|
||||
member.stats.buffs.int ?= 0
|
||||
member.stats.buffs.int += user._statsComputed.int * .2
|
||||
member.stats.buffs.int += Math.ceil(user._statsComputed.int * .05)
|
||||
|
||||
frost:
|
||||
text: 'Chilling Frost'
|
||||
|
|
@ -266,7 +262,7 @@ api.spells =
|
|||
target: 'task'
|
||||
notes: "You savagely hit a single task with all of your might, beating it into submission. The task's redness decreases."
|
||||
cast: (user, target) ->
|
||||
target.value += user._statsComputed.str * .01 * crit(user, 'per')
|
||||
target.value += user._statsComputed.str * .01 * user.fns.crit('per')
|
||||
defensiveStance:
|
||||
text: 'Defensive Stance'
|
||||
mana: 25
|
||||
|
|
@ -275,7 +271,7 @@ api.spells =
|
|||
notes: "You take a moment to relax your body and enter a defensive stance to ready yourself for the tasks' next onslaught. Reduces damage from dailies at the end of the day."
|
||||
cast: (user, target) ->
|
||||
user.stats.buffs.con ?= 0
|
||||
user.stats.buffs.con += user._statsComputed.con * .3
|
||||
user.stats.buffs.con += Math.ceil(user._statsComputed.con * .05)
|
||||
valorousPresence:
|
||||
text: 'Valorous Presence'
|
||||
mana: 20
|
||||
|
|
@ -285,7 +281,7 @@ api.spells =
|
|||
cast: (user, target) ->
|
||||
_.each target, (member) ->
|
||||
member.stats.buffs.str ?= 0
|
||||
member.stats.buffs.str += user._statsComputed.str * .2
|
||||
member.stats.buffs.str += Math.ceil(user._statsComputed.str * .05)
|
||||
intimidate:
|
||||
text: 'Intimidating Gaze'
|
||||
mana: 15
|
||||
|
|
@ -295,7 +291,7 @@ api.spells =
|
|||
cast: (user, target) ->
|
||||
_.each target, (member) ->
|
||||
member.stats.buffs.con ?= 0
|
||||
member.stats.buffs.con += user._statsComputed.con * .2
|
||||
member.stats.buffs.con += Math.ceil(user._statsComputed.con * .03)
|
||||
|
||||
rogue:
|
||||
pickPocket:
|
||||
|
|
@ -303,9 +299,9 @@ api.spells =
|
|||
mana: 10
|
||||
lvl: 6
|
||||
target: 'task'
|
||||
notes: "Your nimble fingers run through the task's pockets and 'find' some treasures for yourself. You gain an increased gold bonus on the task and a higher chance of an item drop."
|
||||
notes: "Your nimble fingers run through the task's pockets and find some treasures for yourself. You gain an increased gold bonus on the task, higher yet the 'fatter' (greener) your task."
|
||||
cast: (user, target) ->
|
||||
user.stats.gp += ((if target.value < 0 then 0 else target.value) + 1) + user._statsComputed.per * .3
|
||||
user.stats.gp += (if target.value < 0 then 1 else target.value+1) + user._statsComputed.per * .075
|
||||
backStab:
|
||||
text: 'Backstab'
|
||||
mana: 15
|
||||
|
|
@ -313,9 +309,9 @@ api.spells =
|
|||
target: 'task'
|
||||
notes: "Without a sound, you sweep behind a task and stab it in the back. You deal higher damage to the task, with a higher chance of a critical hit."
|
||||
cast: (user, target) ->
|
||||
_crit = crit(user, 'per', .5)
|
||||
_crit = user.fns.crit('per', .3)
|
||||
target.value += _crit * .03
|
||||
bonus = ((if target.value < 0 then 0 else target.value) + 1) * _crit
|
||||
bonus = (if target.value < 0 then 1 else target.value+1) * _crit
|
||||
user.stats.exp += bonus
|
||||
user.stats.gp += bonus
|
||||
toolsOfTrade:
|
||||
|
|
@ -328,7 +324,7 @@ api.spells =
|
|||
## lasts 24 hours ##
|
||||
_.each target, (member) ->
|
||||
member.stats.buffs.per ?= 0
|
||||
member.stats.buffs.per += user._statsComputed.per * .2
|
||||
member.stats.buffs.per += Math.ceil(user._statsComputed.per * .03)
|
||||
stealth:
|
||||
text: 'Stealth'
|
||||
mana: 45
|
||||
|
|
@ -347,7 +343,7 @@ api.spells =
|
|||
target: 'self'
|
||||
notes: 'Light covers your body, healing your wounds. You gain a boost to your health.'
|
||||
cast: (user, target) ->
|
||||
user.stats.hp += (user._statsComputed.con + user._statsComputed.int + 10) *.5
|
||||
user.stats.hp += (user._statsComputed.con + user._statsComputed.int + 5) * .075
|
||||
user.stats.hp = 50 if user.stats.hp > 50
|
||||
brightness:
|
||||
text: 'Searing Brightness'
|
||||
|
|
@ -358,7 +354,7 @@ api.spells =
|
|||
cast: (user, target) ->
|
||||
_.each user.tasks, (target) ->
|
||||
return if target.type is 'reward'
|
||||
target.value += user._statsComputed.int * .075
|
||||
target.value += user._statsComputed.int * .006
|
||||
protectAura:
|
||||
text: 'Protective Aura'
|
||||
mana: 30
|
||||
|
|
@ -369,7 +365,7 @@ api.spells =
|
|||
## lasts 24 hours ##
|
||||
_.each target, (member) ->
|
||||
member.stats.buffs.con ?= 0
|
||||
member.stats.buffs.con += user._statsComputed.con * .4
|
||||
member.stats.buffs.con += Math.ceil(user._statsComputed.con * .15)
|
||||
heallAll:
|
||||
text: 'Blessing'
|
||||
mana: 25
|
||||
|
|
@ -378,7 +374,7 @@ api.spells =
|
|||
notes: "Soothing light envelops your party and heals them of their injuries. Your party members gain a boost to their health."
|
||||
cast: (user, target) ->
|
||||
_.each target, (member) ->
|
||||
member.stats.hp += (user._statsComputed.con + user._statsComputed.int + 10) * .3
|
||||
member.stats.hp += (user._statsComputed.con + user._statsComputed.int + 5) * .04
|
||||
member.stats.hp = 50 if member.stats.hp > 50
|
||||
|
||||
special:
|
||||
|
|
|
|||
|
|
@ -65,6 +65,16 @@ api.tnl = (lvl) ->
|
|||
else Math.round(((Math.pow(lvl, 2) * 0.25) + (10 * lvl) + 139.75) / 10) * 10
|
||||
# round to nearest 10?
|
||||
|
||||
###
|
||||
A hyperbola function that creates diminishing returns, so you can't go to infinite (eg, with Exp gain).
|
||||
{max} The asymptote
|
||||
{bonus} All the numbers combined for your point bonus (eg, task.value * user.stats.int * critChance, etc)
|
||||
{halfway} (optional) the point at which the graph starts bending
|
||||
###
|
||||
api.diminishingReturns = (bonus, max, halfway=bonus/2) ->
|
||||
max*(bonus/(bonus+halfway))
|
||||
|
||||
|
||||
###
|
||||
Preen history for users with > 7 history entries
|
||||
This takes an infinite array of single day entries [day day day day day...], and turns it into a condensed array
|
||||
|
|
@ -676,26 +686,25 @@ api.wrap = (user) ->
|
|||
# (Only for up-scoring, ignore up-onlies and rewards)
|
||||
if direction is 'up' and task.type != 'reward' and !(task.type is 'habit' and !task.down)
|
||||
# TODO STR Improves the amount by which Dailies and +/- Habits decrease in threat when scored, by .25% per point.
|
||||
task.value += nextDelta * user._statsComputed.str * .005
|
||||
task.value += nextDelta * user._statsComputed.str * .004
|
||||
delta += nextDelta
|
||||
|
||||
addPoints = ->
|
||||
# ===== CRITICAL HITS =====
|
||||
crit =
|
||||
if user.fns.predictableRandom() <= .03 then 1.5 + (.05*user._statsComputed.str)
|
||||
else 1
|
||||
_crit = user.fns.crit()
|
||||
|
||||
# Exp Modifier
|
||||
# ===== Intelligence =====
|
||||
# TODO Increases Experience gain by .2% per point.
|
||||
intMod = 1 + (user._statsComputed.int * .075)
|
||||
stats.exp += Math.round(delta * intMod * task.priority * crit * 6)
|
||||
intBonus = 1 + (user._statsComputed.int * .025)
|
||||
stats.exp += Math.round (delta * intBonus * task.priority * _crit * 6)
|
||||
|
||||
# GP modifier
|
||||
gpMod = delta * task.priority * crit
|
||||
# ===== PERCEPTION =====
|
||||
# TODO Increases Gold gained from tasks by .3% per point.
|
||||
gpMod *= (1 + user._statsComputed.per *.06)
|
||||
perBonus = (1 + user._statsComputed.per *.02)
|
||||
gpMod = (delta * task.priority * _crit * perBonus)
|
||||
gpMod *=
|
||||
stats.gp +=
|
||||
if task.streak
|
||||
streakBonus = task.streak / 100 + 1 # eg, 1-day streak is 1.1, 2-day is 1.2, etc
|
||||
|
|
@ -708,9 +717,9 @@ api.wrap = (user) ->
|
|||
subtractPoints = ->
|
||||
# ===== CONSTITUTION =====
|
||||
# TODO Decreases HP loss from bad habits / missed dailies by 0.5% per point.
|
||||
conMod = 1 - (user._statsComputed.con / 250)
|
||||
conMod = 0.1 if conMod < .1
|
||||
hpMod = delta * conMod * task.priority
|
||||
conBonus = 1 - (user._statsComputed.con / 250)
|
||||
conBonus = 0.1 if conBonus < .1
|
||||
hpMod = delta * conBonus * task.priority * 2 # constant 2 multiplier for better results
|
||||
stats.hp += Math.round(hpMod * 10) / 10 # round to 1dp
|
||||
|
||||
switch task.type
|
||||
|
|
@ -807,6 +816,10 @@ api.wrap = (user) ->
|
|||
x = Math.sin(seed++) * 10000
|
||||
x - Math.floor(x)
|
||||
|
||||
crit: (stat='str', chance=.03) ->
|
||||
if user.fns.predictableRandom() <= chance then 1.5 + (.02*user._statsComputed[stat])
|
||||
else 1
|
||||
|
||||
###
|
||||
Get a random property from an object
|
||||
http://stackoverflow.com/questions/2532218/pick-random-property-from-a-javascript-object
|
||||
|
|
|
|||
|
|
@ -33,97 +33,111 @@ shared.wrap(user)
|
|||
s = user.stats
|
||||
task = user.tasks[id]
|
||||
party = [user]
|
||||
taskValue = -10
|
||||
|
||||
clearUser = (i=1) ->
|
||||
_.merge user.stats, {exp:0, gp:0, hp:50, lvl:i, str:i, con:i, per:i, int:i, mp: 100}
|
||||
console.log "\n\n================================================"
|
||||
console.log "New Simulation"
|
||||
console.log "================================================\n\n"
|
||||
|
||||
clearUser = (lvl=1) ->
|
||||
_.merge user.stats, {exp:0, gp:0, hp:50, lvl:lvl, str:lvl, con:lvl, per:lvl, int:lvl, mp: 100}
|
||||
_.merge s.buffs, {str:0,con:0,int:0,per:0}
|
||||
|
||||
_.times 10, (n) ->
|
||||
console.log "lvl\t\texp\t\thp\t\tgp\t\ttask.value"
|
||||
i = n*10 + 1
|
||||
clearUser(i)
|
||||
task.value = taskValue
|
||||
delta = user.ops.score params:{id, direction:'up'}
|
||||
console.log "#{s.lvl}\t\t#{s.exp}/#{shared.tnl(s.lvl)}\t\t#{s.hp}\t\t#{s.gp.toFixed(2)}\t\t#{task.value.toFixed(2)} (↑ Δ#{delta.toFixed(2)})"
|
||||
_.each [1,50,99], (lvl) ->
|
||||
console.log "[LEVEL #{lvl}] (#{lvl} points in every attr)\n\n"
|
||||
_.each {red:-5,yellow:0,green:5}, (taskVal, color) ->
|
||||
console.log "[task.value = #{taskVal} (#{color})]"
|
||||
console.log "direction\texpΔ\t\thpΔ\tgpΔ\ttask.valΔ\ttask.valΔ bonus"
|
||||
_.each ['up','down'], (direction) ->
|
||||
clearUser(lvl)
|
||||
b4 = {hp:s.hp, taskVal}
|
||||
task.value = taskVal
|
||||
delta = user.ops.score params:{id, direction}
|
||||
console.log "#{if direction is 'up' then '↑' else '↓'}\t\t#{s.exp}/#{shared.tnl(s.lvl)}\t\t#{(b4.hp-s.hp).toFixed(1)}\t#{s.gp.toFixed(1)}\t#{delta.toFixed(1)}\t\t#{(task.value-b4.taskVal-delta).toFixed(1)}"
|
||||
|
||||
task.value = taskValue
|
||||
delta = user.ops.score params:{id, direction:'down'}
|
||||
console.log "#{s.lvl}\t\t#{s.exp}/#{shared.tnl(s.lvl)}\t\t#{s.hp}\t\t#{s.gp.toFixed(2)}\t\t#{task.value.toFixed(2)} (↓ Δ#{delta.toFixed(2)})"
|
||||
str = '- [Wizard]'
|
||||
|
||||
console.log '[Wizard]'
|
||||
task.value = taskVal;clearUser(lvl)
|
||||
b4 = {taskVal}
|
||||
shared.content.spells.wizard.fireball.cast(user,task)
|
||||
str += "\tfireball(task.valΔ:#{(task.value-taskVal).toFixed(1)} exp:#{s.exp.toFixed(1)})"
|
||||
|
||||
task.value = taskValue;clearUser(i)
|
||||
shared.content.spells.wizard.fireball.cast(user,task)
|
||||
console.log "fireball: task.value=#{task.value} hp=#{s.exp}"
|
||||
task.value = taskVal;clearUser(lvl)
|
||||
_party = [user, {stats:{mp:0}}]
|
||||
shared.content.spells.wizard.mpheal.cast(user,_party)
|
||||
str += "\t| mpheal(mp:#{_party[1].stats.mp})"
|
||||
|
||||
task.value = taskValue;clearUser(i)
|
||||
shared.content.spells.wizard.mpheal.cast(user,party)
|
||||
console.log "mpheal: mp=#{s.mp} (from 100)"
|
||||
task.value = taskVal;clearUser(lvl)
|
||||
shared.content.spells.wizard.earth.cast(user,party)
|
||||
str += "\t\t\t\t| earth(buffs.int:#{s.buffs.int})"
|
||||
|
||||
task.value = taskValue;clearUser(i)
|
||||
shared.content.spells.wizard.earth.cast(user,party)
|
||||
console.log "earth: buffs.int=#{s.buffs.int}"
|
||||
task.value = taskVal;clearUser(lvl)
|
||||
shared.content.spells.wizard.frost.cast(user,{})
|
||||
str += "\t\t\t| frost(N/A)"
|
||||
|
||||
task.value = taskValue;clearUser(i)
|
||||
shared.content.spells.wizard.frost.cast(user,{})
|
||||
console.log "frost: -"
|
||||
console.log str
|
||||
str = '- [Warrior]'
|
||||
|
||||
console.log '[Warrior]'
|
||||
task.value = taskVal;clearUser(lvl)
|
||||
shared.content.spells.warrior.smash.cast(user,task)
|
||||
b4 = {taskVal}
|
||||
str += "\tsmash(task.valΔ:#{(task.value-taskVal).toFixed(1)})"
|
||||
|
||||
task.value = taskValue;clearUser(i)
|
||||
shared.content.spells.warrior.smash.cast(user,task)
|
||||
console.log "smash: task.value=#{task.value}"
|
||||
task.value = taskVal;clearUser(lvl)
|
||||
shared.content.spells.warrior.defensiveStance.cast(user,{})
|
||||
str += "\t\t| defensiveStance(buffs.con:#{s.buffs.con})"
|
||||
|
||||
task.value = taskValue;clearUser(i)
|
||||
shared.content.spells.warrior.defensiveStance.cast(user,{})
|
||||
console.log "defensiveStance: buffs.con=#{s.buffs.con}"
|
||||
task.value = taskVal;clearUser(lvl)
|
||||
shared.content.spells.warrior.valorousPresence.cast(user,party)
|
||||
str += "\t\t\t| valorousPresence(buffs.str:#{s.buffs.str})"
|
||||
|
||||
task.value = taskValue;clearUser(i)
|
||||
shared.content.spells.warrior.valorousPresence.cast(user,party)
|
||||
console.log "valorousPresence: buffs.str=#{s.buffs.str}"
|
||||
task.value = taskVal;clearUser(lvl)
|
||||
shared.content.spells.warrior.intimidate.cast(user,party)
|
||||
str += "\t\t| intimidate(buffs.con:#{s.buffs.con})"
|
||||
|
||||
task.value = taskValue;clearUser(i)
|
||||
shared.content.spells.warrior.intimidate.cast(user,party)
|
||||
console.log "intimidate: buffs.con=#{s.buffs.con}"
|
||||
console.log str
|
||||
str = '- [Rogue]'
|
||||
|
||||
console.log '[Rogue]'
|
||||
task.value = taskVal;clearUser(lvl)
|
||||
shared.content.spells.rogue.pickPocket.cast(user,task)
|
||||
str += "\tpickPocket(gp:#{s.gp.toFixed(1)})"
|
||||
|
||||
task.value = taskValue;clearUser(i)
|
||||
shared.content.spells.rogue.pickPocket.cast(user,task)
|
||||
console.log "pickPocket: gp=#{s.gp}"
|
||||
task.value = taskVal;clearUser(lvl)
|
||||
shared.content.spells.rogue.backStab.cast(user,task)
|
||||
b4 = {taskVal}
|
||||
str += "\t\t| backStab(task.valΔ:#{(task.value-b4.taskVal).toFixed(1)} exp:#{s.exp.toFixed(1)} gp:#{s.gp.toFixed(1)})"
|
||||
|
||||
task.value = taskValue;clearUser(i)
|
||||
shared.content.spells.rogue.backStab.cast(user,task)
|
||||
console.log "backStab: task.value=#{task.value} exp=#{s.exp} gp=#{s.gp}"
|
||||
task.value = taskVal;clearUser(lvl)
|
||||
shared.content.spells.rogue.toolsOfTrade.cast(user,party)
|
||||
str += "\t| toolsOfTrade(buffs.per:#{s.buffs.per})"
|
||||
|
||||
task.value = taskValue;clearUser(i)
|
||||
shared.content.spells.rogue.toolsOfTrade.cast(user,party)
|
||||
console.log "toolsOfTrade: buffs.per=#{s.buffs.per}"
|
||||
task.value = taskVal;clearUser(lvl)
|
||||
shared.content.spells.rogue.stealth.cast(user,{})
|
||||
str += "\t\t| stealth(avoiding #{user.stats.buffs.stealth} tasks)"
|
||||
|
||||
task.value = taskValue;clearUser(i)
|
||||
shared.content.spells.rogue.stealth.cast(user,{})
|
||||
console.log "stealth: avoiding #{user.stats.buffs.stealth} tasks"
|
||||
console.log str
|
||||
str = '- [Healer]'
|
||||
|
||||
console.log '[Healer]'
|
||||
task.value = taskVal;clearUser(lvl)
|
||||
s.hp=0
|
||||
shared.content.spells.healer.heal.cast(user,{})
|
||||
str += "\theal(hp:#{s.hp.toFixed(1)})"
|
||||
|
||||
task.value = taskValue;clearUser(i)
|
||||
s.hp=0
|
||||
shared.content.spells.healer.heal.cast(user,{})
|
||||
console.log "heal: hp=#{s.hp}"
|
||||
task.value = taskVal;clearUser(lvl)
|
||||
shared.content.spells.healer.brightness.cast(user,{})
|
||||
b4 = {taskVal}
|
||||
str += "\t\t\t| brightness(task.valΔ:#{(task.value-b4.taskVal).toFixed(1)})"
|
||||
|
||||
task.value = taskValue;clearUser(i)
|
||||
shared.content.spells.healer.brightness.cast(user,{})
|
||||
console.log "brightness: task.value=#{task.value}"
|
||||
task.value = taskVal;clearUser(lvl)
|
||||
shared.content.spells.healer.protectAura.cast(user,party)
|
||||
str += "\t\t\t| protectAura(buffs.con:#{s.buffs.con})"
|
||||
|
||||
task.value = taskValue;clearUser(i)
|
||||
shared.content.spells.healer.protectAura.cast(user,party)
|
||||
console.log "protectAura: buffs.con=#{s.buffs.con}"
|
||||
task.value = taskVal;clearUser(lvl)
|
||||
s.hp=0
|
||||
shared.content.spells.healer.heallAll.cast(user,party)
|
||||
str += "\t\t| heallAll(hp:#{s.hp.toFixed(1)})"
|
||||
|
||||
task.value = taskValue;clearUser(i)
|
||||
s.hp=0
|
||||
shared.content.spells.healer.heallAll.cast(user,party)
|
||||
console.log "heallAll: hp=#{s.hp}"
|
||||
console.log str
|
||||
console.log '\n'
|
||||
|
||||
|
||||
console.log '------------------------------------------------------------'
|
||||
|
|
|
|||
Loading…
Reference in a new issue