async + user aggregate hp loss

This commit is contained in:
Tyler Renelle 2012-09-24 21:15:12 -04:00
parent ce901f7b93
commit 9d165a0ff7
4 changed files with 56 additions and 38 deletions

View file

@ -302,6 +302,6 @@ ready(function(model) {
model.set('_items.weapon', content.items.weapon[1]);
return model.set('_user.balance', model.get('_user.balance') - 0.50);
};
setTimeout(scoring.cron, 2000);
setTimeout(scoring.cron, 1);
return setInterval(scoring.cron, 3600000);
});

View file

@ -157,6 +157,7 @@ score = function(taskId, direction, options) {
}
sign = direction === "up" ? 1 : -1;
delta = value < 0 ? (-0.1 * value + 1) * sign : (Math.pow(0.9, value)) * sign;
delta *= options.times;
adjustvalue = type !== 'reward';
if ((type === 'habit') && (taskObj.up === false || taskObj.down === false)) {
adjustvalue = false;
@ -164,7 +165,6 @@ score = function(taskId, direction, options) {
if (adjustvalue) {
value += delta;
}
value *= options.times;
if (type === 'habit') {
if (taskObj.value !== value) {
task.push('history', {
@ -174,6 +174,13 @@ score = function(taskId, direction, options) {
}
}
task.set('value', value);
if (options.cron) {
if (type === 'daily') {
return delta;
} else {
return 0;
}
}
_ref2 = userObj.stats, money = _ref2.money, hp = _ref2.hp, exp = _ref2.exp, lvl = _ref2.lvl;
if (type === 'reward') {
money -= task.get('value');
@ -200,13 +207,14 @@ score = function(taskId, direction, options) {
};
cron = function() {
var daysPassed, expTally, lastCron, lvl, tallyTask, today, todoTally;
var daysPassed, hpTally, lastCron, tallyTask, tasks, today, todoTally;
today = new Date();
user.setNull('lastCron', today);
lastCron = user.get('lastCron');
daysPassed = helpers.daysBetween(today, lastCron);
if (daysPassed > 0) {
todoTally = 0;
hpTally = 0;
tallyTask = function(taskObj, callback) {
var absVal, completed, dayMapping, daysFailed, id, repeat, task, type, value;
id = taskObj.id, type = taskObj.type, completed = taskObj.completed, repeat = taskObj.repeat;
@ -237,7 +245,7 @@ cron = function() {
}
});
}
score(id, 'down', {
hpTally += score(id, 'down', {
cron: true,
times: daysFailed
});
@ -260,24 +268,28 @@ cron = function() {
}
return callback();
};
_.each(user.get('tasks'), function(taskObj) {
return tallyTask(taskObj, function() {});
tasks = _.toArray(user.get('tasks'));
return async.forEach(tasks, tallyTask, function(err) {
var expTally, lvl;
user.push('history.todos', {
date: today,
value: todoTally
});
expTally = user.get('stats.exp');
lvl = 0;
while (lvl < (user.get('stats.lvl') - 1)) {
lvl++;
expTally += (lvl * 100) / 5;
}
user.push('history.exp', {
date: today,
value: expTally
});
updateStats({
hp: user.get('stats.hp') + hpTally
});
return user.set('lastCron', today);
});
user.push('history.todos', {
date: today,
value: todoTally
});
expTally = user.get('stats.exp');
lvl = 0;
while (lvl < (user.get('stats.lvl') - 1)) {
lvl++;
expTally += (lvl * 100) / 5;
}
user.push('history.exp', {
date: today,
value: expTally
});
return user.set('lastCron', today);
}
};

View file

@ -256,5 +256,5 @@ ready (model) ->
# FIXME seems can't call scoring.cron() instantly, have to call after some time (2s here)
# Doesn't do anything otherwise. Don't know why... model not initialized enough yet?
setTimeout scoring.cron, 2000 # Run once on refresh
setTimeout scoring.cron, 1 # Run once on refresh
setInterval scoring.cron, 3600000 # Then run once every hour

View file

@ -136,6 +136,9 @@ score = (taskId, direction, options={cron:false, times:1}) ->
# Would love to use inverse log for the whole thing, but after 13 fails it hits infinity
sign = if (direction == "up") then 1 else -1
delta = if (value < 0) then (( -0.1 * value + 1 ) * sign) else (( Math.pow(0.9,value) ) * sign)
# If multiple days have passed, multiply times days missed
delta *= options.times
# Don't adjust values for rewards, or for habits that don't have both + and -
adjustvalue = (type != 'reward')
@ -143,13 +146,14 @@ score = (taskId, direction, options={cron:false, times:1}) ->
adjustvalue = false
value += delta if adjustvalue
# If multiple days have passed, multiply times days missed
value *= options.times
if type == 'habit'
# Add habit value to habit-history (if different)
task.push 'history', { date: new Date(), value: value } if taskObj.value != value
task.set('value', value)
if options.cron
# Will modify the user later as an aggregate, just return the delta
return if (type == 'daily') then delta else 0
# Update the user's status
{money, hp, exp, lvl} = userObj.stats
@ -189,6 +193,7 @@ cron = ->
# Tally function, which is called asyncronously below - but function is defined here.
# We need access to some closure variables above
todoTally = 0
hpTally = 0
tallyTask = (taskObj, callback) ->
# setTimeout {THIS_FUNCTION}, 1 # strange hack that seems necessary when using async
{id, type, completed, repeat} = taskObj
@ -211,7 +216,7 @@ cron = ->
thatDay = moment().subtract('days', n+1)
if repeat[dayMapping[thatDay.day()]]==true
daysFailed++
score(id, 'down', {cron:true, times:daysFailed})
hpTally += score(id, 'down', {cron:true, times:daysFailed})
value = task.get('value') #get updated value
if type == 'daily'
@ -223,20 +228,21 @@ cron = ->
callback()
# Tally each task
_.each user.get('tasks'), (taskObj) -> tallyTask(taskObj, ->)
# _.each user.get('tasks'), (taskObj) -> tallyTask(taskObj, ->)
# Asyncronous version:
# tasks = _.toArray(user.get('tasks'))
# async.forEach tasks, tallyTask, (err) ->
tasks = _.toArray(user.get('tasks'))
async.forEach tasks, tallyTask, (err) ->
# Finished tallying, this is the 'completed' callback
user.push 'history.todos', { date: today, value: todoTally }
# tally experience
expTally = user.get 'stats.exp'
lvl = 0 #iterator
while lvl < (user.get('stats.lvl')-1)
lvl++
expTally += (lvl*100)/5
user.push 'history.exp', { date: today, value: expTally }
user.set('lastCron', today) # reset cron
user.push 'history.todos', { date: today, value: todoTally }
# tally experience
expTally = user.get 'stats.exp'
lvl = 0 #iterator
while lvl < (user.get('stats.lvl')-1)
lvl++
expTally += (lvl*100)/5
user.push 'history.exp', { date: today, value: expTally }
updateStats({hp:user.get('stats.hp')+hpTally}) # finally, the user if they've failed the last few days
user.set('lastCron', today) # reset cron
module.exports = {