From 6c8e2975b42a57d7ec587ed858e65d7a2f5d9dff Mon Sep 17 00:00:00 2001 From: Tyler Renelle Date: Sat, 21 Dec 2013 10:56:05 -0700 Subject: [PATCH] math-balancing WIP for passive stats & abilities --- dist/habitrpg-shared.js | 106 +++++++++++++++------------ script/content.coffee | 40 +++++------ script/index.coffee | 35 ++++++--- tests/math_samples.coffee | 148 +++++++++++++++++++++----------------- 4 files changed, 183 insertions(+), 146 deletions(-) diff --git a/dist/habitrpg-shared.js b/dist/habitrpg-shared.js index c042dfcaf4..63c10b1250 100644 --- a/dist/habitrpg-shared.js +++ b/dist/habitrpg-shared.js @@ -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 diff --git a/script/content.coffee b/script/content.coffee index 7f7b879c35..c7e21d51f2 100644 --- a/script/content.coffee +++ b/script/content.coffee @@ -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: diff --git a/script/index.coffee b/script/index.coffee index 20e234e1ea..366f3d5ea5 100644 --- a/script/index.coffee +++ b/script/index.coffee @@ -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 diff --git a/tests/math_samples.coffee b/tests/math_samples.coffee index c54f50abff..83c64634d8 100644 --- a/tests/math_samples.coffee +++ b/tests/math_samples.coffee @@ -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 '------------------------------------------------------------'