diff --git a/common/dist/scripts/habitrpg-shared.js b/common/dist/scripts/habitrpg-shared.js index 35a0c07d60..4630ac67c3 100644 --- a/common/dist/scripts/habitrpg-shared.js +++ b/common/dist/scripts/habitrpg-shared.js @@ -2623,7 +2623,7 @@ api.spells = { if ((_base = user.stats.buffs).stealth == null) { _base.stealth = 0; } - return user.stats.buffs.stealth += Math.ceil(user.dailys.length * user._statsComputed.per / 100); + return user.stats.buffs.stealth += Math.ceil(diminishingReturns(user._statsComputed.per, user.dailys.length * 0.64, 55)); } } }, @@ -4847,6 +4847,23 @@ api.shouldDo = function(day, repeat, options) { }; +/* + ------------------------------------------------------ + Level cap + ------------------------------------------------------ + */ + +api.maxLevel = 100; + +api.capByLevel = function(lvl) { + if (lvl > api.maxLevel) { + return api.maxLevel; + } else { + return lvl; + } +}; + + /* ------------------------------------------------------ Scoring @@ -5465,20 +5482,16 @@ api.wrap = function(user, main) { }, rebirth: function(req, cb, ga) { var flags, gear, lvl, stats; - if (user.balance < 2 && user.stats.lvl < 100) { + if (user.balance < 2 && user.stats.lvl < api.maxLevel) { return typeof cb === "function" ? cb({ code: 401, message: i18n.t('notEnoughGems', req.language) }) : void 0; } - if (user.stats.lvl < 100) { + if (user.stats.lvl < api.maxLevel) { user.balance -= 2; } - if (user.stats.lvl < 100) { - lvl = user.stats.lvl; - } else { - lvl = 100; - } + lvl = api.capByLevel(user.stats.lvl); _.each(user.tasks, function(task) { if (task.type !== 'reward') { task.value = 0; @@ -6252,7 +6265,7 @@ api.wrap = function(user, main) { con: 0, per: 0, int: 0, - points: user.stats.lvl + points: api.capByLevel(user.stats.lvl) }); user.flags.classSelected = false; if (ga != null) { @@ -6266,7 +6279,7 @@ api.wrap = function(user, main) { user.flags.classSelected = true; user.preferences.disableClasses = true; user.preferences.autoAllocate = true; - user.stats.str = user.stats.lvl; + user.stats.str = api.capByLevel(user.stats.lvl); user.stats.points = 0; return typeof cb === "function" ? cb(null, _.pick(user, $w('stats flags preferences'))) : void 0; }, @@ -6703,13 +6716,14 @@ api.wrap = function(user, main) { */ autoAllocate: function() { return user.stats[(function() { - var diff, ideal, preference, stats, suggested; + var diff, ideal, lvlDiv7, preference, stats, suggested; switch (user.preferences.allocationMode) { case "flat": stats = _.pick(user.stats, $w('con str per int')); return _.invert(stats)[_.min(stats)]; case "classbased": - ideal = [user.stats.lvl / 7 * 3, user.stats.lvl / 7 * 2, user.stats.lvl / 7, user.stats.lvl / 7]; + lvlDiv7 = user.stats.lvl / 7; + ideal = [lvlDiv7 * 3, lvlDiv7 * 2, lvlDiv7, lvlDiv7]; preference = (function() { switch (user.stats["class"]) { case "wizard": @@ -6761,12 +6775,15 @@ api.wrap = function(user, main) { stats.exp -= tnl; user.stats.lvl++; tnl = api.tnl(user.stats.lvl); + user.stats.hp = 50; + if (user.stats.lvl > api.maxLevel) { + continue; + } if (user.preferences.automaticAllocation) { user.fns.autoAllocate(); } else { user.stats.points = user.stats.lvl - (user.stats.con + user.stats.str + user.stats.per + user.stats.int); } - user.stats.hp = 50; } } user.stats.exp = stats.exp; @@ -6820,7 +6837,7 @@ api.wrap = function(user, main) { if (!user.flags.rebirthEnabled && (user.stats.lvl >= 50 || user.achievements.ultimateGear || user.achievements.beastMaster)) { user.flags.rebirthEnabled = true; } - if (user.stats.lvl >= 100 && !user.flags.freeRebirth) { + if (user.stats.lvl >= api.maxLevel && !user.flags.freeRebirth) { return user.flags.freeRebirth = true; } }, @@ -6913,20 +6930,18 @@ api.wrap = function(user, main) { _base.down = 0; } user.todos.concat(user.dailys).forEach(function(task) { - var absVal, completed, delta, fractionChecked, id, repeat, scheduleMisses, type, _ref1; + var EvadeTask, absVal, completed, delta, fractionChecked, id, repeat, scheduleMisses, type, _ref1; if (!task) { return; } id = task.id, type = task.type, completed = task.completed, repeat = task.repeat; - if ((type === 'daily') && !completed && user.stats.buffs.stealth && user.stats.buffs.stealth--) { - return; - } + EvadeTask = 0; + scheduleMisses = daysMissed; if (completed) { if (type === 'daily') { dailyChecked += 1; } } else { - scheduleMisses = daysMissed; if ((type === 'daily') && repeat) { scheduleMisses = 0; _.times(daysMissed, function(n) { @@ -6935,11 +6950,15 @@ api.wrap = function(user, main) { days: n + 1 }); if (api.shouldDo(thatDay, repeat, user.preferences)) { - return scheduleMisses++; + scheduleMisses++; + if (user.stats.buffs.stealth) { + user.stats.buffs.stealth--; + return EvadeTask++; + } } }); } - if (scheduleMisses > 0) { + if (scheduleMisses > EvadeTask) { if (type === 'daily') { perfect = false; if (((_ref1 = task.checklist) != null ? _ref1.length : void 0) > 0) { @@ -6958,7 +6977,7 @@ api.wrap = function(user, main) { direction: 'down' }, query: { - times: scheduleMisses, + times: scheduleMisses - EvadeTask, cron: true } }); @@ -6974,10 +6993,13 @@ api.wrap = function(user, main) { value: task.value }); task.completed = false; - return _.each(task.checklist, (function(i) { - i.completed = false; - return true; - })); + if (completed || (scheduleMisses > 0)) { + return _.each(task.checklist, (function(i) { + i.completed = false; + return true; + })); + } + break; case 'todo': absVal = completed ? Math.abs(task.value) : task.value; return todoTally += absVal; @@ -7015,7 +7037,7 @@ api.wrap = function(user, main) { user.markModified('dailys'); } } - user.stats.buffs = perfect ? ((_base3 = user.achievements).perfect != null ? _base3.perfect : _base3.perfect = 0, user.achievements.perfect++, user.stats.lvl < 100 ? lvlDiv2 = Math.ceil(user.stats.lvl / 2) : lvlDiv2 = 50, { + user.stats.buffs = perfect ? ((_base3 = user.achievements).perfect != null ? _base3.perfect : _base3.perfect = 0, user.achievements.perfect++, lvlDiv2 = Math.ceil(api.capByLevel(user.stats.lvl) / 2), { str: lvlDiv2, int: lvlDiv2, per: lvlDiv2, @@ -7106,11 +7128,7 @@ api.wrap = function(user, main) { val = user.fns.dotGet(path); return m2 + (~path.indexOf('items.gear') ? (item = content.gear.flat[val], (+(item != null ? item[stat] : void 0) || 0) * ((item != null ? item.klass : void 0) === user.stats["class"] || (item != null ? item.specialClass : void 0) === user.stats["class"] ? 1.5 : 1)) : +val[stat] || 0); }, 0); - if (user.stats.lvl < 100) { - m[stat] += (user.stats.lvl - 1) / 2; - } else { - m[stat] += 50; - } + m[stat] += Math.floor(api.capByLevel(user.stats.lvl) / 2); return m; }; })(this), {}); diff --git a/common/script/content.coffee b/common/script/content.coffee index 2637028692..59ff118f5d 100644 --- a/common/script/content.coffee +++ b/common/script/content.coffee @@ -620,8 +620,8 @@ api.spells = notes: t('spellRogueStealthNotes') cast: (user, target) -> user.stats.buffs.stealth ?= 0 - ## scales to user's # of dailies; maxes out at 100% at 100 per ## - user.stats.buffs.stealth += Math.ceil(user.dailys.length * user._statsComputed.per / 100) + ## scales to user's # of dailies; Diminishing Returns, maxes out at 64%, halfway point at 55 PER## + user.stats.buffs.stealth += Math.ceil( diminishingReturns(user._statsComputed.per, user.dailys.length*0.64,55)) healer: heal: diff --git a/common/script/index.coffee b/common/script/index.coffee index 4175c7832c..e219557e02 100644 --- a/common/script/index.coffee +++ b/common/script/index.coffee @@ -1393,7 +1393,7 @@ api.wrap = (user, main=true) -> user.stats.hp = 50 - return if user.stats.lvl > api.maxLevel + continue if user.stats.lvl > api.maxLevel # Auto-allocate a point, or give them a new manual point if user.preferences.automaticAllocation @@ -1510,22 +1510,24 @@ api.wrap = (user, main=true) -> {id, type, completed, repeat} = task - return if (type is 'daily') && !completed && user.stats.buffs.stealth && user.stats.buffs.stealth-- # User "evades" a certain number of uncompleted dailies (includes uncompletd GREY dailies - TODO fix that?) - # All processing of Dailies is calculated AFTER stealth -- stealthed Dailies are treated as just not being there - # Deduct points for missed Daily tasks, but not for Todos (just increase todo's value) + EvadeTask = 0 + scheduleMisses = daysMissed if completed if type is 'daily' dailyChecked += 1 else - scheduleMisses = daysMissed # for dailys which have repeat dates, need to calculate how many they've missed according to their own schedule if (type is 'daily') and repeat scheduleMisses = 0 _.times daysMissed, (n) -> thatDay = moment(now).subtract({days: n + 1}) - scheduleMisses++ if api.shouldDo(thatDay, repeat, user.preferences) - if scheduleMisses > 0 + if api.shouldDo(thatDay, repeat, user.preferences) + scheduleMisses++ + if user.stats.buffs.stealth + user.stats.buffs.stealth-- + EvadeTask++ + if scheduleMisses > EvadeTask if type is 'daily' perfect = false if task.checklist?.length > 0 # Partially completed checklists dock fewer mana points @@ -1534,15 +1536,16 @@ api.wrap = (user, main=true) -> dailyChecked += fractionChecked else dailyDueUnchecked += 1 - delta = user.ops.score({params:{id:task.id, direction:'down'}, query:{times:scheduleMisses, cron:true}}); + delta = user.ops.score({params:{id:task.id, direction:'down'}, query:{times:(scheduleMisses-EvadeTask), cron:true}}); # this line occurs for todos or dailys user.party.quest.progress.down += delta if type is 'daily' - switch type when 'daily' + # This occurs whether or not the task is completed (task.history ?= []).push({ date: +new Date, value: task.value }) task.completed = false - _.each task.checklist, ((i)->i.completed=false;true) + if completed || (scheduleMisses > 0) + _.each task.checklist, ((i)->i.completed=false;true) # this should not happen for grey tasks unless they are completed when 'todo' #get updated value absVal = if (completed) then Math.abs(task.value) else task.value @@ -1583,12 +1586,8 @@ api.wrap = (user, main=true) -> # Add 10 MP, or 10% of max MP if that'd be more. Perform this after Perfect Day for maximum benefit # Adjust for fraction of dailies completed - #console.log("Prior MP: " + user.stats.mp) dailyChecked=1 if dailyDueUnchecked is 0 and dailyChecked is 0 - #console.log("DueUnchecked: " + dailyDueUnchecked) - #console.log("Checked: " + dailyChecked) user.stats.mp += _.max([10,.1 * user._statsComputed.maxMP]) * dailyChecked / (dailyDueUnchecked + dailyChecked) - #console.log("After MP: " +user.stats.mp) user.stats.mp = user._statsComputed.maxMP if user.stats.mp > user._statsComputed.maxMP # After all is said and done, progress up user's effect on quest, return those values & reset the user's