mirror of
https://github.com/codeninjasllc/codecombat.git
synced 2025-05-03 01:14:46 -04:00
Hiding locked items with no slot selected. Silhouetting items that are too far above you. Only showing items with a gem cost in the inventory screen. Sorting items by gem cost. Animating double-clicking items to show their motion to the slot, sort of.
This commit is contained in:
parent
56ae82757a
commit
47c090f7c7
6 changed files with 67 additions and 22 deletions
app
models
styles/game-menu
templates/game-menu
views/game-menu
server
|
@ -294,7 +294,11 @@ module.exports = class ThangType extends CocoModel
|
||||||
itemComponentRef = _.find(
|
itemComponentRef = _.find(
|
||||||
@get('components') or [],
|
@get('components') or [],
|
||||||
(compRef) -> compRef.original is LevelComponent.ItemID)
|
(compRef) -> compRef.original is LevelComponent.ItemID)
|
||||||
return itemComponentRef?.config?.slots or []
|
return itemComponentRef?.config?.slots or ['right-hand'] # ['right-hand'] is default
|
||||||
|
|
||||||
|
getAllowedHeroClasses: ->
|
||||||
|
return [heroClass] if heroClass = @get 'heroClass'
|
||||||
|
['Warrior', 'Ranger', 'Wizard']
|
||||||
|
|
||||||
getFrontFacingStats: ->
|
getFrontFacingStats: ->
|
||||||
components = @get('components') or []
|
components = @get('components') or []
|
||||||
|
@ -341,3 +345,10 @@ module.exports = class ThangType extends CocoModel
|
||||||
display = display.join ', '
|
display = display.join ', '
|
||||||
display = display.replace /9001m?/, 'Infinity'
|
display = display.replace /9001m?/, 'Infinity'
|
||||||
name: name, display: display
|
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'
|
||||||
|
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
|
||||||
|
|
|
@ -14,6 +14,11 @@ $selectedAreaHeight: 150px
|
||||||
$stashMargin: 20px
|
$stashMargin: 20px
|
||||||
$stashWidth: $totalWidth - $equippedWidth - $stashMargin
|
$stashWidth: $totalWidth - $equippedWidth - $stashMargin
|
||||||
|
|
||||||
|
.ui-effects-transfer
|
||||||
|
outline: 2px solid #28f
|
||||||
|
@include box-shadow(0 0 10px #28f)
|
||||||
|
z-index: 9001
|
||||||
|
|
||||||
#inventory-view
|
#inventory-view
|
||||||
position: relative
|
position: relative
|
||||||
height: $inventoryHeight
|
height: $inventoryHeight
|
||||||
|
@ -200,6 +205,11 @@ $stashWidth: $totalWidth - $equippedWidth - $stashMargin
|
||||||
padding: 4px
|
padding: 4px
|
||||||
background-color: white
|
background-color: white
|
||||||
|
|
||||||
|
&.Warrior .list-group-item:not(.Warrior), &.Ranger .list-group-item:not(.Ranger), &.Wizard .list-group-item:not(.Wizard)
|
||||||
|
// Our code hides and shows (modifies display), but we can be invisible this other way.
|
||||||
|
visibility: hidden
|
||||||
|
position: absolute
|
||||||
|
|
||||||
.list-group-item
|
.list-group-item
|
||||||
padding: 4px 0
|
padding: 4px 0
|
||||||
@include transition(0.5s ease)
|
@include transition(0.5s ease)
|
||||||
|
@ -244,6 +254,18 @@ $stashWidth: $totalWidth - $equippedWidth - $stashMargin
|
||||||
.item-info:after
|
.item-info:after
|
||||||
content: ' (locked)'
|
content: ' (locked)'
|
||||||
|
|
||||||
|
&.silhouette
|
||||||
|
h4
|
||||||
|
visibility: hidden
|
||||||
|
position: absolute
|
||||||
|
h4:before
|
||||||
|
content: '???'
|
||||||
|
visibility: visible
|
||||||
|
.item-info:after
|
||||||
|
display: none
|
||||||
|
img
|
||||||
|
@include filter(contrast(25%) brightness(25%))
|
||||||
|
|
||||||
.item-view
|
.item-view
|
||||||
cursor: pointer
|
cursor: pointer
|
||||||
|
|
||||||
|
|
|
@ -55,5 +55,5 @@
|
||||||
h4#locked-description
|
h4#locked-description
|
||||||
ul.list-group
|
ul.list-group
|
||||||
for item in lockedItems
|
for item in lockedItems
|
||||||
li.list-group-item(class=item.classes, data-item-id=item.get('original'))
|
li.list-group-item(class=item.classes, data-item-id=item.get('original'), style="display: none")
|
||||||
|
|
||||||
|
|
|
@ -48,15 +48,24 @@ module.exports = class InventoryView extends CocoView
|
||||||
context.equipped = _.values(@equipment)
|
context.equipped = _.values(@equipment)
|
||||||
context.items = @items.models
|
context.items = @items.models
|
||||||
|
|
||||||
context.unlockedItems = []
|
|
||||||
context.lockedItems = []
|
|
||||||
for item in @items.models
|
for item in @items.models
|
||||||
item.classes = item.getAllowedSlots()
|
item.classes = item.getAllowedSlots()
|
||||||
item.classes.push 'equipped' if item.get('original') in context.equipped
|
item.classes.push 'equipped' if item.get('original') in context.equipped
|
||||||
locked = @allowedItems and not (item.get('original') in @allowedItems)
|
locked = @allowedItems and not (item.get('original') in @allowedItems)
|
||||||
item.classes.push 'locked' if locked
|
item.classes.push 'locked' if locked and item.get('slug') isnt 'simple-boots'
|
||||||
(if locked then context.lockedItems else context.unlockedItems).push item
|
for heroClass in item.getAllowedHeroClasses()
|
||||||
@items.models.sort (a, b) -> ('locked' in a.classes) - ('locked' in b.classes)
|
item.classes.push heroClass
|
||||||
|
item.classes.push 'silhouette' if item.isSilhouettedItem()
|
||||||
|
|
||||||
|
@items.models.sort (a, b) ->
|
||||||
|
lockScore = 90019001 * (('locked' in a.classes) - ('locked' in b.classes))
|
||||||
|
gemScore = a.get('gems') - b.get('gems')
|
||||||
|
lockScore + gemScore
|
||||||
|
|
||||||
|
context.unlockedItems = []
|
||||||
|
context.lockedItems = []
|
||||||
|
for item in @items.models
|
||||||
|
(if 'locked' in item.classes then context.lockedItems else context.unlockedItems).push item
|
||||||
|
|
||||||
context.slots = @slots
|
context.slots = @slots
|
||||||
context.equipment = _.clone @equipment
|
context.equipment = _.clone @equipment
|
||||||
|
@ -184,6 +193,7 @@ module.exports = class InventoryView extends CocoView
|
||||||
@onSelectionChanged()
|
@onSelectionChanged()
|
||||||
slot = @getSelectedSlot()
|
slot = @getSelectedSlot()
|
||||||
slot = @$el.find('.item-slot:not(.disabled):first') if not slot.length
|
slot = @$el.find('.item-slot:not(.disabled):first') if not slot.length
|
||||||
|
$(e.target).effect('transfer', to: slot, duration: 500, easing: 'easeOutCubic') if e
|
||||||
@unequipItemFromSlot(slot)
|
@unequipItemFromSlot(slot)
|
||||||
@equipSelectedItemToSlot(slot)
|
@equipSelectedItemToSlot(slot)
|
||||||
@onSelectionChanged()
|
@onSelectionChanged()
|
||||||
|
@ -261,9 +271,9 @@ module.exports = class InventoryView extends CocoView
|
||||||
@hideSelectedSlotItem()
|
@hideSelectedSlotItem()
|
||||||
else
|
else
|
||||||
unlockedCount = @$el.find('#available-equipment .list-group-item:not(.locked)').show().length
|
unlockedCount = @$el.find('#available-equipment .list-group-item:not(.locked)').show().length
|
||||||
lockedCount = @$el.find('#available-equipment .list-group-item.locked').show().length
|
@$el.find('#available-equipment .list-group-item.locked').hide()
|
||||||
@$el.find('#unlocked-description').text("#{unlockedCount} items owned").toggle unlockedCount > 0
|
@$el.find('#unlocked-description').text("#{unlockedCount} items owned").toggle unlockedCount > 0
|
||||||
@$el.find('#locked-description').text("#{lockedCount} items locked").toggle lockedCount > 0
|
@$el.find('#locked-description').text("#{lockedCount} items locked").hide()
|
||||||
#@$el.find('#available-equipment .list-group-item.equipped').hide()
|
#@$el.find('#available-equipment .list-group-item.equipped').hide()
|
||||||
|
|
||||||
@$el.find('.item-slot').removeClass('disabled')
|
@$el.find('.item-slot').removeClass('disabled')
|
||||||
|
@ -327,30 +337,30 @@ module.exports = class InventoryView extends CocoView
|
||||||
# This is temporary, until we have a more general way of awarding items and configuring needed/locked items per level.
|
# This is temporary, until we have a more general way of awarding items and configuring needed/locked items per level.
|
||||||
gear =
|
gear =
|
||||||
'simple-boots': '53e237bf53457600003e3f05'
|
'simple-boots': '53e237bf53457600003e3f05'
|
||||||
'longsword': '53e218d853457600003e3ebe'
|
'simple-sword': '53e218d853457600003e3ebe'
|
||||||
'leather-tunic': '53e22eac53457600003e3efc'
|
'leather-tunic': '53e22eac53457600003e3efc'
|
||||||
'leather-boots': '53e2384453457600003e3f07'
|
'leather-boots': '53e2384453457600003e3f07'
|
||||||
'programmaticon-i': '53e4108204c00d4607a89f78'
|
'programmaticon-i': '53e4108204c00d4607a89f78'
|
||||||
'crude-glasses': '53e238df53457600003e3f0b'
|
'crude-wooden-glasses': '53e238df53457600003e3f0b'
|
||||||
'builders-hammer': '53f4e6e3d822c23505b74f42'
|
'builders-hammer': '53f4e6e3d822c23505b74f42'
|
||||||
gearByLevel =
|
gearByLevel =
|
||||||
'dungeons-of-kithgard': {feet: 'simple-boots'}
|
'dungeons-of-kithgard': {feet: 'simple-boots'}
|
||||||
'gems-in-the-deep': {feet: 'simple-boots'}
|
'gems-in-the-deep': {feet: 'simple-boots'}
|
||||||
'forgetful-gemsmith': {feet: 'simple-boots'}
|
'forgetful-gemsmith': {feet: 'simple-boots'}
|
||||||
'shadow-guard': {feet: 'simple-boots'}
|
'shadow-guard': {feet: 'simple-boots'}
|
||||||
'true-names': {feet: 'simple-boots', 'right-hand': 'longsword'}
|
'true-names': {feet: 'simple-boots', 'right-hand': 'simple-sword'}
|
||||||
'the-raised-sword': {feet: 'simple-boots', 'right-hand': 'longsword', torso: 'leather-tunic'}
|
'the-raised-sword': {feet: 'simple-boots', 'right-hand': 'simple-sword', torso: 'leather-tunic'}
|
||||||
'the-first-kithmaze': {feet: 'simple-boots', 'programming-book': 'programmaticon-i'}
|
'the-first-kithmaze': {feet: 'simple-boots', 'programming-book': 'programmaticon-i'}
|
||||||
'the-second-kithmaze': {feet: 'simple-boots', 'programming-book': 'programmaticon-i'}
|
'the-second-kithmaze': {feet: 'simple-boots', 'programming-book': 'programmaticon-i'}
|
||||||
'new-sight': {'right-hand': 'longsword', 'programming-book': 'programmaticon-i'}
|
'new-sight': {'right-hand': 'simple-sword', 'programming-book': 'programmaticon-i'}
|
||||||
'lowly-kithmen': {feet: 'simple-boots', 'right-hand': 'longsword', 'programming-book': 'programmaticon-i', eyes: 'crude-glasses'}
|
'lowly-kithmen': {feet: 'simple-boots', 'right-hand': 'simple-sword', 'programming-book': 'programmaticon-i', eyes: 'crude-wooden-glasses'}
|
||||||
'closing-the-distance': {feet: 'simple-boots', 'right-hand': 'longsword', torso: 'leather-tunic', eyes: 'crude-glasses'}
|
'closing-the-distance': {feet: 'simple-boots', 'right-hand': 'simple-sword', torso: 'leather-tunic', eyes: 'crude-wooden-glasses'}
|
||||||
'the-final-kithmaze': {feet: 'simple-boots', 'right-hand': 'longsword', torso: 'leather-tunic', 'programming-book': 'programmaticon-i', eyes: 'crude-glasses'}
|
'the-final-kithmaze': {feet: 'simple-boots', 'right-hand': 'simple-sword', torso: 'leather-tunic', 'programming-book': 'programmaticon-i', eyes: 'crude-wooden-glasses'}
|
||||||
'kithgard-gates': {feet: 'simple-boots', 'right-hand': 'builders-hammer', torso: 'leather-tunic'}
|
'kithgard-gates': {feet: 'simple-boots', 'right-hand': 'builders-hammer', torso: 'leather-tunic'}
|
||||||
'defense-of-plainswood': {feet: 'simple-boots', 'right-hand': 'builders-hammer'}
|
'defense-of-plainswood': {feet: 'simple-boots', 'right-hand': 'builders-hammer'}
|
||||||
'winding-trail': {feet: 'leather-boots', 'right-hand': 'builders-hammer'}
|
'winding-trail': {feet: 'leather-boots', 'right-hand': 'builders-hammer'}
|
||||||
'thornbush-farm': {feet: 'leather-boots', 'right-hand': 'builders-hammer', eyes: 'crude-glasses'}
|
'thornbush-farm': {feet: 'leather-boots', 'right-hand': 'builders-hammer', eyes: 'crude-wooden-glasses'}
|
||||||
'a-fiery-trap': {feet: 'leather-boots', 'right-hand': 'builders-hammer', eyes: 'crude-glasses'}
|
'a-fiery-trap': {feet: 'leather-boots', 'right-hand': 'builders-hammer', eyes: 'crude-wooden-glasses'}
|
||||||
return unless necessaryGear = gearByLevel[@options.levelID]
|
return unless necessaryGear = gearByLevel[@options.levelID]
|
||||||
if @inserted
|
if @inserted
|
||||||
if @supermodel.finished()
|
if @supermodel.finished()
|
||||||
|
@ -363,7 +373,7 @@ module.exports = class InventoryView extends CocoView
|
||||||
inWorldMap = $('#world-map-view').length
|
inWorldMap = $('#world-map-view').length
|
||||||
for slot, item of necessaryGear
|
for slot, item of necessaryGear
|
||||||
continue if item is 'leather-tunic' and inWorldMap # Don't tell them they need it until they need it in the level
|
continue if item is 'leather-tunic' and inWorldMap # Don't tell them they need it until they need it in the level
|
||||||
continue if equipment[slot] and not ((item is 'builders-hammer' and equipment[slot] is gear.longsword) or (item is 'leather-boots' and equipment[slot] is gear['simple-boots']))
|
continue if equipment[slot] and not ((item is 'builders-hammer' and equipment[slot] is gear['simple-sword']) or (item is 'leather-boots' and equipment[slot] is gear['simple-boots']))
|
||||||
availableSlotSelector = "#available-equipment li[data-item-id='#{gear[item]}']"
|
availableSlotSelector = "#available-equipment li[data-item-id='#{gear[item]}']"
|
||||||
@highlightElement availableSlotSelector, delay: 500, sides: ['right'], rotation: Math.PI / 2
|
@highlightElement availableSlotSelector, delay: 500, sides: ['right'], rotation: Math.PI / 2
|
||||||
@$el.find(availableSlotSelector).addClass 'should-equip'
|
@$el.find(availableSlotSelector).addClass 'should-equip'
|
||||||
|
@ -386,6 +396,7 @@ module.exports = class InventoryView extends CocoView
|
||||||
onHeroSelectionUpdated: (e) ->
|
onHeroSelectionUpdated: (e) ->
|
||||||
@selectedHero = e.hero
|
@selectedHero = e.hero
|
||||||
@loadHero()
|
@loadHero()
|
||||||
|
@$el.removeClass('Warrior Ranger Wizard').addClass(@selectedHero.get('heroClass'))
|
||||||
|
|
||||||
loadHero: ->
|
loadHero: ->
|
||||||
return unless @supermodel.finished() and @selectedHero and not @$el.hasClass 'secret'
|
return unless @supermodel.finished() and @selectedHero and not @$el.hasClass 'secret'
|
||||||
|
|
|
@ -46,9 +46,9 @@ module.exports = class Handler
|
||||||
omissions = ['original'].concat(deltasLib.DOC_SKIP_PATHS)
|
omissions = ['original'].concat(deltasLib.DOC_SKIP_PATHS)
|
||||||
delta = differ.diff(_.omit(document.toObject(), omissions), _.omit(req.body, omissions))
|
delta = differ.diff(_.omit(document.toObject(), omissions), _.omit(req.body, omissions))
|
||||||
flattened = deltasLib.flattenDelta(delta)
|
flattened = deltasLib.flattenDelta(delta)
|
||||||
_.all(flattened, (delta) ->
|
_.all flattened, (delta) ->
|
||||||
# sometimes coverage gets moved around... allow other changes to happen to i18nCoverage
|
# sometimes coverage gets moved around... allow other changes to happen to i18nCoverage
|
||||||
return _.isArray(delta.o) and (('i18n' in delta.dataPath and delta.o.length is 1) or 'i18nCoverage' in delta.dataPath))
|
return _.isArray(delta.o) and (('i18n' in delta.dataPath and delta.o.length is 1) or 'i18nCoverage' in delta.dataPath)
|
||||||
|
|
||||||
formatEntity: (req, document) -> document?.toObject()
|
formatEntity: (req, document) -> document?.toObject()
|
||||||
getEditableProperties: (req, document) ->
|
getEditableProperties: (req, document) ->
|
||||||
|
|
|
@ -60,6 +60,7 @@ ThangTypeHandler = class ThangTypeHandler extends Handler
|
||||||
query = slug: {$exists: true}
|
query = slug: {$exists: true}
|
||||||
if req.query.view is 'items'
|
if req.query.view is 'items'
|
||||||
query.kind = 'Item'
|
query.kind = 'Item'
|
||||||
|
query.gems = {$exists: true} # Items without gems don't show up anywhere
|
||||||
else if req.query.view is 'heroes'
|
else if req.query.view is 'heroes'
|
||||||
#query.kind = 'Hero' # TODO: when all the heroes are tagged, just use this
|
#query.kind = 'Hero' # TODO: when all the heroes are tagged, just use this
|
||||||
query.original = {$in: _.values heroes} # TODO: when all the heroes are tagged, don't do this
|
query.original = {$in: _.values heroes} # TODO: when all the heroes are tagged, don't do this
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue