diff --git a/src/app/algos.coffee b/src/app/algos.coffee index 3a72add2cb..0ba65e1c45 100644 --- a/src/app/algos.coffee +++ b/src/app/algos.coffee @@ -1,5 +1,5 @@ - -MODIFIER = .02 +XP = 15 +HP = 2 priorityValue = (priority='!') -> switch priority @@ -9,7 +9,11 @@ priorityValue = (priority='!') -> else 1 module.exports.tnl = (level) -> - return (Math.pow(level,2)*10)+(level*10)+80 + if level >= 100 + value = 0 + else + value = Math.round(((Math.pow(level,2)*0.25)+(10 * level) + 139.75)/10)*10 # round to nearest 10 + return value ### Calculates Exp modificaiton based on level and weapon strength @@ -18,11 +22,12 @@ module.exports.tnl = (level) -> {level} current user level {priority} user-defined priority multiplier ### -module.exports.expModifier = (value, weaponStrength, level, priority='!') -> - levelModifier = (level-1) * MODIFIER - weaponModifier = weaponStrength / 100 - strength = 1 + weaponModifier + levelModifier - return value * strength * priorityValue(priority) +module.exports.expModifier = (value, weaponStr, level, priority='!') -> + str = (level-1) * 2 # ultimately get this from user + totalStr = (str + weaponStr) / 100 + strMod = 1 + totalStr + exp = value * XP * strMod * priorityValue(priority) + return Math.round(exp) ### Calculates HP modification based on level and armor defence @@ -32,11 +37,12 @@ module.exports.expModifier = (value, weaponStrength, level, priority='!') -> {level} current user level {priority} user-defined priority multiplier ### -module.exports.hpModifier = (value, armorDefense, helmDefense, shieldDefense, level, priority='!') -> - levelModifier = (level-1) * MODIFIER - armorModifier = (armorDefense + helmDefense + shieldDefense) / 100 - defense = 1 - levelModifier + armorModifier - return value * defense * priorityValue(priority) +module.exports.hpModifier = (value, armorDef, helmDef, shieldDef, level, priority='!') -> + def = (level-1) * 2 # ultimately get this from user? + totalDef = (def + armorDef + helmDef + shieldDef) / 100 #ultimate get this from user + defMod = 1 - totalDef + hp = value * HP * defMod * priorityValue(priority) + return Math.round(hp * 10)/10 # round to 1dp ### Future use @@ -52,10 +58,10 @@ module.exports.gpModifier = (value, modifier, priority='!') -> {direction} up or down ### module.exports.taskDeltaFormula = (currentValue, direction) -> - if direction is 'up' - delta = Math.max(Math.pow(0.95,currentValue),0.25) - else - delta = -Math.min(Math.pow(0.95,currentValue),5) - #console.log("CV = " + currentValue + " Dir = " + direction + " delta = " + delta) - delta = 20 if delta > 20 - return delta \ No newline at end of file + if currentValue < -47.27 then currentValue = -47.27 + else if currentValue > 21.27 then currentValue = 21.27 + delta = Math.pow(0.9747,currentValue) + return delta if direction is 'up' + return -delta + + diff --git a/src/app/browser.coffee b/src/app/browser.coffee index f4d5c8e31d..fcc32647ee 100644 --- a/src/app/browser.coffee +++ b/src/app/browser.coffee @@ -9,7 +9,10 @@ restoreRefs = module.exports.restoreRefs = (model) -> # see https://github.com/lefnire/habitrpg/issues/4 # also update in scoring.coffee. TODO create a function accessible in both locations #TODO find a method of calling algos.tnl() - 10*Math.pow(lvl,2)+(lvl*10)+80 + if lvl==100 + 0 + else + Math.round(((Math.pow(lvl,2)*0.25)+(10 * lvl) + 139.75)/10)*10 #refLists _.each ['habit', 'daily', 'todo', 'reward'], (type) -> @@ -171,13 +174,14 @@ setupGrowlNotifications = (model) -> else if num > 0 statsNotification " + #{rounded} HP", 'hp' # gained hp from potion/level? - user.on 'set', 'stats.exp', (captures, args, isLocal, silent) -> - num = captures - args - rounded = Math.abs(num.toFixed(1)) - if num < 0 and not silent - statsNotification " - #{rounded} XP", 'xp' - else if num > 0 - statsNotification " + #{rounded} XP", 'xp' + user.on 'set', 'stats.exp', (captures, args, isLocal, silent=false) -> + # unless silent + num = captures - args + rounded = Math.abs(num.toFixed(1)) + if num < 0 and num > -100 # TODO fix hackey negative notification supress + statsNotification " - #{rounded} XP", 'xp' + else if num > 0 + statsNotification " + #{rounded} XP", 'xp' user.on 'set', 'stats.gp', (captures, args) -> num = captures - args @@ -195,7 +199,7 @@ setupGrowlNotifications = (model) -> user.on 'set', 'stats.lvl', (captures, args) -> if captures > args if captures is 1 and args is 0 - statsNotification ' You died!', 'death' + statsNotification ' You died! Game over.', 'death' else statsNotification ' Level Up!', 'lvl' diff --git a/src/app/debug.coffee b/src/app/debug.coffee index 24195797bb..1f2172d272 100644 --- a/src/app/debug.coffee +++ b/src/app/debug.coffee @@ -8,8 +8,13 @@ module.exports.app = (appExports, model) -> user.set 'lastCron', yesterday window.location.reload() + appExports.emulateTenDays = -> + yesterday = +moment().subtract('days', 10).toDate() + user.set 'lastCron', yesterday + window.location.reload() + appExports.cheat = -> - user.incr 'stats.exp', 20 + user.incr 'stats.exp', model.get '_tnl' user.incr 'stats.gp', 1000 appExports.reset = -> diff --git a/src/app/helpers.coffee b/src/app/helpers.coffee index ff0c82459d..b6389bfba9 100644 --- a/src/app/helpers.coffee +++ b/src/app/helpers.coffee @@ -19,6 +19,9 @@ module.exports.viewHelpers = (view) -> view.fn "floor", (num) -> Math.floor num + + view.fn "ceil", (num) -> + Math.ceil num view.fn "lt", (a, b) -> a < b diff --git a/src/app/scoring.coffee b/src/app/scoring.coffee index a63a31a467..5cc5a8428c 100644 --- a/src/app/scoring.coffee +++ b/src/app/scoring.coffee @@ -46,14 +46,13 @@ score = (model, taskId, direction, times, batch, cron) -> # (aka, the total delta). This weirdness won't be necessary when calculating mathematically # rather than iteratively nextDelta = algos.taskDeltaFormula(value, direction) - value = Math.max(value + nextDelta, -31) if adjustvalue #cap values so we don't get silly values + value += nextDelta if adjustvalue delta += nextDelta addPoints = -> level = user.get('stats.lvl') weaponStrength = items.items.weapon[user.get('items.weapon')].strength - modified = algos.expModifier(delta,weaponStrength,level, priority) - exp += modified*10 + exp += algos.expModifier(delta,weaponStrength,level, priority) gp += algos.gpModifier(delta, 1, priority) subtractPoints = -> @@ -61,8 +60,7 @@ score = (model, taskId, direction, times, batch, cron) -> armorDefense = items.items.armor[user.get('items.armor')].defense helmDefense = items.items.head[user.get('items.head')].defense shieldDefense = items.items.shield[user.get('items.shield')].defense - modified = algos.hpModifier(delta,armorDefense,helmDefense,shieldDefense,level, priority) - hp += modified + hp += algos.hpModifier(delta,armorDefense,helmDefense,shieldDefense,level, priority) switch type when 'habit' @@ -81,7 +79,8 @@ score = (model, taskId, direction, times, batch, cron) -> subtractPoints() else calculateDelta(false) - addPoints() # obviously for delta>0, but also a trick to undo accidental checkboxes + if delta != 0 + addPoints() # obviously for delta>0, but also a trick to undo accidental checkboxes when 'todo' if cron? #cron @@ -137,20 +136,30 @@ updateStats = (model, newStats, batch) -> obj.stats.hp = newStats.hp if newStats.exp? - # level up & carry-over exp tnl = model.get '_tnl' - silent = false - if newStats.exp >= tnl - silent = true - user.set('stats.exp', newStats.exp) - while newStats.exp >= tnl # keep levelling up - newStats.exp -= tnl - obj.stats.lvl++ - tnl = algos.tnl(obj.stats.lvl) - obj.stats.hp = 50 + #silent = false + # if we're at level 100, turn xp to gold + if obj.stats.lvl >= 100 + newStats.gp += newStats.exp / 15 + newStats.exp = 0 + obj.stats.lvl = 100 + else + # level up & carry-over exp + if newStats.exp >= tnl + #silent = true # push through the negative xp silently + user.set('stats.exp', newStats.exp) # push normal + notification + while newStats.exp >= tnl and obj.stats.lvl < 100 # keep levelling up + newStats.exp -= tnl + obj.stats.lvl++ + tnl = algos.tnl(obj.stats.lvl) + if obj.stats.lvl== 100 + newStats.exp = 0 + obj.stats.hp = 50 obj.stats.exp = newStats.exp - user.pass(silent:true).set('stats.exp', obj.stats.exp) if silent + #if silent + #console.log("pushing silent :" + obj.stats.exp) + #user.pass(true).set('stats.exp', obj.stats.exp) # Set flags when they unlock features if !obj.flags.customizationsNotification and (obj.stats.exp > 10 or obj.stats.lvl > 1) @@ -218,7 +227,7 @@ cron = (model) -> value = obj.tasks[taskObj.id].value #get updated value absVal = if (completed) then Math.abs(value) else value todoTally += absVal - else if type is 'habit' #reset 'onlies' value to 0 + else if type is 'habit' # slowly reset 'onlies' value to 0 if taskObj.up==false or taskObj.down==false if Math.abs(taskObj.value) < 0.02 batch.set "tasks.#{taskObj.id}.value", 0 diff --git a/views/app/footer.html b/views/app/footer.html index 35be956150..bd7626f248 100644 --- a/views/app/footer.html +++ b/views/app/footer.html @@ -19,7 +19,8 @@ {else}