diff --git a/common/dist/scripts/habitrpg-shared.js b/common/dist/scripts/habitrpg-shared.js index 4f5ac0ac59..35a0c07d60 100644 --- a/common/dist/scripts/habitrpg-shared.js +++ b/common/dist/scripts/habitrpg-shared.js @@ -10,7 +10,7 @@ if (typeof window !== 'undefined') { } },{"./script/index.coffee":4,"lodash":6,"moment":7}],2:[function(require,module,exports){ -var api, classes, diminishingReturns, events, gear, gearTypes, i18n, moment, repeat, t, _; +var api, calculateBonus, classes, diminishingReturns, events, gear, gearTypes, i18n, moment, repeat, t, _; _ = require('lodash'); @@ -2430,6 +2430,16 @@ diminishingReturns = function(bonus, max, halfway) { return max * (bonus / (bonus + halfway)); }; +calculateBonus = function(value, stat, crit, stat_scale) { + if (crit == null) { + crit = 1; + } + if (stat_scale == null) { + stat_scale = 0.5; + } + return (value < 0 ? 1 : value + 1) + (stat * stat_scale * crit); +}; + api.spells = { wizard: { fireball: { @@ -2439,12 +2449,14 @@ api.spells = { target: 'task', notes: t('spellWizardFireballNotes'), cast: function(user, target) { - var bonus; + var bonus, _base; bonus = user._statsComputed.int * user.fns.crit('per'); - target.value += diminishingReturns(bonus * .02, 4); bonus *= Math.ceil((target.value < 0 ? 1 : target.value + 1) * .075); user.stats.exp += diminishingReturns(bonus, 75); - return user.party.quest.progress.up += diminishingReturns(bonus * .1, 50, 30); + if ((_base = user.party.quest.progress).up == null) { + _base.up = 0; + } + return user.party.quest.progress.up += Math.ceil(user._statsComputed.int * .1); } }, mpheal: { @@ -2456,11 +2468,8 @@ api.spells = { cast: function(user, target) { return _.each(target, function(member) { var bonus; - bonus = Math.ceil(user._statsComputed.int * .1); - if (bonus > 25) { - bonus = 25; - } - return member.stats.mp += bonus; + bonus = user._statsComputed.int; + return member.stats.mp += Math.ceil(diminishingReturns(bonus, 25, 125)); }); } }, @@ -2472,11 +2481,12 @@ api.spells = { notes: t('spellWizardEarthNotes'), cast: function(user, target) { return _.each(target, function(member) { - var _base; + var bonus, _base; + bonus = user._statsComputed.int; if ((_base = member.stats.buffs).int == null) { _base.int = 0; } - return member.stats.buffs.int += Math.ceil(user._statsComputed.int * .05); + return member.stats.buffs.int += Math.ceil(diminishingReturns(bonus, 30, 200)); }); } }, @@ -2499,8 +2509,13 @@ api.spells = { target: 'task', notes: t('spellWarriorSmashNotes'), cast: function(user, target) { - target.value += 2.5 * (user._statsComputed.str / (user._statsComputed.str + 50)) * user.fns.crit('con'); - return user.party.quest.progress.up += Math.ceil(user._statsComputed.str * .2); + var bonus, _base; + bonus = user._statsComputed.str * user.fns.crit('con'); + target.value += diminishingReturns(bonus, 2.5, 35); + if ((_base = user.party.quest.progress).up == null) { + _base.up = 0; + } + return user.party.quest.progress.up += diminishingReturns(bonus, 55, 70); } }, defensiveStance: { @@ -2510,11 +2525,12 @@ api.spells = { target: 'self', notes: t('spellWarriorDefensiveStanceNotes'), cast: function(user, target) { - var _base; + var bonus, _base; + bonus = user._statsComputed.con; if ((_base = user.stats.buffs).con == null) { _base.con = 0; } - return user.stats.buffs.con += Math.ceil(user._statsComputed.con * .05); + return user.stats.buffs.con += Math.ceil(diminishingReturns(bonus, 40, 200)); } }, valorousPresence: { @@ -2525,11 +2541,12 @@ api.spells = { notes: t('spellWarriorValorousPresenceNotes'), cast: function(user, target) { return _.each(target, function(member) { - var _base; + var bonus, _base; + bonus = user._statsComputed.str; if ((_base = member.stats.buffs).str == null) { _base.str = 0; } - return member.stats.buffs.str += Math.ceil(user._statsComputed.str * .05); + return member.stats.buffs.str += Math.ceil(diminishingReturns(bonus, 20, 200)); }); } }, @@ -2541,11 +2558,12 @@ api.spells = { notes: t('spellWarriorIntimidateNotes'), cast: function(user, target) { return _.each(target, function(member) { - var _base; + var bonus, _base; + bonus = user._statsComputed.con; if ((_base = member.stats.buffs).con == null) { _base.con = 0; } - return member.stats.buffs.con += Math.ceil(user._statsComputed.con * .03); + return member.stats.buffs.con += Math.ceil(diminishingReturns(bonus, 24, 200)); }); } } @@ -2559,8 +2577,8 @@ api.spells = { notes: t('spellRoguePickPocketNotes'), cast: function(user, target) { var bonus; - bonus = (target.value < 0 ? 1 : target.value + 2) + (user._statsComputed.per * 0.5); - return user.stats.gp += 25 * (bonus / (bonus + 75)); + bonus = calculateBonus(target.value, user._statsComputed.per); + return user.stats.gp += diminishingReturns(bonus, 25, 75); } }, backStab: { @@ -2572,10 +2590,9 @@ api.spells = { cast: function(user, target) { var bonus, _crit; _crit = user.fns.crit('str', .3); - target.value += _crit * .03; - bonus = (target.value < 0 ? 1 : target.value + 1) * _crit; - user.stats.exp += bonus; - return user.stats.gp += bonus; + bonus = calculateBonus(target.value, user._statsComputed.str, _crit); + user.stats.exp += diminishingReturns(bonus, 75, 50); + return user.stats.gp += diminishingReturns(bonus, 18, 75); } }, toolsOfTrade: { @@ -2586,11 +2603,12 @@ api.spells = { notes: t('spellRogueToolsOfTradeNotes'), cast: function(user, target) { return _.each(target, function(member) { - var _base; + var bonus, _base; + bonus = user._statsComputed.per; if ((_base = member.stats.buffs).per == null) { _base.per = 0; } - return member.stats.buffs.per += Math.ceil(user._statsComputed.per * .03); + return member.stats.buffs.per += Math.ceil(diminishingReturns(bonus, 400, 100)); }); } }, @@ -2634,7 +2652,7 @@ api.spells = { if (target.type === 'reward') { return; } - return target.value += 1.5 * (user._statsComputed.int / (user._statsComputed.int + 40)); + return target.value += 4 * (user._statsComputed.int / (user._statsComputed.int + 40)); }); } }, @@ -2646,11 +2664,12 @@ api.spells = { notes: t('spellHealerProtectAuraNotes'), cast: function(user, target) { return _.each(target, function(member) { - var _base; + var bonus, _base; + bonus = user._statsComputed.con; if ((_base = member.stats.buffs).con == null) { _base.con = 0; } - return member.stats.buffs.con += Math.ceil(user._statsComputed.con * .15); + return member.stats.buffs.con += Math.ceil(diminishingReturns(bonus, 200, 200)); }); } }, @@ -6300,7 +6319,7 @@ api.wrap = function(user, main) { return typeof cb === "function" ? cb(null, 'items.special') : void 0; }, score: function(req, cb) { - var addPoints, calculateDelta, calculateReverseDelta, changeTaskValue, delta, direction, id, mpDelta, multiplier, num, options, stats, subtractPoints, task, th, _ref; + var addPoints, calculateDelta, calculateReverseDelta, changeTaskValue, delta, direction, gainMP, id, multiplier, num, options, stats, subtractPoints, task, th, _ref; _ref = req.params, id = _ref.id, direction = _ref.direction; task = user.tasks[id]; options = req.query || {}; @@ -6379,11 +6398,14 @@ api.wrap = function(user, main) { if (user.preferences.automaticAllocation === true && user.preferences.allocationMode === 'taskbased' && !(task.type === 'todo' && direction === 'down')) { user.stats.training[task.attribute] += nextDelta; } - if (direction === 'up' && !(task.type === 'habit' && !task.down)) { + if (direction === 'up') { user.party.quest.progress.up = user.party.quest.progress.up || 0; if ((_ref1 = task.type) === 'daily' || _ref1 === 'todo') { user.party.quest.progress.up += nextDelta * (1 + (user._statsComputed.str / 200)); } + if (task.type === 'habit') { + user.party.quest.progress.up += nextDelta * (0.5 + (user._statsComputed.str / 400)); + } } task.value += nextDelta; } @@ -6411,9 +6433,20 @@ api.wrap = function(user, main) { hpMod = delta * conBonus * task.priority * 2; return stats.hp += Math.round(hpMod * 10) / 10; }; + gainMP = function(delta) { + delta *= user._tmp.crit || 1; + user.stats.mp += delta; + if (user.stats.mp >= user._statsComputed.maxMP) { + user.stats.mp = user._statsComputed.maxMP; + } + if (user.stats.mp < 0) { + return user.stats.mp = 0; + } + }; switch (task.type) { case 'habit': changeTaskValue(); + gainMP(_.max([0.25, .0025 * user._statsComputed.maxMP]) * (direction === 'down' ? -1 : 1)); if (delta > 0) { addPoints(); } else { @@ -6443,6 +6476,7 @@ api.wrap = function(user, main) { } } else { changeTaskValue(); + gainMP(_.max([1, .01 * user._statsComputed.maxMP]) * (direction === 'down' ? -1 : 1)); if (direction === 'down') { delta = calculateDelta(); } @@ -6475,18 +6509,7 @@ api.wrap = function(user, main) { return m + (i.completed ? 1 : 0); }), 1), 1 ]); - mpDelta = _.max([multiplier, .01 * user._statsComputed.maxMP * multiplier]); - mpDelta *= user._tmp.crit || 1; - if (direction === 'down') { - mpDelta *= -1; - } - user.stats.mp += mpDelta; - if (user.stats.mp >= user._statsComputed.maxMP) { - user.stats.mp = user._statsComputed.maxMP; - } - if (user.stats.mp < 0) { - user.stats.mp = 0; - } + gainMP(_.max([multiplier, .01 * user._statsComputed.maxMP * multiplier]) * (direction === 'down' ? -1 : 1)); } break; case 'reward': @@ -6562,14 +6585,16 @@ api.wrap = function(user, main) { return x - Math.floor(x); }, crit: function(stat, chance) { + var s; if (stat == null) { stat = 'str'; } if (chance == null) { chance = .03; } - if (user.fns.predictableRandom() <= chance * (1 + user._statsComputed[stat] / 100)) { - return 1.5 + (.02 * user._statsComputed[stat]); + s = user._statsComputed[stat]; + if (user.fns.predictableRandom() <= chance * (1 + s / 100)) { + return 1.5 + 4 * s / (s + 200); } else { return 1; } @@ -6814,7 +6839,7 @@ api.wrap = function(user, main) { {user} */ cron: function(options) { - var clearBuffs, daysMissed, expTally, lvl, lvlDiv2, now, perfect, plan, progress, todoTally, _base, _base1, _base2, _base3, _progress, _ref, _ref1, _ref2; + var clearBuffs, dailyChecked, dailyDueUnchecked, daysMissed, expTally, lvl, lvlDiv2, now, perfect, plan, progress, todoTally, _base, _base1, _base2, _base3, _progress, _ref, _ref1, _ref2; if (options == null) { options = {}; } @@ -6882,11 +6907,13 @@ api.wrap = function(user, main) { return; } todoTally = 0; + dailyChecked = 0; + dailyDueUnchecked = 0; if ((_base = user.party.quest.progress).down == null) { _base.down = 0; } user.todos.concat(user.dailys).forEach(function(task) { - var absVal, completed, delta, id, repeat, scheduleMisses, type; + var absVal, completed, delta, fractionChecked, id, repeat, scheduleMisses, type, _ref1; if (!task) { return; } @@ -6894,7 +6921,11 @@ api.wrap = function(user, main) { if ((type === 'daily') && !completed && user.stats.buffs.stealth && user.stats.buffs.stealth--) { return; } - if (!completed) { + if (completed) { + if (type === 'daily') { + dailyChecked += 1; + } + } else { scheduleMisses = daysMissed; if ((type === 'daily') && repeat) { scheduleMisses = 0; @@ -6911,6 +6942,15 @@ api.wrap = function(user, main) { if (scheduleMisses > 0) { if (type === 'daily') { perfect = false; + if (((_ref1 = task.checklist) != null ? _ref1.length : void 0) > 0) { + fractionChecked = _.reduce(task.checklist, (function(m, i) { + return m + (i.completed ? 1 : 0); + }), 0) / task.checklist.length; + dailyDueUnchecked += 1 - fractionChecked; + dailyChecked += fractionChecked; + } else { + dailyDueUnchecked += 1; + } } delta = user.ops.score({ params: { @@ -6983,7 +7023,10 @@ api.wrap = function(user, main) { stealth: 0, streaks: false }) : clearBuffs; - user.stats.mp += _.max([10, .1 * user._statsComputed.maxMP]); + if (dailyDueUnchecked === 0 && dailyChecked === 0) { + dailyChecked = 1; + } + user.stats.mp += _.max([10, .1 * user._statsComputed.maxMP]) * dailyChecked / (dailyDueUnchecked + dailyChecked); if (user.stats.mp > user._statsComputed.maxMP) { user.stats.mp = user._statsComputed.maxMP; }