diff --git a/lib/app/index.js b/lib/app/index.js
index 44e5d6fa5f..9f3dfc97a1 100644
--- a/lib/app/index.js
+++ b/lib/app/index.js
@@ -197,8 +197,11 @@ ready(function(model) {
});
}
tour.start();
- model.on('set', '_user.tasks.*.completed', function(i, completed, previous, isLocal) {
+ model.on('set', '_user.tasks.*.completed', function(i, completed, previous, isLocal, passed) {
var direction, from, ids, index, task, to, _ref3;
+ if (passed.cron != null) {
+ return;
+ }
direction = function() {
if (completed === true && previous === false) {
return 'up';
@@ -206,7 +209,7 @@ ready(function(model) {
if (completed === false && previous === true) {
return 'down';
}
- return console.error('Error: direction neither "up" nor "down" on checkbox set.');
+ throw new Error("Direction neither 'up' nor 'down' on checkbox set.");
};
task = model.at("_user.tasks." + i);
Scoring.score({
diff --git a/lib/app/scoring.js b/lib/app/scoring.js
new file mode 100644
index 0000000000..9451d75616
--- /dev/null
+++ b/lib/app/scoring.js
@@ -0,0 +1,157 @@
+// Generated by CoffeeScript 1.3.3
+var content, expModifier, hpModifier, score, tally, updateStats;
+
+content = require('./content');
+
+expModifier = function(user, value) {
+ var dmg, modified;
+ dmg = user.get('items.weapon') * .03;
+ dmg += user.get('stats.lvl') * .03;
+ modified = value + (value * dmg);
+ return modified;
+};
+
+hpModifier = function(user, value) {
+ var ac, modified;
+ ac = user.get('items.armor') * .03;
+ ac += user.get('stats.lvl') * .03;
+ modified = value - (value * ac);
+ return modified;
+};
+
+updateStats = function(user, stats) {
+ var money, tnl;
+ if (stats.hp != null) {
+ if (stats.hp < 0) {
+ user.set('stats.lvl', 0);
+ } else {
+ user.set('stats.hp', stats.hp);
+ }
+ }
+ if (stats.exp != null) {
+ tnl = user.get('_tnl');
+ if (stats.exp >= tnl) {
+ stats.exp -= tnl;
+ user.set('stats.lvl', user.get('stats.lvl') + 1);
+ }
+ if (!user.get('items.itemsEnabled') && stats.exp >= 50) {
+ user.set('items.itemsEnabled', true);
+ $('ul.items').popover({
+ title: content.items.unlockedMessage.title,
+ placement: 'left',
+ trigger: 'manual',
+ html: true,
+ content: "

" + content.items.unlockedMessage.content + "
[Close] "
+ });
+ $('ul.items').popover('show');
+ }
+ user.set('stats.exp', stats.exp);
+ }
+ if (stats.money != null) {
+ if (!(typeof money !== "undefined" && money !== null) || money < 0) {
+ money = 0.0;
+ }
+ return user.set('stats.money', stats.money);
+ }
+};
+
+exports.score = score = function(spec) {
+ var adjustvalue, cron, delta, direction, exp, hp, lvl, money, sign, task, type, user, value, _ref, _ref1;
+ if (spec == null) {
+ spec = {
+ user: null,
+ task: null,
+ direction: null,
+ cron: null
+ };
+ }
+ _ref = [spec.user, spec.task, spec.direction, spec.cron], user = _ref[0], task = _ref[1], direction = _ref[2], cron = _ref[3];
+ sign = direction === "up" ? 1 : -1;
+ value = task.get('value');
+ delta = value < 0 ? (-0.1 * value + 1) * sign : (Math.pow(0.9, value)) * sign;
+ type = task.get('type');
+ adjustvalue = type !== 'reward';
+ if ((type === 'habit') && (task.get("up") === false || task.get("down") === false)) {
+ adjustvalue = false;
+ }
+ if (adjustvalue) {
+ value += delta;
+ }
+ if (type === 'habit') {
+ if (task.get('value') !== value) {
+ task.push('history', {
+ date: new Date(),
+ value: value
+ });
+ }
+ }
+ task.set('value', value);
+ _ref1 = [user.get('stats.money'), user.get('stats.hp'), user.get('stats.exp'), user.get('stats.lvl')], money = _ref1[0], hp = _ref1[1], exp = _ref1[2], lvl = _ref1[3];
+ if (type === 'reward') {
+ money -= task.get('value');
+ if (money < 0) {
+ hp += money;
+ money = 0;
+ }
+ }
+ if ((delta > 0 || (type === 'daily' || type === 'todo')) && !cron) {
+ exp += expModifier(user, delta);
+ money += delta;
+ } else if (type !== 'reward' && type !== 'todo') {
+ hp += hpModifier(user, delta);
+ }
+ updateStats(user, {
+ hp: hp,
+ exp: exp,
+ money: money
+ });
+ return delta;
+};
+
+exports.tally = tally = function(model) {
+ var absVal, completed, expTally, key, lvl, task, todoTally, type, user, value, _ref;
+ user = model.at('_user');
+ todoTally = 0;
+ for (key in model.get('_user.tasks')) {
+ task = model.at("_user.tasks." + key);
+ _ref = [task.get('type'), task.get('value'), task.get('completed')], type = _ref[0], value = _ref[1], completed = _ref[2];
+ if (type === 'todo' || type === 'daily') {
+ if (!completed) {
+ score({
+ user: user,
+ task: task,
+ direction: 'down',
+ cron: true
+ });
+ }
+ if (type === 'daily') {
+ task.push("history", {
+ date: new Date(),
+ value: value
+ });
+ } else {
+ absVal = completed ? Math.abs(value) : value;
+ todoTally += absVal;
+ }
+ if (type === 'daily') {
+ task.pass({
+ cron: true
+ }).set('completed', false);
+ }
+ }
+ }
+ model.push('_user.history.todos', {
+ date: new Date(),
+ value: todoTally
+ });
+ expTally = user.get('stats.exp');
+ lvl = 0;
+ while (lvl < (user.get('stats.lvl') - 1)) {
+ lvl++;
+ expTally += 50 * Math.pow(lvl, 2) - 150 * lvl + 200;
+ }
+ return model.push('_user.history.exp', {
+ date: new Date(),
+ value: expTally
+ });
+};
diff --git a/src/app/index.coffee b/src/app/index.coffee
index 0cf015e5a2..5c86304171 100644
--- a/src/app/index.coffee
+++ b/src/app/index.coffee
@@ -164,11 +164,12 @@ ready (model) ->
# @render()
# return false
- model.on 'set', '_user.tasks.*.completed', (i, completed, previous, isLocal) ->
+ model.on 'set', '_user.tasks.*.completed', (i, completed, previous, isLocal, passed) ->
+ return if passed.cron? # Don't do this stuff on cron
direction = () ->
return 'up' if completed==true and previous == false
return 'down' if completed==false and previous == true
- console.error 'Error: direction neither "up" nor "down" on checkbox set.'
+ throw new Error("Direction neither 'up' nor 'down' on checkbox set.")
# Score the user based on todo task
task = model.at("_user.tasks.#{i}")
diff --git a/src/app/scoring.coffee b/src/app/scoring.coffee
index 0d07f17ac9..f818488e3e 100644
--- a/src/app/scoring.coffee
+++ b/src/app/scoring.coffee
@@ -49,6 +49,7 @@ updateStats = (user, stats) ->
user.set 'stats.money', stats.money
exports.score = score = (spec = {user:null, task:null, direction:null, cron:null}) ->
+ # console.log spec, "scoring.coffee: score( ->spec<- )"
[user, task, direction, cron] = [spec.user, spec.task, spec.direction, spec.cron]
# For negative values, use a line: something like y=-.1x+1
@@ -66,17 +67,10 @@ exports.score = score = (spec = {user:null, task:null, direction:null, cron:null
adjustvalue = false
value += delta if adjustvalue
- # # up/down -voting as checkbox & assigning as completed, 2 birds one stone
- # completed = task.get("completed")
- # if type != 'habit'
- # completed = true if direction=="up"
- # completed = false if direction=="down"
- # else
if type == 'habit'
# Add habit value to habit-history (if different)
task.push 'history', { date: new Date(), value: value } if task.get('value') != value
task.set('value', value)
- # task.set('completed', completed)
# Update the user's status
[money, hp, exp, lvl] = [user.get('stats.money'), user.get('stats.hp'), user.get('stats.exp'), user.get('stats.lvl')]
@@ -91,7 +85,7 @@ exports.score = score = (spec = {user:null, task:null, direction:null, cron:null
# Add points to exp & money if positive delta
# Only take away mony if it was a mistake (aka, a checkbox)
- if delta > 0 or ( type in ['daily', 'todo'] and !cron )
+ if (delta > 0 or ( type in ['daily', 'todo'])) and !cron
exp += expModifier(user, delta)
money += delta
# Deduct from health (rewards case handled above)
@@ -121,7 +115,7 @@ exports.tally = tally = (model) ->
else
absVal = if (completed) then Math.abs(value) else value
todoTally += absVal
- task.set('completed', false) if type == 'daily'
+ task.pass({cron:true}).set('completed', false) if type == 'daily'
model.push '_user.history.todos', { date: new Date(), value: todoTally }
# tally experience