modify everything to accomdate migratino

This commit is contained in:
Tyler Renelle 2013-02-04 21:13:19 -05:00
parent 96338f3169
commit 6966f6a439
9 changed files with 147 additions and 147 deletions

View file

@ -85,7 +85,7 @@ module.exports.setupGrowlNotifications = (model) ->
statsNotification = (html, type) ->
#don't show notifications if user dead
return if user.get('stats.lvl') == 0
return if user.get('pub.stats.lvl') == 0
$.bootstrapGrowl html,
type: type # (null, 'info', 'error', 'success')
top_offset: 20
@ -95,7 +95,7 @@ module.exports.setupGrowlNotifications = (model) ->
allow_dismiss: true
stackup_spacing: 10 # spacing between consecutive stacecked growls.
user.on 'set', 'items.itemsEnabled', (captures, args) ->
user.on 'set', 'priv.flags.itemsEnabled', (captures, args) ->
return unless captures == true
message = "Congratulations, you have unlocked the Item Store! You can now buy weapons, armor, potions, etc. Read each item's comment for more information."
$('ul.items').popover
@ -109,7 +109,7 @@ module.exports.setupGrowlNotifications = (model) ->
</div>"
$('ul.items').popover 'show'
user.on 'set', 'flags.partyEnabled', (captures, args) ->
user.on 'set', 'priv.flags.partyEnabled', (captures, args) ->
return unless captures == true
message = "Congratulations, you have unlocked the Party System! You can now group with your friends by adding their User Ids."
$('#add-party-button').popover
@ -125,24 +125,24 @@ module.exports.setupGrowlNotifications = (model) ->
# Setup listeners which trigger notifications
user.on 'set', 'stats.hp', (captures, args) ->
user.on 'set', 'pub.stats.hp', (captures, args) ->
num = captures - args
rounded = Math.abs(num.toFixed(1))
if num < 0
statsNotification "<i class='icon-heart'></i>HP -#{rounded}", 'error' # lost hp from purchase
user.on 'set', 'stats.money', (captures, args) ->
user.on 'set', 'pub.stats.gp', (captures, args) ->
num = captures - args
rounded = Math.abs(num.toFixed(1))
# made purchase
if num < 0
# FIXME use 'warning' when unchecking an accidently completed daily/todo, and notify of exp too
statsNotification "<i class='icon-star'></i>GP -#{rounded}", 'success'
# gained money (and thereby exp)
# gained gp (and thereby exp)
else if num > 0
num = Math.abs(num)
statsNotification "<i class='icon-star'></i>Exp,GP +#{rounded}", 'success'
user.on 'set', 'stats.lvl', (captures, args) ->
user.on 'set', 'pub.stats.lvl', (captures, args) ->
if captures > args
statsNotification('<i class="icon-chevron-up"></i> Level Up!', 'info')

View file

@ -44,7 +44,7 @@ module.exports.viewHelpers = (view) ->
else
return "0"
view.fn "money", (num) ->
view.fn "gp", (num) ->
if num
return num.toFixed(2)
else
@ -53,10 +53,13 @@ module.exports.viewHelpers = (view) ->
view.fn "lessThan", (a, b) ->
a < b
view.fn "tokens", (money) ->
return money/0.25
view.fn "tokens", (gp) ->
return gp/0.25
view.fn 'currentArmor', (gender, armor, armorSet) ->
view.fn 'currentArmor', (user) ->
user = { pub:{ items: {armor:0}, preferences: {gender:'m', armorSet:'v1'}}} unless user?
armor = user.pub.items.armor
{gender, armorSet} = user.pub.items
if gender == 'f'
str = "armor#{armor}_f"
if parseInt(armor) > 1

View file

@ -16,10 +16,10 @@ _ = require('underscore')
setupListReferences = (model) ->
taskTypes = ['habit', 'daily', 'todo', 'reward']
_.each taskTypes, (type) -> model.refList "_#{type}List", "_user.tasks", "_user.#{type}Ids"
_.each taskTypes, (type) -> model.refList "_#{type}List", "_user.priv.tasks", "_user.priv.idLists.#{type}"
setupModelFns = (model) ->
model.fn '_user._tnl', '_user.stats.lvl', (lvl) ->
model.fn '_tnl', '_user.pub.stats.lvl', (lvl) ->
# see https://github.com/lefnire/habitrpg/issues/4
# also update in scoring.coffee. TODO create a function accessible in both locations
(lvl*100)/5
@ -47,12 +47,12 @@ get '/', (page, model, next) ->
model.ref '_user', user
batch = new schema.BatchUpdate(model)
batch.startTransaction()
obj = batch.obj()
# Setup Item Store
items = user.get('items')
_view.items =
armor: content.items.armor[parseInt(items?.armor || 0) + 1]
weapon: content.items.weapon[parseInt(items?.weapon || 0) + 1]
armor: content.items.armor[parseInt(obj.pub.items?.armor || 0) + 1]
weapon: content.items.weapon[parseInt(obj.pub.items?.weapon || 0) + 1]
potion: content.items.potion
reroll: content.items.reroll
@ -65,8 +65,8 @@ get '/', (page, model, next) ->
setupModelFns(model)
# Subscribe to friends
if !_.isEmpty(user.get('party'))
model.subscribe model.query('users').party(user.get('party')), (err, party) ->
if !_.isEmpty(obj.pub.party)
model.subscribe model.query('users').party(obj.pub.party), (err, party) ->
model.ref '_party', party
page.render()
@ -83,8 +83,8 @@ ready (model) ->
scoring.setModel(model)
#set cron immediately
lastCron = user.get('lastCron')
user.set('lastCron', +new Date) if (!lastCron? or lastCron == 'new')
lastCron = user.get('priv.lastCron')
user.set('priv.lastCron', +new Date) if (!lastCron? or lastCron == 'new')
# Setup model in scoring functions
scoring.cron(resetDom)
@ -98,7 +98,7 @@ ready (model) ->
require('../server/private').app(exports, model)
user.on 'set', 'tasks.*.completed', (i, completed, previous, isLocal, passed) ->
user.on 'set', 'priv.tasks.*.completed', (i, completed, previous, isLocal, passed) ->
return if passed? && passed.cron # Don't do this stuff on cron
direction = () ->
return 'up' if completed==true and previous == false
@ -106,7 +106,7 @@ ready (model) ->
throw new Error("Direction neither 'up' nor 'down' on checkbox set.")
# Score the user based on todo task
task = user.at("tasks.#{i}")
task = user.at("priv.tasks.#{i}")
scoring.score(i, direction())
exports.addTask = (e, el, next) ->
@ -145,10 +145,10 @@ ready (model) ->
id = $(e.target).parents('li.task').attr('data-id')
return unless id?
task = user.at "tasks.#{id}"
task = user.at "priv.tasks.#{id}"
type = task.get('type')
history = task.get('history')
history = task.get('priv.history')
if history and history.length>2
# prevent delete-and-recreate hack on red tasks
if task.get('value') < 0
@ -168,22 +168,22 @@ ready (model) ->
# fix when query subscriptions implemented properly
$('[rel=tooltip]').tooltip('hide')
ids = user.get("#{type}Ids")
ids = user.get("priv.idLists.#{type}")
ids.splice(ids.indexOf(id),1)
user.del('tasks.'+id)
user.set("#{type}Ids", ids)
user.del('priv.tasks.'+id)
user.set("priv.idLists.#{type}", ids)
exports.clearCompleted = (e, el) ->
todoIds = user.get('todoIds')
todoIds = user.get('priv.idLists.todo')
removed = false
_.each model.get('_todoList'), (task) ->
if task.completed
removed = true
user.del('tasks.'+task.id)
user.del('priv.tasks.'+task.id)
todoIds.splice(todoIds.indexOf(task.id), 1)
if removed
user.set('todoIds', todoIds)
user.set('priv.idLists.todo', todoIds)
exports.toggleDay = (e, el) ->
task = model.at(e.target)
@ -226,22 +226,22 @@ ready (model) ->
#TODO: this should be working but it's not. so instead, i'm passing all needed values as data-attrs
# item = model.at(e.target)
money = user.get 'stats.money'
gp = user.get 'pub.stats.gp'
[type, value, index] = [ $(el).attr('data-type'), $(el).attr('data-value'), $(el).attr('data-index') ]
return if money < value
user.set 'stats.money', money - value
return if gp < value
user.set 'pub.stats.gp', gp - value
if type == 'armor'
user.set 'items.armor', index
user.set 'pub.items.armor', index
model.set '_view.items.armor', content.items.armor[parseInt(index) + 1]
else if type == 'weapon'
user.set 'items.weapon', index
user.set 'pub.items.weapon', index
model.set '_view.items.weapon', content.items.weapon[parseInt(index) + 1]
else if type == 'potion'
hp = user.get 'stats.hp'
hp = user.get 'pub.stats.hp'
hp += 15
hp = 50 if hp > 50
user.set 'stats.hp', hp
user.set 'pub.stats.hp', hp
exports.score = (e, el, next) ->
direction = $(el).attr('data-direction')
@ -252,14 +252,14 @@ ready (model) ->
revive = (batch) ->
# Reset stats
batch.set 'stats.hp', 50
batch.set 'stats.lvl', 1
batch.set 'stats.money', 0
batch.set 'stats.exp', 0
batch.set 'pub.stats.hp', 50
batch.set 'pub.stats.lvl', 1
batch.set 'pub.stats.gp', 0
batch.set 'pub.stats.exp', 0
# Reset items
batch.set 'items.armor', 0
batch.set 'items.weapon', 0
batch.set 'pub.items.armor', 0
batch.set 'pub.items.weapon', 0
# Reset item store
model.set '_view.items.armor', content.items.armor[1]
@ -275,33 +275,33 @@ ready (model) ->
batch = new schema.BatchUpdate(model)
batch.startTransaction()
taskTypes = ['habit', 'daily', 'todo', 'reward']
batch.set 'tasks', {}
_.each taskTypes, (type) -> batch.set "#{type}Ids", []
batch.set 'balance', 2 if user.get('balance') < 2 #only if they haven't manually bought tokens
batch.set 'priv.tasks', {}
_.each taskTypes, (type) -> batch.set "priv.idLists.#{type}", []
batch.set 'priv.balance', 2 if user.get('priv.balance') < 2 #only if they haven't manually bought tokens
revive(batch, true)
batch.commit()
resetDom(model)
exports.closeKickstarterNofitication = (e, el) ->
user.set('notifications.kickstarter', 'hide')
user.set('priv.flags.kickstarter', 'hide')
exports.setMale = -> user.set('preferences.gender', 'm')
exports.setFemale = -> user.set('preferences.gender', 'f')
exports.setArmorsetV1 = -> user.set('preferences.armorSet', 'v1')
exports.setArmorsetV2 = -> user.set('preferences.armorSet', 'v2')
exports.setMale = -> user.set('pub.preferences.gender', 'm')
exports.setFemale = -> user.set('pub.preferences.gender', 'f')
exports.setArmorsetV1 = -> user.set('pub.preferences.armorSet', 'v1')
exports.setArmorsetV2 = -> user.set('pub.preferences.armorSet', 'v2')
exports.addParty = ->
id = model.get('_newPartyMember').replace(/[\s"]/g, '')
debugger
return if _.isEmpty(id)
if user.get('party').indexOf(id) != -1
if user.get('pub.party').indexOf(id) != -1
model.set "_view.addPartyError", "#{id} already in party."
return
query = model.query('users').party([id])
model.fetch query, (err, users) ->
partyMember = users.at(0).get()
if partyMember?.id?
user.push('party', id)
user.push('pub.party', id)
$('#add-party-modal').modal('hide')
window.location.reload() #TODO break old subscription, setup new subscript, remove this reload
model.set '_newPartyMember', ''
@ -310,6 +310,6 @@ ready (model) ->
exports.emulateNextDay = ->
yesterday = +moment().subtract('days', 1).toDate()
user.set 'lastCron', yesterday
user.set 'priv.lastCron', yesterday
window.location.reload()

View file

@ -30,11 +30,11 @@ userSchema =
module.exports.newUserObject = ->
# deep clone, else further new users get duplicate objects
newUser = require('lodash').cloneDeep userSchema
newUser = lodash.cloneDeep userSchema
newUser.priv.apiToken = derby.uuid()
for task in content.defaultTasks
guid = task.id = derby.uuid()
newUser.tasks[guid] = task
newUser.priv.tasks[guid] = task
switch task.type
when 'habit' then newUser.priv.idLists.habit.push guid
when 'daily' then newUser.priv.idLists.daily.push guid
@ -44,26 +44,24 @@ module.exports.newUserObject = ->
module.exports.updateUser = (batch) ->
user = batch.user
obj = user.batch.obj()
obj = batch.obj()
batch.set('priv.apiToken', derby.uuid()) unless obj.priv.apiToken
## Task List Cleanup
# FIXME temporary hack to fix lists (Need to figure out why these are happening)
tasks = user.get('tasks')
tasks = obj.priv.tasks
_.each ['habit','daily','todo','reward'], (type) ->
path = "#{type}Ids"
# 1. remove duplicates
# 2. restore missing zombie tasks back into list
taskIds = _.pluck( _.where(tasks, {type:type}), 'id')
union = _.union user.get(path), taskIds
union = _.union obj.priv.idLists[type], taskIds
# 2. remove empty (grey) tasks
preened = _.filter(union, (val) -> _.contains(taskIds, val))
# There were indeed issues found, set the new list
batch.set(path, preened) # if _.difference(preened, userObj[path]).length != 0
batch.set("priv.idLists.#{type}", preened) # if _.difference(preened, userObj[path]).length != 0
module.exports.BatchUpdate = BatchUpdate = (model) ->
user = model.at("_user")
@ -102,9 +100,9 @@ module.exports.BatchUpdate = BatchUpdate = (model) ->
eg, user.set('stats', {hp:50, exp:10...}) will break dom bindings, but user.set('stats.hp',50) is ok
###
setStats: (stats) ->
stats ?= obj.stats
stats ?= obj.pub.stats
that = @
_.each Object.keys(stats), (key) -> that.set "stats.#{key}", stats[key]
_.each Object.keys(stats), (key) -> that.set "pub.stats.#{key}", stats[key]
# queue: (path, val) ->
# # Special function for setting object properties by string dot-notation. See http://stackoverflow.com/a/6394168/362790

View file

@ -20,8 +20,8 @@ setModel = (m) ->
{modifiers} may manually pass in stats as {weapon, exp}. This is used for testing
###
expModifier = (value, modifiers = {}) ->
weapon = modifiers.weapon || user.get('items.weapon')
lvl = modifiers.lvl || user.get('stats.lvl')
weapon = modifiers.weapon || user.get('pub.items.weapon')
lvl = modifiers.lvl || user.get('pub.stats.lvl')
dmg = weapon * MODIFIER # each new weapon increases exp gain
dmg += (lvl-1) * MODIFIER # same for lvls
modified = value + (value * dmg)
@ -33,8 +33,8 @@ expModifier = (value, modifiers = {}) ->
{modifiers} may manually pass in modifier as {armor, lvl}. This is used for testing
###
hpModifier = (value, modifiers = {}) ->
armor = modifiers.armor || user.get('items.armor')
lvl = modifiers.lvl || user.get('stats.lvl')
armor = modifiers.armor || user.get('pub.items.armor')
lvl = modifiers.lvl || user.get('pub.stats.lvl')
ac = armor * MODIFIER # each new armor decreases HP loss
ac += (lvl-1) * MODIFIER # same for lvls
modified = value - (value * ac)
@ -62,37 +62,37 @@ updateStats = (newStats, batch) ->
obj = batch.obj()
# if user is dead, dont do anything
return if obj.stats.lvl == 0
return if obj.pub.stats.lvl == 0
if newStats.hp?
# Game Over
if newStats.hp <= 0
obj.stats.lvl = 0 # signifies dead
obj.stats.hp = 0
obj.pub.stats.lvl = 0 # signifies dead
obj.pub.stats.hp = 0
return
else
obj.stats.hp = newStats.hp
obj.pub.stats.hp = newStats.hp
if newStats.exp?
# level up & carry-over exp
tnl = user.get '_tnl'
tnl = model.get '_tnl'
if newStats.exp >= tnl
newStats.exp -= tnl
obj.stats.lvl++
obj.stats.hp = 50
if !obj.items.itemsEnabled and obj.stats.lvl >= 2
obj.pub.stats.lvl++
obj.pub.stats.hp = 50
if !obj.priv.flags.itemsEnabled and obj.pub.stats.lvl >= 2
# Set to object, then also send to browser right away to get model.on() subscription notification
batch.set 'items.itemsEnabled', true
obj.items.itemsEnabled = true
# if !obj.flags.partyEnabled and obj.stats.lvl >= 3
# batch.set 'flags.partyEnabled', true
# obj.flags.partyEnabled = true
obj.stats.exp = newStats.exp
batch.set 'priv.flags.itemsEnabled', true
obj.priv.flags.itemsEnabled = true
if !obj.priv.flags.partyEnabled and obj.pub.stats.lvl >= 3
batch.set 'priv.flags.partyEnabled', true
obj.priv.flags.partyEnabled = true
obj.pub.stats.exp = newStats.exp
if newStats.money?
#FIXME what was I doing here? I can't remember, money isn't defined
money = 0.0 if (!money? or money<0)
obj.stats.money = newStats.money
if newStats.gp?
#FIXME what was I doing here? I can't remember, gp isn't defined
gp = 0.0 if (!gp? or gp<0)
obj.pub.stats.gp = newStats.gp
# {taskId} task you want to score
# {direction} 'up' or 'down'
@ -106,10 +106,10 @@ score = (taskId, direction, times, batch, cron) ->
batch.startTransaction()
obj = batch.obj()
{money, hp, exp, lvl} = obj.stats
{gp, hp, exp, lvl} = obj.pub.stats
taskPath = "tasks.#{taskId}"
taskObj = obj.tasks[taskId]
taskPath = "priv.tasks.#{taskId}"
taskObj = obj.priv.tasks[taskId]
{type, value} = taskObj
delta = 0
@ -127,7 +127,7 @@ score = (taskId, direction, times, batch, cron) ->
addPoints = ->
modified = expModifier(delta)
exp += modified
money += modified
gp += modified
subtractPoints = ->
modified = hpModifier(delta)
@ -162,21 +162,21 @@ score = (taskId, direction, times, batch, cron) ->
# Don't adjust values for rewards
calculateDelta(false)
# purchase item
money -= taskObj.value
gp -= taskObj.value
num = parseFloat(taskObj.value).toFixed(2)
# if too expensive, reduce health & zero money
if money < 0
hp += money # hp - money difference
money = 0
# if too expensive, reduce health & zero gp
if gp < 0
hp += gp # hp - gp difference
gp = 0
taskObj.value = value
batch.set "#{taskPath}.value", taskObj.value
origStats = _.clone obj.stats
updateStats {hp: hp, exp: exp, money: money}, batch
origStats = _.clone obj.pub.stats
updateStats {hp: hp, exp: exp, gp: gp}, batch
if commit
# newStats / origStats is a glorious hack to trick Derby into seeing the change in model.on(*)
newStats = _.clone batch.obj().stats
_.each Object.keys(origStats), (key) -> obj.stats[key] = origStats[key]
newStats = _.clone batch.obj().pub.stats
_.each Object.keys(origStats), (key) -> obj.pub.stats[key] = origStats[key]
batch.setStats(newStats)
# batch.setStats()
batch.commit()
@ -188,16 +188,16 @@ score = (taskId, direction, times, batch, cron) ->
###
cron = (resetDom_cb) ->
today = +new Date
daysPassed = helpers.daysBetween(today, user.get('lastCron'))
daysPassed = helpers.daysBetween(today, user.get('privlastCron'))
if daysPassed > 0
batch = new schema.BatchUpdate(model)
batch.startTransaction()
batch.set 'lastCron', today
batch.set 'priv.lastCron', today
obj = batch.obj()
hpBefore = obj.stats.hp #we'll use this later so we can animate hp loss
hpBefore = obj.pub.stats.hp #we'll use this later so we can animate hp loss
# Tally each task
todoTally = 0
_.each obj.tasks, (taskObj) ->
_.each obj.priv.tasks, (taskObj) ->
unless taskObj.id?
console.error "a task had a null id during cron, this should not be happening"
return
@ -222,31 +222,31 @@ cron = (resetDom_cb) ->
if type == 'daily'
taskObj.history ?= []
taskObj.history.push { date: +new Date, value: value }
batch.set "tasks.#{taskObj.id}.history", taskObj.history
batch.set "tasks.#{taskObj.id}.completed", false
batch.set "priv.tasks.#{taskObj.id}.history", taskObj.history
batch.set "priv.tasks.#{taskObj.id}.completed", false
else
value = obj.tasks[taskObj.id].value #get updated value
value = obj.priv.tasks[taskObj.id].value #get updated value
absVal = if (completed) then Math.abs(value) else value
todoTally += absVal
# Finished tallying
obj.history ?= {}; obj.history.todos ?= []; obj.history.exp ?= []
obj.history.todos.push { date: today, value: todoTally }
obj.priv.history ?= {}; obj.priv.history.todos ?= []; obj.priv.history.exp ?= []
obj.priv.history.todos.push { date: today, value: todoTally }
# tally experience
expTally = obj.stats.exp
expTally = obj.pub.stats.exp
lvl = 0 #iterator
while lvl < (obj.stats.lvl-1)
while lvl < (obj.pub.stats.lvl-1)
lvl++
expTally += (lvl*100)/5
obj.history.exp.push { date: today, value: expTally }
obj.priv.history.exp.push { date: today, value: expTally }
# Set the new user specs, and animate HP loss
[hpAfter, obj.stats.hp] = [obj.stats.hp, hpBefore]
[hpAfter, obj.pub.stats.hp] = [obj.pub.stats.hp, hpBefore]
batch.setStats()
batch.set('history', obj.history)
batch.set('history', obj.priv.history)
batch.commit()
resetDom_cb(model)
setTimeout (-> user.set 'stats.hp', hpAfter), 1000 # animate hp loss
setTimeout (-> user.set 'pub.stats.hp', hpAfter), 1000 # animate hp loss
module.exports = {

View file

@ -31,8 +31,8 @@ module.exports.deleteStaleAccounts = ->
collection.findEach un_registered, (err, user) ->
throw err if err
return unless user? #why does this happen sometimes?
if !!user.lastCron # for now ignore missing crons, still looking into why this is happening
lastCron = new Date(user.lastCron)
if !!user.priv.lastCron # for now ignore missing crons, still looking into why this is happening
lastCron = new Date(user.priv.lastCron)
diff = Math.abs(moment(today).sod().diff(moment(lastCron).sod(), "days"))
if diff > 10
removeAccount(collection, user._id)

View file

@ -35,9 +35,8 @@ module.exports.app = (appExports, model) ->
appExports.buyReroll = (e, el, next) ->
batch = new schema.BatchUpdate(model)
obj = model.get('_user')
batch.set 'balance', obj.balance-1
_.each obj.tasks, (task) -> batch.set("tasks.#{task.id}.value", 0) unless task.type == 'reward'
console.log(obj)
batch.set 'priv.balance', obj.priv.balance-1
_.each obj.priv.tasks, (task) -> batch.set("priv.tasks.#{task.id}.value", 0) unless task.type == 'reward'
batch.commit()
module.exports.routes = (expressApp) ->
@ -54,8 +53,8 @@ module.exports.routes = (expressApp) ->
userId = model.session.userId
model.fetch "users.#{userId}", (err, user) ->
model.ref '_user', "users.#{userId}"
model.set('_user.balance', model.get('_user.balance')+5)
model.set('_user.flags.ads','hide')
model.set('_user.priv.balance', model.get('_user.priv.balance')+5)
model.set('_user.priv.flags.ads','hide')
return res.send(200)
api_key = process.env.STRIPE_API_KEY # secret stripe API key

View file

@ -49,8 +49,8 @@ module.exports = (expressApp, root, derby) ->
# Create task if doesn't exist
# TODO add service & icon to task
unless model.get("_user.tasks.#{taskId}")
model.refList "_habitList", "_user.tasks", "_user.habitIds"
unless model.get("_user.priv.tasks.#{taskId}")
model.refList "_habitList", "_user.priv.tasks", "_user.priv.idLists.habit"
model.at('_habitList').push {
id: taskId
type: 'habit'

View file

@ -14,28 +14,28 @@
<pre class=prettyprint>{_user.id}</pre>
<h6>API Token</h6>
<pre class=prettyprint>{_user.preferences.api_token}</pre>
<pre class=prettyprint>{_user.priv.apiToken}</pre>
<hr/>
<h4>Gender</h4>
<label class="radio">
<input type="radio" name="genderRadios" value="m" x-bind="click:setMale" checked="{equal(_user.preferences.gender,'m')}">
<input type="radio" name="genderRadios" value="m" x-bind="click:setMale" checked="{equal(_user.pub.preferences.gender,'m')}">
Male
</label>
<label class="radio">
<input type="radio" name="genderRadios" value="f" x-bind="click:setFemale" checked="{equal(_user.preferences.gender,'f')}">
<input type="radio" name="genderRadios" value="f" x-bind="click:setFemale" checked="{equal(_user.pub.preferences.gender,'f')}">
Female
</label>
{#if equal(_user.preferences.gender,'f')}
{#if equal(_user.pub.preferences.gender,'f')}
<h4>Armor Set</h4>
<label class="radio">
<input type="radio" name="armorSet" value="v1" x-bind="click:setArmorsetV1" checked="{equal(_user.preferences.armorSet,'v1')}">
<input type="radio" name="armorSet" value="v1" x-bind="click:setArmorsetV1" checked="{equal(_user.pub.preferences.armorSet,'v1')}">
v1
</label>
<label class="radio">
<input type="radio" name="armorSet" value="v2" x-bind="click:setArmorsetV2" checked="{equal(_user.preferences.armorSet,'v2')}">
<input type="radio" name="armorSet" value="v2" x-bind="click:setArmorsetV2" checked="{equal(_user.pub.preferences.armorSet,'v2')}">
v2
</label>
{/}
@ -79,7 +79,7 @@
</app:myModal>
{/}
<!-- Game Over Modal -->
<div style="{#unless equal(_user.stats.lvl,0)}display:none;{/}">
<div style="{#unless equal(_user.pub.stats.lvl,0)}display:none;{/}">
<app:myModal noDismiss=true modalId='dead-modal'>
<table>
<tr>
@ -100,7 +100,7 @@
<app:userTokens/>
<p>Highly discouraged because red tasks provide good incentive to improve (<a target="_blank" href="https://github.com/lefnire/habitrpg#all-my-tasks-are-red-im-dying-too-fast">read more</a>). However, this becomes necessary after long bouts of bad habits.</p>
<@footer>
{#if lessThan(_user.balance,1)}
{#if lessThan(_user.priv.balance,1)}
<a data-dismiss="modal" x-bind="click:showStripe" class="btn btn-danger btn-large">Buy More Tokens</a><span class='token-cost'>Not enough tokens</span>
{else}
<a data-dismiss="modal" x-bind=click:buyReroll class="btn btn-danger btn-large">Re-Roll</a><span class='token-cost'>4 Tokens</span>
@ -125,7 +125,7 @@
</ul>
{/}
{#if equal(_user.notifications.kickstarter,'show')}
{#if equal(_user.priv.flags.kickstarter,'show')}
<div class='alert alert-success'>
<a x-bind="click:closeKickstarterNofitication" class='pull-right'>Dismiss</a>
Help Habit by backing the <strong><a href="http://kck.st/XoA3Yg">Kickstarter</a></strong>! Funds iPhone & Android apps, <a href="https://github.com/lefnire/habitrpg/issues?labels=critical&page=1&state=open">bug fixes</a>, and the <a href="https://github.com/lefnire/habitrpg/issues/58">Groups feature</a>.
@ -165,39 +165,39 @@
<!-- Avatar -->
<td class="avatar main-avatar">
<div class='avatar-sprites'>
<img class='weapon weapon-{_user.items.weapon}' src="/img/BrowserQuest/habitrpg_mods/weapon{_user.items.weapon}.png" />
<img class='armor armor-{_user.items.armor}' src="/img/BrowserQuest/habitrpg_mods/{currentArmor(_user.preferences.gender, _user.items.armor, _user.preferences.armorSet)}" />
<img class='weapon weapon-{_user.pub.items.weapon}' src="/img/BrowserQuest/habitrpg_mods/weapon{_user.pub.items.weapon}.png" />
<img class='armor armor-{_user.pub.items.armor}' src="/img/BrowserQuest/habitrpg_mods/{currentArmor(_user)}" />
</div>
<div id="lvl"><span class="badge badge-info">Lvl {_user.stats.lvl}</span></div>
<div id="lvl"><span class="badge badge-info">Lvl {_user.pub.stats.lvl}</span></div>
</td>
<!-- Progress Bars -->
<td id="bars" style="width:{#if _party}70%{else}90%{/};">
<div class="progress progress-danger" rel=tooltip data-placement=bottom title="Health">
<div class="bar" style="width: {percent(_user.stats.hp, 50)}%;"></div>
<span class="progress-text"><i class=icon-heart></i> {round(_user.stats.hp)} / 50</span>
<div class="bar" style="width: {percent(_user.pub.stats.hp, 50)}%;"></div>
<span class="progress-text"><i class=icon-heart></i> {round(_user.pub.stats.hp)} / 50</span>
</div>
<div class="progress progress-warning" rel=tooltip data-placement=bottom title="Experience">
<div class="bar" style="width: {percent(_user.stats.exp,_user._tnl)}%;"></div>
<div class="bar" style="width: {percent(_user.pub.stats.exp,_tnl)}%;"></div>
<span class="progress-text">
{#if _user.history.exp}
<a x-bind=click:toggleChart data-toggle-id="exp-chart" data-history-path="_user.history.exp" rel=tooltip title="Progress"><i class=icon-signal></i></a>&nbsp;
{/}
<i class=icon-star></i> {round(_user.stats.exp)} / {_user._tnl}
<i class=icon-star></i> {round(_user.pub.stats.exp)} / {_tnl}
</span>
</div>
</td>
<!-- Party -->
{#if _user.flags.partyEnabled}
{#if _user.priv.flags.partyEnabled}
{#each _party as :member}
<td class="avatar party-avatar" rel="tooltip" title="{username(:member.auth)}" data-placement="bottom" >
<div class='avatar-sprites'>
<img class='weapon weapon-{:member.items.weapon}' src="/img/BrowserQuest/habitrpg_mods/weapon{:member.items.weapon}.png" />
<img class='armor armor-{:member.items.armor}' src="/img/BrowserQuest/habitrpg_mods/{currentArmor(:member.preferences.gender, :member.items.armor, :member.preferences.armorSet)}" />
<img class='weapon weapon-{:member.pub.items.weapon}' src="/img/BrowserQuest/habitrpg_mods/weapon{:member.pub.items.weapon}.png" />
<img class='armor armor-{:member.pub.items.armor}' src="/img/BrowserQuest/habitrpg_mods/{currentArmor(:member)}" />
</div>
<div id="lvl"><span class="badge badge-info">Lvl {:member.stats.lvl}</span></div>
<div id="lvl"><span class="badge badge-info">Lvl {:member.pub.stats.lvl}</span></div>
</td>
{/}
<td><a class="btn" id="add-party-button" data-target="#add-party-modal" data-toggle="modal"><i class="icon-user"></i></a></td>
@ -281,7 +281,7 @@
<!--Title -->
<div class="row-fluid">
<div class="span6"><h2>Rewards</h2></div>
<div class="span6" id="money">{gold(_user.stats.money)} <img src='/img/coin_single_gold.png'/> {silver(_user.stats.money)} <img src='/img/coin_single_silver.png'/></div>
<div class="span6" id="money">{gold(_user.pub.stats.money)} <img src='/img/coin_single_gold.png'/> {silver(_user.pub.stats.money)} <img src='/img/coin_single_silver.png'/></div>
</div>
<!-- Content -->
@ -289,7 +289,7 @@
{#each _rewardList as :task}<app:task />{/}
</ul>
{#if _user.items.itemsEnabled}
{#if _user.priv.flags.itemsEnabled}
<ul class='items'>
{#with _view.items.armor as :item}<app:item />{/}
{#with _view.items.weapon as :item}<app:item />{/}
@ -346,12 +346,12 @@
<userTokens:>
<div class="pull-right">
<div class="input-append">
<span class="uneditable-input" style="width:auto;">{tokens(_user.balance)}</span>
<span class="uneditable-input" style="width:auto;">{tokens(_user.priv.balance)}</span>
<span class="add-on">Tokens</span>
</div>
<a class="label" data-toggle="modal" href='#reset-modal'><i class="icon-ban-circle"></i>Reset</a>
</div>
<!--<span class="well pull-right">Tokens: {tokens(_user.balance)}</span>-->
<!--<span class="well pull-right">Tokens: {tokens(_user.priv.balance)}</span>-->
<newTask: nonvoid>
<form class="form-inline new-task-form" id=new-{{@type}} data-task-type={{@type}} x-bind=submit:addTask>