habitrpg-shared: move task.score => misc.score so api can use it too

This commit is contained in:
Tyler Renelle 2013-05-23 17:35:24 +01:00
parent 32cf11b533
commit 9e2c9045c5
3 changed files with 36 additions and 37 deletions

View file

@ -3,6 +3,37 @@ algos = require 'habitrpg-shared/script/algos'
items = require('habitrpg-shared/script/items').items
helpers = require('habitrpg-shared/script/helpers')
###
algos.score wrapper for habitrpg-helpers to work in Derby. We need to do model.set() instead of simply setting the
object properties, and it's very difficult to diff the two objects and find dot-separated paths to set. So we to first
clone our user object (if we don't do that, it screws with model.on() listeners, ping Tyler for an explaination),
perform the updates while tracking paths, then all the values at those paths
###
module.exports.score = (model, taskId, direction, allowUndo=false) ->
#return setTimeout( (-> score(taskId, direction)), 500) if model._txnQueue.length > 0
user = model.at("_user")
uObj = hydrate(user.get()) # see https://github.com/codeparty/racer/issues/116
tObj = uObj.tasks[taskId]
# Stuff for undo
if allowUndo
tObjBefore = _.cloneDeep tObj
tObjBefore.completed = !tObjBefore.completed if tObjBefore.type in ['daily', 'todo']
previousUndo = model.get('_undo')
clearTimeout(previousUndo.timeoutId) if previousUndo?.timeoutId
timeoutId = setTimeout (-> model.del('_undo')), 20000
model.set '_undo', {stats:_.cloneDeep(uObj.stats), task:tObjBefore, timeoutId: timeoutId}
paths = {}
delta = algos.score(uObj, tObj, direction, {paths:paths})
_.each paths, (v,k) -> user.set(k,helpers.dotGet(k, uObj)); true
model.set('_streakBonus', uObj._tmp.streakBonus) if uObj._tmp?.streakBonus
if uObj._tmp?.drop and $?
model.set '_drop', uObj._tmp.drop
$('#item-dropped-modal').modal 'show'
delta
###
Make sure model.get() returns all properties, see https://github.com/codeparty/racer/issues/116
###

View file

@ -12,31 +12,6 @@ module.exports.app = (appExports, model) ->
character = require './character'
user = model.at('_user')
###
algos.score wrapper for habitrpg-helpers to work in Derby. We need to do model.set() instead of simply setting the
object properties, and it's very difficult to diff the two objects and find dot-separated paths to set. So we to first
clone our user object (if we don't do that, it screws with model.on() listeners, ping Tyler for an explaination),
perform the updates while tracking paths, then all the values at those paths
###
score = (taskId, direction) ->
#return setTimeout( (-> score(taskId, direction)), 500) if model._txnQueue.length > 0
uObj = misc.hydrate(user.get()) # see https://github.com/codeparty/racer/issues/116
tObj = uObj.tasks[taskId]
# Stuff for undo
tObjBefore = _.cloneDeep tObj
tObjBefore.completed = !tObjBefore.completed if tObjBefore.type in ['daily', 'todo']
setUndo _.cloneDeep(uObj.stats), tObjBefore # set previous state for undo
paths = {}
algos.score(uObj, tObj, direction, {paths:paths})
_.each paths, (v,k) -> user.set(k,helpers.dotGet(k, uObj)); true
model.set('_streakBonus', uObj._tmp.streakBonus) if uObj._tmp?.streakBonus
if uObj._tmp?.drop and $?
model.set '_drop', uObj._tmp.drop
$('#item-dropped-modal').modal 'show'
appExports.addTask = (e, el) ->
type = $(el).attr('data-task-type')
newModel = model.at('_new' + type.charAt(0).toUpperCase() + type.slice(1))
@ -69,7 +44,7 @@ module.exports.app = (appExports, model) ->
if task.get('value') < 0
if confirm("Are you sure? Deleting this task will hurt you (to prevent deleting, then re-creating red tasks).") is true
task.set('type','habit') # hack to make sure it hits HP, instead of performing "undo checkbox"
score(id, 'down')
misc.score(model, id, 'down', true)
else
return # Cancel. Don't delete, don't hurt user
@ -130,29 +105,22 @@ module.exports.app = (appExports, model) ->
appExports.todosShowRemaining = -> model.set '_showCompleted', false
appExports.todosShowCompleted = -> model.set '_showCompleted', true
setUndo = (stats, task) ->
previousUndo = model.get('_undo')
clearTimeout(previousUndo.timeoutId) if previousUndo?.timeoutId
timeoutId = setTimeout (-> model.del('_undo')), 10000
model.set '_undo', {stats:stats, task:task, timeoutId: timeoutId}
###
Call scoring functions for habits & rewards (todos & dailies handled below)
###
appExports.score = (e, el) ->
id = $(el).parents('li').attr('data-id')
direction = $(el).attr('data-direction')
score(id, direction)
misc.score(model, id, direction, true)
###
This is how we handle appExports.score for todos & dailies. Due to Derby's special handling of `checked={:task.completd}`,
the above function doesn't work so we need a listener here
###
user.on 'set', 'tasks.*.completed', (i, completed, previous, isLocal, passed) ->
return if passed? && passed.cron # Don't do this stuff on cron
return if passed?.cron # Don't do this stuff on cron
direction = if completed then 'up' else 'down'
score(i, direction)
misc.score(model, i, direction, true)
###
Undo

View file

@ -256,7 +256,7 @@ scoreTask = (req, res, next) ->
model.at("_#{type}List").push task
#FIXME
delta = algos.score(user.get(), taskId, direction)
delta = misc.score(model, taskId, direction)
result = model.get '_user.stats'
result.delta = delta
res.json result