mirror of
https://github.com/codeninjasllc/codecombat.git
synced 2025-03-14 07:00:01 -04:00
Designing the Notify to show level progress
This commit is contained in:
parent
d766a24e11
commit
d8bb802468
8 changed files with 105 additions and 35 deletions
|
@ -5,6 +5,5 @@ module.exports = class Achievement extends CocoModel
|
|||
@schema: require 'schemas/models/achievement'
|
||||
urlRoot: '/db/achievement'
|
||||
|
||||
initialize: (id) ->
|
||||
super()
|
||||
@set('_id', id) if id?
|
||||
isRepeatable: ->
|
||||
@get('proportionalTo')?
|
|
@ -74,3 +74,17 @@ module.exports = class User extends CocoModel
|
|||
@set('emails', newSubs)
|
||||
|
||||
isEmailSubscriptionEnabled: (name) -> (@get('emails') or {})[name]?.enabled
|
||||
|
||||
a = 5
|
||||
b = 40
|
||||
|
||||
# y = a * ln(1/b * (x + b))
|
||||
@levelFromExp: (xp) ->
|
||||
if xp > 0 then Math.floor(a * Math.log((1/b) * (xp + b))) else 0
|
||||
|
||||
# x = (e^(y/a) - 1) * b
|
||||
@expForLevel: (level) ->
|
||||
Math.ceil((Math.exp(level / a) - 1) * b)
|
||||
|
||||
level: ->
|
||||
User.levelFromExp(@get('points'))
|
|
@ -1,19 +1,36 @@
|
|||
.notifyjs-achievement-base
|
||||
opacity: 0.85
|
||||
width: 200px
|
||||
width: 400px
|
||||
background: #F5F5F5
|
||||
padding: 5px
|
||||
padding: 40px 10px 0px 10px
|
||||
border-radius: 10px
|
||||
text-align: center
|
||||
|
||||
.achievement-title
|
||||
font-weight: bold
|
||||
.achievement-body
|
||||
|
||||
.achievement-image
|
||||
// pass
|
||||
.achievement-title
|
||||
font-family: Bangers
|
||||
font-size: 22px
|
||||
|
||||
.achievement-name
|
||||
// pass
|
||||
.achievement-image
|
||||
img
|
||||
float: left
|
||||
width: 100px
|
||||
height: 100px
|
||||
border-radius: 50%
|
||||
margin: 0px 30px 30px 30px
|
||||
|
||||
.achievement-description
|
||||
// pass
|
||||
.achievement-message
|
||||
&:empty
|
||||
display: none
|
||||
|
||||
|
||||
.achievement-progress
|
||||
padding: 10px 0px 0px 0px
|
||||
|
||||
.progress-wrapper
|
||||
.progress-bar-wrapper
|
||||
width: 100%
|
||||
.earned-exp
|
||||
font-family: Bangers
|
||||
float: right
|
|
@ -1,6 +1,12 @@
|
|||
div
|
||||
div.clearfix
|
||||
div.achievement-title(data-notify-html="title")
|
||||
div.clearfix.achievement-body
|
||||
div.achievement-image(data-notify-html="image")
|
||||
div.achievement-name(data-notify-html="name")
|
||||
div.achievement-description(data-notify-html="description")
|
||||
div.achievement-title(data-notify-html="title")
|
||||
div.achievement-description(data-notify-html="description")
|
||||
|
||||
div.achievement-progress
|
||||
div.achievement-message(data-notify-html="message")
|
||||
div.progress-wrapper
|
||||
div.progress-bar-wrapper(data-notify-html="progressBar")
|
||||
div.earned-exp(data-notify-html="earnedExp")
|
||||
|
||||
|
|
|
@ -16,6 +16,7 @@ module.exports = class AchievementEditView extends View
|
|||
|
||||
constructor: (options, @achievementID) ->
|
||||
super options
|
||||
console.log @achievementID
|
||||
@achievement = new Achievement(_id: @achievementID)
|
||||
@achievement.saveBackups = true
|
||||
|
||||
|
|
|
@ -8,6 +8,7 @@ locale = require 'locale/locale'
|
|||
|
||||
AchievementNotify = require '../../templates/achievement_notify'
|
||||
Achievement = require '../../models/Achievement'
|
||||
User = require '../../models/User'
|
||||
|
||||
filterKeyboardEvents = (allowedEvents, func) ->
|
||||
return (splat...) ->
|
||||
|
@ -26,32 +27,57 @@ module.exports = class RootView extends CocoView
|
|||
'achievements:new': 'handleNewAchievements'
|
||||
|
||||
initialize: ->
|
||||
$ ->
|
||||
$ =>
|
||||
$.notify.addStyle 'achievement',
|
||||
html: $(AchievementNotify())
|
||||
|
||||
test = new Achievement(_id:'537ce4855c91b8d1dda7fda8')
|
||||
test.fetch(success:@showNewAchievement)
|
||||
|
||||
showNewAchievement: (achievement) ->
|
||||
currentLevel = me.level()
|
||||
nextLevel = currentLevel + 1
|
||||
currentLevelExp = User.expForLevel(currentLevel)
|
||||
nextLevelExp = User.expForLevel(nextLevel)
|
||||
totalExpNeeded = nextLevelExp - currentLevelExp
|
||||
currentExp = me.get('points')
|
||||
worth = achievement.get('worth')
|
||||
alreadyAchievedPercentage = 100 * (currentExp - currentLevelExp - achievement.get('worth')) / totalExpNeeded
|
||||
newlyAchievedPercentage = 100 * achievement.get('worth') / totalExpNeeded
|
||||
|
||||
console.debug "Current level is #{currentLevel} (#{currentLevelExp} xp), next level is #{nextLevel} (#{nextLevelExp} xp)."
|
||||
console.debug "Need a total of #{nextLevelExp - currentLevelExp}, already had #{currentExp - currentLevelExp - worth} and just now earned #{worth}"
|
||||
|
||||
alreadyAchievedBar = $("<div class='progress-bar progress-bar-warning' style='width:#{alreadyAchievedPercentage}%'></div>")
|
||||
newlyAchievedBar = $("<div class='progress-bar progress-bar-success' style='width:#{newlyAchievedPercentage}%'></div>")
|
||||
progressBar = $('<div class="progress"></div>').append(alreadyAchievedBar).append(newlyAchievedBar)
|
||||
message = "Reached level #{currentLevel}!" if currentExp - worth < currentLevelExp
|
||||
|
||||
imageURL = '/file/' + achievement.get('icon')
|
||||
data =
|
||||
title: 'Achievement Unlocked'
|
||||
name: achievement.get('name')
|
||||
title: achievement.get('name')
|
||||
image: $("<img src='#{imageURL}' />")
|
||||
description: achievement.get('description')
|
||||
progressBar: progressBar
|
||||
earnedExp: "+ #{worth} XP"
|
||||
message: message
|
||||
|
||||
options =
|
||||
autoHideDelay: 15000
|
||||
globalPosition: 'bottom right'
|
||||
showDuration: 400
|
||||
style: 'achievement'
|
||||
autoHide: true
|
||||
autoHide: false
|
||||
clickToHide: true
|
||||
|
||||
$.notify( data, options )
|
||||
|
||||
handleNewAchievements: (earnedAchievements) ->
|
||||
console.debug 'Got new earned achievements'
|
||||
# TODO performance?
|
||||
_.each(earnedAchievements.models, (earnedAchievement) =>
|
||||
achievement = new Achievement(earnedAchievement.get('achievement'))
|
||||
achievement = new Achievement(_id: earnedAchievement.get('achievement'))
|
||||
console.log achievement
|
||||
achievement.fetch(
|
||||
success: @showNewAchievement
|
||||
)
|
||||
|
|
|
@ -21,7 +21,6 @@ loadAchievements()
|
|||
module.exports = AchievablePlugin = (schema, options) ->
|
||||
checkForAchievement = (doc) ->
|
||||
collectionName = doc.constructor.modelName
|
||||
console.log achievements
|
||||
for achievement in achievements[collectionName]
|
||||
console.log achievement.get 'name'
|
||||
|
||||
|
@ -56,7 +55,14 @@ module.exports = AchievablePlugin = (schema, options) ->
|
|||
achievement: achievement._id.toHexString()
|
||||
achievementName: achievement.get 'name'
|
||||
}
|
||||
if isRepeatable
|
||||
earnedPoints = 0
|
||||
wrapUp = ->
|
||||
# Update user's experience points
|
||||
User.update({_id: userID}, {$inc: {points: earnedPoints}}, {}, (err, count) ->
|
||||
console.error err if err?
|
||||
)
|
||||
|
||||
if isRepeatable # TODO test more thoroughly
|
||||
console.log 'Upserting repeatable achievement called \'' + (achievement.get 'name') + '\' for ' + userID
|
||||
proportionalTo = achievement.get 'proportionalTo'
|
||||
originalAmount = util.getByPath(originalDocObj, proportionalTo) or 0
|
||||
|
@ -66,20 +72,22 @@ module.exports = AchievablePlugin = (schema, options) ->
|
|||
earned.notified = false
|
||||
earned.achievedAmount = newAmount
|
||||
earned.changed = Date.now()
|
||||
upsertQuery = EarnedAchievement.findOneAndUpdate earned, upsert:true
|
||||
upsertQuery.exec (err, docs) ->
|
||||
return console.log err if err?
|
||||
EarnedAchievement.findOneAndUpdate({achievement:earned.achievement, user:earned.user}, earned, upsert:true, (err, docs) ->
|
||||
return console.log err if err?
|
||||
)
|
||||
|
||||
earnedPoints = achievement.get('worth') * (newAmount - originalAmount)
|
||||
wrapUp()
|
||||
|
||||
# Update user's denormalized score
|
||||
userQuery = User.findOne(_id: userID)
|
||||
userQuery.exec (err, user) ->
|
||||
return console.error(err) if err?
|
||||
previousPoints = user.get('points') - achievement.get('worth') * originalAmount
|
||||
user.set('points', previousPoints + achievement.get('worth') * newAmount)
|
||||
else # not alreadyAchieved
|
||||
console.log 'Creating a new earned achievement called \'' + (achievement.get 'name') + '\' for ' + userID
|
||||
(new EarnedAchievement(earned)).save (err, doc) ->
|
||||
console.log err if err?
|
||||
return console.log err if err?
|
||||
|
||||
earnedPoints = achievement.get('worth')
|
||||
wrapUp()
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -4,7 +4,6 @@ crypto = require('crypto')
|
|||
{salt, isProduction} = require('../../server_config')
|
||||
mail = require '../commons/mail'
|
||||
log = require 'winston'
|
||||
plugins = require '../plugins/achievements'
|
||||
|
||||
sendwithus = require '../sendwithus'
|
||||
|
||||
|
|
Loading…
Reference in a new issue