From 7bd30d6924059ad76da46935a3e16aa7af31e528 Mon Sep 17 00:00:00 2001 From: Tyler Renelle Date: Tue, 12 Mar 2013 00:22:51 -0400 Subject: [PATCH] temporary wrap exports for browser (see http://caolanmcmahon.com/posts/writing_for_node_and_the_browser/). We may want to use Browserify. I thougth requirejs would handle require() for module.exports, but i was wrong --- algos.js | 191 +++++++++-------- items.js | 618 +++++++++++++++++++++++++++-------------------------- scoring.js | 322 ++++++++++++++++++++++++++++ 3 files changed, 730 insertions(+), 401 deletions(-) create mode 100644 scoring.js diff --git a/algos.js b/algos.js index ec2dc2dfe7..bd543e0f36 100644 --- a/algos.js +++ b/algos.js @@ -1,110 +1,113 @@ -// Generated by CoffeeScript 1.4.0 -var HP, XP, priorityValue; +(function(exports){ -XP = 15; + var HP, XP, priorityValue; -HP = 2; + XP = 15; -priorityValue = function(priority) { - if (priority == null) { - priority = '!'; - } - switch (priority) { - case '!': - return 1; - case '!!': - return 1.5; - case '!!!': - return 2; - default: - return 1; - } -}; + HP = 2; -module.exports.tnl = function(level) { - var value; - if (level >= 100) { - value = 0; - } else { - value = Math.round(((Math.pow(level, 2) * 0.25) + (10 * level) + 139.75) / 10) * 10; - } - return value; -}; + priorityValue = function(priority) { + if (priority == null) { + priority = '!'; + } + switch (priority) { + case '!': + return 1; + case '!!': + return 1.5; + case '!!!': + return 2; + default: + return 1; + } + }; -/* - Calculates Exp modificaiton based on level and weapon strength - {value} task.value for exp gain - {weaponStrength) weapon strength - {level} current user level - {priority} user-defined priority multiplier - */ + exports.tnl = function(level) { + var value; + if (level >= 100) { + value = 0; + } else { + value = Math.round(((Math.pow(level, 2) * 0.25) + (10 * level) + 139.75) / 10) * 10; + } + return value; + }; + + /* + Calculates Exp modificaiton based on level and weapon strength + {value} task.value for exp gain + {weaponStrength) weapon strength + {level} current user level + {priority} user-defined priority multiplier + */ -module.exports.expModifier = function(value, weaponStr, level, priority) { - var exp, str, strMod, totalStr; - if (priority == null) { - priority = '!'; - } - str = (level - 1) / 2; - totalStr = (str + weaponStr) / 100; - strMod = 1 + totalStr; - exp = value * XP * strMod * priorityValue(priority); - return Math.round(exp); -}; + exports.expModifier = function(value, weaponStr, level, priority) { + var exp, str, strMod, totalStr; + if (priority == null) { + priority = '!'; + } + str = (level - 1) / 2; + 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 - {value} task.value for hp loss - {armorDefense} defense from armor - {helmDefense} defense from helm - {level} current user level - {priority} user-defined priority multiplier - */ + /* + 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 + {priority} user-defined priority multiplier + */ -module.exports.hpModifier = function(value, armorDef, helmDef, shieldDef, level, priority) { - var def, defMod, hp, totalDef; - if (priority == null) { - priority = '!'; - } - def = (level - 1) / 2; - totalDef = (def + armorDef + helmDef + shieldDef) / 100; - defMod = 1 - totalDef; - hp = value * HP * defMod * priorityValue(priority); - return Math.round(hp * 10) / 10; -}; + exports.hpModifier = function(value, armorDef, helmDef, shieldDef, level, priority) { + var def, defMod, hp, totalDef; + if (priority == null) { + priority = '!'; + } + def = (level - 1) / 2; + totalDef = (def + armorDef + helmDef + shieldDef) / 100; + defMod = 1 - totalDef; + hp = value * HP * defMod * priorityValue(priority); + return Math.round(hp * 10) / 10; + }; -/* - Future use - {priority} user-defined priority multiplier - */ + /* + Future use + {priority} user-defined priority multiplier + */ -module.exports.gpModifier = function(value, modifier, priority) { - if (priority == null) { - priority = '!'; - } - return value * modifier * priorityValue(priority); -}; + exports.gpModifier = function(value, modifier, priority) { + if (priority == null) { + priority = '!'; + } + return value * modifier * priorityValue(priority); + }; -/* - 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 - */ + /* + 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 = function(currentValue, direction) { - var delta; - if (currentValue < -47.27) { - currentValue = -47.27; - } else if (currentValue > 21.27) { - currentValue = 21.27; - } - delta = Math.pow(0.9747, currentValue); - if (direction === 'up') { - return delta; - } - return -delta; -}; + exports.taskDeltaFormula = function(currentValue, direction) { + var delta; + if (currentValue < -47.27) { + currentValue = -47.27; + } else if (currentValue > 21.27) { + currentValue = 21.27; + } + delta = Math.pow(0.9747, currentValue); + if (direction === 'up') { + return delta; + } + return -delta; + }; + +})(typeof exports === 'undefined'? this['habitrpgAlgos']={}: exports); \ No newline at end of file diff --git a/items.js b/items.js index 9d9a04f314..dd8907775e 100644 --- a/items.js +++ b/items.js @@ -1,308 +1,312 @@ -module.exports.items = { - weapon: [ - { - index: 0, - text: "Training Sword", - classes: "weapon_0", - notes: 'Training weapon.', - strength: 0, +(function(exports){ + + exports.items = { + weapon: [ + { + 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.', + 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.', + 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.', + 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 - }, { - 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.', - 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.', - 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.', - 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 - }, - pets: [ - { - index: 0, - text: 'Bear Cub', - name: 'bearcub', - icon: 'Pet-BearCub-Base.png', - value: 3 - }, { - index: 1, - text: 'Cactus', - name: 'cactus', - icon: 'Pet-Cactus-Base.png', - value: 3 - }, { - index: 2, - text: 'Drake', - name: 'dragon', - icon: 'Pet-Dragon-Base.png', - value: 3 - }, { - index: 3, - text: 'Flying Pig', - name: 'flyingpig', - icon: 'Pet-FlyingPig-Base.png', - value: 3 - }, { - index: 4, - text: 'Fox', - name: 'fox', - icon: 'Pet-Fox-Base.png', - value: 3 - }, { - index: 5, - text: 'Lion Cub', - name: 'lioncub', - icon: 'Pet-LionCub-Base.png', - value: 3 - }, { - index: 6, - text: 'Panda Cub', - name: 'pandacub', - icon: 'Pet-PandaCub-Base.png', - value: 3 - }, { - index: 7, - text: 'Tiger Cub', - name: 'tigercub', - icon: 'Pet-TigerCub-Base.png', - value: 3 - }, { - index: 8, - text: 'Desert Wolf', - name: 'wolfDesert', - icon: 'Pet-Wolf-Desert.png', - value: 3 - }, { - index: 9, - text: 'Golden Wolf', - name: 'wolfGolden', - icon: 'Pet-Wolf-Golden.png', - value: 3 - }, { - index: 10, - text: 'Red Wolf', - name: 'wolfRed', - icon: 'Pet-Wolf-Red.png', - value: 3 - }, { - index: 11, - text: 'Shade Wolf', - name: 'wolfShade', - icon: 'Pet-Wolf-Shade.png', - value: 3 - }, { - index: 12, - text: 'Skeleton Wolf', - name: 'wolfSkeleton', - icon: 'Pet-Wolf-Skeleton.png', - value: 3 - }, { - index: 13, - text: 'Veteran Wolf', - name: 'wolfVeteran', - icon: 'Pet-Wolf-Veteran.png', - value: 3 - }, { - index: 14, - text: 'White Wolf', - name: 'wolfWhite', - icon: 'Pet-Wolf-White.png', - value: 3 - }, { - index: 15, - text: 'Zombie Wolf', - name: 'wolfZombie', - icon: 'Pet-Wolf-Zombie.png', - value: 3 - }, { - index: 16, - text: 'Wolf', - name: 'wolfBorder', - icon: 'wolf_border.png', - value: 3 - } - ] -}; \ No newline at end of file + }, + pets: [ + { + index: 0, + text: 'Bear Cub', + name: 'bearcub', + icon: 'Pet-BearCub-Base.png', + value: 3 + }, { + index: 1, + text: 'Cactus', + name: 'cactus', + icon: 'Pet-Cactus-Base.png', + value: 3 + }, { + index: 2, + text: 'Drake', + name: 'dragon', + icon: 'Pet-Dragon-Base.png', + value: 3 + }, { + index: 3, + text: 'Flying Pig', + name: 'flyingpig', + icon: 'Pet-FlyingPig-Base.png', + value: 3 + }, { + index: 4, + text: 'Fox', + name: 'fox', + icon: 'Pet-Fox-Base.png', + value: 3 + }, { + index: 5, + text: 'Lion Cub', + name: 'lioncub', + icon: 'Pet-LionCub-Base.png', + value: 3 + }, { + index: 6, + text: 'Panda Cub', + name: 'pandacub', + icon: 'Pet-PandaCub-Base.png', + value: 3 + }, { + index: 7, + text: 'Tiger Cub', + name: 'tigercub', + icon: 'Pet-TigerCub-Base.png', + value: 3 + }, { + index: 8, + text: 'Desert Wolf', + name: 'wolfDesert', + icon: 'Pet-Wolf-Desert.png', + value: 3 + }, { + index: 9, + text: 'Golden Wolf', + name: 'wolfGolden', + icon: 'Pet-Wolf-Golden.png', + value: 3 + }, { + index: 10, + text: 'Red Wolf', + name: 'wolfRed', + icon: 'Pet-Wolf-Red.png', + value: 3 + }, { + index: 11, + text: 'Shade Wolf', + name: 'wolfShade', + icon: 'Pet-Wolf-Shade.png', + value: 3 + }, { + index: 12, + text: 'Skeleton Wolf', + name: 'wolfSkeleton', + icon: 'Pet-Wolf-Skeleton.png', + value: 3 + }, { + index: 13, + text: 'Veteran Wolf', + name: 'wolfVeteran', + icon: 'Pet-Wolf-Veteran.png', + value: 3 + }, { + index: 14, + text: 'White Wolf', + name: 'wolfWhite', + icon: 'Pet-Wolf-White.png', + value: 3 + }, { + index: 15, + text: 'Zombie Wolf', + name: 'wolfZombie', + icon: 'Pet-Wolf-Zombie.png', + value: 3 + }, { + index: 16, + text: 'Wolf', + name: 'wolfBorder', + icon: 'wolf_border.png', + value: 3 + } + ] + }; + +})(typeof exports === 'undefined'? this['habitrpgItems']={}: exports); \ No newline at end of file diff --git a/scoring.js b/scoring.js new file mode 100644 index 0000000000..c013d7b9e3 --- /dev/null +++ b/scoring.js @@ -0,0 +1,322 @@ +return; + +//TODO + + +// Generated by CoffeeScript 1.4.0 +var MODIFIER, algos, async, browser, character, cron, helpers, items, moment, score, updateStats, _; + +async = require('async'); + +moment = require('moment'); + +_ = require('underscore'); + +helpers = require('./helpers'); + +browser = require('./browser'); + +character = require('./character'); + +items = require('./items'); + +algos = require('./algos'); + +MODIFIER = algos.MODIFIER; + +score = function(model, taskId, direction, times, batch, cron) { + var addPoints, calculateDelta, commit, delta, exp, gp, historyEntry, hp, lvl, newStats, num, obj, origStats, priority, r, subtractPoints, taskObj, taskPath, type, user, value, _ref, _ref1; + user = model.at('_user'); + commit = false; + if (batch == null) { + commit = true; + batch = new character.BatchUpdate(model); + batch.startTransaction(); + } + obj = batch.obj(); + _ref = obj.stats, gp = _ref.gp, hp = _ref.hp, exp = _ref.exp, lvl = _ref.lvl; + taskPath = "tasks." + taskId; + taskObj = obj.tasks[taskId]; + type = taskObj.type, value = taskObj.value; + priority = taskObj.priority || '!'; + if (taskObj.value > obj.stats.gp && taskObj.type === 'reward') { + r = confirm("Not enough GP to purchase this reward, buy anyway and lose HP? (Punishment for taking a reward you didn't earn)."); + if (!r) { + batch.commit(); + return; + } + } + delta = 0; + if (times == null) { + times = 1; + } + calculateDelta = function(adjustvalue) { + if (adjustvalue == null) { + adjustvalue = true; + } + return _.times(times, function(n) { + var nextDelta; + nextDelta = algos.taskDeltaFormula(value, direction); + if (adjustvalue) { + value += nextDelta; + } + return delta += nextDelta; + }); + }; + addPoints = function() { + var level, weaponStrength; + level = user.get('stats.lvl'); + weaponStrength = items.items.weapon[user.get('items.weapon')].strength; + exp += algos.expModifier(delta, weaponStrength, level, priority); + return gp += algos.gpModifier(delta, 1, priority); + }; + subtractPoints = function() { + var armorDefense, helmDefense, level, shieldDefense; + 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; + return hp += algos.hpModifier(delta, armorDefense, helmDefense, shieldDefense, level, priority); + }; + switch (type) { + case 'habit': + calculateDelta(); + if (delta > 0) { + addPoints(); + } else { + subtractPoints(); + } + if ((_ref1 = taskObj.history) == null) { + taskObj.history = []; + } + if (taskObj.value !== value) { + historyEntry = { + date: +(new Date), + value: value + }; + taskObj.history.push(historyEntry); + batch.set("" + taskPath + ".history", taskObj.history); + } + break; + case 'daily': + if (cron != null) { + calculateDelta(); + subtractPoints(); + } else { + calculateDelta(false); + if (delta !== 0) { + addPoints(); + } + } + break; + case 'todo': + if (cron != null) { + calculateDelta(); + } else { + calculateDelta(); + addPoints(); + } + break; + case 'reward': + calculateDelta(false); + gp -= Math.abs(taskObj.value); + num = parseFloat(taskObj.value).toFixed(2); + if (gp < 0) { + hp += gp; + gp = 0; + } + } + taskObj.value = value; + batch.set("" + taskPath + ".value", taskObj.value); + origStats = _.clone(obj.stats); + updateStats(model, { + hp: hp, + exp: exp, + gp: gp + }, batch); + if (commit) { + newStats = _.clone(batch.obj().stats); + _.each(Object.keys(origStats), function(key) { + return obj.stats[key] = origStats[key]; + }); + batch.setStats(newStats); + 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 = function(model, newStats, batch) { + var gp, obj, tnl, user; + user = model.at('_user'); + obj = batch.obj(); + if (obj.stats.lvl === 0) { + return; + } + if (newStats.hp != null) { + if (newStats.hp <= 0) { + obj.stats.lvl = 0; + obj.stats.hp = 0; + return; + } else { + obj.stats.hp = newStats.hp; + } + } + if (newStats.exp != null) { + tnl = model.get('_tnl'); + if (obj.stats.lvl >= 100) { + newStats.gp += newStats.exp / 15; + newStats.exp = 0; + obj.stats.lvl = 100; + } else { + if (newStats.exp >= tnl) { + user.set('stats.exp', newStats.exp); + while (newStats.exp >= tnl && obj.stats.lvl < 100) { + 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; + if (!obj.flags.customizationsNotification && (obj.stats.exp > 10 || obj.stats.lvl > 1)) { + batch.set('flags.customizationsNotification', true); + obj.flags.customizationsNotification = true; + } + if (!obj.flags.itemsEnabled && obj.stats.lvl >= 2) { + batch.set('flags.itemsEnabled', true); + obj.flags.itemsEnabled = true; + } + if (!obj.flags.partyEnabled && obj.stats.lvl >= 3) { + batch.set('flags.partyEnabled', true); + obj.flags.partyEnabled = true; + } + if (!obj.flags.petsEnabled && obj.stats.lvl >= 4) { + batch.set('flags.petsEnabled', true); + obj.flags.petsEnabled = true; + } + } + if (newStats.gp != null) { + if (!(typeof gp !== "undefined" && gp !== null) || gp < 0) { + gp = 0.0; + } + return obj.stats.gp = newStats.gp; + } +}; + +/* + At end of day, add value to all incomplete Daily & Todo tasks (further incentive) + For incomplete Dailys, deduct experience +*/ + + +cron = function(model) { + var batch, daysPassed, expTally, hpAfter, hpBefore, lvl, obj, today, todoTally, user, _base, _base1, _ref, _ref1, _ref2, _ref3; + user = model.at('_user'); + today = +(new Date); + daysPassed = helpers.daysBetween(user.get('lastCron'), today, user.get('preferences.dayStart')); + if (daysPassed > 0) { + batch = new character.BatchUpdate(model); + batch.startTransaction(); + batch.set('lastCron', today); + obj = batch.obj(); + hpBefore = obj.stats.hp; + todoTally = 0; + _.each(obj.tasks, function(taskObj) { + var absVal, completed, daysFailed, id, newValue, repeat, type, value, _ref; + id = taskObj.id, type = taskObj.type, completed = taskObj.completed, repeat = taskObj.repeat; + if (type === 'todo' || type === 'daily') { + if (!completed) { + daysFailed = daysPassed; + if (type === 'daily' && repeat) { + daysFailed = 0; + _.times(daysPassed, function(n) { + var thatDay; + thatDay = moment().subtract('days', n + 1); + if (repeat[helpers.dayMapping[thatDay.day()]] === true) { + return daysFailed++; + } + }); + } + score(model, id, 'down', daysFailed, batch, true); + } + if (type === 'daily') { + if (completed) { + newValue = taskObj.value + algos.taskDeltaFormula(taskObj.value, 'up'); + batch.set("tasks." + taskObj.id + ".value", newValue); + } + if ((_ref = taskObj.history) == null) { + taskObj.history = []; + } + taskObj.history.push({ + date: +(new Date), + value: taskObj.value + }); + batch.set("tasks." + taskObj.id + ".history", taskObj.history); + return batch.set("tasks." + taskObj.id + ".completed", false); + } else { + value = obj.tasks[taskObj.id].value; + absVal = completed ? Math.abs(value) : value; + return todoTally += absVal; + } + } else if (type === 'habit') { + if (taskObj.up === false || taskObj.down === false) { + if (Math.abs(taskObj.value) < 0.1) { + return batch.set("tasks." + taskObj.id + ".value", 0); + } else { + return batch.set("tasks." + taskObj.id + ".value", taskObj.value / 2); + } + } + } + }); + if ((_ref = obj.history) == null) { + obj.history = {}; + } + if ((_ref1 = (_base = obj.history).todos) == null) { + _base.todos = []; + } + if ((_ref2 = (_base1 = obj.history).exp) == null) { + _base1.exp = []; + } + obj.history.todos.push({ + date: today, + value: todoTally + }); + expTally = obj.stats.exp; + lvl = 0; + while (lvl < (obj.stats.lvl - 1)) { + lvl++; + expTally += algos.tnl(lvl); + } + obj.history.exp.push({ + date: today, + value: expTally + }); + _ref3 = [obj.stats.hp, hpBefore], hpAfter = _ref3[0], obj.stats.hp = _ref3[1]; + batch.setStats(); + batch.set('history', obj.history); + batch.commit(); + browser.resetDom(model); + return setTimeout((function() { + return user.set('stats.hp', hpAfter); + }), 1000); + } +}; + +exports = { + score: score, + cron: cron, + expModifier: algos.expModifier, + hpModifier: algos.hpModifier, + taskDeltaFormula: algos.taskDeltaFormula +};