From 2a49b640239a987faaa5e8958e9e11e612b9c4ab Mon Sep 17 00:00:00 2001 From: Philip How Date: Thu, 28 Feb 2013 23:09:12 +0000 Subject: [PATCH 1/5] Better notifications --- src/app/browser.coffee | 34 ++++++++++++++++++++++------------ styles/app/alerts.styl | 15 +++++++++++---- 2 files changed, 33 insertions(+), 16 deletions(-) diff --git a/src/app/browser.coffee b/src/app/browser.coffee index 2830fefd48..5becd6bcc0 100644 --- a/src/app/browser.coffee +++ b/src/app/browser.coffee @@ -6,7 +6,7 @@ module.exports.restoreRefs = restoreRefs = (model) -> 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 + 10*Math.pow(lvl,2)+(lvl*10)+80 #refLists _.each ['habit', 'daily', 'todo', 'reward'], (type) -> @@ -193,20 +193,30 @@ 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) -> + num = captures - args + rounded = Math.abs(num.toFixed(1)) + if num < 0 + 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 diff --git a/styles/app/alerts.styl b/styles/app/alerts.styl index 8ecbd0e45e..38e411f480 100644 --- a/styles/app/alerts.styl +++ b/styles/app/alerts.styl @@ -34,9 +34,16 @@ borderDarken = 20% // alert icons -.icon-gp - background: url("img/sprites/shop_sprites.png") no-repeat - background-size: 400px - background-position: -386px 0 +.icon-gold + background: url("img/coin_single_gold.png") no-repeat + background-position: center center + background-size: 18px + width: 14px + height: 14px + +.icon-silver + background: url("img/coin_single_silver.png") no-repeat + background-position: center center + background-size: 18px width: 14px height: 14px \ No newline at end of file From 4597cba8139864809d0814bd4fbd334a5a1d883b Mon Sep 17 00:00:00 2001 From: Philip How Date: Thu, 28 Feb 2013 23:42:38 +0000 Subject: [PATCH 2/5] Changes to XP and GP gain --- src/app/scoring.coffee | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/app/scoring.coffee b/src/app/scoring.coffee index 4f1b78db70..ea8ab4b1fb 100644 --- a/src/app/scoring.coffee +++ b/src/app/scoring.coffee @@ -142,8 +142,8 @@ module.exports.Scoring = (model) -> addPoints = -> modified = expModifier(delta) - exp += modified - gp += modified + exp += modified*10 + gp += delta subtractPoints = -> modified = hpModifier(delta) From 08839278b38f0e29cc293c1f656aaae58a1993cc Mon Sep 17 00:00:00 2001 From: Philip How Date: Sat, 2 Mar 2013 18:23:43 +0000 Subject: [PATCH 3/5] Notification and Algorithim changes --- src/app/algos.coffee | 50 ++++++++++++++++++++++++++++ src/app/browser.coffee | 22 ++++++++----- src/app/character.coffee | 1 + src/app/helpers.coffee | 3 ++ src/app/items.coffee | 50 ++++++++++++++-------------- src/app/scoring.coffee | 70 +++++++++++----------------------------- views/app/header.html | 2 +- 7 files changed, 112 insertions(+), 86 deletions(-) create mode 100644 src/app/algos.coffee diff --git a/src/app/algos.coffee b/src/app/algos.coffee new file mode 100644 index 0000000000..69ab9b4e93 --- /dev/null +++ b/src/app/algos.coffee @@ -0,0 +1,50 @@ + +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=.9^x, y>= -5 + {currentValue} the current value of the task + {direction} up or down +### +module.exports.taskDeltaFormula = (currentValue, direction) -> + sign = if (direction is 'up') then 1 else -1 + delta = Math.pow(0.9,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 5becd6bcc0..63e6994d58 100644 --- a/src/app/browser.coffee +++ b/src/app/browser.coffee @@ -1,11 +1,13 @@ _ = 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 + #TODO find a method of calling algos.tnl() 10*Math.pow(lvl,2)+(lvl*10)+80 #refLists @@ -85,7 +87,9 @@ setupSortable = (model) -> # Note, have to setup helper function here and call it for each type later # due to variable binding of "type" setupSortable = (type) -> - $("ul.#{type}s").sortable + for key, value of type + parsedType = value + $("ul.#{parsedType}s").sortable dropOnEmpty: false cursor: "move" items: "li" @@ -191,19 +195,21 @@ setupGrowlNotifications = (model) -> # Setup listeners which trigger notifications user.on 'set', 'stats.hp', (captures, args) -> num = captures - args + console.log("hp = " + num) rounded = Math.abs(num.toFixed(1)) if num < 0 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) -> - num = captures - args - rounded = Math.abs(num.toFixed(1)) - if num < 0 - statsNotification " - #{rounded} XP", 'xp' - else if num > 0 - statsNotification " + #{rounded} XP", 'xp' + user.on 'set', 'stats.exp', (captures, args, isLocal, silent) -> + if not silent + num = captures - args + rounded = Math.abs(num.toFixed(1)) + if num < 0 + statsNotification " - #{rounded} XP", 'xp' + else if num > 0 + statsNotification " + #{rounded} XP", 'xp' user.on 'set', 'stats.gp', (captures, args) -> num = captures - args diff --git a/src/app/character.coffee b/src/app/character.coffee index 07b0996dcb..de1b280c2d 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/helpers.coffee b/src/app/helpers.coffee index 38733f11d5..5c2cccaa15 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 911458e60c..a9ca688f52 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 } diff --git a/src/app/scoring.coffee b/src/app/scoring.coffee index ea8ab4b1fb..9abe1fc3ff 100644 --- a/src/app/scoring.coffee +++ b/src/app/scoring.coffee @@ -5,53 +5,12 @@ helpers = require './helpers' browser = require './browser' character = require './character' items = require './items' +algos = require './algos' module.exports.Scoring = (model) -> - - MODIFIER = .02 # each new level, armor, weapon add 2% modifier (this mechanism will change) + MODIFIER = algos.MODIFIER # each new level, armor, weapon add 2% modifier (this mechanism will change) user = model.at '_user' - ### - Calculates Exp & GP modification based on weapon & lvl - {value} task.value for gain - {modifiers} may manually pass in stats as {weapon, exp}. This is used for testing - ### - expModifier = (value, modifiers = {}) -> - weapon = modifiers.weapon || user.get('items.weapon') - lvl = modifiers.lvl || user.get('stats.lvl') - dmg = items.items.weapon[weapon].modifier # each new weapon increases exp gain - dmg += (lvl-1) * MODIFIER # same for lvls - modified = value + (value * dmg) - return modified - - ### - Calculates HP-loss modification based on armor & lvl - {value} task.value which is hurting us - {modifiers} may manually pass in modifier as {armor, lvl}. This is used for testing - ### - hpModifier = (value, modifiers = {}) -> - armor = modifiers.armor || user.get('items.armor') - head = modifiers.head || user.get('items.head') - shield = modifiers.shield || user.get('items.shield') - lvl = modifiers.lvl || user.get('stats.lvl') - ac = items.items.armor[armor].modifier + items.items.head[head].modifier + items.items.shield[shield].modifier # each new armor decreases HP loss - ac += (lvl-1) * MODIFIER # same for lvls - modified = value - (value * ac) - return modified - - ### - Calculates the next task.value based on direction - For negative values, use a line: something like y=-.1x+1 - For positibe values, taper off with inverse log: y=.9^x - Would love to use inverse log for the whole thing, but after 13 fails it hits infinity. Revisit this formula later - {currentValue} the current value of the task, determines it's next value - {direction} 'up' or 'down' - ### - taskDeltaFormula = (currentValue, direction) -> - sign = if (direction == "up") then 1 else -1 - delta = if (currentValue < 0) then (( -0.1 * currentValue + 1 ) * sign) else (( Math.pow(0.9,currentValue) ) * sign) - return delta - ### Updates user stats with new stats. Handles death, leveling up, etc {stats} new stats @@ -75,12 +34,15 @@ module.exports.Scoring = (model) -> if newStats.exp? # level up & carry-over exp tnl = model.get '_tnl' + silent = false if newStats.exp >= tnl + silent = true newStats.exp -= tnl obj.stats.lvl++ obj.stats.hp = 50 obj.stats.exp = newStats.exp + user.pass(silent:true).set('stats.exp', obj.stats.exp) if silent # Set flags when they unlock features if !obj.flags.customizationsNotification and (obj.stats.exp > 10 or obj.stats.lvl > 1) @@ -107,7 +69,6 @@ module.exports.Scoring = (model) -> # {times} # times to call score on this task (1 unless cron, usually) # {update} if we're running updates en-mass (eg, cron on server) pass in userObj score = (taskId, direction, times, batch, cron) -> - commit = false unless batch? commit = true @@ -136,17 +97,23 @@ module.exports.Scoring = (model) -> # Each iteration calculate the delta (nextDelta), which is then accumulated in delta # (aka, the total delta). This weirdness won't be necessary when calculating mathematically # rather than iteratively - nextDelta = taskDeltaFormula(value, direction) + nextDelta = algos.taskDeltaFormula(value, direction) value += nextDelta if adjustvalue delta += nextDelta addPoints = -> - modified = expModifier(delta) + level = user.get('stats.lvl') + weaponStrength = items.items.weapon[user.get('items.weapon')].strength + modified = algos.expModifier(delta,weaponStrength,level) exp += modified*10 gp += delta subtractPoints = -> - modified = hpModifier(delta) + level = user.get('stats.lvl') + 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) hp += modified switch type @@ -249,7 +216,7 @@ module.exports.Scoring = (model) -> lvl = 0 #iterator while lvl < (obj.stats.lvl-1) lvl++ - expTally += (lvl*100)/5 + expTally += algos.tnl(lvl) obj.history.exp.push { date: today, value: expTally } # Set the new user specs, and animate HP loss @@ -262,12 +229,11 @@ module.exports.Scoring = (model) -> return { - MODIFIER: MODIFIER score: score cron: cron # testing stuff - expModifier: expModifier - hpModifier: hpModifier - taskDeltaFormula: taskDeltaFormula + expModifier: algos.expModifier + hpModifier: algos.hpModifier + taskDeltaFormula: algos.taskDeltaFormula } diff --git a/views/app/header.html b/views/app/header.html index f3bc5f3c3a..2491090dae 100644 --- a/views/app/header.html +++ b/views/app/header.html @@ -29,7 +29,7 @@ {#if _user.history.exp}   {/} - {round(_user.stats.exp)} / {_tnl} + {floor(_user.stats.exp)} / {_tnl} From 9283b8adb4141ec4b106ecfff5018b9ce39d5320 Mon Sep 17 00:00:00 2001 From: Philip How Date: Sat, 2 Mar 2013 20:02:57 +0000 Subject: [PATCH 4/5] Add death notification and algorithm fixes --- src/app/algos.coffee | 14 +++-- src/app/browser.coffee | 11 ++-- src/app/debug.coffee | 9 +++ src/app/items.coffee | 2 +- src/app/scoring.coffee | 123 ++++++++++++++++++++++------------------- styles/app/alerts.styl | 14 +++++ 6 files changed, 104 insertions(+), 69 deletions(-) diff --git a/src/app/algos.coffee b/src/app/algos.coffee index 69ab9b4e93..205842d178 100644 --- a/src/app/algos.coffee +++ b/src/app/algos.coffee @@ -37,14 +37,18 @@ module.exports.gpModifier = (value, modifier) -> ### Calculates the next task.value based on direction - Uses a capped inverse log y=.9^x, y>= -5 + 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) -> - sign = if (direction is 'up') then 1 else -1 - delta = Math.pow(0.9,currentValue) * sign - if delta < -5 then delta = -5 - console.log("CurrentValue: " + currentValue + " delta: " + delta) + 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 63e6994d58..4f7b4168bf 100644 --- a/src/app/browser.coffee +++ b/src/app/browser.coffee @@ -184,7 +184,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') @@ -195,7 +195,6 @@ setupGrowlNotifications = (model) -> # Setup listeners which trigger notifications user.on 'set', 'stats.hp', (captures, args) -> num = captures - args - console.log("hp = " + num) rounded = Math.abs(num.toFixed(1)) if num < 0 statsNotification " - #{rounded} HP", 'hp' # lost hp from purchase @@ -203,10 +202,9 @@ setupGrowlNotifications = (model) -> statsNotification " + #{rounded} HP", 'hp' # gained hp from potion/level? user.on 'set', 'stats.exp', (captures, args, isLocal, silent) -> - if not silent num = captures - args rounded = Math.abs(num.toFixed(1)) - if num < 0 + if num < 0 and not silent statsNotification " - #{rounded} XP", 'xp' else if num > 0 statsNotification " + #{rounded} XP", 'xp' @@ -226,4 +224,7 @@ setupGrowlNotifications = (model) -> 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' \ No newline at end of file diff --git a/src/app/debug.coffee b/src/app/debug.coffee index 25cb833b8f..24195797bb 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/items.coffee b/src/app/items.coffee index a9ca688f52..58799b1d1c 100644 --- a/src/app/items.coffee +++ b/src/app/items.coffee @@ -169,7 +169,7 @@ module.exports.app = (appExports, model) -> return unless captures == true html = """
- + Congratulations, you have unlocked the Item Store! You can now buy weapons, armor, potions, etc. Read each item's comment for more information. [Close]
diff --git a/src/app/scoring.coffee b/src/app/scoring.coffee index 9abe1fc3ff..a25bc8d34e 100644 --- a/src/app/scoring.coffee +++ b/src/app/scoring.coffee @@ -11,59 +11,6 @@ module.exports.Scoring = (model) -> MODIFIER = algos.MODIFIER # each new level, armor, weapon add 2% modifier (this mechanism will change) user = model.at '_user' - ### - Updates user stats with new stats. Handles death, leveling up, etc - {stats} new stats - {update} if aggregated changes, pass in userObj as update. otherwise commits will be made immediately - ### - updateStats = (newStats, batch) -> - obj = batch.obj() - - # if user is dead, dont do anything - return if obj.stats.lvl == 0 - - if newStats.hp? - # Game Over - if newStats.hp <= 0 - obj.stats.lvl = 0 # signifies dead - obj.stats.hp = 0 - return - else - 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 - newStats.exp -= tnl - obj.stats.lvl++ - obj.stats.hp = 50 - - obj.stats.exp = newStats.exp - user.pass(silent:true).set('stats.exp', obj.stats.exp) if silent - - # Set flags when they unlock features - if !obj.flags.customizationsNotification and (obj.stats.exp > 10 or obj.stats.lvl > 1) - batch.set 'flags.customizationsNotification', true - obj.flags.customizationsNotification = true - if !obj.flags.itemsEnabled and obj.stats.lvl >= 2 - # Set to object, then also send to browser right away to get model.on() subscription notification - batch.set 'flags.itemsEnabled', true - obj.flags.itemsEnabled = true - if !obj.flags.partyEnabled and obj.stats.lvl >= 3 - batch.set 'flags.partyEnabled', true - obj.flags.partyEnabled = true - if !obj.flags.petsEnabled and obj.stats.lvl >= 4 - batch.set 'flags.petsEnabled', true - obj.flags.petsEnabled = true - - if newStats.gp? - #FIXME what was I doing here? I can't remember, gp isn't defined - gp = 0.0 if (!gp? or gp<0) - obj.stats.gp = newStats.gp - # {taskId} task you want to score # {direction} 'up' or 'down' # {times} # times to call score on this task (1 unless cron, usually) @@ -119,7 +66,8 @@ module.exports.Scoring = (model) -> switch type when 'habit' # Don't adjust values for habits that don't have both + and - - adjustvalue = if (taskObj.up==false or taskObj.down==false) then false else true + #adjustvalue = if (taskObj.up==false or taskObj.down==false) then false else true + adjustvalue = true; calculateDelta(adjustvalue) # Add habit value to habit-history (if different) if (delta > 0) then addPoints() else subtractPoints() @@ -130,15 +78,20 @@ module.exports.Scoring = (model) -> batch.set "#{taskPath}.history", taskObj.history when 'daily' - calculateDelta() + #calculateDelta() if cron? # cron + calculateDelta() subtractPoints() else + calculateDelta(false) addPoints() # obviously for delta>0, but also a trick to undo accidental checkboxes when 'todo' - calculateDelta() - unless cron? # don't touch stats on cron + if cron? #cron + calculateDelta() + #don't touch stats on cron + else + calculateDelta(false) addPoints() # obviously for delta>0, but also a trick to undo accidental checkboxes when 'reward' @@ -161,10 +114,64 @@ module.exports.Scoring = (model) -> newStats = _.clone batch.obj().stats _.each Object.keys(origStats), (key) -> obj.stats[key] = origStats[key] batch.setStats(newStats) - # batch.setStats() + # batch.setStats() batch.commit() return delta + ### + Updates user stats with new stats. Handles death, leveling up, etc + {stats} new stats + {update} if aggregated changes, pass in userObj as update. otherwise commits will be made immediately + ### + updateStats = (newStats, batch) -> + obj = batch.obj() + + # if user is dead, dont do anything + return if obj.stats.lvl == 0 + + if newStats.hp? + # Game Over + if newStats.hp <= 0 + obj.stats.lvl = 0 # signifies dead + obj.stats.hp = 0 + return + else + 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) + newStats.exp -= tnl + obj.stats.lvl++ + obj.stats.hp = 50 + + obj.stats.exp = newStats.exp + user.pass(silent:true).set('stats.exp', obj.stats.exp) if silent + + # Set flags when they unlock features + if !obj.flags.customizationsNotification and (obj.stats.exp > 10 or obj.stats.lvl > 1) + batch.set 'flags.customizationsNotification', true + obj.flags.customizationsNotification = true + if !obj.flags.itemsEnabled and obj.stats.lvl >= 2 + # Set to object, then also send to browser right away to get model.on() subscription notification + batch.set 'flags.itemsEnabled', true + obj.flags.itemsEnabled = true + if !obj.flags.partyEnabled and obj.stats.lvl >= 3 + batch.set 'flags.partyEnabled', true + obj.flags.partyEnabled = true + if !obj.flags.petsEnabled and obj.stats.lvl >= 4 + batch.set 'flags.petsEnabled', true + obj.flags.petsEnabled = true + + if newStats.gp? + #FIXME what was I doing here? I can't remember, gp isn't defined + gp = 0.0 if (!gp? or gp<0) + obj.stats.gp = newStats.gp + ### At end of day, add value to all incomplete Daily & Todo tasks (further incentive) For incomplete Dailys, deduct experience diff --git a/styles/app/alerts.styl b/styles/app/alerts.styl index 38e411f480..97f490cf52 100644 --- a/styles/app/alerts.styl +++ b/styles/app/alerts.styl @@ -8,6 +8,8 @@ lvlColor = #d9edf7 lvlText = #3a87ad xpColor = #DCC0FB xpText = #635673 +deathColor = #4E4E4E +deathText = #ABABAB borderDarken = 20% // alert styles @@ -32,6 +34,11 @@ borderDarken = 20% border-color: darken(xpColor,borderDarken) color: xpText +.alert-death + background-color: deathColor + border-color: deathColor + color: deathText + // alert icons .icon-gold @@ -46,4 +53,11 @@ borderDarken = 20% background-position: center center background-size: 18px width: 14px + height: 14px + +.icon-death + background: url("img/sprites/dead.png") no-repeat + background-position: center center + background-size: 14px + width: 14px height: 14px \ No newline at end of file From 81eb070ee65c02ec8903f0fbe806b0cbdd93436c Mon Sep 17 00:00:00 2001 From: Philip How Date: Sat, 2 Mar 2013 20:03:16 +0000 Subject: [PATCH 5/5] Reset button --- views/app/footer.html | 1 + 1 file changed, 1 insertion(+) diff --git a/views/app/footer.html b/views/app/footer.html index 60ccc1b9c9..35be956150 100644 --- a/views/app/footer.html +++ b/views/app/footer.html @@ -20,6 +20,7 @@
+
{/}