mirror of
https://github.com/HabitRPG/habitica.git
synced 2025-12-18 07:07:35 +01:00
don't need public/private paths after all, can check path requests in store accessControl callbacks
This commit is contained in:
@@ -52,42 +52,40 @@ db.users.find().forEach(function(user){
|
|||||||
// Note 'public' and 'private' are reserved words
|
// Note 'public' and 'private' are reserved words
|
||||||
var newUser = {
|
var newUser = {
|
||||||
auth: user.auth, // we need this top-level due to derby-auth
|
auth: user.auth, // we need this top-level due to derby-auth
|
||||||
pub:{
|
apiToken: user.preferences.api_token || null, // set on update, we need derby.uuid()
|
||||||
party: null,
|
preferences: {
|
||||||
invitations: [],
|
armorSet: user.preferences.armorSet || 'v1',
|
||||||
items: {
|
gender: user.preferences.gender || 'm'
|
||||||
armor: user.items.armor || 0,
|
|
||||||
weapon: user.items.weapon || 0
|
|
||||||
},
|
|
||||||
stats: {
|
|
||||||
gp: user.stats.money || 0,
|
|
||||||
hp: user.stats.hp || 50,
|
|
||||||
exp: user.stats.exp || 0,
|
|
||||||
lvl: user.stats.lvl || 1
|
|
||||||
},
|
|
||||||
preferences: {
|
|
||||||
armorSet: user.preferences.armorSet || 'v1',
|
|
||||||
gender: user.preferences.gender || 'm'
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
priv: {
|
balance: user.balance || 2,
|
||||||
balance: user.balance || 2,
|
lastCron: user.lastCron || +new Date,
|
||||||
lastCron: user.lastCron || +new Date,
|
history: user.history || [],
|
||||||
tasks: user.tasks || {},
|
stats: {
|
||||||
history: user.history || [],
|
gp: user.stats.money || 0,
|
||||||
apiToken: user.preferences.api_token || null, // set on update, we need derby.uuid()
|
hp: user.stats.hp || 50,
|
||||||
idLists: {
|
exp: user.stats.exp || 0,
|
||||||
habit:user.habitList || [],
|
lvl: user.stats.lvl || 1
|
||||||
daily:user.dailyList || [],
|
},
|
||||||
todo:user.todoList || [],
|
items: {
|
||||||
reward:user.rewardList || []
|
armor: user.items.armor || 0,
|
||||||
},
|
weapon: user.items.weapon || 0
|
||||||
flags: {
|
},
|
||||||
partyEnabled: false,
|
tasks: user.tasks || {},
|
||||||
itemsEnabled: user.items.itemsEnabled || false,
|
idLists: {
|
||||||
kickstarter: user.notifications.kickstarter || 'show',
|
habit: user.habitIds || [],
|
||||||
ads: user.flags.ads || null // null because it's set on registration
|
daily: user.dailyIds || [],
|
||||||
}
|
todo: user.todoIds || [],
|
||||||
|
reward: user.rewardIds || []
|
||||||
|
},
|
||||||
|
flags: {
|
||||||
|
partyEnabled: false,
|
||||||
|
itemsEnabled: user.items.itemsEnabled || false,
|
||||||
|
kickstarter: user.notifications.kickstarter || 'show',
|
||||||
|
ads: user.flags.ads || null // null because it's set on registration
|
||||||
|
},
|
||||||
|
party: {
|
||||||
|
current: null,
|
||||||
|
invitation: null
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -85,7 +85,7 @@ module.exports.setupGrowlNotifications = (model) ->
|
|||||||
|
|
||||||
statsNotification = (html, type) ->
|
statsNotification = (html, type) ->
|
||||||
#don't show notifications if user dead
|
#don't show notifications if user dead
|
||||||
return if user.get('pub.stats.lvl') == 0
|
return if user.get('stats.lvl') == 0
|
||||||
$.bootstrapGrowl html,
|
$.bootstrapGrowl html,
|
||||||
type: type # (null, 'info', 'error', 'success')
|
type: type # (null, 'info', 'error', 'success')
|
||||||
top_offset: 20
|
top_offset: 20
|
||||||
@@ -95,7 +95,7 @@ module.exports.setupGrowlNotifications = (model) ->
|
|||||||
allow_dismiss: true
|
allow_dismiss: true
|
||||||
stackup_spacing: 10 # spacing between consecutive stacecked growls.
|
stackup_spacing: 10 # spacing between consecutive stacecked growls.
|
||||||
|
|
||||||
user.on 'set', 'priv.flags.itemsEnabled', (captures, args) ->
|
user.on 'set', 'flags.itemsEnabled', (captures, args) ->
|
||||||
return unless captures == true
|
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."
|
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
|
$('ul.items').popover
|
||||||
@@ -109,7 +109,7 @@ module.exports.setupGrowlNotifications = (model) ->
|
|||||||
</div>"
|
</div>"
|
||||||
$('ul.items').popover 'show'
|
$('ul.items').popover 'show'
|
||||||
|
|
||||||
user.on 'set', 'priv.flags.partyEnabled', (captures, args) ->
|
user.on 'set', 'flags.partyEnabled', (captures, args) ->
|
||||||
return unless captures == true
|
return unless captures == true
|
||||||
message = "Congratulations, you have unlocked the Party System! You can now group with your friends by adding their User Ids."
|
message = "Congratulations, you have unlocked the Party System! You can now group with your friends by adding their User Ids."
|
||||||
$('#add-party-button').popover
|
$('#add-party-button').popover
|
||||||
@@ -125,13 +125,13 @@ module.exports.setupGrowlNotifications = (model) ->
|
|||||||
|
|
||||||
|
|
||||||
# Setup listeners which trigger notifications
|
# Setup listeners which trigger notifications
|
||||||
user.on 'set', 'pub.stats.hp', (captures, args) ->
|
user.on 'set', 'stats.hp', (captures, args) ->
|
||||||
num = captures - args
|
num = captures - args
|
||||||
rounded = Math.abs(num.toFixed(1))
|
rounded = Math.abs(num.toFixed(1))
|
||||||
if num < 0
|
if num < 0
|
||||||
statsNotification "<i class='icon-heart'></i>HP -#{rounded}", 'error' # lost hp from purchase
|
statsNotification "<i class='icon-heart'></i>HP -#{rounded}", 'error' # lost hp from purchase
|
||||||
|
|
||||||
user.on 'set', 'pub.stats.gp', (captures, args) ->
|
user.on 'set', 'stats.gp', (captures, args) ->
|
||||||
num = captures - args
|
num = captures - args
|
||||||
rounded = Math.abs(num.toFixed(1))
|
rounded = Math.abs(num.toFixed(1))
|
||||||
# made purchase
|
# made purchase
|
||||||
@@ -143,6 +143,6 @@ module.exports.setupGrowlNotifications = (model) ->
|
|||||||
num = Math.abs(num)
|
num = Math.abs(num)
|
||||||
statsNotification "<i class='icon-star'></i>Exp,GP +#{rounded}", 'success'
|
statsNotification "<i class='icon-star'></i>Exp,GP +#{rounded}", 'success'
|
||||||
|
|
||||||
user.on 'set', 'pub.stats.lvl', (captures, args) ->
|
user.on 'set', 'stats.lvl', (captures, args) ->
|
||||||
if captures > args
|
if captures > args
|
||||||
statsNotification('<i class="icon-chevron-up"></i> Level Up!', 'info')
|
statsNotification('<i class="icon-chevron-up"></i> Level Up!', 'info')
|
||||||
@@ -57,9 +57,9 @@ module.exports.viewHelpers = (view) ->
|
|||||||
return gp/0.25
|
return gp/0.25
|
||||||
|
|
||||||
view.fn 'currentArmor', (user) ->
|
view.fn 'currentArmor', (user) ->
|
||||||
user = { pub:{ items: {armor:0}, preferences: {gender:'m', armorSet:'v1'}}} unless user?
|
user = { items: {armor:0}, preferences: {gender:'m', armorSet:'v1'}} unless user?
|
||||||
armor = user.pub.items.armor
|
armor = user.items.armor
|
||||||
{gender, armorSet} = user.pub.items
|
{gender, armorSet} = user.preferences
|
||||||
if gender == 'f'
|
if gender == 'f'
|
||||||
str = "armor#{armor}_f"
|
str = "armor#{armor}_f"
|
||||||
if parseInt(armor) > 1
|
if parseInt(armor) > 1
|
||||||
|
|||||||
@@ -16,10 +16,10 @@ _ = require('underscore')
|
|||||||
|
|
||||||
setupListReferences = (model) ->
|
setupListReferences = (model) ->
|
||||||
taskTypes = ['habit', 'daily', 'todo', 'reward']
|
taskTypes = ['habit', 'daily', 'todo', 'reward']
|
||||||
_.each taskTypes, (type) -> model.refList "_#{type}List", "_user.priv.tasks", "_user.priv.idLists.#{type}"
|
_.each taskTypes, (type) -> model.refList "_#{type}List", "_user.tasks", "_user.idLists.#{type}"
|
||||||
|
|
||||||
setupModelFns = (model) ->
|
setupModelFns = (model) ->
|
||||||
model.fn '_tnl', '_user.pub.stats.lvl', (lvl) ->
|
model.fn '_tnl', '_user.stats.lvl', (lvl) ->
|
||||||
# see https://github.com/lefnire/habitrpg/issues/4
|
# see https://github.com/lefnire/habitrpg/issues/4
|
||||||
# also update in scoring.coffee. TODO create a function accessible in both locations
|
# also update in scoring.coffee. TODO create a function accessible in both locations
|
||||||
(lvl*100)/5
|
(lvl*100)/5
|
||||||
@@ -51,8 +51,8 @@ get '/', (page, model, next) ->
|
|||||||
|
|
||||||
# Setup Item Store
|
# Setup Item Store
|
||||||
_view.items =
|
_view.items =
|
||||||
armor: content.items.armor[parseInt(obj.pub.items?.armor || 0) + 1]
|
armor: content.items.armor[parseInt(obj.items?.armor || 0) + 1]
|
||||||
weapon: content.items.weapon[parseInt(obj.pub.items?.weapon || 0) + 1]
|
weapon: content.items.weapon[parseInt(obj.items?.weapon || 0) + 1]
|
||||||
potion: content.items.potion
|
potion: content.items.potion
|
||||||
reroll: content.items.reroll
|
reroll: content.items.reroll
|
||||||
|
|
||||||
@@ -65,8 +65,8 @@ get '/', (page, model, next) ->
|
|||||||
setupModelFns(model)
|
setupModelFns(model)
|
||||||
|
|
||||||
# Subscribe to friends
|
# Subscribe to friends
|
||||||
if !_.isEmpty(obj.pub.party)
|
if !_.isEmpty(obj.party)
|
||||||
model.subscribe model.query('users').party(obj.pub.party), (err, party) ->
|
model.subscribe model.query('users').party(obj.party), (err, party) ->
|
||||||
model.ref '_party', party
|
model.ref '_party', party
|
||||||
|
|
||||||
page.render()
|
page.render()
|
||||||
@@ -83,8 +83,8 @@ ready (model) ->
|
|||||||
scoring.setModel(model)
|
scoring.setModel(model)
|
||||||
|
|
||||||
#set cron immediately
|
#set cron immediately
|
||||||
lastCron = user.get('priv.lastCron')
|
lastCron = user.get('lastCron')
|
||||||
user.set('priv.lastCron', +new Date) if (!lastCron? or lastCron == 'new')
|
user.set('lastCron', +new Date) if (!lastCron? or lastCron == 'new')
|
||||||
|
|
||||||
# Setup model in scoring functions
|
# Setup model in scoring functions
|
||||||
scoring.cron(resetDom)
|
scoring.cron(resetDom)
|
||||||
@@ -98,7 +98,7 @@ ready (model) ->
|
|||||||
|
|
||||||
require('../server/private').app(exports, model)
|
require('../server/private').app(exports, model)
|
||||||
|
|
||||||
user.on 'set', 'priv.tasks.*.completed', (i, completed, previous, isLocal, passed) ->
|
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? && passed.cron # Don't do this stuff on cron
|
||||||
direction = () ->
|
direction = () ->
|
||||||
return 'up' if completed==true and previous == false
|
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.")
|
throw new Error("Direction neither 'up' nor 'down' on checkbox set.")
|
||||||
|
|
||||||
# Score the user based on todo task
|
# Score the user based on todo task
|
||||||
task = user.at("priv.tasks.#{i}")
|
task = user.at("tasks.#{i}")
|
||||||
scoring.score(i, direction())
|
scoring.score(i, direction())
|
||||||
|
|
||||||
exports.addTask = (e, el, next) ->
|
exports.addTask = (e, el, next) ->
|
||||||
@@ -145,10 +145,10 @@ ready (model) ->
|
|||||||
id = $(e.target).parents('li.task').attr('data-id')
|
id = $(e.target).parents('li.task').attr('data-id')
|
||||||
return unless id?
|
return unless id?
|
||||||
|
|
||||||
task = user.at "priv.tasks.#{id}"
|
task = user.at "tasks.#{id}"
|
||||||
type = task.get('type')
|
type = task.get('type')
|
||||||
|
|
||||||
history = task.get('priv.history')
|
history = task.get('history')
|
||||||
if history and history.length>2
|
if history and history.length>2
|
||||||
# prevent delete-and-recreate hack on red tasks
|
# prevent delete-and-recreate hack on red tasks
|
||||||
if task.get('value') < 0
|
if task.get('value') < 0
|
||||||
@@ -168,22 +168,22 @@ ready (model) ->
|
|||||||
# fix when query subscriptions implemented properly
|
# fix when query subscriptions implemented properly
|
||||||
$('[rel=tooltip]').tooltip('hide')
|
$('[rel=tooltip]').tooltip('hide')
|
||||||
|
|
||||||
ids = user.get("priv.idLists.#{type}")
|
ids = user.get("idLists.#{type}")
|
||||||
ids.splice(ids.indexOf(id),1)
|
ids.splice(ids.indexOf(id),1)
|
||||||
user.del('priv.tasks.'+id)
|
user.del('tasks.'+id)
|
||||||
user.set("priv.idLists.#{type}", ids)
|
user.set("idLists.#{type}", ids)
|
||||||
|
|
||||||
|
|
||||||
exports.clearCompleted = (e, el) ->
|
exports.clearCompleted = (e, el) ->
|
||||||
todoIds = user.get('priv.idLists.todo')
|
todoIds = user.get('idLists.todo')
|
||||||
removed = false
|
removed = false
|
||||||
_.each model.get('_todoList'), (task) ->
|
_.each model.get('_todoList'), (task) ->
|
||||||
if task.completed
|
if task.completed
|
||||||
removed = true
|
removed = true
|
||||||
user.del('priv.tasks.'+task.id)
|
user.del('tasks.'+task.id)
|
||||||
todoIds.splice(todoIds.indexOf(task.id), 1)
|
todoIds.splice(todoIds.indexOf(task.id), 1)
|
||||||
if removed
|
if removed
|
||||||
user.set('priv.idLists.todo', todoIds)
|
user.set('idLists.todo', todoIds)
|
||||||
|
|
||||||
exports.toggleDay = (e, el) ->
|
exports.toggleDay = (e, el) ->
|
||||||
task = model.at(e.target)
|
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
|
#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)
|
# item = model.at(e.target)
|
||||||
|
|
||||||
gp = user.get 'pub.stats.gp'
|
gp = user.get 'stats.gp'
|
||||||
[type, value, index] = [ $(el).attr('data-type'), $(el).attr('data-value'), $(el).attr('data-index') ]
|
[type, value, index] = [ $(el).attr('data-type'), $(el).attr('data-value'), $(el).attr('data-index') ]
|
||||||
|
|
||||||
return if gp < value
|
return if gp < value
|
||||||
user.set 'pub.stats.gp', gp - value
|
user.set 'stats.gp', gp - value
|
||||||
if type == 'armor'
|
if type == 'armor'
|
||||||
user.set 'pub.items.armor', index
|
user.set 'items.armor', index
|
||||||
model.set '_view.items.armor', content.items.armor[parseInt(index) + 1]
|
model.set '_view.items.armor', content.items.armor[parseInt(index) + 1]
|
||||||
else if type == 'weapon'
|
else if type == 'weapon'
|
||||||
user.set 'pub.items.weapon', index
|
user.set 'items.weapon', index
|
||||||
model.set '_view.items.weapon', content.items.weapon[parseInt(index) + 1]
|
model.set '_view.items.weapon', content.items.weapon[parseInt(index) + 1]
|
||||||
else if type == 'potion'
|
else if type == 'potion'
|
||||||
hp = user.get 'pub.stats.hp'
|
hp = user.get 'stats.hp'
|
||||||
hp += 15
|
hp += 15
|
||||||
hp = 50 if hp > 50
|
hp = 50 if hp > 50
|
||||||
user.set 'pub.stats.hp', hp
|
user.set 'stats.hp', hp
|
||||||
|
|
||||||
exports.score = (e, el, next) ->
|
exports.score = (e, el, next) ->
|
||||||
direction = $(el).attr('data-direction')
|
direction = $(el).attr('data-direction')
|
||||||
@@ -252,14 +252,14 @@ ready (model) ->
|
|||||||
|
|
||||||
revive = (batch) ->
|
revive = (batch) ->
|
||||||
# Reset stats
|
# Reset stats
|
||||||
batch.set 'pub.stats.hp', 50
|
batch.set 'stats.hp', 50
|
||||||
batch.set 'pub.stats.lvl', 1
|
batch.set 'stats.lvl', 1
|
||||||
batch.set 'pub.stats.gp', 0
|
batch.set 'stats.gp', 0
|
||||||
batch.set 'pub.stats.exp', 0
|
batch.set 'stats.exp', 0
|
||||||
|
|
||||||
# Reset items
|
# Reset items
|
||||||
batch.set 'pub.items.armor', 0
|
batch.set 'items.armor', 0
|
||||||
batch.set 'pub.items.weapon', 0
|
batch.set 'items.weapon', 0
|
||||||
|
|
||||||
# Reset item store
|
# Reset item store
|
||||||
model.set '_view.items.armor', content.items.armor[1]
|
model.set '_view.items.armor', content.items.armor[1]
|
||||||
@@ -275,33 +275,33 @@ ready (model) ->
|
|||||||
batch = new schema.BatchUpdate(model)
|
batch = new schema.BatchUpdate(model)
|
||||||
batch.startTransaction()
|
batch.startTransaction()
|
||||||
taskTypes = ['habit', 'daily', 'todo', 'reward']
|
taskTypes = ['habit', 'daily', 'todo', 'reward']
|
||||||
batch.set 'priv.tasks', {}
|
batch.set 'tasks', {}
|
||||||
_.each taskTypes, (type) -> batch.set "priv.idLists.#{type}", []
|
_.each taskTypes, (type) -> batch.set "idLists.#{type}", []
|
||||||
batch.set 'priv.balance', 2 if user.get('priv.balance') < 2 #only if they haven't manually bought tokens
|
batch.set 'balance', 2 if user.get('balance') < 2 #only if they haven't manually bought tokens
|
||||||
revive(batch, true)
|
revive(batch, true)
|
||||||
batch.commit()
|
batch.commit()
|
||||||
resetDom(model)
|
resetDom(model)
|
||||||
|
|
||||||
exports.closeKickstarterNofitication = (e, el) ->
|
exports.closeKickstarterNofitication = (e, el) ->
|
||||||
user.set('priv.flags.kickstarter', 'hide')
|
user.set('flags.kickstarter', 'hide')
|
||||||
|
|
||||||
exports.setMale = -> user.set('pub.preferences.gender', 'm')
|
exports.setMale = -> user.set('preferences.gender', 'm')
|
||||||
exports.setFemale = -> user.set('pub.preferences.gender', 'f')
|
exports.setFemale = -> user.set('preferences.gender', 'f')
|
||||||
exports.setArmorsetV1 = -> user.set('pub.preferences.armorSet', 'v1')
|
exports.setArmorsetV1 = -> user.set('preferences.armorSet', 'v1')
|
||||||
exports.setArmorsetV2 = -> user.set('pub.preferences.armorSet', 'v2')
|
exports.setArmorsetV2 = -> user.set('preferences.armorSet', 'v2')
|
||||||
|
|
||||||
exports.addParty = ->
|
exports.addParty = ->
|
||||||
id = model.get('_newPartyMember').replace(/[\s"]/g, '')
|
id = model.get('_newPartyMember').replace(/[\s"]/g, '')
|
||||||
debugger
|
debugger
|
||||||
return if _.isEmpty(id)
|
return if _.isEmpty(id)
|
||||||
if user.get('pub.party').indexOf(id) != -1
|
if user.get('party').indexOf(id) != -1
|
||||||
model.set "_view.addPartyError", "#{id} already in party."
|
model.set "_view.addPartyError", "#{id} already in party."
|
||||||
return
|
return
|
||||||
query = model.query('users').party([id])
|
query = model.query('users').party([id])
|
||||||
model.fetch query, (err, users) ->
|
model.fetch query, (err, users) ->
|
||||||
partyMember = users.at(0).get()
|
partyMember = users.at(0).get()
|
||||||
if partyMember?.id?
|
if partyMember?.id?
|
||||||
user.push('pub.party', id)
|
user.push('party', id)
|
||||||
$('#add-party-modal').modal('hide')
|
$('#add-party-modal').modal('hide')
|
||||||
window.location.reload() #TODO break old subscription, setup new subscript, remove this reload
|
window.location.reload() #TODO break old subscription, setup new subscript, remove this reload
|
||||||
model.set '_newPartyMember', ''
|
model.set '_newPartyMember', ''
|
||||||
@@ -310,6 +310,6 @@ ready (model) ->
|
|||||||
|
|
||||||
exports.emulateNextDay = ->
|
exports.emulateNextDay = ->
|
||||||
yesterday = +moment().subtract('days', 1).toDate()
|
yesterday = +moment().subtract('days', 1).toDate()
|
||||||
user.set 'priv.lastCron', yesterday
|
user.set 'lastCron', yesterday
|
||||||
window.location.reload()
|
window.location.reload()
|
||||||
|
|
||||||
|
|||||||
@@ -6,62 +6,62 @@ derby = require 'derby'
|
|||||||
|
|
||||||
userSchema =
|
userSchema =
|
||||||
# _id
|
# _id
|
||||||
pub:
|
stats: { gp: 0, exp: 0, lvl: 1, hp: 50 }
|
||||||
stats: { gp: 0, exp: 0, lvl: 1, hp: 50 }
|
party: {
|
||||||
party: null
|
current: null
|
||||||
invitations: []
|
invitation: null
|
||||||
items: { armor: 0, weapon: 0 }
|
}
|
||||||
preferences: { gender: 'm', armorSet: 'v1' }
|
items: { armor: 0, weapon: 0 }
|
||||||
priv:
|
preferences: { gender: 'm', armorSet: 'v1' }
|
||||||
idLists:
|
idLists:
|
||||||
habit: []
|
habit: []
|
||||||
daily: []
|
daily: []
|
||||||
todo: []
|
todo: []
|
||||||
reward: []
|
reward: []
|
||||||
apiToken: null # set in newUserObject below
|
apiToken: null # set in newUserObject below
|
||||||
lastCron: 'new' #this will be replaced with `+new Date` on first run
|
lastCron: 'new' #this will be replaced with `+new Date` on first run
|
||||||
balance: 2
|
balance: 2
|
||||||
tasks: {}
|
tasks: {}
|
||||||
flags:
|
flags:
|
||||||
partyEnabled: false
|
partyEnabled: false
|
||||||
itemsEnabled: false
|
itemsEnabled: false
|
||||||
kickstarter: 'show'
|
kickstarter: 'show'
|
||||||
# ads: 'show' # added on registration
|
# ads: 'show' # added on registration
|
||||||
|
|
||||||
module.exports.newUserObject = ->
|
module.exports.newUserObject = ->
|
||||||
# deep clone, else further new users get duplicate objects
|
# deep clone, else further new users get duplicate objects
|
||||||
newUser = lodash.cloneDeep userSchema
|
newUser = lodash.cloneDeep userSchema
|
||||||
newUser.priv.apiToken = derby.uuid()
|
newUser.apiToken = derby.uuid()
|
||||||
for task in content.defaultTasks
|
for task in content.defaultTasks
|
||||||
guid = task.id = derby.uuid()
|
guid = task.id = derby.uuid()
|
||||||
newUser.priv.tasks[guid] = task
|
newUser.tasks[guid] = task
|
||||||
switch task.type
|
switch task.type
|
||||||
when 'habit' then newUser.priv.idLists.habit.push guid
|
when 'habit' then newUser.idLists.habit.push guid
|
||||||
when 'daily' then newUser.priv.idLists.daily.push guid
|
when 'daily' then newUser.idLists.daily.push guid
|
||||||
when 'todo' then newUser.priv.idLists.todo.push guid
|
when 'todo' then newUser.idLists.todo.push guid
|
||||||
when 'reward' then newUser.priv.idLists.reward.push guid
|
when 'reward' then newUser.idLists.reward.push guid
|
||||||
return newUser
|
return newUser
|
||||||
|
|
||||||
module.exports.updateUser = (batch) ->
|
module.exports.updateUser = (batch) ->
|
||||||
user = batch.user
|
user = batch.user
|
||||||
obj = batch.obj()
|
obj = batch.obj()
|
||||||
|
|
||||||
batch.set('priv.apiToken', derby.uuid()) unless obj.priv.apiToken
|
batch.set('apiToken', derby.uuid()) unless obj.apiToken
|
||||||
|
|
||||||
## Task List Cleanup
|
## Task List Cleanup
|
||||||
# FIXME temporary hack to fix lists (Need to figure out why these are happening)
|
# FIXME temporary hack to fix lists (Need to figure out why these are happening)
|
||||||
tasks = obj.priv.tasks
|
tasks = obj.tasks
|
||||||
_.each ['habit','daily','todo','reward'], (type) ->
|
_.each ['habit','daily','todo','reward'], (type) ->
|
||||||
# 1. remove duplicates
|
# 1. remove duplicates
|
||||||
# 2. restore missing zombie tasks back into list
|
# 2. restore missing zombie tasks back into list
|
||||||
taskIds = _.pluck( _.where(tasks, {type:type}), 'id')
|
taskIds = _.pluck( _.where(tasks, {type:type}), 'id')
|
||||||
union = _.union obj.priv.idLists[type], taskIds
|
union = _.union obj.idLists[type], taskIds
|
||||||
|
|
||||||
# 2. remove empty (grey) tasks
|
# 2. remove empty (grey) tasks
|
||||||
preened = _.filter(union, (val) -> _.contains(taskIds, val))
|
preened = _.filter(union, (val) -> _.contains(taskIds, val))
|
||||||
|
|
||||||
# There were indeed issues found, set the new list
|
# There were indeed issues found, set the new list
|
||||||
batch.set("priv.idLists.#{type}", preened) # if _.difference(preened, userObj[path]).length != 0
|
batch.set("idLists.#{type}", preened) # if _.difference(preened, userObj[path]).length != 0
|
||||||
|
|
||||||
module.exports.BatchUpdate = BatchUpdate = (model) ->
|
module.exports.BatchUpdate = BatchUpdate = (model) ->
|
||||||
user = model.at("_user")
|
user = model.at("_user")
|
||||||
@@ -100,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
|
eg, user.set('stats', {hp:50, exp:10...}) will break dom bindings, but user.set('stats.hp',50) is ok
|
||||||
###
|
###
|
||||||
setStats: (stats) ->
|
setStats: (stats) ->
|
||||||
stats ?= obj.pub.stats
|
stats ?= obj.stats
|
||||||
that = @
|
that = @
|
||||||
_.each Object.keys(stats), (key) -> that.set "pub.stats.#{key}", stats[key]
|
_.each Object.keys(stats), (key) -> that.set "stats.#{key}", stats[key]
|
||||||
|
|
||||||
# queue: (path, val) ->
|
# queue: (path, val) ->
|
||||||
# # Special function for setting object properties by string dot-notation. See http://stackoverflow.com/a/6394168/362790
|
# # Special function for setting object properties by string dot-notation. See http://stackoverflow.com/a/6394168/362790
|
||||||
|
|||||||
@@ -20,8 +20,8 @@ setModel = (m) ->
|
|||||||
{modifiers} may manually pass in stats as {weapon, exp}. This is used for testing
|
{modifiers} may manually pass in stats as {weapon, exp}. This is used for testing
|
||||||
###
|
###
|
||||||
expModifier = (value, modifiers = {}) ->
|
expModifier = (value, modifiers = {}) ->
|
||||||
weapon = modifiers.weapon || user.get('pub.items.weapon')
|
weapon = modifiers.weapon || user.get('items.weapon')
|
||||||
lvl = modifiers.lvl || user.get('pub.stats.lvl')
|
lvl = modifiers.lvl || user.get('stats.lvl')
|
||||||
dmg = weapon * MODIFIER # each new weapon increases exp gain
|
dmg = weapon * MODIFIER # each new weapon increases exp gain
|
||||||
dmg += (lvl-1) * MODIFIER # same for lvls
|
dmg += (lvl-1) * MODIFIER # same for lvls
|
||||||
modified = value + (value * dmg)
|
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
|
{modifiers} may manually pass in modifier as {armor, lvl}. This is used for testing
|
||||||
###
|
###
|
||||||
hpModifier = (value, modifiers = {}) ->
|
hpModifier = (value, modifiers = {}) ->
|
||||||
armor = modifiers.armor || user.get('pub.items.armor')
|
armor = modifiers.armor || user.get('items.armor')
|
||||||
lvl = modifiers.lvl || user.get('pub.stats.lvl')
|
lvl = modifiers.lvl || user.get('stats.lvl')
|
||||||
ac = armor * MODIFIER # each new armor decreases HP loss
|
ac = armor * MODIFIER # each new armor decreases HP loss
|
||||||
ac += (lvl-1) * MODIFIER # same for lvls
|
ac += (lvl-1) * MODIFIER # same for lvls
|
||||||
modified = value - (value * ac)
|
modified = value - (value * ac)
|
||||||
@@ -62,37 +62,37 @@ updateStats = (newStats, batch) ->
|
|||||||
obj = batch.obj()
|
obj = batch.obj()
|
||||||
|
|
||||||
# if user is dead, dont do anything
|
# if user is dead, dont do anything
|
||||||
return if obj.pub.stats.lvl == 0
|
return if obj.stats.lvl == 0
|
||||||
|
|
||||||
if newStats.hp?
|
if newStats.hp?
|
||||||
# Game Over
|
# Game Over
|
||||||
if newStats.hp <= 0
|
if newStats.hp <= 0
|
||||||
obj.pub.stats.lvl = 0 # signifies dead
|
obj.stats.lvl = 0 # signifies dead
|
||||||
obj.pub.stats.hp = 0
|
obj.stats.hp = 0
|
||||||
return
|
return
|
||||||
else
|
else
|
||||||
obj.pub.stats.hp = newStats.hp
|
obj.stats.hp = newStats.hp
|
||||||
|
|
||||||
if newStats.exp?
|
if newStats.exp?
|
||||||
# level up & carry-over exp
|
# level up & carry-over exp
|
||||||
tnl = model.get '_tnl'
|
tnl = model.get '_tnl'
|
||||||
if newStats.exp >= tnl
|
if newStats.exp >= tnl
|
||||||
newStats.exp -= tnl
|
newStats.exp -= tnl
|
||||||
obj.pub.stats.lvl++
|
obj.stats.lvl++
|
||||||
obj.pub.stats.hp = 50
|
obj.stats.hp = 50
|
||||||
if !obj.priv.flags.itemsEnabled and obj.pub.stats.lvl >= 2
|
if !obj.flags.itemsEnabled and obj.stats.lvl >= 2
|
||||||
# Set to object, then also send to browser right away to get model.on() subscription notification
|
# Set to object, then also send to browser right away to get model.on() subscription notification
|
||||||
batch.set 'priv.flags.itemsEnabled', true
|
batch.set 'flags.itemsEnabled', true
|
||||||
obj.priv.flags.itemsEnabled = true
|
obj.flags.itemsEnabled = true
|
||||||
if !obj.priv.flags.partyEnabled and obj.pub.stats.lvl >= 3
|
if !obj.flags.partyEnabled and obj.stats.lvl >= 3
|
||||||
batch.set 'priv.flags.partyEnabled', true
|
batch.set 'flags.partyEnabled', true
|
||||||
obj.priv.flags.partyEnabled = true
|
obj.flags.partyEnabled = true
|
||||||
obj.pub.stats.exp = newStats.exp
|
obj.stats.exp = newStats.exp
|
||||||
|
|
||||||
if newStats.gp?
|
if newStats.gp?
|
||||||
#FIXME what was I doing here? I can't remember, gp isn't defined
|
#FIXME what was I doing here? I can't remember, gp isn't defined
|
||||||
gp = 0.0 if (!gp? or gp<0)
|
gp = 0.0 if (!gp? or gp<0)
|
||||||
obj.pub.stats.gp = newStats.gp
|
obj.stats.gp = newStats.gp
|
||||||
|
|
||||||
# {taskId} task you want to score
|
# {taskId} task you want to score
|
||||||
# {direction} 'up' or 'down'
|
# {direction} 'up' or 'down'
|
||||||
@@ -106,10 +106,10 @@ score = (taskId, direction, times, batch, cron) ->
|
|||||||
batch.startTransaction()
|
batch.startTransaction()
|
||||||
obj = batch.obj()
|
obj = batch.obj()
|
||||||
|
|
||||||
{gp, hp, exp, lvl} = obj.pub.stats
|
{gp, hp, exp, lvl} = obj.stats
|
||||||
|
|
||||||
taskPath = "priv.tasks.#{taskId}"
|
taskPath = "tasks.#{taskId}"
|
||||||
taskObj = obj.priv.tasks[taskId]
|
taskObj = obj.tasks[taskId]
|
||||||
{type, value} = taskObj
|
{type, value} = taskObj
|
||||||
|
|
||||||
delta = 0
|
delta = 0
|
||||||
@@ -171,12 +171,12 @@ score = (taskId, direction, times, batch, cron) ->
|
|||||||
|
|
||||||
taskObj.value = value
|
taskObj.value = value
|
||||||
batch.set "#{taskPath}.value", taskObj.value
|
batch.set "#{taskPath}.value", taskObj.value
|
||||||
origStats = _.clone obj.pub.stats
|
origStats = _.clone obj.stats
|
||||||
updateStats {hp: hp, exp: exp, gp: gp}, batch
|
updateStats {hp: hp, exp: exp, gp: gp}, batch
|
||||||
if commit
|
if commit
|
||||||
# newStats / origStats is a glorious hack to trick Derby into seeing the change in model.on(*)
|
# newStats / origStats is a glorious hack to trick Derby into seeing the change in model.on(*)
|
||||||
newStats = _.clone batch.obj().pub.stats
|
newStats = _.clone batch.obj().stats
|
||||||
_.each Object.keys(origStats), (key) -> obj.pub.stats[key] = origStats[key]
|
_.each Object.keys(origStats), (key) -> obj.stats[key] = origStats[key]
|
||||||
batch.setStats(newStats)
|
batch.setStats(newStats)
|
||||||
# batch.setStats()
|
# batch.setStats()
|
||||||
batch.commit()
|
batch.commit()
|
||||||
@@ -192,12 +192,12 @@ cron = (resetDom_cb) ->
|
|||||||
if daysPassed > 0
|
if daysPassed > 0
|
||||||
batch = new schema.BatchUpdate(model)
|
batch = new schema.BatchUpdate(model)
|
||||||
batch.startTransaction()
|
batch.startTransaction()
|
||||||
batch.set 'priv.lastCron', today
|
batch.set 'lastCron', today
|
||||||
obj = batch.obj()
|
obj = batch.obj()
|
||||||
hpBefore = obj.pub.stats.hp #we'll use this later so we can animate hp loss
|
hpBefore = obj.stats.hp #we'll use this later so we can animate hp loss
|
||||||
# Tally each task
|
# Tally each task
|
||||||
todoTally = 0
|
todoTally = 0
|
||||||
_.each obj.priv.tasks, (taskObj) ->
|
_.each obj.tasks, (taskObj) ->
|
||||||
unless taskObj.id?
|
unless taskObj.id?
|
||||||
console.error "a task had a null id during cron, this should not be happening"
|
console.error "a task had a null id during cron, this should not be happening"
|
||||||
return
|
return
|
||||||
@@ -222,31 +222,31 @@ cron = (resetDom_cb) ->
|
|||||||
if type == 'daily'
|
if type == 'daily'
|
||||||
taskObj.history ?= []
|
taskObj.history ?= []
|
||||||
taskObj.history.push { date: +new Date, value: value }
|
taskObj.history.push { date: +new Date, value: value }
|
||||||
batch.set "priv.tasks.#{taskObj.id}.history", taskObj.history
|
batch.set "tasks.#{taskObj.id}.history", taskObj.history
|
||||||
batch.set "priv.tasks.#{taskObj.id}.completed", false
|
batch.set "tasks.#{taskObj.id}.completed", false
|
||||||
else
|
else
|
||||||
value = obj.priv.tasks[taskObj.id].value #get updated value
|
value = obj.tasks[taskObj.id].value #get updated value
|
||||||
absVal = if (completed) then Math.abs(value) else value
|
absVal = if (completed) then Math.abs(value) else value
|
||||||
todoTally += absVal
|
todoTally += absVal
|
||||||
|
|
||||||
# Finished tallying
|
# Finished tallying
|
||||||
obj.priv.history ?= {}; obj.priv.history.todos ?= []; obj.priv.history.exp ?= []
|
obj.history ?= {}; obj.history.todos ?= []; obj.history.exp ?= []
|
||||||
obj.priv.history.todos.push { date: today, value: todoTally }
|
obj.history.todos.push { date: today, value: todoTally }
|
||||||
# tally experience
|
# tally experience
|
||||||
expTally = obj.pub.stats.exp
|
expTally = obj.stats.exp
|
||||||
lvl = 0 #iterator
|
lvl = 0 #iterator
|
||||||
while lvl < (obj.pub.stats.lvl-1)
|
while lvl < (obj.stats.lvl-1)
|
||||||
lvl++
|
lvl++
|
||||||
expTally += (lvl*100)/5
|
expTally += (lvl*100)/5
|
||||||
obj.priv.history.exp.push { date: today, value: expTally }
|
obj.history.exp.push { date: today, value: expTally }
|
||||||
|
|
||||||
# Set the new user specs, and animate HP loss
|
# Set the new user specs, and animate HP loss
|
||||||
[hpAfter, obj.pub.stats.hp] = [obj.pub.stats.hp, hpBefore]
|
[hpAfter, obj.stats.hp] = [obj.stats.hp, hpBefore]
|
||||||
batch.setStats()
|
batch.setStats()
|
||||||
batch.set('history', obj.priv.history)
|
batch.set('history', obj.history)
|
||||||
batch.commit()
|
batch.commit()
|
||||||
resetDom_cb(model)
|
resetDom_cb(model)
|
||||||
setTimeout (-> user.set 'pub.stats.hp', hpAfter), 1000 # animate hp loss
|
setTimeout (-> user.set 'stats.hp', hpAfter), 1000 # animate hp loss
|
||||||
|
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
|
|||||||
@@ -31,8 +31,8 @@ module.exports.deleteStaleAccounts = ->
|
|||||||
collection.findEach un_registered, (err, user) ->
|
collection.findEach un_registered, (err, user) ->
|
||||||
throw err if err
|
throw err if err
|
||||||
return unless user? #why does this happen sometimes?
|
return unless user? #why does this happen sometimes?
|
||||||
if !!user.priv.lastCron # for now ignore missing crons, still looking into why this is happening
|
if !!user.lastCron # for now ignore missing crons, still looking into why this is happening
|
||||||
lastCron = new Date(user.priv.lastCron)
|
lastCron = new Date(user.lastCron)
|
||||||
diff = Math.abs(moment(today).sod().diff(moment(lastCron).sod(), "days"))
|
diff = Math.abs(moment(today).sod().diff(moment(lastCron).sod(), "days"))
|
||||||
if diff > 10
|
if diff > 10
|
||||||
removeAccount(collection, user._id)
|
removeAccount(collection, user._id)
|
||||||
|
|||||||
@@ -35,8 +35,8 @@ module.exports.app = (appExports, model) ->
|
|||||||
appExports.buyReroll = (e, el, next) ->
|
appExports.buyReroll = (e, el, next) ->
|
||||||
batch = new schema.BatchUpdate(model)
|
batch = new schema.BatchUpdate(model)
|
||||||
obj = model.get('_user')
|
obj = model.get('_user')
|
||||||
batch.set 'priv.balance', obj.priv.balance-1
|
batch.set 'balance', obj.balance-1
|
||||||
_.each obj.priv.tasks, (task) -> batch.set("priv.tasks.#{task.id}.value", 0) unless task.type == 'reward'
|
_.each obj.tasks, (task) -> batch.set("tasks.#{task.id}.value", 0) unless task.type == 'reward'
|
||||||
batch.commit()
|
batch.commit()
|
||||||
|
|
||||||
module.exports.routes = (expressApp) ->
|
module.exports.routes = (expressApp) ->
|
||||||
@@ -53,8 +53,8 @@ module.exports.routes = (expressApp) ->
|
|||||||
userId = model.session.userId
|
userId = model.session.userId
|
||||||
model.fetch "users.#{userId}", (err, user) ->
|
model.fetch "users.#{userId}", (err, user) ->
|
||||||
model.ref '_user', "users.#{userId}"
|
model.ref '_user', "users.#{userId}"
|
||||||
model.set('_user.priv.balance', model.get('_user.priv.balance')+5)
|
model.set('_user.balance', model.get('_user.balance')+5)
|
||||||
model.set('_user.priv.flags.ads','hide')
|
model.set('_user.flags.ads','hide')
|
||||||
return res.send(200)
|
return res.send(200)
|
||||||
|
|
||||||
api_key = process.env.STRIPE_API_KEY # secret stripe API key
|
api_key = process.env.STRIPE_API_KEY # secret stripe API key
|
||||||
|
|||||||
@@ -49,8 +49,8 @@ module.exports = (expressApp, root, derby) ->
|
|||||||
|
|
||||||
# Create task if doesn't exist
|
# Create task if doesn't exist
|
||||||
# TODO add service & icon to task
|
# TODO add service & icon to task
|
||||||
unless model.get("_user.priv.tasks.#{taskId}")
|
unless model.get("_user.tasks.#{taskId}")
|
||||||
model.refList "_habitList", "_user.priv.tasks", "_user.priv.idLists.habit"
|
model.refList "_habitList", "_user.tasks", "_user.idLists.habit"
|
||||||
model.at('_habitList').push {
|
model.at('_habitList').push {
|
||||||
id: taskId
|
id: taskId
|
||||||
type: 'habit'
|
type: 'habit'
|
||||||
|
|||||||
@@ -14,28 +14,28 @@
|
|||||||
<pre class=prettyprint>{_user.id}</pre>
|
<pre class=prettyprint>{_user.id}</pre>
|
||||||
|
|
||||||
<h6>API Token</h6>
|
<h6>API Token</h6>
|
||||||
<pre class=prettyprint>{_user.priv.apiToken}</pre>
|
<pre class=prettyprint>{_user.apiToken}</pre>
|
||||||
|
|
||||||
<hr/>
|
<hr/>
|
||||||
<h4>Gender</h4>
|
<h4>Gender</h4>
|
||||||
<label class="radio">
|
<label class="radio">
|
||||||
<input type="radio" name="genderRadios" value="m" x-bind="click:setMale" checked="{equal(_user.pub.preferences.gender,'m')}">
|
<input type="radio" name="genderRadios" value="m" x-bind="click:setMale" checked="{equal(_user.preferences.gender,'m')}">
|
||||||
Male
|
Male
|
||||||
</label>
|
</label>
|
||||||
<label class="radio">
|
<label class="radio">
|
||||||
<input type="radio" name="genderRadios" value="f" x-bind="click:setFemale" checked="{equal(_user.pub.preferences.gender,'f')}">
|
<input type="radio" name="genderRadios" value="f" x-bind="click:setFemale" checked="{equal(_user.preferences.gender,'f')}">
|
||||||
Female
|
Female
|
||||||
</label>
|
</label>
|
||||||
|
|
||||||
|
|
||||||
{#if equal(_user.pub.preferences.gender,'f')}
|
{#if equal(_user.preferences.gender,'f')}
|
||||||
<h4>Armor Set</h4>
|
<h4>Armor Set</h4>
|
||||||
<label class="radio">
|
<label class="radio">
|
||||||
<input type="radio" name="armorSet" value="v1" x-bind="click:setArmorsetV1" checked="{equal(_user.pub.preferences.armorSet,'v1')}">
|
<input type="radio" name="armorSet" value="v1" x-bind="click:setArmorsetV1" checked="{equal(_user.preferences.armorSet,'v1')}">
|
||||||
v1
|
v1
|
||||||
</label>
|
</label>
|
||||||
<label class="radio">
|
<label class="radio">
|
||||||
<input type="radio" name="armorSet" value="v2" x-bind="click:setArmorsetV2" checked="{equal(_user.pub.preferences.armorSet,'v2')}">
|
<input type="radio" name="armorSet" value="v2" x-bind="click:setArmorsetV2" checked="{equal(_user.preferences.armorSet,'v2')}">
|
||||||
v2
|
v2
|
||||||
</label>
|
</label>
|
||||||
{/}
|
{/}
|
||||||
@@ -79,7 +79,7 @@
|
|||||||
</app:myModal>
|
</app:myModal>
|
||||||
{/}
|
{/}
|
||||||
<!-- Game Over Modal -->
|
<!-- Game Over Modal -->
|
||||||
<div style="{#unless equal(_user.pub.stats.lvl,0)}display:none;{/}">
|
<div style="{#unless equal(_user.stats.lvl,0)}display:none;{/}">
|
||||||
<app:myModal noDismiss=true modalId='dead-modal'>
|
<app:myModal noDismiss=true modalId='dead-modal'>
|
||||||
<table>
|
<table>
|
||||||
<tr>
|
<tr>
|
||||||
@@ -100,7 +100,7 @@
|
|||||||
<app:userTokens/>
|
<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>
|
<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>
|
<@footer>
|
||||||
{#if lessThan(_user.priv.balance,1)}
|
{#if lessThan(_user.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>
|
<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}
|
{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>
|
<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>
|
</ul>
|
||||||
{/}
|
{/}
|
||||||
|
|
||||||
{#if equal(_user.priv.flags.kickstarter,'show')}
|
{#if equal(_user.flags.kickstarter,'show')}
|
||||||
<div class='alert alert-success'>
|
<div class='alert alert-success'>
|
||||||
<a x-bind="click:closeKickstarterNofitication" class='pull-right'>Dismiss</a>
|
<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>.
|
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 -->
|
<!-- Avatar -->
|
||||||
<td class="avatar main-avatar">
|
<td class="avatar main-avatar">
|
||||||
<div class='avatar-sprites'>
|
<div class='avatar-sprites'>
|
||||||
<img class='weapon weapon-{_user.pub.items.weapon}' src="/img/BrowserQuest/habitrpg_mods/weapon{_user.pub.items.weapon}.png" />
|
<img class='weapon weapon-{_user.items.weapon}' src="/img/BrowserQuest/habitrpg_mods/weapon{_user.items.weapon}.png" />
|
||||||
<img class='armor armor-{_user.pub.items.armor}' src="/img/BrowserQuest/habitrpg_mods/{currentArmor(_user)}" />
|
<img class='armor armor-{_user.items.armor}' src="/img/BrowserQuest/habitrpg_mods/{currentArmor(_user)}" />
|
||||||
</div>
|
</div>
|
||||||
<div id="lvl"><span class="badge badge-info">Lvl {_user.pub.stats.lvl}</span></div>
|
<div id="lvl"><span class="badge badge-info">Lvl {_user.stats.lvl}</span></div>
|
||||||
</td>
|
</td>
|
||||||
|
|
||||||
<!-- Progress Bars -->
|
<!-- Progress Bars -->
|
||||||
<td id="bars" style="width:{#if _party}70%{else}90%{/};">
|
<td id="bars" style="width:{#if _party}70%{else}90%{/};">
|
||||||
<div class="progress progress-danger" rel=tooltip data-placement=bottom title="Health">
|
<div class="progress progress-danger" rel=tooltip data-placement=bottom title="Health">
|
||||||
<div class="bar" style="width: {percent(_user.pub.stats.hp, 50)}%;"></div>
|
<div class="bar" style="width: {percent(_user.stats.hp, 50)}%;"></div>
|
||||||
<span class="progress-text"><i class=icon-heart></i> {round(_user.pub.stats.hp)} / 50</span>
|
<span class="progress-text"><i class=icon-heart></i> {round(_user.stats.hp)} / 50</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="progress progress-warning" rel=tooltip data-placement=bottom title="Experience">
|
<div class="progress progress-warning" rel=tooltip data-placement=bottom title="Experience">
|
||||||
<div class="bar" style="width: {percent(_user.pub.stats.exp,_tnl)}%;"></div>
|
<div class="bar" style="width: {percent(_user.stats.exp,_tnl)}%;"></div>
|
||||||
<span class="progress-text">
|
<span class="progress-text">
|
||||||
{#if _user.history.exp}
|
{#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>
|
<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>
|
||||||
{/}
|
{/}
|
||||||
<i class=icon-star></i> {round(_user.pub.stats.exp)} / {_tnl}
|
<i class=icon-star></i> {round(_user.stats.exp)} / {_tnl}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
|
|
||||||
<!-- Party -->
|
<!-- Party -->
|
||||||
{#if _user.priv.flags.partyEnabled}
|
{#if _user.flags.partyEnabled}
|
||||||
{#each _party as :member}
|
{#each _party as :member}
|
||||||
<td class="avatar party-avatar" rel="tooltip" title="{username(:member.auth)}" data-placement="bottom" >
|
<td class="avatar party-avatar" rel="tooltip" title="{username(:member.auth)}" data-placement="bottom" >
|
||||||
<div class='avatar-sprites'>
|
<div class='avatar-sprites'>
|
||||||
<img class='weapon weapon-{:member.pub.items.weapon}' src="/img/BrowserQuest/habitrpg_mods/weapon{:member.pub.items.weapon}.png" />
|
<img class='weapon weapon-{:member.items.weapon}' src="/img/BrowserQuest/habitrpg_mods/weapon{:member.items.weapon}.png" />
|
||||||
<img class='armor armor-{:member.pub.items.armor}' src="/img/BrowserQuest/habitrpg_mods/{currentArmor(:member)}" />
|
<img class='armor armor-{:member.items.armor}' src="/img/BrowserQuest/habitrpg_mods/{currentArmor(:member)}" />
|
||||||
</div>
|
</div>
|
||||||
<div id="lvl"><span class="badge badge-info">Lvl {:member.pub.stats.lvl}</span></div>
|
<div id="lvl"><span class="badge badge-info">Lvl {:member.stats.lvl}</span></div>
|
||||||
</td>
|
</td>
|
||||||
{/}
|
{/}
|
||||||
<td><a class="btn" id="add-party-button" data-target="#add-party-modal" data-toggle="modal"><i class="icon-user"></i></a></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 -->
|
<!--Title -->
|
||||||
<div class="row-fluid">
|
<div class="row-fluid">
|
||||||
<div class="span6"><h2>Rewards</h2></div>
|
<div class="span6"><h2>Rewards</h2></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 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>
|
</div>
|
||||||
|
|
||||||
<!-- Content -->
|
<!-- Content -->
|
||||||
@@ -289,7 +289,7 @@
|
|||||||
{#each _rewardList as :task}<app:task />{/}
|
{#each _rewardList as :task}<app:task />{/}
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
{#if _user.priv.flags.itemsEnabled}
|
{#if _user.flags.itemsEnabled}
|
||||||
<ul class='items'>
|
<ul class='items'>
|
||||||
{#with _view.items.armor as :item}<app:item />{/}
|
{#with _view.items.armor as :item}<app:item />{/}
|
||||||
{#with _view.items.weapon as :item}<app:item />{/}
|
{#with _view.items.weapon as :item}<app:item />{/}
|
||||||
@@ -346,12 +346,12 @@
|
|||||||
<userTokens:>
|
<userTokens:>
|
||||||
<div class="pull-right">
|
<div class="pull-right">
|
||||||
<div class="input-append">
|
<div class="input-append">
|
||||||
<span class="uneditable-input" style="width:auto;">{tokens(_user.priv.balance)}</span>
|
<span class="uneditable-input" style="width:auto;">{tokens(_user.balance)}</span>
|
||||||
<span class="add-on">Tokens</span>
|
<span class="add-on">Tokens</span>
|
||||||
</div>
|
</div>
|
||||||
<a class="label" data-toggle="modal" href='#reset-modal'><i class="icon-ban-circle"></i>Reset</a>
|
<a class="label" data-toggle="modal" href='#reset-modal'><i class="icon-ban-circle"></i>Reset</a>
|
||||||
</div>
|
</div>
|
||||||
<!--<span class="well pull-right">Tokens: {tokens(_user.priv.balance)}</span>-->
|
<!--<span class="well pull-right">Tokens: {tokens(_user.balance)}</span>-->
|
||||||
|
|
||||||
<newTask: nonvoid>
|
<newTask: nonvoid>
|
||||||
<form class="form-inline new-task-form" id=new-{{@type}} data-task-type={{@type}} x-bind=submit:addTask>
|
<form class="form-inline new-task-form" id=new-{{@type}} data-task-type={{@type}} x-bind=submit:addTask>
|
||||||
|
|||||||
Reference in New Issue
Block a user