2012-06-20 22:15:38 +00:00
|
|
|
derby = require('derby')
|
|
|
|
|
{get, view, ready} = derby.createApp module
|
|
|
|
|
derby.use require('derby-ui-boot')
|
2012-06-21 00:47:08 +00:00
|
|
|
derby.use(require('../../ui'))
|
2012-07-08 02:29:34 +00:00
|
|
|
content = require('./content')
|
2012-07-21 01:39:29 +00:00
|
|
|
score = require('./score')
|
2012-04-27 02:19:31 +00:00
|
|
|
|
2012-06-10 00:15:33 +00:00
|
|
|
## VIEW HELPERS ##
|
2012-07-27 23:38:28 +00:00
|
|
|
|
|
|
|
|
view.fn 'taskClasses', (type, completed, value) ->
|
2012-06-27 13:37:36 +00:00
|
|
|
#TODO figure out how to just pass in the task model, so i can access all these properties from one object
|
2012-06-20 21:13:47 +00:00
|
|
|
classes = type
|
2012-06-26 12:45:35 +00:00
|
|
|
classes += " completed" if completed
|
2012-06-27 13:37:36 +00:00
|
|
|
|
2012-06-26 12:02:16 +00:00
|
|
|
switch
|
2012-06-26 15:02:29 +00:00
|
|
|
when value<-8 then classes += ' color-worst'
|
|
|
|
|
when value>=-8 and value<-5 then classes += ' color-worse'
|
|
|
|
|
when value>=-5 and value<-1 then classes += ' color-bad'
|
|
|
|
|
when value>=-1 and value<1 then classes += ' color-neutral'
|
|
|
|
|
when value>=1 and value<5 then classes += ' color-good'
|
|
|
|
|
when value>=5 and value<10 then classes += ' color-better'
|
|
|
|
|
when value>=10 then classes += ' color-best'
|
2012-06-10 00:15:33 +00:00
|
|
|
return classes
|
2012-06-20 21:30:10 +00:00
|
|
|
|
2012-06-20 22:34:15 +00:00
|
|
|
view.fn "percent", (x, y) ->
|
|
|
|
|
x=1 if x==0
|
|
|
|
|
Math.round(x/y*100)
|
|
|
|
|
|
2012-06-20 21:30:10 +00:00
|
|
|
view.fn "round", (num) ->
|
|
|
|
|
Math.round num
|
|
|
|
|
|
|
|
|
|
view.fn "gold", (num) ->
|
2012-07-08 22:58:11 +00:00
|
|
|
if num
|
|
|
|
|
return num.toFixed(1).split('.')[0]
|
|
|
|
|
else
|
|
|
|
|
return "0"
|
2012-06-20 21:30:10 +00:00
|
|
|
|
|
|
|
|
view.fn "silver", (num) ->
|
2012-07-08 22:58:11 +00:00
|
|
|
if num
|
|
|
|
|
num.toFixed(1).split('.')[1]
|
|
|
|
|
else
|
|
|
|
|
return "0"
|
2012-07-08 20:59:07 +00:00
|
|
|
|
|
|
|
|
## ROUTES ##
|
|
|
|
|
|
2012-07-19 18:48:49 +00:00
|
|
|
get '/:uidParam?', (page, model, {uidParam}) ->
|
|
|
|
|
|
|
|
|
|
model.fetch 'users', (err, users) ->
|
2012-07-17 19:55:36 +00:00
|
|
|
|
2012-07-17 22:10:17 +00:00
|
|
|
# Previously saved session (eg, http://localhost/{guid}) (temporary solution until authentication built)
|
2012-07-19 18:48:49 +00:00
|
|
|
if uidParam? and users.get(uidParam)
|
|
|
|
|
model.set '_userId', uidParam # set for this request
|
|
|
|
|
model.session.userId = uidParam # and for next requests
|
|
|
|
|
|
2012-07-17 19:55:36 +00:00
|
|
|
# Current browser session
|
2012-07-17 18:47:19 +00:00
|
|
|
# The session middleware will assign a _userId automatically
|
2012-07-17 19:55:36 +00:00
|
|
|
userId = model.get '_userId'
|
2012-07-19 18:48:49 +00:00
|
|
|
user = users.get(userId)
|
|
|
|
|
|
|
|
|
|
# Else, select a new userId and initialize user
|
|
|
|
|
unless user?
|
2012-07-17 18:47:19 +00:00
|
|
|
newUser = {
|
2012-07-17 19:33:08 +00:00
|
|
|
stats: { money: 0, exp: 0, lvl: 1, hp: 50 }
|
|
|
|
|
items: { itemsEnabled: false, armor: 0, weapon: 0 }
|
2012-07-27 23:38:28 +00:00
|
|
|
tasks: {}, habitIds: [], dailyIds: [], todoIds: [], completedIds: [], rewardIds: []
|
2012-07-17 18:47:19 +00:00
|
|
|
}
|
2012-07-17 19:45:05 +00:00
|
|
|
for task in content.defaultTasks
|
2012-07-21 01:45:53 +00:00
|
|
|
guid = task.id = require('derby/node_modules/racer').uuid()
|
2012-07-17 19:45:05 +00:00
|
|
|
newUser.tasks[guid] = task
|
|
|
|
|
switch task.type
|
|
|
|
|
when 'habit' then newUser.habitIds.push guid
|
|
|
|
|
when 'daily' then newUser.dailyIds.push guid
|
|
|
|
|
when 'todo' then newUser.todoIds.push guid
|
|
|
|
|
when 'reward' then newUser.rewardIds.push guid
|
2012-07-18 12:59:29 +00:00
|
|
|
users.set userId, newUser
|
2012-07-19 18:48:49 +00:00
|
|
|
|
2012-07-21 01:39:29 +00:00
|
|
|
# #TODO these *Access functions aren't being called, why?
|
|
|
|
|
# model.store.accessControl = true
|
|
|
|
|
# model.store.readPathAccess 'users.*', (id, accept) ->
|
|
|
|
|
# console.log "model.writeAccess called with id:#{id}" # never called
|
|
|
|
|
# accept(id == userId)
|
|
|
|
|
# model.store.writeAccess '*', 'users.*', (id, accept) ->
|
|
|
|
|
# console.log "model.writeAccess called with id:#{id}" # never called
|
|
|
|
|
# accept(id == userId)
|
2012-07-19 18:48:49 +00:00
|
|
|
|
|
|
|
|
getHabits(page, model, userId)
|
|
|
|
|
|
|
|
|
|
getHabits = (page, model, userId) ->
|
2012-07-08 20:59:07 +00:00
|
|
|
|
2012-07-19 18:48:49 +00:00
|
|
|
model.subscribe "users.#{userId}", (err, user) ->
|
2012-07-19 18:52:03 +00:00
|
|
|
|
|
|
|
|
console.log userId, 'userId' # = 26c48325-2fea-4e2e-a60f-a5fa28d7b410
|
|
|
|
|
console.log err, 'err' # = Unauthorized: No access control declared for path users.26c48325-2fea-4e2e-a60f-a5fa28d7b410 ???
|
2012-07-19 18:48:49 +00:00
|
|
|
|
2012-07-08 20:59:07 +00:00
|
|
|
model.ref '_user', user
|
|
|
|
|
|
2012-07-17 19:33:08 +00:00
|
|
|
# Store
|
2012-07-09 01:20:30 +00:00
|
|
|
model.set '_items'
|
|
|
|
|
armor: content.items.armor[parseInt(user.get('items.armor')) + 1]
|
|
|
|
|
weapon: content.items.weapon[parseInt(user.get('items.weapon')) + 1]
|
|
|
|
|
potion: content.items.potion
|
|
|
|
|
reroll: content.items.reroll
|
2012-07-08 23:37:36 +00:00
|
|
|
|
2012-07-08 20:59:07 +00:00
|
|
|
# http://tibia.wikia.com/wiki/Formula
|
2012-07-21 01:39:29 +00:00
|
|
|
model.fn '_user._tnl', '_user.stats.lvl', (lvl) -> 50 * Math.pow(lvl, 2) - 150 * lvl + 200
|
2012-07-08 20:59:07 +00:00
|
|
|
|
|
|
|
|
# Default Tasks
|
|
|
|
|
model.refList "_habitList", "_user.tasks", "_user.habitIds"
|
|
|
|
|
model.refList "_dailyList", "_user.tasks", "_user.dailyIds"
|
|
|
|
|
model.refList "_todoList", "_user.tasks", "_user.todoIds"
|
2012-07-27 23:38:28 +00:00
|
|
|
model.refList "_completedList", "_user.tasks", "_user.completedIds"
|
2012-07-08 20:59:07 +00:00
|
|
|
model.refList "_rewardList", "_user.tasks", "_user.rewardIds"
|
|
|
|
|
|
|
|
|
|
page.render()
|
2012-04-27 02:19:31 +00:00
|
|
|
|
|
|
|
|
## CONTROLLER FUNCTIONS ##
|
|
|
|
|
|
|
|
|
|
ready (model) ->
|
2012-07-08 03:43:35 +00:00
|
|
|
|
2012-07-17 19:55:36 +00:00
|
|
|
model.set '_purl', window.location.origin + '/' + model.get('_userId')
|
2012-07-11 23:27:53 +00:00
|
|
|
|
2012-07-09 01:51:25 +00:00
|
|
|
$('[rel=popover]').popover()
|
|
|
|
|
#TODO: this isn't very efficient, do model.on set for specific attrs for popover
|
|
|
|
|
model.on 'set', '*', ->
|
|
|
|
|
$('[rel=popover]').popover()
|
2012-06-27 13:37:36 +00:00
|
|
|
|
2012-07-07 04:07:30 +00:00
|
|
|
# Make the lists draggable using jQuery UI
|
|
|
|
|
# Note, have to setup helper function here and call it for each type later
|
|
|
|
|
# due to variable binding of "type"
|
|
|
|
|
setupSortable = (type) ->
|
|
|
|
|
$("ul.#{type}s").sortable
|
2012-06-26 15:44:37 +00:00
|
|
|
dropOnEmpty: false
|
|
|
|
|
cursor: "move"
|
|
|
|
|
items: "li"
|
|
|
|
|
opacity: 0.4
|
|
|
|
|
scroll: true
|
2012-05-03 01:07:36 +00:00
|
|
|
axis: 'y'
|
|
|
|
|
update: (e, ui) ->
|
|
|
|
|
item = ui.item[0]
|
|
|
|
|
domId = item.id
|
|
|
|
|
id = item.getAttribute 'data-id'
|
2012-07-07 04:07:30 +00:00
|
|
|
to = $("ul.#{type}s").children().index(item)
|
2012-05-03 01:07:36 +00:00
|
|
|
# Use the Derby ignore option to suppress the normal move event
|
|
|
|
|
# binding, since jQuery UI will move the element in the DOM.
|
|
|
|
|
# Also, note that refList index arguments can either be an index
|
|
|
|
|
# or the item's id property
|
2012-07-07 04:07:30 +00:00
|
|
|
model.at("_#{type}List").pass(ignore: domId).move {id}, to
|
|
|
|
|
setupSortable(type) for type in ['habit', 'daily', 'todo', 'reward']
|
2012-07-07 16:31:51 +00:00
|
|
|
|
|
|
|
|
tour = new Tour()
|
2012-07-08 02:34:34 +00:00
|
|
|
for step in content.tourSteps
|
|
|
|
|
tour.addStep
|
|
|
|
|
element: step.element
|
|
|
|
|
title: step.title
|
|
|
|
|
content: step.content
|
|
|
|
|
placement: step.placement
|
2012-07-07 16:31:51 +00:00
|
|
|
tour.start()
|
2012-06-26 15:34:45 +00:00
|
|
|
|
|
|
|
|
#TODO: implement this for completed tab
|
|
|
|
|
# clearCompleted: ->
|
|
|
|
|
# _.each @options.habits.doneTodos(), (todo) ->
|
|
|
|
|
# todo.destroy()
|
|
|
|
|
# @render()
|
|
|
|
|
# return false
|
2012-06-26 15:31:58 +00:00
|
|
|
|
2012-07-28 00:35:05 +00:00
|
|
|
model.on 'set', '_user.tasks.*.completed', (i, completed, previous, isLocal) ->
|
|
|
|
|
|
|
|
|
|
[from, to, shouldTransfer, direction] = [null, null, false, null]
|
|
|
|
|
if completed==true and previous==false and isLocal
|
|
|
|
|
[from, to, shouldTransfer, direction] = ['_todoList', '_completedList', true, 'up']
|
|
|
|
|
else if completed==false and previous==true and isLocal
|
|
|
|
|
[from, to, shouldTransfer, direction] = ['_completedList', '_todoList', true, 'down']
|
|
|
|
|
if shouldTransfer
|
|
|
|
|
task = model.at("_user.tasks.#{i}")
|
|
|
|
|
# Score the user based on todo task
|
|
|
|
|
score({user:model.at('_user'), task:task, direction:direction})
|
|
|
|
|
# Then move the task to/from _todoList/_completedList
|
|
|
|
|
ids = _.map model.get(from), (obj) ->
|
|
|
|
|
obj.id
|
|
|
|
|
index = ids.indexOf(i)
|
|
|
|
|
model.push to, task.get(), () ->
|
|
|
|
|
model.remove from, index
|
|
|
|
|
|
2012-06-09 18:25:10 +00:00
|
|
|
exports.addTask = (e, el, next) ->
|
|
|
|
|
type = $(el).attr('data-task-type')
|
|
|
|
|
list = model.at "_#{type}List"
|
|
|
|
|
newModel = model.at('_new' + type.charAt(0).toUpperCase() + type.slice(1))
|
2012-04-27 17:04:44 +00:00
|
|
|
# Don't add a blank todo
|
2012-06-09 18:25:10 +00:00
|
|
|
return unless text = view.escapeHtml newModel.get()
|
|
|
|
|
newModel.set ''
|
|
|
|
|
switch type
|
2012-06-20 21:43:23 +00:00
|
|
|
|
2012-06-09 18:25:10 +00:00
|
|
|
when 'habit'
|
2012-06-26 15:02:29 +00:00
|
|
|
list.push {type: type, text: text, notes: '', value: 0, up: true, down: true}
|
2012-06-20 21:43:23 +00:00
|
|
|
|
2012-06-09 18:25:10 +00:00
|
|
|
when 'reward'
|
2012-06-26 15:02:29 +00:00
|
|
|
list.push {type: type, text: text, notes: '', value: 20 }
|
2012-06-20 21:43:23 +00:00
|
|
|
|
2012-06-09 18:25:10 +00:00
|
|
|
when 'daily', 'todo'
|
2012-06-26 15:02:29 +00:00
|
|
|
list.push {type: type, text: text, notes: '', value: 0, completed: false }
|
2012-06-25 22:26:12 +00:00
|
|
|
|
|
|
|
|
# list.on 'set', '*.completed', (i, completed, previous, isLocal) ->
|
|
|
|
|
# # Move the item to the bottom if it was checked off
|
|
|
|
|
# list.move i, -1 if completed && isLocal
|
2012-04-27 17:04:44 +00:00
|
|
|
|
2012-07-07 02:09:51 +00:00
|
|
|
exports.del = (e, el) ->
|
2012-04-27 17:04:44 +00:00
|
|
|
# Derby extends model.at to support creation from DOM nodes
|
2012-07-07 02:09:51 +00:00
|
|
|
task = model.at(e.target)
|
|
|
|
|
#TODO bug where I have to delete from _users.tasks AND _{type}List,
|
|
|
|
|
# fix when query subscriptions implemented properly
|
2012-07-08 22:58:11 +00:00
|
|
|
model.del('_user.tasks.'+task.get('id'))
|
|
|
|
|
task.remove()
|
2012-06-25 01:51:13 +00:00
|
|
|
|
2012-06-29 13:45:50 +00:00
|
|
|
exports.toggleTaskEdit = (e, el) ->
|
2012-07-17 20:35:26 +00:00
|
|
|
hideId = $(el).attr('data-hide-id')
|
|
|
|
|
toggleId = $(el).attr('data-toggle-id')
|
|
|
|
|
$(document.getElementById(hideId)).hide()
|
|
|
|
|
$(document.getElementById(toggleId)).toggle()
|
2012-06-29 08:33:09 +00:00
|
|
|
|
2012-07-07 02:46:22 +00:00
|
|
|
exports.toggleChart = (e, el) ->
|
2012-07-17 20:35:26 +00:00
|
|
|
hideSelector = $(el).attr('data-hide-id')
|
|
|
|
|
chartSelector = $(el).attr('data-toggle-id')
|
2012-07-07 02:46:22 +00:00
|
|
|
historyPath = $(el).attr('data-history-path')
|
|
|
|
|
$(document.getElementById(hideSelector)).hide()
|
|
|
|
|
$(document.getElementById(chartSelector)).toggle()
|
2012-06-29 08:33:09 +00:00
|
|
|
|
|
|
|
|
matrix = [['Date', 'Score']]
|
2012-07-07 02:46:22 +00:00
|
|
|
for obj in model.get(historyPath)
|
2012-06-29 08:51:50 +00:00
|
|
|
date = new Date(obj.date)
|
2012-07-11 19:38:01 +00:00
|
|
|
readableDate = date.toISOString() #use toDateString() when done debugging
|
2012-06-29 08:51:50 +00:00
|
|
|
matrix.push [ readableDate, obj.value ]
|
2012-06-29 08:33:09 +00:00
|
|
|
data = google.visualization.arrayToDataTable matrix
|
2012-06-29 08:44:52 +00:00
|
|
|
|
2012-06-29 08:33:09 +00:00
|
|
|
options = {
|
|
|
|
|
title: 'History'
|
2012-06-29 08:44:52 +00:00
|
|
|
#TODO use current background color: $(el).css('background-color), but convert to hex (see http://goo.gl/ql5pR)
|
|
|
|
|
backgroundColor: 'whiteSmoke'
|
2012-06-29 08:33:09 +00:00
|
|
|
}
|
|
|
|
|
|
2012-07-07 02:46:22 +00:00
|
|
|
chart = new google.visualization.LineChart(document.getElementById( chartSelector ))
|
2012-06-29 08:33:09 +00:00
|
|
|
chart.draw(data, options)
|
2012-06-29 13:45:50 +00:00
|
|
|
|
2012-07-08 22:58:11 +00:00
|
|
|
exports.buyItem = (e, el, next) ->
|
|
|
|
|
user = model.at '_user'
|
2012-07-09 01:20:30 +00:00
|
|
|
#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)
|
|
|
|
|
|
2012-07-08 22:58:11 +00:00
|
|
|
money = user.get 'stats.money'
|
2012-07-09 01:20:30 +00:00
|
|
|
[type, value, index] = [ $(el).attr('data-type'), $(el).attr('data-value'), $(el).attr('data-index') ]
|
2012-07-08 22:58:11 +00:00
|
|
|
|
2012-07-09 01:20:30 +00:00
|
|
|
return if money < value
|
2012-07-08 22:58:11 +00:00
|
|
|
user.set 'stats.money', money - value
|
|
|
|
|
if type == 'armor'
|
2012-07-09 01:20:30 +00:00
|
|
|
user.set 'items.armor', index
|
|
|
|
|
model.set '_items.armor', content.items.armor[parseInt(index) + 1]
|
2012-07-08 22:58:11 +00:00
|
|
|
else if type == 'weapon'
|
2012-07-09 01:20:30 +00:00
|
|
|
user.set 'items.weapon', index
|
|
|
|
|
model.set '_items.weapon', content.items.weapon[parseInt(index) + 1]
|
2012-07-08 22:58:11 +00:00
|
|
|
else if type == 'potion'
|
|
|
|
|
hp = user.get 'stats.hp'
|
|
|
|
|
hp += 15
|
|
|
|
|
hp = 50 if hp > 50
|
|
|
|
|
user.set 'stats.hp', hp
|
|
|
|
|
else if type == 'reroll'
|
2012-07-09 01:35:32 +00:00
|
|
|
for taskId of user.get('tasks')
|
|
|
|
|
task = model.at('_user.tasks.'+taskId)
|
|
|
|
|
task.set('value', 0) unless task.get('type')=='reward'
|
2012-07-09 02:23:57 +00:00
|
|
|
|
|
|
|
|
|
2012-06-20 20:40:59 +00:00
|
|
|
exports.vote = (e, el, next) ->
|
2012-06-10 00:41:21 +00:00
|
|
|
direction = $(el).attr('data-direction')
|
2012-06-26 14:55:24 +00:00
|
|
|
direction = 'up' if direction == 'true/'
|
|
|
|
|
direction = 'down' if direction == 'false/'
|
2012-07-21 01:39:29 +00:00
|
|
|
user = model.at('_user')
|
2012-06-20 20:40:59 +00:00
|
|
|
task = model.at $(el).parents('li')[0]
|
2012-07-21 01:39:29 +00:00
|
|
|
|
2012-07-28 00:35:05 +00:00
|
|
|
score({user:user, task:task, direction:direction})
|
2012-06-28 22:11:13 +00:00
|
|
|
|
2012-07-09 02:23:57 +00:00
|
|
|
# Note: Set 12am daily cron for this
|
|
|
|
|
# At end of day, add value to all incomplete Daily & Todo tasks (further incentive)
|
|
|
|
|
# For incomplete Dailys, deduct experience
|
|
|
|
|
#TODO: remove from exports when cron implemented
|
|
|
|
|
exports.endOfDayTally = endOfDayTally = (e, el) ->
|
|
|
|
|
# users = model.at('users') #TODO this isn't working, iterate over all users
|
|
|
|
|
# for user in users
|
|
|
|
|
user = model.at '_user'
|
|
|
|
|
todoTally = 0
|
|
|
|
|
for key of model.get '_user.tasks'
|
|
|
|
|
task = model.at "_user.tasks.#{key}"
|
|
|
|
|
[type, value, completed] = [task.get('type'), task.get('value'), task.get('completed')]
|
2012-07-21 01:39:29 +00:00
|
|
|
if type in ['todo', 'daily']
|
|
|
|
|
# Deduct experience for missed Daily tasks,
|
|
|
|
|
# but not for Todos (just increase todo's value)
|
2012-07-28 00:35:05 +00:00
|
|
|
score({user:user, task:task, direction:'down', cron:true}) unless completed
|
2012-07-09 02:23:57 +00:00
|
|
|
if type == 'daily'
|
|
|
|
|
task.push "history", { date: new Date(), value: value }
|
|
|
|
|
else
|
|
|
|
|
absVal = if (completed) then Math.abs(value) else value
|
|
|
|
|
todoTally += absVal
|
|
|
|
|
task.set('completed', false) if type == 'daily'
|
|
|
|
|
model.push '_user.history.todos', { date: new Date(), value: todoTally }
|
|
|
|
|
|
|
|
|
|
# tally experience
|
|
|
|
|
expTally = user.get 'stats.exp'
|
|
|
|
|
lvl = 0 #iterator
|
2012-07-16 23:01:18 +00:00
|
|
|
while lvl < (user.get('stats.lvl')-1)
|
2012-07-09 02:23:57 +00:00
|
|
|
lvl++
|
|
|
|
|
expTally += 50 * Math.pow(lvl, 2) - 150 * lvl + 200
|
|
|
|
|
model.push '_user.history.exp', { date: new Date(), value: expTally }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#TODO: remove when cron implemented
|
2012-07-11 19:58:17 +00:00
|
|
|
exports.poormanscron = poormanscron = ->
|
2012-07-11 19:24:23 +00:00
|
|
|
model.setNull('_user.lastCron', new Date())
|
2012-07-13 14:43:53 +00:00
|
|
|
lastCron = new Date( (new Date(model.get('_user.lastCron'))).toDateString() ) # calculate as midnight
|
|
|
|
|
today = new Date((new Date).toDateString()) # calculate as midnight
|
2012-07-11 19:26:27 +00:00
|
|
|
DAY = 1000 * 60 * 60 * 24
|
2012-07-11 18:37:47 +00:00
|
|
|
daysPassed = Math.floor((today.getTime() - lastCron.getTime()) / DAY)
|
2012-07-09 02:23:57 +00:00
|
|
|
if daysPassed > 0
|
2012-07-11 19:13:08 +00:00
|
|
|
model.set('_user.lastCron', today) # reset cron
|
2012-07-16 23:01:18 +00:00
|
|
|
for n in [1..daysPassed]
|
|
|
|
|
console.log {today: today, lastCron: lastCron, daysPassed: daysPassed, n:n}, "[debug] Cron (#{today}, #{n})"
|
|
|
|
|
endOfDayTally()
|
2012-07-11 14:17:47 +00:00
|
|
|
poormanscron() # Run once on refresh
|
|
|
|
|
setInterval (-> # Then run once every hour
|
|
|
|
|
poormanscron()
|
|
|
|
|
), 3600000
|
|
|
|
|
|
2012-07-09 03:29:54 +00:00
|
|
|
exports.revive = (e, el) ->
|
|
|
|
|
stats = model.at '_user.stats'
|
|
|
|
|
stats.set 'hp', 50; stats.set 'lvl', 1; stats.set 'exp', 0; stats.set 'money', 0
|
|
|
|
|
model.set '_user.items.armor', 0
|
|
|
|
|
model.set '_user.items.weapon', 0
|
|
|
|
|
model.set '_items.armor', content.items.armor[1]
|
|
|
|
|
model.set '_items.weapon', content.items.weapon[1]
|
|
|
|
|
|
2012-06-26 15:44:10 +00:00
|
|
|
## SHORTCUTS ##
|
2012-04-27 17:04:44 +00:00
|
|
|
|
|
|
|
|
exports.shortcuts = (e) ->
|
|
|
|
|
return unless e.metaKey || e.ctrlKey
|
|
|
|
|
code = e.which
|
|
|
|
|
return unless command = (switch code
|
|
|
|
|
when 66 then 'bold' # Bold: Ctrl/Cmd + B
|
|
|
|
|
when 73 then 'italic' # Italic: Ctrl/Cmd + I
|
|
|
|
|
when 32 then 'removeFormat' # Clear formatting: Ctrl/Cmd + Space
|
|
|
|
|
when 220 then 'removeFormat' # Clear formatting: Ctrl/Cmd + \
|
|
|
|
|
else null
|
|
|
|
|
)
|
|
|
|
|
document.execCommand command, false, null
|
|
|
|
|
e.preventDefault() if e.preventDefault
|
|
|
|
|
return false
|
|
|
|
|
|
|
|
|
|
# Tell Firefox to use elements for styles instead of CSS
|
|
|
|
|
# See: https://developer.mozilla.org/en/Rich-Text_Editing_in_Mozilla
|
|
|
|
|
document.execCommand 'useCSS', false, true
|
|
|
|
|
document.execCommand 'styleWithCSS', false, false
|