diff --git a/src/app/algos.coffee b/src/app/algos.coffee new file mode 100644 index 00000000000..205842d178f --- /dev/null +++ b/src/app/algos.coffee @@ -0,0 +1,54 @@ + +MODIFIER = .02 + +module.exports.tnl = (level) -> + return (Math.pow(level,2)*10)+(level*10)+80 + +### + Calculates Exp modificaiton based on level and weapon strength + {value} task.value for exp gain + {weaponStrength) weapon strength + {level} current user level +### +module.exports.expModifier = (value, weaponStrength, level) -> + levelModifier = (level-1) * MODIFIER + weaponModifier = weaponStrength / 100 + strength = 1 + weaponModifier + levelModifier + return value * strength + +### + Calculates HP modification based on level and armor defence + {value} task.value for hp loss + {armorDefense} defense from armor + {helmDefense} defense from helm + {level} current user level +### +module.exports.hpModifier = (value, armorDefense, helmDefense, shieldDefense, level) -> + levelModifier = (level-1) * MODIFIER + armorModifier = (armorDefense + helmDefense + shieldDefense) / 100 + defense = 1 - levelModifier + armorModifier + return value * defense + +### + Future use +### +module.exports.gpModifier = (value, modifier) -> + return value * modifier + +### + Calculates the next task.value based on direction + Uses a capped inverse log y=.95^x, y>= -5 + {currentValue} the current value of the task + {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) + #sign = if (direction is 'up') then 1 else -1 + #delta = Math.pow(0.95,currentValue) * sign + #if delta < -5 then delta = -5 + #console.log("CurrentValue: " + currentValue + " delta: " + delta) + #delta = if (currentValue < 0) then (( -0.1 * currentValue + 1 ) * sign) else (( Math.pow(0.9,currentValue) ) * sign) + return delta \ No newline at end of file diff --git a/src/app/browser.coffee b/src/app/browser.coffee index 7cfdb67d593..351573cf437 100644 --- a/src/app/browser.coffee +++ b/src/app/browser.coffee @@ -1,12 +1,14 @@ _ = require 'underscore' moment = require 'moment' +#algos = require './algos' module.exports.restoreRefs = restoreRefs = (model) -> # tnl function model.fn '_tnl', '_user.stats.lvl', (lvl) -> # see https://github.com/lefnire/habitrpg/issues/4 # also update in scoring.coffee. TODO create a function accessible in both locations - (lvl*100)/5 + #TODO find a method of calling algos.tnl() + 10*Math.pow(lvl,2)+(lvl*10)+80 #refLists _.each ['habit', 'daily', 'todo', 'reward'], (type) -> @@ -176,7 +178,7 @@ setupGrowlNotifications = (model) -> return if user.get('stats.lvl') == 0 $.bootstrapGrowl html, ele: '#notification-area', - type: type # (null, 'info', 'error', 'success', 'gp', 'xp', 'hp', 'lvl') + type: type # (null, 'info', 'error', 'success', 'gp', 'xp', 'hp', 'lvl','death') top_offset: 20 align: 'right' # ('left', 'right', or 'center') width: 250 # (integer, or 'auto') @@ -189,21 +191,34 @@ setupGrowlNotifications = (model) -> num = captures - args rounded = Math.abs(num.toFixed(1)) if num < 0 - statsNotification " -#{rounded} HP", 'hp' # lost hp from purchase + statsNotification " - #{rounded} HP", 'hp' # lost hp from purchase + 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.gp', (captures, args) -> num = captures - args - rounded = Math.abs(num.toFixed(1)) - # made purchase - if num < 0 - # FIXME use 'warning' when unchecking an accidently completed daily/todo, and notify of exp too - statsNotification " -#{rounded} GP", 'gp' - # gained gp (and thereby exp) - else if num > 0 - num = Math.abs(num) - statsNotification " +#{rounded} XP", 'xp' - statsNotification " +#{rounded} GP", 'gp' + absolute = Math.abs(num) + gold = Math.floor(absolute) + silver = Math.floor((absolute-gold)*100) + sign = if num < 0 then '-' else '+' + if gold and silver > 0 + statsNotification "#{sign} #{gold} #{silver} ", 'gp' + else if gold > 0 + statsNotification "#{sign} #{gold} ", 'gp' + else if silver > 0 + statsNotification "#{sign} #{silver} ", 'gp' user.on 'set', 'stats.lvl', (captures, args) -> if captures > args - statsNotification(' Level Up!', 'lvl') \ No newline at end of file + if captures is 1 and args is 0 + statsNotification ' You died!', 'death' + else + statsNotification ' Level Up!', 'lvl' diff --git a/src/app/character.coffee b/src/app/character.coffee index 07b0996dcb6..de1b280c2da 100644 --- a/src/app/character.coffee +++ b/src/app/character.coffee @@ -221,6 +221,7 @@ module.exports.BatchUpdate = BatchUpdate = (model) -> commit: -> model._dontPersist = false # some hackery in our own branched racer-db-mongo, see findAndModify of lefnire/racer-db-mongo#habitrpg index.js + # pass true if we have levelled to supress xp notification user.set "update__", updates transactionInProgress = false updates = {} diff --git a/src/app/debug.coffee b/src/app/debug.coffee index 25cb833b8fc..24195797bb1 100644 --- a/src/app/debug.coffee +++ b/src/app/debug.coffee @@ -11,3 +11,12 @@ module.exports.app = (appExports, model) -> appExports.cheat = -> user.incr 'stats.exp', 20 user.incr 'stats.gp', 1000 + + appExports.reset = -> + user.set 'stats.exp', 0 + user.set 'stats.lvl', 0 + user.set 'stats.gp', 0 + user.set 'items.weapon', 0 + user.set 'items.armor', 0 + user.set 'items.head', 0 + user.set 'items.shield', 0 \ No newline at end of file diff --git a/src/app/helpers.coffee b/src/app/helpers.coffee index 38733f11d5c..5c2cccaa151 100644 --- a/src/app/helpers.coffee +++ b/src/app/helpers.coffee @@ -14,6 +14,9 @@ module.exports.viewHelpers = (view) -> view.fn "round", (num) -> Math.round num + + view.fn "floor", (num) -> + Math.floor num view.fn "lt", (a, b) -> a < b diff --git a/src/app/items.coffee b/src/app/items.coffee index 911458e60c9..58799b1d1ce 100644 --- a/src/app/items.coffee +++ b/src/app/items.coffee @@ -2,37 +2,37 @@ _ = require 'underscore' items = module.exports.items = weapon: [ - {index: 0, text: "Training Sword", classes: "weapon_0", notes:'Training weapon.', modifier: 0.00, value:0} - {index: 1, text: "Sword", classes:'weapon_1', notes:'Increases experience gain by 3%.', modifier: 0.03, value:20} - {index: 2, text: "Axe", classes:'weapon_2', notes:'Increases experience gain by 6%.', modifier: 0.06, value:30} - {index: 3, text: "Morningstar", classes:'weapon_3', notes:'Increases experience gain by 9%.', modifier: 0.09, value:45} - {index: 4, text: "Blue Sword", classes:'weapon_4', notes:'Increases experience gain by 12%.', modifier: 0.12, value:65} - {index: 5, text: "Red Sword", classes:'weapon_5', notes:'Increases experience gain by 15%.', modifier: 0.15, value:90} - {index: 6, text: "Golden Sword", classes:'weapon_6', notes:'Increases experience gain by 18%.', modifier: 0.18, value:120} + {index: 0, text: "Training Sword", classes: "weapon_0", notes:'Training weapon.', strength: 0, value:0} + {index: 1, text: "Sword", classes:'weapon_1', notes:'Increases experience gain by 3%.', strength: 3, value:20} + {index: 2, text: "Axe", classes:'weapon_2', notes:'Increases experience gain by 6%.', strength: 6, value:30} + {index: 3, text: "Morningstar", classes:'weapon_3', notes:'Increases experience gain by 9%.', strength: 9, value:45} + {index: 4, text: "Blue Sword", classes:'weapon_4', notes:'Increases experience gain by 12%.', strength: 12, value:65} + {index: 5, text: "Red Sword", classes:'weapon_5', notes:'Increases experience gain by 15%.', strength: 15, value:90} + {index: 6, text: "Golden Sword", classes:'weapon_6', notes:'Increases experience gain by 18%.', strength: 18, value:120} ] armor: [ - {index: 0, text: "Cloth Armor", classes: 'armor_0', notes:'Training armor.', modifier: 0.00, value:0} - {index: 1, text: "Leather Armor", classes: 'armor_1', notes:'Decreases HP loss by 4%.', modifier: 0.04, value:30} - {index: 2, text: "Chain Mail", classes: 'armor_2', notes:'Decreases HP loss by 6%.', modifier: 0.06, value:45} - {index: 3, text: "Plate Mail", classes: 'armor_3', notes:'Decreases HP loss by 7%.', modifier: 0.07, value:65} - {index: 4, text: "Red Armor", classes: 'armor_4', notes:'Decreases HP loss by 8%.', modifier: 0.08, value:90} - {index: 5, text: "Golden Armor", classes: 'armor_5', notes:'Decreases HP loss by 10%.', modifier: 0.1, value:120} + {index: 0, text: "Cloth Armor", classes: 'armor_0', notes:'Training armor.', defense: 0, value:0} + {index: 1, text: "Leather Armor", classes: 'armor_1', notes:'Decreases HP loss by 4%.', defense: 4, value:30} + {index: 2, text: "Chain Mail", classes: 'armor_2', notes:'Decreases HP loss by 6%.', defense: 6, value:45} + {index: 3, text: "Plate Mail", classes: 'armor_3', notes:'Decreases HP loss by 7%.', defense: 7, value:65} + {index: 4, text: "Red Armor", classes: 'armor_4', notes:'Decreases HP loss by 8%.', defense: 8, value:90} + {index: 5, text: "Golden Armor", classes: 'armor_5', notes:'Decreases HP loss by 10%.', defense: 10, value:120} ] head: [ - {index: 0, text: "No Helm", classes: 'head_0', notes:'Training helm.', modifier: 0.00, value:0} - {index: 1, text: "Leather Helm", classes: 'head_1', notes:'Decreases HP loss by 2%.', modifier: 0.02, value:15} - {index: 2, text: "Chain Coif", classes: 'head_2', notes:'Decreases HP loss by 3%.', modifier: 0.03, value:25} - {index: 3, text: "Plate Helm", classes: 'head_3', notes:'Decreases HP loss by 4%.', modifier: 0.04, value:45} - {index: 4, text: "Red Helm", classes: 'head_4', notes:'Decreases HP loss by 5%.', modifier: 0.05, value:60} - {index: 5, text: "Golden Helm", classes: 'head_5', notes:'Decreases HP loss by 6%.', modifier: 0.06, value:80} + {index: 0, text: "No Helm", classes: 'head_0', notes:'Training helm.', defense: 0, value:0} + {index: 1, text: "Leather Helm", classes: 'head_1', notes:'Decreases HP loss by 2%.', defense: 2, value:15} + {index: 2, text: "Chain Coif", classes: 'head_2', notes:'Decreases HP loss by 3%.', defense: 3, value:25} + {index: 3, text: "Plate Helm", classes: 'head_3', notes:'Decreases HP loss by 4%.', defense: 4, value:45} + {index: 4, text: "Red Helm", classes: 'head_4', notes:'Decreases HP loss by 5%.', defense: 5, value:60} + {index: 5, text: "Golden Helm", classes: 'head_5', notes:'Decreases HP loss by 6%.', defense: 6, value:80} ] shield: [ - {index: 0, text: "No Shield", classes: 'shield_0', notes:'No Shield.', modifier: 0.00, value:0} - {index: 1, text: "Wooden Shield", classes: 'shield_1', notes:'Decreases HP loss by 3%', modifier: 0.03, value:20} - {index: 2, text: "Buckler", classes: 'shield_2', notes:'Decreases HP loss by 4%.', modifier: 0.04, value:35} - {index: 3, text: "Enforced Shield", classes: 'shield_3', notes:'Decreases HP loss by 5%.', modifier: 0.05, value:55} - {index: 4, text: "Red Shield", classes: 'shield_4', notes:'Decreases HP loss by 7%.', modifier: 0.07, value:70} - {index: 5, text: "Golden Shield", classes: 'shield_5', notes:'Decreases HP loss by 8%.', modifier: 0.08, value:90} + {index: 0, text: "No Shield", classes: 'shield_0', notes:'No Shield.', defense: 0, value:0} + {index: 1, text: "Wooden Shield", classes: 'shield_1', notes:'Decreases HP loss by 3%', defense: 3, value:20} + {index: 2, text: "Buckler", classes: 'shield_2', notes:'Decreases HP loss by 4%.', defense: 4, value:35} + {index: 3, text: "Enforced Shield", classes: 'shield_3', notes:'Decreases HP loss by 5%.', defense: 5, value:55} + {index: 4, text: "Red Shield", classes: 'shield_4', notes:'Decreases HP loss by 7%.', defense: 7, value:70} + {index: 5, text: "Golden Shield", classes: 'shield_5', notes:'Decreases HP loss by 8%.', defense: 8, value:90} ] potion: {type: 'potion', text: "Potion", notes: "Recover 15 HP", value: 25, classes: 'potion'} reroll: {type: 'reroll', text: "Re-Roll", classes: 'reroll', notes: "Resets your tasks. When you're struggling and everything's red, use for a clean slate.", value:0 } @@ -169,7 +169,7 @@ module.exports.app = (appExports, model) -> return unless captures == true html = """