mirror of
https://github.com/codeninjasllc/codecombat.git
synced 2024-11-28 10:06:08 -05:00
Merge branch 'master' into production
This commit is contained in:
commit
40081fc853
11 changed files with 69 additions and 22 deletions
|
@ -167,6 +167,7 @@
|
|||
medium: "Medium"
|
||||
hard: "Hard"
|
||||
player: "Player"
|
||||
player_level: "Level" # Like player level 5, not like level: Dungeons of Kithgard
|
||||
|
||||
units:
|
||||
second: "second"
|
||||
|
|
|
@ -396,8 +396,16 @@ module.exports = class ThangType extends CocoModel
|
|||
name: name, display: display
|
||||
|
||||
isSilhouettedItem: ->
|
||||
# TODO: have items have actual levels instead of just going by their gem count
|
||||
return console.error "Trying to determine whether #{@get('name')} should be a silhouetted item, but it has no gem cost." unless @get 'gems'
|
||||
console.info "Add (or make sure you have fetched) a tier for #{@get('name')} to more accurately determine whether it is silhouetted." unless @get('tier')?
|
||||
tier = @get 'tier'
|
||||
if tier?
|
||||
return @levelRequiredForItem() > me.level()
|
||||
points = me.get('points')
|
||||
expectedTotalGems = (points ? 0) * 1.5 # Not actually true, but roughly kinda close for tier 0, kinda tier 1
|
||||
@get('gems') > (100 + expectedTotalGems) * 2
|
||||
@get('gems') > (100 + expectedTotalGems) * 1.2
|
||||
|
||||
levelRequiredForItem: ->
|
||||
return console.error "Trying to determine what level is required for #{@get('name')}, but it has no tier." unless @get('tier')?
|
||||
tier = @get 'tier'
|
||||
me.constructor.levelForTier(Math.pow(tier, 0.7))
|
||||
|
|
|
@ -63,9 +63,22 @@ module.exports = class User extends CocoModel
|
|||
@expForLevel: (level) ->
|
||||
if level > 1 then Math.ceil Math.exp((level - 1)/ a) * b - c else 0
|
||||
|
||||
@tierFromLevel: (level) ->
|
||||
# TODO: math
|
||||
# For now, just eyeball it.
|
||||
tiersByLevel[Math.min(level, tiersByLevel.length - 1)]
|
||||
|
||||
@levelForTier: (tier) ->
|
||||
# TODO: math
|
||||
for tierThreshold, level in tiersByLevel
|
||||
return level if tierThreshold >= tier
|
||||
|
||||
level: ->
|
||||
User.levelFromExp(@get('points'))
|
||||
|
||||
tier: ->
|
||||
User.tierFromLevel @level()
|
||||
|
||||
gems: ->
|
||||
gemsEarned = @get('earned')?.gems ? 0
|
||||
gemsPurchased = @get('purchased')?.gems ? 0
|
||||
|
@ -146,3 +159,5 @@ module.exports = class User extends CocoModel
|
|||
@kithmazeGroup = 'haunted-kithmaze' if me.isAdmin()
|
||||
application.tracker.identify kithmazeGroup: @kithmazeGroup unless me.isAdmin()
|
||||
@kithmazeGroup
|
||||
|
||||
tiersByLevel = [-1, 0, 0.05, 0.14, 0.18, 0.32, 0.41, 0.5, 0.64, 0.82, 0.91, 1.04, 1.22, 1.35, 1.48, 1.65, 1.78, 1.96, 2.1, 2.24, 2.38, 2.55, 2.69, 2.86, 3.03, 3.16, 3.29, 3.42, 3.58, 3.74, 3.89, 4.04, 4.19, 4.32, 4.47, 4.64, 4.79, 4.96]
|
||||
|
|
|
@ -109,6 +109,7 @@ _.extend ThangTypeSchema.properties,
|
|||
terrains: c.array {title: 'Terrains', description: 'If specified, limits this ThangType to levels with matching terrains.', uniqueItems: true}, c.terrainString
|
||||
gems: {type: 'integer', minimum: 0, title: 'Gem Cost', description: 'How many gems this item or hero costs.'}
|
||||
heroClass: {type: 'string', enum: ['Warrior', 'Ranger', 'Wizard'], title: 'Hero Class', description: 'What class this is (if a hero) or is restricted to (if an item). Leave undefined for most items.'}
|
||||
tier: {type: 'number', minimum: 0, title: 'Tier', description: 'What tier (fractional) this item or hero is in.'}
|
||||
actions: c.object {title: 'Actions', additionalProperties: {$ref: '#/definitions/action'}}
|
||||
soundTriggers: c.object {title: 'Sound Triggers', additionalProperties: c.array({}, {$ref: '#/definitions/sound'})},
|
||||
say: c.object {format: 'slug-props', additionalProperties: {$ref: '#/definitions/sound'}},
|
||||
|
|
|
@ -140,6 +140,9 @@
|
|||
text-align: center
|
||||
position: relative
|
||||
|
||||
&.silhouetted
|
||||
cursor: default
|
||||
|
||||
strong
|
||||
position: absolute
|
||||
top: 7px
|
||||
|
@ -276,6 +279,18 @@
|
|||
@include filter(contrast(0%) brightness(0%))
|
||||
opacity: 0.3
|
||||
|
||||
.required-level
|
||||
position: absolute
|
||||
left: 0
|
||||
right: 5px
|
||||
top: 70px
|
||||
font-size: 20px
|
||||
line-height: 20px
|
||||
font-family: Open Sans Condensed
|
||||
text-transform: uppercase
|
||||
font-weight: bold
|
||||
z-index: 2
|
||||
|
||||
|
||||
//- Unlock buttons (both in list and details areas)
|
||||
|
||||
|
|
|
@ -26,11 +26,16 @@
|
|||
.nano-content
|
||||
for item in itemCategoryCollections[category].models
|
||||
- var hidden = item.comingSoon && !me.isAdmin()
|
||||
div(class="item" + (hidden ? " hide" : ""), data-item-id=item.id)
|
||||
- hidden = hidden || (!item.get('gems') && !item.owned)
|
||||
div(class="item" + (hidden ? " hide" : "") + (item.silhouetted && !item.owned ? " silhouetted" : ""), data-item-id=item.id)
|
||||
if item.silhouetted && !item.owned
|
||||
span.glyphicon.glyphicon-lock.bolder
|
||||
span.glyphicon.glyphicon-lock
|
||||
img.item-silhouette(src=item.getPortraitURL())
|
||||
if item.level
|
||||
.required-level
|
||||
div(data-i18n="general.player_level")
|
||||
div= item.level
|
||||
else
|
||||
strong.big-font= item.name
|
||||
img.item-img(src=item.getPortraitURL())
|
||||
|
|
|
@ -64,6 +64,8 @@
|
|||
.user-status.header-font
|
||||
span.gem.gem-20
|
||||
span.spr= me.gems()
|
||||
span.spl.spr(data-i18n="general.player_level")
|
||||
span.spr= me.level()
|
||||
if me.get('anonymous')
|
||||
span.spr(data-i18n="play.anonymous_player") Anonymous Player
|
||||
button.btn.btn-default.btn-flat.btn-sm(data-toggle='coco-modal', data-target='modal/AuthModal', data-i18n="login.log_in")
|
||||
|
|
|
@ -4,8 +4,6 @@ WizardLank = require 'lib/surface/WizardLank'
|
|||
ThangType = require 'models/ThangType'
|
||||
Simulator = require 'lib/simulator/Simulator'
|
||||
|
||||
InventoryModal = require 'views/game-menu/InventoryModal'
|
||||
|
||||
{me} = require '/lib/auth'
|
||||
|
||||
module.exports = class HomeView extends RootView
|
||||
|
@ -40,4 +38,3 @@ module.exports = class HomeView extends RootView
|
|||
|
||||
afterInsert: ->
|
||||
super(arguments...)
|
||||
@openModalView(new InventoryModal({levelID: 'the-raised-sword'}))
|
|
@ -44,14 +44,15 @@ module.exports = class InventoryModal extends ModalView
|
|||
# TODO: switch to item store loading system?
|
||||
@items.url = '/db/thang.type?view=items'
|
||||
@items.setProjection [
|
||||
'name',
|
||||
'slug',
|
||||
'components',
|
||||
'original',
|
||||
'rasterIcon',
|
||||
'gems',
|
||||
'description',
|
||||
'heroClass',
|
||||
'name'
|
||||
'slug'
|
||||
'components'
|
||||
'original'
|
||||
'rasterIcon'
|
||||
'gems'
|
||||
'tier'
|
||||
'description'
|
||||
'heroClass'
|
||||
'i18n'
|
||||
]
|
||||
@supermodel.loadCollection(@items, 'items')
|
||||
|
|
|
@ -62,6 +62,7 @@ module.exports = class PlayItemsModal extends ModalView
|
|||
'original'
|
||||
'rasterIcon'
|
||||
'gems'
|
||||
'tier'
|
||||
'i18n'
|
||||
'heroClass'
|
||||
]
|
||||
|
@ -77,7 +78,8 @@ module.exports = class PlayItemsModal extends ModalView
|
|||
gemsOwned = me.gems()
|
||||
needMore = itemFetcher.models.length is PAGE_SIZE
|
||||
for model in itemFetcher.models
|
||||
continue unless cost = model.get('gems')
|
||||
model.owned = me.ownsItem model.get('original')
|
||||
continue unless (cost = model.get('gems')) or model.owned
|
||||
category = slotToCategory[model.getAllowedSlots()[0]] or 'misc'
|
||||
@itemCategoryCollections[category] ?= new Backbone.Collection()
|
||||
collection = @itemCategoryCollections[category]
|
||||
|
@ -85,10 +87,10 @@ module.exports = class PlayItemsModal extends ModalView
|
|||
collection.add(model)
|
||||
model.name = utils.i18n model.attributes, 'name'
|
||||
model.affordable = cost <= gemsOwned
|
||||
model.owned = me.ownsItem model.get('original')
|
||||
model.silhouetted = model.isSilhouettedItem()
|
||||
model.silhouetted = not model.owned and model.isSilhouettedItem()
|
||||
model.level = model.levelRequiredForItem() if model.get('tier')?
|
||||
model.equippable = 'Warrior' in model.getAllowedHeroClasses() # Temp: while there are no wizards/rangers
|
||||
model.comingSoon = not model.getFrontFacingStats().props.length and not _.size model.getFrontFacingStats().stats # Temp: while there are placeholder items
|
||||
model.comingSoon = not model.getFrontFacingStats().props.length and not _.size model.getFrontFacingStats().stats and not model.owned # Temp: while there are placeholder items
|
||||
@idToItem[model.id] = model
|
||||
|
||||
if needMore
|
||||
|
@ -127,7 +129,7 @@ module.exports = class PlayItemsModal extends ModalView
|
|||
item = null
|
||||
else
|
||||
item = @idToItem[itemEl.data('item-id')]
|
||||
if item.silhouetted
|
||||
if item.silhouetted and not item.owned
|
||||
item = null
|
||||
else
|
||||
itemEl.addClass('selected') unless wasSelected
|
||||
|
@ -158,4 +160,3 @@ module.exports = class PlayItemsModal extends ModalView
|
|||
button.addClass('confirm').text($.i18n.t('play.confirm'))
|
||||
@$el.one 'click', (e) ->
|
||||
button.removeClass('confirm').text($.i18n.t('play.unlock')) if e.target isnt button[0]
|
||||
|
||||
|
|
|
@ -40,6 +40,7 @@ ThangTypeHandler = class ThangTypeHandler extends Handler
|
|||
'description'
|
||||
'gems'
|
||||
'heroClass'
|
||||
'tier'
|
||||
'extendedName'
|
||||
]
|
||||
|
||||
|
@ -61,7 +62,7 @@ ThangTypeHandler = class ThangTypeHandler extends Handler
|
|||
query = slug: {$exists: true}
|
||||
if req.query.view is 'items'
|
||||
query.kind = 'Item'
|
||||
query.gems = {$exists: true} # Items without gems don't show up anywhere
|
||||
query.tier = {$exists: true} # Items without a tier don't show up anywhere, whereas items without gems don't show up in the store
|
||||
else if req.query.view is 'heroes'
|
||||
#query.kind = 'Hero' # TODO: when ChooseHeroView is refactored, just use this
|
||||
query.original = {$in: _.values heroes} # TODO: when ChooseHeroView is refactored, don't do this
|
||||
|
|
Loading…
Reference in a new issue