mirror of
https://github.com/sudoxnym/habitica.git
synced 2026-05-19 20:28:53 +00:00
habitrpg-shared: *almost* working wth new scoring (c0cf9780fe) - need to fix for cron, API, and other misc bugs
This commit is contained in:
parent
6a36f4bd1d
commit
0b445df909
9 changed files with 46 additions and 112 deletions
|
|
@ -16,9 +16,7 @@
|
|||
"guid": "*",
|
||||
"moment": "*",
|
||||
"stripe": "*",
|
||||
"lodash": "1.0.x",
|
||||
"coffee-script": "1.4.x",
|
||||
"underscore": "*",
|
||||
"mongoskin": "*",
|
||||
"nconf": "*",
|
||||
"icalendar": "git://github.com/lefnire/node-icalendar#master",
|
||||
|
|
@ -26,7 +24,8 @@
|
|||
"resolve": "~0.2.3",
|
||||
"expect.js": "~0.2.0",
|
||||
"derby-i18n": "git://github.com/switz/derby-i18n#master",
|
||||
"relative-date": "~1.1.1"
|
||||
"relative-date": "~1.1.1",
|
||||
"lodash": "~1.2.1"
|
||||
},
|
||||
"private": true,
|
||||
"subdomain": "habitrpg",
|
||||
|
|
|
|||
|
|
@ -1,74 +0,0 @@
|
|||
XP = 15
|
||||
HP = 2
|
||||
|
||||
priorityValue = module.exports.priorityValue = (priority='!') ->
|
||||
switch priority
|
||||
when '!' then 1
|
||||
when '!!' then 1.5
|
||||
when '!!!' then 2
|
||||
else 1
|
||||
|
||||
module.exports.tnl = (level) ->
|
||||
if level >= 100
|
||||
value = 0
|
||||
else
|
||||
value = Math.round(((Math.pow(level,2)*0.25)+(10 * level) + 139.75)/10)*10 # round to nearest 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 = (value, weaponStr, level, priority='!') ->
|
||||
str = (level-1) / 2 # ultimately get this from user
|
||||
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
|
||||
###
|
||||
module.exports.hpModifier = (value, armorDef, helmDef, shieldDef, level, priority='!') ->
|
||||
def = (level-1) / 2 # ultimately get this from user?
|
||||
totalDef = (def + armorDef + helmDef + shieldDef) / 100 #ultimate get this from user
|
||||
defMod = 1 - totalDef
|
||||
hp = value * HP * defMod * priorityValue(priority)
|
||||
return Math.round(hp * 10)/10 # round to 1dp
|
||||
|
||||
###
|
||||
Future use
|
||||
{priority} user-defined priority multiplier
|
||||
###
|
||||
module.exports.gpModifier = (value, modifier, priority='!', streak, model) ->
|
||||
val = value * modifier * priorityValue(priority)
|
||||
if streak and model
|
||||
streakBonus = streak / 100 + 1 # eg, 1-day streak is 1.1, 2-day is 1.2, etc
|
||||
afterStreak = val * streakBonus
|
||||
model.set('_streakBonus', afterStreak - val) if (val > 0) # can we do this without model? just global emit?
|
||||
return afterStreak
|
||||
else
|
||||
return val
|
||||
|
||||
###
|
||||
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 = (currentValue, direction) ->
|
||||
if currentValue < -47.27 then currentValue = -47.27
|
||||
else if currentValue > 21.27 then currentValue = 21.27
|
||||
delta = Math.pow(0.9747,currentValue)
|
||||
return delta if direction is 'up'
|
||||
return -delta
|
||||
|
||||
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
browser = require './browser'
|
||||
items = require './items'
|
||||
algos = require './algos'
|
||||
algos = require 'habitrpg-shared/script/algos'
|
||||
|
||||
moment = require 'moment'
|
||||
_ = require 'underscore'
|
||||
|
|
@ -22,7 +22,6 @@ module.exports.app = (appExports, model) ->
|
|||
owned = user.get('items')
|
||||
# unless they're already at 0-everything
|
||||
if parseInt(owned.armor)>0 or parseInt(owned.head)>0 or parseInt(owned.shield)>0 or parseInt(owned.weapon)>0
|
||||
console.log 'test'
|
||||
# find a random item to lose
|
||||
until loseThisItem
|
||||
#candidate = {0:'items.armor', 1:'items.head', 2:'items.shield', 3:'items.weapon', 4:'stats.gp'}[Math.random()*5|0]
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
moment = require 'moment'
|
||||
algos = require './algos'
|
||||
algos = require 'habitrpg-shared/script/algos'
|
||||
|
||||
module.exports.app = (appExports, model) ->
|
||||
user = model.at('_user')
|
||||
|
|
|
|||
|
|
@ -117,7 +117,7 @@ ready (model) ->
|
|||
user = model.at('_user')
|
||||
model.setNull '_user.apiToken', derby.uuid()
|
||||
|
||||
require('./scoring').cron(model)
|
||||
#FIXME require('habitrpg-shared/script/algos').cron(user)
|
||||
|
||||
require('./character').app(exports, model)
|
||||
require('./tasks').app(exports, model)
|
||||
|
|
|
|||
|
|
@ -1,12 +1,35 @@
|
|||
scoring = require './scoring'
|
||||
algos = require 'habitrpg-shared/script/algos'
|
||||
helpers = require 'habitrpg-shared/script/helpers'
|
||||
_ = require 'underscore'
|
||||
_ = require 'lodash'
|
||||
moment = require 'moment'
|
||||
character = require './character'
|
||||
|
||||
|
||||
###
|
||||
Make scoring functionality available to the app
|
||||
###
|
||||
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 = (user, taskId, direction) ->
|
||||
uObj = _.cloneDeep user.get() # need to clone, else derby won't catch model.set()'s after obj property sets
|
||||
tObj = uObj.tasks[taskId]
|
||||
|
||||
# Stuff for undo
|
||||
tObjBefore = _.cloneDeep tObj
|
||||
tObjBefore.completed = !tObjBefore.completed if tObj.type in ['daily', 'todo']
|
||||
setUndo 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))
|
||||
|
||||
appExports.addTask = (e, el) ->
|
||||
type = $(el).attr('data-task-type')
|
||||
newModel = model.at('_new' + type.charAt(0).toUpperCase() + type.slice(1))
|
||||
|
|
@ -28,26 +51,24 @@ module.exports.app = (appExports, model) ->
|
|||
model.unshift "_#{type}List", newTask
|
||||
newModel.set ''
|
||||
|
||||
appExports.del = (e, el) ->
|
||||
appExports.del = (e) ->
|
||||
# Derby extends model.at to support creation from DOM nodes
|
||||
task = e.at()
|
||||
id = task.get('id')
|
||||
|
||||
history = task.get('history')
|
||||
if history and history.length>2
|
||||
if history and history.length > 2
|
||||
# prevent delete-and-recreate hack on red tasks
|
||||
if task.get('value') < 0
|
||||
result = confirm("Are you sure? Deleting this task will hurt you (to prevent deleting, then re-creating red tasks).")
|
||||
if result != true
|
||||
return # Cancel. Don't delete, don't hurt user
|
||||
else
|
||||
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"
|
||||
scoring.score(model, id, direction:'down')
|
||||
score(user, id, 'down')
|
||||
else
|
||||
return # Cancel. Don't delete, don't hurt user
|
||||
|
||||
# prevent accidently deleting long-standing tasks
|
||||
else
|
||||
result = confirm("Are you sure you want to delete this task?")
|
||||
return if result != true
|
||||
return unless confirm("Are you sure you want to delete this task?") is true
|
||||
|
||||
#TODO bug where I have to delete from _users.tasks AND _{type}List,
|
||||
# fix when query subscriptions implemented properly
|
||||
|
|
@ -113,14 +134,9 @@ module.exports.app = (appExports, model) ->
|
|||
Call scoring functions for habits & rewards (todos & dailies handled below)
|
||||
###
|
||||
appExports.score = (e, el) ->
|
||||
task= model.at $(el).parents('li')[0]
|
||||
taskObj = task.get()
|
||||
task = model.at $(el).parents('li')[0]
|
||||
direction = $(el).attr('data-direction')
|
||||
|
||||
# set previous state for undo
|
||||
setUndo _.clone(user.get('stats')), _.clone(taskObj)
|
||||
|
||||
scoring.score(model, taskObj.id, direction)
|
||||
score(user, task.get('id'), direction)
|
||||
|
||||
###
|
||||
This is how we handle appExports.score for todos & dailies. Due to Derby's special handling of `checked={:task.completd}`,
|
||||
|
|
@ -129,13 +145,7 @@ module.exports.app = (appExports, model) ->
|
|||
user.on 'set', 'tasks.*.completed', (i, completed, previous, isLocal, passed) ->
|
||||
return if passed? && passed.cron # Don't do this stuff on cron
|
||||
direction = if completed then 'up' else 'down'
|
||||
|
||||
# set previous state for undo
|
||||
taskObj = _.clone user.get("tasks.#{i}")
|
||||
taskObj.completed = previous
|
||||
setUndo _.clone(user.get('stats')), taskObj
|
||||
|
||||
scoring.score(model, i, direction)
|
||||
score(user, i, direction)
|
||||
|
||||
###
|
||||
Undo
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
_ = require 'underscore'
|
||||
algos = require './algos'
|
||||
algos = require 'habitrpg-shared/script/algos'
|
||||
items = require('habitrpg-shared/script/items').items
|
||||
helpers = require('habitrpg-shared/script/helpers')
|
||||
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
express = require 'express'
|
||||
router = new express.Router()
|
||||
|
||||
scoring = require '../app/scoring'
|
||||
_ = require 'underscore'
|
||||
{ tnl } = require '../app/algos'
|
||||
algos = require 'habitrpg-shared/script/algos'
|
||||
{ tnl } = algos
|
||||
validator = require 'derby-auth/node_modules/validator'
|
||||
check = validator.check
|
||||
sanitize = validator.sanitize
|
||||
|
|
@ -255,7 +255,8 @@ scoreTask = (req, res, next) ->
|
|||
model.refList "_#{type}List", "_user.tasks", "_user.#{type}Ids"
|
||||
model.at("_#{type}List").push task
|
||||
|
||||
delta = scoring.score(model, taskId, direction)
|
||||
#FIXME
|
||||
delta = algos.score(user.get(), taskId, direction)
|
||||
result = model.get '_user.stats'
|
||||
result.delta = delta
|
||||
res.json result
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
express = require 'express'
|
||||
router = new express.Router()
|
||||
|
||||
scoring = require '../app/scoring'
|
||||
_ = require 'underscore'
|
||||
icalendar = require('icalendar')
|
||||
api = require './api'
|
||||
|
|
|
|||
Loading…
Reference in a new issue