mirror of
https://github.com/codeninjasllc/codecombat.git
synced 2025-04-26 14:03:28 -04:00
Merge branch 'master' into production
This commit is contained in:
commit
3475770f13
28 changed files with 965 additions and 730 deletions
app
Router.coffee
lib
locale
schemas/models
styles
templates
views
server
|
@ -15,8 +15,7 @@ module.exports = class CocoRouter extends Backbone.Router
|
|||
@initializeSocialMediaServices = _.once @initializeSocialMediaServices
|
||||
|
||||
routes:
|
||||
'': go('HomeView') # This will go somewhere deprecated when FrontView is done.
|
||||
'front': go('FrontView') # This will become '' when it is done.
|
||||
'': go('HomeView')
|
||||
|
||||
'about': go('AboutView')
|
||||
|
||||
|
@ -85,7 +84,6 @@ module.exports = class CocoRouter extends Backbone.Router
|
|||
|
||||
'play-old': go('play/MainPlayView') # This used to be 'play'.
|
||||
'play': go('play/WorldMapView')
|
||||
'play-hero': go('play/WorldMapView') # Legacy URL for /play; leave up until start of 2015, I guess.
|
||||
'play/ladder/:levelID': go('play/ladder/LadderView')
|
||||
'play/ladder': go('play/ladder/MainLadderView')
|
||||
'play/level/:levelID': go('play/level/PlayLevelView')
|
||||
|
|
|
@ -141,6 +141,7 @@ module.exports = LevelOptions =
|
|||
hidesRealTimePlayback: true
|
||||
requiredGear: {'right-hand': 'simple-sword', 'programming-book': 'programmaticon-i', torso: 'tarnished-bronze-breastplate'}
|
||||
restrictedGear: {feet: 'leather-boots'}
|
||||
suspectCode: [{name: 'enemy-in-quotes', pattern: /['"]enemy/m}] # '
|
||||
'master-of-names':
|
||||
hidesHUD: true
|
||||
hidesSay: true
|
||||
|
|
|
@ -12,7 +12,7 @@ module.exports = class Tracker
|
|||
|
||||
identify: (traits) ->
|
||||
console.log 'Would identify', traits if debugAnalytics
|
||||
return unless me and @isProduction and analytics?
|
||||
return unless me and @isProduction and analytics? and not me.isAdmin()
|
||||
# https://segment.io/docs/methods/identify
|
||||
traits ?= {}
|
||||
for userTrait in ['email', 'anonymous', 'dateCreated', 'name', 'wizardColor1', 'testGroupNumber', 'gender']
|
||||
|
@ -20,14 +20,14 @@ module.exports = class Tracker
|
|||
analytics.identify me.id, traits
|
||||
|
||||
trackPageView: ->
|
||||
return unless @isProduction and analytics?
|
||||
return unless @isProduction and analytics? and not me.isAdmin()
|
||||
url = Backbone.history.getFragment()
|
||||
console.log 'Going to track visit for', "/#{url}" if debugAnalytics
|
||||
analytics.pageview "/#{url}"
|
||||
|
||||
trackEvent: (event, properties, includeProviders=null) =>
|
||||
console.log 'Would track analytics event:', event, properties if debugAnalytics
|
||||
return unless me and @isProduction and analytics?
|
||||
return unless me and @isProduction and analytics? and not me.isAdmin()
|
||||
console.log 'Going to track analytics event:', event, properties if debugAnalytics
|
||||
properties = properties or {}
|
||||
context = {}
|
||||
|
|
|
@ -1,42 +1,42 @@
|
|||
module.exports = nativeDescription: "Bahasa Indonesia", englishDescription: "Indonesian", translation:
|
||||
# home:
|
||||
home:
|
||||
# slogan: "Learn to Code by Playing a Game"
|
||||
# no_ie: "CodeCombat does not run in Internet Explorer 8 or older. Sorry!" # Warning that only shows up in IE8 and older
|
||||
# no_mobile: "CodeCombat wasn't designed for mobile devices and may not work!" # Warning that shows up on mobile devices
|
||||
# play: "Play" # The big play button that just starts playing a level
|
||||
# old_browser: "Uh oh, your browser is too old to run CodeCombat. Sorry!" # Warning that shows up on really old Firefox/Chrome/Safari
|
||||
# old_browser_suffix: "You can try anyway, but it probably won't work."
|
||||
# campaign: "Campaign"
|
||||
# for_beginners: "For Beginners"
|
||||
# multiplayer: "Multiplayer" # Not currently shown on home page
|
||||
# for_developers: "For Developers" # Not currently shown on home page.
|
||||
# or_ipad: "Or download for iPad"
|
||||
no_ie: "Maaf, CodeCombat tidak bisa dijalankan pada Internet Explorer 8 dan sebelumnya" # Warning that only shows up in IE8 and older
|
||||
no_mobile: "Maaf. CodeCombat tidak dibuat untuk perangkat mobile" # Warning that shows up on mobile devices
|
||||
play: "Play" # The big play button that just starts playing a level
|
||||
old_browser: "Uh oh, Maaf. Versi broser anda terlalu lama " # Warning that shows up on really old Firefox/Chrome/Safari
|
||||
old_browser_suffix: "Anda bisa mencoba, tapi mungkin tidak akan berjalan."
|
||||
campaign: "Campaign"
|
||||
for_beginners: "Pemula"
|
||||
multiplayer: "Multiplayer" # Not currently shown on home page
|
||||
for_developers: "Developers" # Not currently shown on home page.
|
||||
or_ipad: "atau download untuk iPad"
|
||||
|
||||
# nav:
|
||||
# play: "Levels" # The top nav bar entry where players choose which levels to play
|
||||
# community: "Community"
|
||||
# editor: "Editor"
|
||||
# blog: "Blog"
|
||||
# forum: "Forum"
|
||||
# account: "Account"
|
||||
# profile: "Profile"
|
||||
# stats: "Stats"
|
||||
# code: "Code"
|
||||
# admin: "Admin" # Only shows up when you are an admin
|
||||
# home: "Home"
|
||||
nav:
|
||||
play: "Levels" # The top nav bar entry where players choose which levels to play
|
||||
community: "Community"
|
||||
editor: "Editor"
|
||||
blog: "Blog"
|
||||
forum: "Forum"
|
||||
account: "Akun"
|
||||
profile: "Profile"
|
||||
stats: "Mulai"
|
||||
code: "Code"
|
||||
admin: "Admin" # Only shows up when you are an admin
|
||||
home: "Home"
|
||||
# contribute: "Contribute"
|
||||
# legal: "Legal"
|
||||
legal: "Legal"
|
||||
# about: "About"
|
||||
# contact: "Contact"
|
||||
# twitter_follow: "Follow"
|
||||
contact: "Kontak"
|
||||
twitter_follow: "Follow"
|
||||
# teachers: "Teachers"
|
||||
|
||||
# modal:
|
||||
# close: "Close"
|
||||
# okay: "Okay"
|
||||
modal:
|
||||
close: "Close"
|
||||
okay: "Okay"
|
||||
|
||||
# not_found:
|
||||
# page_not_found: "Page not found"
|
||||
not_found:
|
||||
page_not_found: "Alamat tidak ditemukan"
|
||||
|
||||
diplomat_suggestion:
|
||||
# title: "Help translate CodeCombat!" # This shows up when a player switches to a non-English language using the language selector.
|
||||
|
@ -46,22 +46,22 @@ module.exports = nativeDescription: "Bahasa Indonesia", englishDescription: "Ind
|
|||
# learn_more: "Learn more about being a Diplomat"
|
||||
# subscribe_as_diplomat: "Subscribe as a Diplomat"
|
||||
|
||||
# play:
|
||||
play:
|
||||
# play_as: "Play As" # Ladder page
|
||||
# spectate: "Spectate" # Ladder page
|
||||
# players: "players" # Hover over a level on /play
|
||||
# hours_played: "hours played" # Hover over a level on /play
|
||||
# items: "Items" # Tooltip on item shop button from /play
|
||||
# unlock: "Unlock" # For purchasing items and heroes
|
||||
# confirm: "Confirm"
|
||||
confirm: "Konfirmasi"
|
||||
# owned: "Owned" # For items you own
|
||||
# locked: "Locked"
|
||||
# available: "Available"
|
||||
locked: "Terkunci"
|
||||
available: "Trsedia"
|
||||
# skills_granted: "Skills Granted" # Property documentation details
|
||||
# heroes: "Heroes" # Tooltip on hero shop button from /play
|
||||
heroes: "Heroes" # Tooltip on hero shop button from /play
|
||||
# achievements: "Achievements" # Tooltip on achievement list button from /play
|
||||
# account: "Account" # Tooltip on account button from /play
|
||||
# settings: "Settings" # Tooltip on settings button from /play
|
||||
account: "Akun" # Tooltip on account button from /play
|
||||
settings: "Settings" # Tooltip on settings button from /play
|
||||
# next: "Next" # Go from choose hero to choose inventory before playing a level
|
||||
# change_hero: "Change Hero" # Go back from choose inventory to choose hero
|
||||
# choose_inventory: "Equip Items"
|
||||
|
@ -70,10 +70,10 @@ module.exports = nativeDescription: "Bahasa Indonesia", englishDescription: "Ind
|
|||
# anonymous: "Anonymous Player"
|
||||
# level_difficulty: "Difficulty: "
|
||||
# campaign_beginner: "Beginner Campaign"
|
||||
# awaiting_levels_adventurer_prefix: "We release five levels per week."
|
||||
awaiting_levels_adventurer_prefix:"Kami meliris lima level per minggu"
|
||||
# awaiting_levels_adventurer: "Sign up as an Adventurer"
|
||||
# awaiting_levels_adventurer_suffix: "to be the first to play new levels."
|
||||
# choose_your_level: "Choose Your Level" # The rest of this section is the old play view at /play-old and isn't very important.
|
||||
choose_your_level: "Pilih Level Anda" # The rest of this section is the old play view at /play-old and isn't very important.
|
||||
# adventurer_prefix: "You can jump to any level below, or discuss the levels on "
|
||||
# adventurer_forum: "the Adventurer forum"
|
||||
# adventurer_suffix: "."
|
||||
|
@ -81,7 +81,7 @@ module.exports = nativeDescription: "Bahasa Indonesia", englishDescription: "Ind
|
|||
# campaign_old_beginner_description: "... in which you learn the wizardry of programming."
|
||||
# campaign_dev: "Random Harder Levels"
|
||||
# campaign_dev_description: "... in which you learn the interface while doing something a little harder."
|
||||
# campaign_multiplayer: "Multiplayer Arenas"
|
||||
campaign_multiplayer: "Arena Multiplayer"
|
||||
# campaign_multiplayer_description: "... in which you code head-to-head against other players."
|
||||
# campaign_player_created: "Player-Created"
|
||||
# campaign_player_created_description: "... in which you battle against the creativity of your fellow <a href=\"/contribute#artisan\">Artisan Wizards</a>."
|
||||
|
@ -90,11 +90,11 @@ module.exports = nativeDescription: "Bahasa Indonesia", englishDescription: "Ind
|
|||
# campaign_forest: "Forest Campaign"
|
||||
# campaign_dungeon: "Dungeon Campaign"
|
||||
|
||||
# login:
|
||||
# sign_up: "Create Account"
|
||||
# log_in: "Log In"
|
||||
# logging_in: "Logging In"
|
||||
# log_out: "Log Out"
|
||||
login:
|
||||
sign_up: "Buat Akun"
|
||||
log_in: "Masuk"
|
||||
logging_in: "Logging In"
|
||||
log_out: "Keluar"
|
||||
# recover: "recover account"
|
||||
# authenticate_gplus: "Authenticate G+"
|
||||
# load_profile: "Load G+ Profile"
|
||||
|
@ -106,7 +106,7 @@ module.exports = nativeDescription: "Bahasa Indonesia", englishDescription: "Ind
|
|||
# description: "It's free. Just need a couple things and you'll be good to go:"
|
||||
# email_announcements: "Receive announcements by email"
|
||||
# coppa: "13+ or non-USA "
|
||||
# coppa_why: "(Why?)"
|
||||
# coppa_why: "(Kenapa?)"
|
||||
# creating: "Creating Account..."
|
||||
# sign_up: "Sign Up"
|
||||
# log_in: "log in with password"
|
||||
|
|
1029
app/locale/nb.coffee
1029
app/locale/nb.coffee
File diff suppressed because it is too large
Load diff
|
@ -10,7 +10,7 @@ module.exports = nativeDescription: "Türkçe", englishDescription: "Turkish", t
|
|||
for_beginners: "Yeni Başlayanlar için"
|
||||
multiplayer: "Çoklu-oyuncu Kipi" # Not currently shown on home page
|
||||
for_developers: "Geliştiriciler için" # Not currently shown on home page.
|
||||
# or_ipad: "Or download for iPad"
|
||||
or_ipad: "Ya da iPad için indir"
|
||||
|
||||
nav:
|
||||
play: "Oyna" # The top nav bar entry where players choose which levels to play
|
||||
|
@ -52,11 +52,11 @@ module.exports = nativeDescription: "Türkçe", englishDescription: "Turkish", t
|
|||
players: "oyuncu" # Hover over a level on /play
|
||||
hours_played: "saat oynandı" # Hover over a level on /play
|
||||
items: "Ögeler" # Tooltip on item shop button from /play
|
||||
# unlock: "Unlock" # For purchasing items and heroes
|
||||
# confirm: "Confirm"
|
||||
# owned: "Owned" # For items you own
|
||||
# locked: "Locked"
|
||||
# available: "Available"
|
||||
unlock: "Kilidi aç" # For purchasing items and heroes
|
||||
confirm: "Devam et"
|
||||
owned: "Sahipsin" # For items you own
|
||||
locked: "Kilitli"
|
||||
available: "Açık"
|
||||
# skills_granted: "Skills Granted" # Property documentation details
|
||||
heroes: "Kahramanlar" # Tooltip on hero shop button from /play
|
||||
achievements: "Başarımlar" # Tooltip on achievement list button from /play
|
||||
|
@ -65,13 +65,13 @@ module.exports = nativeDescription: "Türkçe", englishDescription: "Turkish", t
|
|||
next: "İleri" # Go from choose hero to choose inventory before playing a level
|
||||
change_hero: "Kahramanı Değiştir" # Go back from choose inventory to choose hero
|
||||
choose_inventory: "Ögeleri Giy"
|
||||
# buy_gems: "Buy Gems"
|
||||
buy_gems: "Taş satın a"
|
||||
older_campaigns: "Daha Eski Görevler"
|
||||
anonymous: "Anonim Oyuncu"
|
||||
level_difficulty: "Zorluk: "
|
||||
campaign_beginner: "Acemi Seferi"
|
||||
# awaiting_levels_adventurer_prefix: "We release five levels per week."
|
||||
# awaiting_levels_adventurer: "Sign up as an Adventurer"
|
||||
awaiting_levels_adventurer: "Maceracı olmak için kayıt ol"
|
||||
# awaiting_levels_adventurer_suffix: "to be the first to play new levels."
|
||||
choose_your_level: "Seviye Seçimi" # The rest of this section is the old play view at /play-old and isn't very important.
|
||||
adventurer_prefix: "Aşağıdaki seviyelerden birini doğrudan oynayabilirsiniz, veya seviye ile ilgili "
|
||||
|
@ -87,8 +87,8 @@ module.exports = nativeDescription: "Türkçe", englishDescription: "Turkish", t
|
|||
campaign_player_created_description: "<a href=\"/contribute#artisan\">Zanaatkâr Büyücüler</a>in yaratıcılıklarına karşı mücadele etmek için..."
|
||||
campaign_classic_algorithms: "Klasik Algoritmalar"
|
||||
campaign_classic_algorithms_description: "... Bilgisayar Bilimleri'nde öğrendiğiniz en yaygın algoritmalar."
|
||||
# campaign_forest: "Forest Campaign"
|
||||
# campaign_dungeon: "Dungeon Campaign"
|
||||
campaign_forest: "Orman Senaryosu"
|
||||
campaign_dungeon: "Zindan Senaryosu"
|
||||
|
||||
login:
|
||||
sign_up: "Hesap Oluştur"
|
||||
|
@ -119,12 +119,12 @@ module.exports = nativeDescription: "Türkçe", englishDescription: "Turkish", t
|
|||
recovery_sent: "Kurtarma e-postası gönderildi."
|
||||
|
||||
items:
|
||||
# primary: "Primary"
|
||||
# secondary: "Secondary"
|
||||
primary: "Birincil"
|
||||
secondary: "İkincil"
|
||||
armor: "Zırh"
|
||||
accessories: "Aksesuarlar"
|
||||
misc: "Çeşitli"
|
||||
# books: "Books"
|
||||
books: "Kitaplar"
|
||||
|
||||
common:
|
||||
loading: "Yükleniyor..."
|
||||
|
@ -137,7 +137,7 @@ module.exports = nativeDescription: "Türkçe", englishDescription: "Turkish", t
|
|||
create: "Oluştur"
|
||||
manual: "El ile"
|
||||
fork: "Çatalla"
|
||||
play: "Oyna" # When used as an action verb, like "Play next level"
|
||||
play: "Oyna" # When used as an action verb, like "Sonraki Seviyeyi Oyna"
|
||||
retry: "Yeniden Dene"
|
||||
watch: "İzle"
|
||||
unwatch: "İzlemeyi Bırak"
|
||||
|
@ -201,16 +201,16 @@ module.exports = nativeDescription: "Türkçe", englishDescription: "Turkish", t
|
|||
restart: "Yeniden başlat"
|
||||
goals: "Hedefler"
|
||||
goal: "Amaç"
|
||||
# running: "Running..."
|
||||
running: "Çalıştırılıyor..."
|
||||
success: "Başarılı!"
|
||||
incomplete: "Tamamlanmamış"
|
||||
timed_out: "Süre bitti"
|
||||
failing: "Başarısız"
|
||||
action_timeline: "Eylem Çizelgesi"
|
||||
click_to_select: "Birimi seçmek için üzerine tıklayın."
|
||||
# control_bar_multiplayer: "Multiplayer"
|
||||
# control_bar_join_game: "Join Game"
|
||||
# reload: "Reload"
|
||||
control_bar_multiplayer: "Çoklu Oyuncu"
|
||||
control_bar_join_game: "Oyuna Katıl"
|
||||
reload: "Yeniden Yükle"
|
||||
reload_title: "Tüm kod yeniden yüklensin mi?"
|
||||
reload_really: "Bu seviyeyi en baştan yüklemek istediğinizden emin misiniz?"
|
||||
reload_confirm: "Tümünü Yeniden Yükle"
|
||||
|
@ -247,13 +247,13 @@ module.exports = nativeDescription: "Türkçe", englishDescription: "Turkish", t
|
|||
tome_available_spells: "Kullanılabilir Büyüler"
|
||||
tome_your_skills: "Yetenekleriniz"
|
||||
# tome_current_method: "Current Method"
|
||||
# hud_continue_short: "Continue"
|
||||
hud_continue_short: "Devam"
|
||||
code_saved: "Kod Kaydedildi"
|
||||
skip_tutorial: "Atla (ESC)"
|
||||
keyboard_shortcuts: "Klavye Kısayolları"
|
||||
loading_ready: "Hazır!"
|
||||
loading_start: "Seviyeyi Başlat"
|
||||
# problem_alert_title: "Fix Your Code"
|
||||
problem_alert_title: "Kodunu Düzelt"
|
||||
time_current: "Şimdi:"
|
||||
time_total: "Max:"
|
||||
time_goto: "Git:"
|
||||
|
@ -308,20 +308,20 @@ module.exports = nativeDescription: "Türkçe", englishDescription: "Turkish", t
|
|||
|
||||
inventory:
|
||||
choose_inventory: "Ögeleri Donan"
|
||||
# equipped_item: "Equipped"
|
||||
# available_item: "Available"
|
||||
equipped_item: "Giyilmiş"
|
||||
available_item: "Açık"
|
||||
# restricted_title: "Restricted"
|
||||
# should_equip: "(double-click to equip)"
|
||||
# equipped: "(equipped)"
|
||||
# locked: "(locked)"
|
||||
should_equip: "(iki kere tıklayarak giy)"
|
||||
equipped: "(giyildi)"
|
||||
locked: "(kitli)"
|
||||
# restricted: "(restricted in this level)"
|
||||
# equip: "Equip"
|
||||
# unequip: "Unequip"
|
||||
equip: "Giy"
|
||||
unequip: "Çıkar"
|
||||
|
||||
# buy_gems:
|
||||
# few_gems: "A few gems"
|
||||
# pile_gems: "Pile of gems"
|
||||
# chest_gems: "Chest of gems"
|
||||
buy_gems:
|
||||
few_gems: "Bir avuç taş"
|
||||
pile_gems: "Bir Torba"
|
||||
chest_gems: "Sandık dolusu taş"
|
||||
# purchasing: "Purchasing..."
|
||||
# declined: "Your card was declined"
|
||||
# retrying: "Server error, retrying."
|
||||
|
@ -330,7 +330,7 @@ module.exports = nativeDescription: "Türkçe", englishDescription: "Turkish", t
|
|||
choose_hero: "Kahramanınızı Seçin"
|
||||
programming_language: "Programlama Dili"
|
||||
programming_language_description: "Hangi programlama dilini kullanmak istiyorsunuz?"
|
||||
# default: "Default"
|
||||
# default: "Normal"
|
||||
# experimental: "Experimental"
|
||||
python_blurb: "Basit ancak güçlü. Python mükemmel bir genel amaçlı dildir."
|
||||
javascript_blurb: "Web'in dili."
|
||||
|
@ -347,8 +347,8 @@ module.exports = nativeDescription: "Türkçe", englishDescription: "Turkish", t
|
|||
health: "Sağlık"
|
||||
speed: "Hız"
|
||||
# regeneration: "Regeneration"
|
||||
# range: "Range" # As in "attack or visual range"
|
||||
# blocks: "Blocks" # As in "this shield blocks this much damage"
|
||||
range: "Menzil" # As in "attack or visual range"
|
||||
blocks: "Blok" # As in "this shield blocks this much damage"
|
||||
skills: "Yetenekler"
|
||||
|
||||
# skill_docs:
|
||||
|
|
|
@ -10,7 +10,7 @@ module.exports = nativeDescription: "简体中文", englishDescription: "Chinese
|
|||
for_beginners: "适合初学者"
|
||||
multiplayer: "多人游戏" # Not currently shown on home page
|
||||
for_developers: "适合开发者" # Not currently shown on home page.
|
||||
# or_ipad: "Or download for iPad"
|
||||
or_ipad: "或者下载iPad版本" # Or download for iPad
|
||||
|
||||
nav:
|
||||
play: "关卡选择" # The top nav bar entry where players choose which levels to play
|
||||
|
@ -208,8 +208,8 @@ module.exports = nativeDescription: "简体中文", englishDescription: "Chinese
|
|||
failing: "失败"
|
||||
action_timeline: "行动时间轴"
|
||||
click_to_select: "点击选择一个单元。"
|
||||
# control_bar_multiplayer: "Multiplayer"
|
||||
# control_bar_join_game: "Join Game"
|
||||
control_bar_multiplayer: "多人游戏"
|
||||
control_bar_join_game: "加入游戏"
|
||||
reload: "重载"
|
||||
reload_title: "重载所有代码?"
|
||||
reload_really: "确定重载这一关,返回开始处吗?"
|
||||
|
|
|
@ -133,6 +133,17 @@ _.extend ThangTypeSchema.properties,
|
|||
rasterIcon: { type: 'string', format: 'image-file', title: 'Raster Image Icon' }
|
||||
containerIcon: { type: 'string' }
|
||||
featureImage: { type: 'string', format: 'image-file', title: 'Feature Image' }
|
||||
featureImageHair: { type: 'string', format: 'image-file', title: 'Feature Image Hair' }
|
||||
featureImageThumb: { type: 'string', format: 'image-file', title: 'Feature Image Thumb' }
|
||||
dollImages: c.object { title: 'Paper Doll Images' },
|
||||
male: { type: 'string', format: 'image-file', title: ' Male' }
|
||||
female: { type: 'string', format: 'image-file', title: ' Female' }
|
||||
maleThumb: { type: 'string', format: 'image-file', title: 'Thumb (Male)' }
|
||||
femaleThumb: { type: 'string', format: 'image-file', title: 'Thumb (Female)' }
|
||||
maleRanger: { type: 'string', format: 'image-file', title: 'Glove (Male Ranger)' }
|
||||
maleRangerThumb: { type: 'string', format: 'image-file', title: 'Thumb (Male Ranger)' }
|
||||
femaleRanger: { type: 'string', format: 'image-file', title: 'Glove (Female Ranger)' }
|
||||
femaleRangeThumbr: { type: 'string', format: 'image-file', title: 'Thumb (Female Ranger)' }
|
||||
colorGroups: c.object
|
||||
title: 'Color Groups'
|
||||
additionalProperties:
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
@import "app/styles/mixins"
|
||||
|
||||
$itemSlotSize: 55px
|
||||
$itemSlotSize: 48px
|
||||
$itemSlotInnerWidth: $itemSlotSize - 4
|
||||
$itemSlotGridHeight: 70px
|
||||
$itemSlotGridWidth: 51px
|
||||
$itemSlotGridHeight: 51px
|
||||
|
||||
.ui-effects-transfer
|
||||
outline: 2px solid #28f
|
||||
|
@ -83,15 +84,6 @@ $itemSlotGridHeight: 70px
|
|||
height: 450px
|
||||
overflow: hidden
|
||||
|
||||
#hero-image
|
||||
@include filter(contrast(0%) brightness(0%))
|
||||
opacity: 0.4
|
||||
width: 225px
|
||||
height: 410px
|
||||
position: absolute
|
||||
left: 10px
|
||||
top: 20px
|
||||
|
||||
.item-slot
|
||||
width: $itemSlotSize
|
||||
height: $itemSlotSize
|
||||
|
@ -101,6 +93,7 @@ $itemSlotGridHeight: 70px
|
|||
position: relative
|
||||
cursor: pointer
|
||||
@include transition(0.5s ease)
|
||||
z-index: 20
|
||||
|
||||
//&.disabled
|
||||
// opacity: 0.5
|
||||
|
@ -134,36 +127,36 @@ $itemSlotGridHeight: 70px
|
|||
background-image: url(/images/pages/game-menu/slot-icons.png)
|
||||
|
||||
|
||||
// A terrible awful bit of styling, but will be gone or messed around with soon anyway
|
||||
// Positioning the slots manually
|
||||
|
||||
&[data-slot]
|
||||
position: absolute
|
||||
top: 10px
|
||||
left: 10px
|
||||
|
||||
&[data-slot="misc-1"]
|
||||
display: none // hiding for now
|
||||
position: absolute
|
||||
left: 250px
|
||||
top: 20px + ($itemSlotGridHeight * 3)
|
||||
left: 10px + ($itemSlotGridWidth * 0)
|
||||
top: 15px + ($itemSlotGridHeight * 3)
|
||||
.placeholder
|
||||
background-position: (-0 * $itemSlotInnerWidth) 0px
|
||||
|
||||
&[data-slot="misc-0"]
|
||||
display: none // hiding for now
|
||||
position: absolute
|
||||
left: 250px
|
||||
top: 20px + ($itemSlotGridHeight * 2)
|
||||
left: 10px + ($itemSlotGridWidth * 0)
|
||||
top: 15px + ($itemSlotGridHeight * 2)
|
||||
.placeholder
|
||||
background-position: (-4 * $itemSlotInnerWidth) 0px
|
||||
|
||||
|
||||
&[data-slot="minion"]
|
||||
position: absolute
|
||||
left: 250px
|
||||
top: 20px + ($itemSlotGridHeight * 1)
|
||||
left: 10px + ($itemSlotGridWidth * 0)
|
||||
top: 15px + ($itemSlotGridHeight * 0)
|
||||
.placeholder
|
||||
background-position: (-1 * $itemSlotInnerWidth) 0px
|
||||
|
||||
&[data-slot="programming-book"]
|
||||
position: absolute
|
||||
left: 250px
|
||||
top: 20px + ($itemSlotGridHeight * 4)
|
||||
left: 10px + ($itemSlotGridWidth * 0)
|
||||
top: 15px + ($itemSlotGridHeight * 0)
|
||||
.placeholder
|
||||
background-position: (-3 * $itemSlotInnerWidth) 0px
|
||||
|
||||
|
@ -172,100 +165,86 @@ $itemSlotGridHeight: 70px
|
|||
// background-position: (-2 * $itemSlotInnerWidth) 0px
|
||||
|
||||
&[data-slot="wrists"]
|
||||
position: absolute
|
||||
left: 20px
|
||||
top: 20px + ($itemSlotGridHeight * 2.5)
|
||||
left: 10px + ($itemSlotGridWidth * 0)
|
||||
top: 15px + ($itemSlotGridHeight * 0)
|
||||
.placeholder
|
||||
background-position: (-5 * $itemSlotInnerWidth) 0px
|
||||
|
||||
&[data-slot="left-ring"]
|
||||
position: absolute
|
||||
left: 250px
|
||||
top: 20px + ($itemSlotGridHeight * 2)
|
||||
left: 10px + ($itemSlotGridWidth * 4)
|
||||
top: 15px + ($itemSlotGridHeight * 0)
|
||||
.placeholder
|
||||
background-position: (-6 * $itemSlotInnerWidth) 0px
|
||||
|
||||
&[data-slot="right-ring"]
|
||||
position: absolute
|
||||
left: 250px
|
||||
top: 20px + ($itemSlotGridHeight * 3)
|
||||
left: 10px + ($itemSlotGridWidth * 1)
|
||||
top: 15px + ($itemSlotGridHeight * 0)
|
||||
.placeholder
|
||||
background-position: (-7 * $itemSlotInnerWidth) 0px
|
||||
|
||||
&[data-slot="torso"]
|
||||
position: absolute
|
||||
left: 90px
|
||||
top: 20px + ($itemSlotGridHeight * 3)
|
||||
left: 10px + ($itemSlotGridWidth * 5)
|
||||
top: 15px + ($itemSlotGridHeight * 2)
|
||||
.placeholder
|
||||
background-position: (-8 * $itemSlotInnerWidth) 0px
|
||||
|
||||
&[data-slot="feet"]
|
||||
position: absolute
|
||||
left: 90px
|
||||
top: 20px + ($itemSlotGridHeight * 5)
|
||||
left: 10px + ($itemSlotGridWidth * 0)
|
||||
top: 15px + ($itemSlotGridHeight * 7.2)
|
||||
.placeholder
|
||||
background-position: (-9 * $itemSlotInnerWidth) 0px
|
||||
|
||||
&[data-slot="neck"]
|
||||
position: absolute
|
||||
left: 90px
|
||||
top: 20px + ($itemSlotGridHeight * 2)
|
||||
left: 10px + ($itemSlotGridWidth * 3)
|
||||
top: 15px + ($itemSlotGridHeight * 0)
|
||||
.placeholder
|
||||
background-position: (-10 * $itemSlotInnerWidth) 0px
|
||||
|
||||
&[data-slot="waist"]
|
||||
position: absolute
|
||||
left: 90px
|
||||
top: 20px + ($itemSlotGridHeight * 4)
|
||||
left: 10px + ($itemSlotGridWidth * 0)
|
||||
top: 15px + ($itemSlotGridHeight * 1)
|
||||
.placeholder
|
||||
background-position: (-11 * $itemSlotInnerWidth) 0px
|
||||
|
||||
&[data-slot="eyes"]
|
||||
position: absolute
|
||||
left: 90px
|
||||
top: 20px + $itemSlotGridHeight
|
||||
left: 10px + ($itemSlotGridWidth * 2)
|
||||
top: 15px + ($itemSlotGridHeight * 0)
|
||||
.placeholder
|
||||
background-position: (-12 * $itemSlotInnerWidth) 0px
|
||||
|
||||
&[data-slot="head"]
|
||||
position: absolute
|
||||
left: 90px
|
||||
top: 20px
|
||||
left: 10px + ($itemSlotGridWidth * 5)
|
||||
top: 15px + ($itemSlotGridHeight * 1)
|
||||
.placeholder
|
||||
background-position: (-13 * $itemSlotInnerWidth) 0px
|
||||
|
||||
&[data-slot="pet"]
|
||||
position: absolute
|
||||
left: 250px
|
||||
top: 20px
|
||||
left: 10px + ($itemSlotGridWidth * 5)
|
||||
top: 15px + ($itemSlotGridHeight * 7.2)
|
||||
.placeholder
|
||||
background-position: (-14 * $itemSlotInnerWidth) 0px
|
||||
|
||||
&[data-slot="gloves"]
|
||||
position: absolute
|
||||
left: 160px
|
||||
top: 20px + ($itemSlotGridHeight * 2.5)
|
||||
left: 10px + ($itemSlotGridWidth * 0)
|
||||
top: 15px + ($itemSlotGridHeight * 2)
|
||||
.placeholder
|
||||
background-position: (-15 * $itemSlotInnerWidth) 0px
|
||||
|
||||
&[data-slot="left-hand"]
|
||||
position: absolute
|
||||
left: 160px
|
||||
top: 20px + ($itemSlotGridHeight * 3.5)
|
||||
left: 10px + ($itemSlotGridWidth * 5)
|
||||
top: 15px + ($itemSlotGridHeight * 3)
|
||||
.placeholder
|
||||
background-position: (-16 * $itemSlotInnerWidth) 0px
|
||||
|
||||
&[data-slot="right-hand"]
|
||||
position: absolute
|
||||
left: 20px
|
||||
top: 20px + ($itemSlotGridHeight * 3.5)
|
||||
left: 10px + ($itemSlotGridWidth * 0)
|
||||
top: 15px + ($itemSlotGridHeight * 3)
|
||||
.placeholder
|
||||
background-position: (-17 * $itemSlotInnerWidth) 0px
|
||||
|
||||
&[data-slot="flag"]
|
||||
position: absolute
|
||||
left: 250px
|
||||
top: 20px + ($itemSlotGridHeight * 5)
|
||||
left: 10px + ($itemSlotGridWidth * 5)
|
||||
top: 15px + ($itemSlotGridHeight * 0)
|
||||
.placeholder
|
||||
background-position: (-2 * $itemSlotInnerWidth) 0px
|
||||
|
||||
|
@ -498,3 +477,130 @@ $itemSlotGridHeight: 70px
|
|||
#equip-item-viewed
|
||||
background: rgb(84,128,44)
|
||||
color: white
|
||||
|
||||
//- Paper doll positioning
|
||||
|
||||
#hero-image
|
||||
//@include filter(contrast(0%) brightness(0%))
|
||||
//opacity: 0.4
|
||||
//width: 225px
|
||||
display: block
|
||||
position: absolute
|
||||
z-index: 12
|
||||
|
||||
&.male
|
||||
left: 65px
|
||||
bottom: 31px
|
||||
|
||||
&.female
|
||||
left: 80px
|
||||
bottom: 31px
|
||||
|
||||
#hero-image-hair
|
||||
position: absolute
|
||||
z-index: 16
|
||||
|
||||
&.female
|
||||
left: 103px
|
||||
bottom: 218px
|
||||
|
||||
&.male
|
||||
left: 124px
|
||||
bottom: 228px
|
||||
|
||||
#hero-image-thumb
|
||||
position: absolute
|
||||
z-index: 16
|
||||
|
||||
&.female
|
||||
left: 81px
|
||||
bottom: 150px
|
||||
@include rotate(-15deg)
|
||||
|
||||
&.male
|
||||
left: 68px
|
||||
bottom: 121px
|
||||
@include rotate(-15deg)
|
||||
|
||||
.doll-image
|
||||
position: absolute
|
||||
z-index: 15
|
||||
|
||||
&.feet
|
||||
z-index: 13
|
||||
|
||||
&.female
|
||||
left: 101px
|
||||
bottom: 37px
|
||||
|
||||
&.male
|
||||
left: 98px
|
||||
bottom: 37px
|
||||
|
||||
&.right-hand
|
||||
&.female
|
||||
left: 48px
|
||||
bottom: 132px
|
||||
@include rotate(-15deg)
|
||||
|
||||
&.male
|
||||
left: 40px
|
||||
bottom: 111px
|
||||
@include rotate(-15deg)
|
||||
|
||||
&.left-hand
|
||||
z-index: 17
|
||||
&.female
|
||||
left: 193px
|
||||
bottom: 72px
|
||||
|
||||
&.male
|
||||
left: 193px
|
||||
bottom: 72px
|
||||
|
||||
&.torso
|
||||
z-index: 14
|
||||
|
||||
&.female
|
||||
left: 72px
|
||||
bottom: 105px
|
||||
|
||||
&.male
|
||||
left: 55px
|
||||
bottom: 69px
|
||||
|
||||
&.gloves
|
||||
z-index: 15
|
||||
|
||||
&.female
|
||||
left: 78px
|
||||
bottom: 133px
|
||||
|
||||
&.female-thumb
|
||||
z-index: 16
|
||||
left: 81px
|
||||
bottom: 150px
|
||||
@include rotate(-15deg)
|
||||
|
||||
&.male
|
||||
left: 65px
|
||||
bottom: 109px
|
||||
|
||||
&.male-thumb
|
||||
z-index: 16
|
||||
left: 68px
|
||||
bottom: 121px
|
||||
@include rotate(-15deg)
|
||||
|
||||
&.head
|
||||
z-index: 16
|
||||
|
||||
&.female
|
||||
left: 72px
|
||||
bottom: 105px
|
||||
|
||||
&.male
|
||||
left: 119px
|
||||
bottom: 180px
|
||||
|
||||
|
||||
|
|
|
@ -70,3 +70,15 @@
|
|||
.alert
|
||||
top: 213px
|
||||
border: 5px solid darkred
|
||||
|
||||
&.hour-of-code
|
||||
#site-footer
|
||||
background-color: rgb(70, 58, 44)
|
||||
height: 185px
|
||||
|
||||
.hour-of-code-explanation
|
||||
color: #9e8777
|
||||
text-align: center
|
||||
|
||||
a
|
||||
color: lighten(#0b63bc, 10%)
|
||||
|
|
|
@ -231,6 +231,23 @@
|
|||
width: calc(33.333333% - 10px)
|
||||
margin: 5px
|
||||
|
||||
.hour-of-code-done
|
||||
clear: both
|
||||
padding-top: 10px
|
||||
|
||||
strong
|
||||
color: white
|
||||
display: block
|
||||
margin-bottom: 10px
|
||||
font-weight: normal
|
||||
|
||||
.image-link
|
||||
float: right
|
||||
margin-left: 10px
|
||||
|
||||
.text-link
|
||||
color: lighten(#0b63bc, 10%)
|
||||
|
||||
|
||||
html.no-borderimage
|
||||
#hero-victory-modal
|
||||
|
|
|
@ -86,3 +86,5 @@ block footer
|
|||
a(href="http://www.fullyillustrated.com/") Fully Illustrated
|
||||
a.firebase-bade(href="https://www.firebase.com/")
|
||||
img(src="/images/pages/base/firebase.png", alt="Powered by Firebase")
|
||||
|
||||
block extra_footer_content
|
||||
|
|
|
@ -26,7 +26,7 @@ block content
|
|||
p
|
||||
span(data-i18n="community.thang_editor_prefix") We call units within the game 'thangs'. Use the
|
||||
a.spl.spr(href="/editor/thang", data-i18n="editor.thang_title")
|
||||
span(data-i18n="community.level_editor_suffix") to modify the CodeCombat source artwork. Allow units to throw projectiles, alter the direction of an animation, change a unit's hit points, or upload your own vector sprites.
|
||||
span(data-i18n="community.thang_editor_suffix") to modify the CodeCombat source artwork. Allow units to throw projectiles, alter the direction of an animation, change a unit's hit points, or upload your own vector sprites.
|
||||
|
||||
.community-columns
|
||||
a(href="/editor/article")
|
||||
|
|
|
@ -10,7 +10,11 @@
|
|||
|
||||
#equipped
|
||||
if selectedHero && selectedHero.get('featureImage')
|
||||
img(src="/file/"+selectedHero.get('featureImage'))#hero-image
|
||||
img(src="/file/"+selectedHero.get('featureImage'), draggable="false")#hero-image
|
||||
if selectedHero.get('featureImageHair')
|
||||
img(src="/file/"+selectedHero.get('featureImageHair'), draggable="false")#hero-image-hair
|
||||
if selectedHero.get('featureImageThumb')
|
||||
img(src="/file/"+selectedHero.get('featureImageThumb'), draggable="false")#hero-image-thumb
|
||||
|
||||
for slot in ['head', 'eyes', 'neck', 'torso', 'gloves', 'wrists', 'left-hand', 'right-hand', 'waist', 'feet', 'left-ring', 'right-ring', 'minion', 'flag', 'pet', 'programming-book', 'misc-0', 'misc-1']
|
||||
.item-slot(data-slot=slot)
|
||||
|
|
|
@ -22,4 +22,13 @@ block outer_content
|
|||
strong(data-i18n="home.old_browser") Uh oh, your browser is too old to run CodeCombat. Sorry!
|
||||
br
|
||||
span(data-i18n="home.old_browser_suffix") You can try anyway, but it probably won't work.
|
||||
|
||||
|
||||
block extra_footer_content
|
||||
if true || explainHourOfCode
|
||||
// Does not show up unless lang is en-US.
|
||||
div.hour-of-code-explanation
|
||||
| The 'Hour of Code' is a nationwide initiative by
|
||||
a(href="http://csedweek.org") Computer Science Education Week
|
||||
| and
|
||||
a(href="http://code.org") Code.org
|
||||
| to introduce millions of students to one hour of computer science and computer programming.
|
|
@ -37,11 +37,3 @@
|
|||
#play-footer
|
||||
p(class='footer-link-text')
|
||||
a(title='Send CodeCombat a message', tabindex=-1, data-toggle="coco-modal", data-target="modal/ContactModal", data-i18n="nav.contact") Contact
|
||||
if explainHourOfCode
|
||||
// Does not show up unless lang is en-US.
|
||||
div.hour-of-code-explanation
|
||||
| The 'Hour of Code' is a nationwide initiative by
|
||||
a(href="http://csedweek.org") Computer Science Education Week
|
||||
| and
|
||||
a(href="http://code.org") Code.org
|
||||
| to introduce millions of students to one hour of computer science and computer programming.
|
|
@ -69,3 +69,12 @@ block modal-footer-content
|
|||
button.btn.btn-primary.return-to-ladder-button(data-href="/play/ladder/#{level.get('slug')}#my-matches", data-dismiss="modal", data-i18n="play_level.victory_return_to_ladder") Return to Ladder
|
||||
else
|
||||
button.btn.btn-success.world-map-button.next-level-button.hide#continue-button(data-i18n="play_level.victory_play_continue") Continue
|
||||
|
||||
if showHourOfCodeDoneButton
|
||||
.hour-of-code-done
|
||||
hr
|
||||
a.image-link(href="http://code.org/api/hour/finish")
|
||||
img(src="/images/level/csedweek-logo-final-small.jpg", alt="CS Ed Week Hour of Code", title="I'm finished with my Hour of Code", width=80)
|
||||
strong(data-i18n="play_level.victory_hour_of_code_done") Are You Done?
|
||||
a.text-link(href="http://code.org/api/hour/finish")
|
||||
span(data-i18n="play_level.victory_hour_of_code_done_yes") Yes, I'm finished with my Hour of Code!
|
||||
|
|
|
@ -1,34 +0,0 @@
|
|||
RootView = require 'views/kinds/RootView'
|
||||
template = require 'templates/front-view'
|
||||
{me} = require '/lib/auth'
|
||||
ModalView = require 'views/kinds/ModalView'
|
||||
|
||||
module.exports = class FrontView extends RootView
|
||||
id: 'front-view'
|
||||
template: template
|
||||
|
||||
events:
|
||||
'click .platform-ios a': 'onIOSClicked'
|
||||
|
||||
getRenderData: ->
|
||||
c = super()
|
||||
if $.browser
|
||||
majorVersion = $.browser.versionNumber
|
||||
c.isOldBrowser = true if $.browser.mozilla && majorVersion < 21
|
||||
c.isOldBrowser = true if $.browser.chrome && majorVersion < 17
|
||||
c.isOldBrowser = true if $.browser.safari && majorVersion < 6
|
||||
else
|
||||
console.warn 'no more jquery browser version...'
|
||||
c
|
||||
|
||||
afterRender: ->
|
||||
super()
|
||||
|
||||
onIOSClicked: (e) ->
|
||||
header = 'Sorry, the iPad app isn\'t ready yet'
|
||||
body = '''
|
||||
<p class="lead">We are working on it!</p>
|
||||
<p>For now, try playing on the web, and totally sign up (with emails enabled) so you can be the first to hear when it is ready.</p>
|
||||
'''
|
||||
notImplementedModal = new ModalView headerContent: header, bodyContent: body
|
||||
@openModalView notImplementedModal
|
|
@ -16,6 +16,12 @@ module.exports = class HomeView extends RootView
|
|||
constructor: ->
|
||||
super()
|
||||
window.tracker?.trackEvent 'Homepage', Action: 'Loaded'
|
||||
if not me.get('hourOfCode') and @getQueryVariable 'hour_of_code'
|
||||
@setUpHourOfCode()
|
||||
elapsed = (new Date() - new Date(me.get('dateCreated')))
|
||||
if me.get('hourOfCode') and elapsed < 86400 * 1000 and me.get('preferredLanguage', true) is 'en-US'
|
||||
# Show the Hour of Code footer explanation in English until it's been more than a day
|
||||
@explainsHourOfCode = true
|
||||
|
||||
getRenderData: ->
|
||||
c = super()
|
||||
|
@ -28,6 +34,7 @@ module.exports = class HomeView extends RootView
|
|||
console.warn 'no more jquery browser version...'
|
||||
c.isEnglish = (me.get('preferredLanguage') or 'en').startsWith 'en'
|
||||
c.languageName = me.get('preferredLanguage')
|
||||
c.explainsHourOfCode = @explainsHourOfCode
|
||||
c
|
||||
|
||||
onClickBeginnerCampaign: (e) ->
|
||||
|
@ -39,3 +46,17 @@ module.exports = class HomeView extends RootView
|
|||
|
||||
afterInsert: ->
|
||||
super(arguments...)
|
||||
@$el.addClass 'hour-of-code' if @explainsHourOfCode
|
||||
if me.isAdmin() and me.get('slug') is 'nick'
|
||||
LevelSetupManager = require 'lib/LevelSetupManager'
|
||||
setupManager = new LevelSetupManager levelID: 'dungeons-of-kithgard', hadEverChosenHero: true, parent: @
|
||||
setupManager.open()
|
||||
|
||||
setUpHourOfCode: ->
|
||||
elapsed = (new Date() - new Date(me.get('dateCreated')))
|
||||
if elapsed < 5 * 60 * 1000
|
||||
me.set 'hourOfCode', true
|
||||
me.patch()
|
||||
# We may also insert the tracking pixel for everyone on the WorldMapView so as to count directly-linked visitors.
|
||||
$('body').append($('<img src="http://code.org/api/hour/begin_codecombat.png" style="visibility: hidden;">'))
|
||||
application.tracker?.trackEvent 'Hour of Code Begin', {}
|
||||
|
|
|
@ -76,7 +76,7 @@ module.exports = class DiplomatView extends ContributeClassView
|
|||
bg: [] # български език, Bulgarian
|
||||
no: ['bardeh', 'torehaug'] # Norsk, Norwegian
|
||||
nn: [] # Norwegian (Nynorsk), Norwegian Nynorsk
|
||||
nb: ['mcclane654'] # Norsk Bokmål, Norwegian (Bokmål)
|
||||
nb: ['ebirkenes','mcclane654'] # Norsk Bokmål, Norwegian (Bokmål)
|
||||
he: ['OverProgram', 'monetita'] # עברית, Hebrew
|
||||
lt: [] # lietuvių kalba, Lithuanian
|
||||
sr: [] # српски, Serbian
|
||||
|
|
|
@ -54,6 +54,7 @@ module.exports = class InventoryModal extends ModalView
|
|||
'components'
|
||||
'original'
|
||||
'rasterIcon'
|
||||
'dollImages'
|
||||
'gems'
|
||||
'tier'
|
||||
'description'
|
||||
|
@ -144,6 +145,7 @@ module.exports = class InventoryModal extends ModalView
|
|||
@canvasHeight = @$el.find('canvas').innerHeight()
|
||||
@inserted = true
|
||||
@requireLevelEquipment()
|
||||
@onEquipmentChanged()
|
||||
|
||||
#- Draggable logic
|
||||
|
||||
|
@ -269,6 +271,7 @@ module.exports = class InventoryModal extends ModalView
|
|||
@makeEquippedSlotDraggable slotEl
|
||||
@requireLevelEquipment()
|
||||
@onSelectionChanged()
|
||||
@onEquipmentChanged()
|
||||
|
||||
unequipSelectedItem: ->
|
||||
slotEl = @getSelectedSlot()
|
||||
|
@ -283,7 +286,7 @@ module.exports = class InventoryModal extends ModalView
|
|||
@showItemDetails(item, 'equip')
|
||||
@requireLevelEquipment()
|
||||
@onSelectionChanged()
|
||||
|
||||
@onEquipmentChanged()
|
||||
|
||||
#- Select/equip helpers
|
||||
|
||||
|
@ -399,6 +402,7 @@ module.exports = class InventoryModal extends ModalView
|
|||
@$el.removeClass('Warrior Ranger Wizard').addClass(@selectedHero.get('heroClass'))
|
||||
@requireLevelEquipment()
|
||||
@render()
|
||||
@onEquipmentChanged()
|
||||
|
||||
onShown: ->
|
||||
# Called when we switch tabs to this within the modal
|
||||
|
@ -515,13 +519,56 @@ module.exports = class InventoryModal extends ModalView
|
|||
return if @destroyed
|
||||
@$el.find('.unlock-button').popover 'destroy'
|
||||
|
||||
|
||||
#- Paper doll equipment updating
|
||||
onEquipmentChanged: ->
|
||||
@removeDollImages()
|
||||
heroClass = @selectedHero?.get('heroClass') ? 'Warrior'
|
||||
gender = if @selectedHero?.get('slug') in heroGenders.male then 'male' else 'female'
|
||||
equipment = @getCurrentEquipmentConfig()
|
||||
slotsWithImages = []
|
||||
for slot, original of equipment
|
||||
item = _.find @items.models, (item) -> item.get('original') is original
|
||||
continue unless dollImages = item?.get('dollImages')
|
||||
didAdd = @addDollImage slot, dollImages, heroClass, gender
|
||||
slotsWithImages.push slot if didAdd
|
||||
@$el.find('#hero-image, #hero-image-hair, #hero-image-thumb').removeClass().addClass "#{gender} #{heroClass}"
|
||||
@$el.find('#hero-image-hair').toggle not ('head' in slotsWithImages)
|
||||
@$el.find('#hero-image-thumb').toggle not ('gloves' in slotsWithImages)
|
||||
|
||||
removeDollImages: ->
|
||||
@$el.find('.doll-image').remove()
|
||||
|
||||
addDollImage: (slot, dollImages, heroClass, gender) ->
|
||||
heroClass = @selectedHero?.get('heroClass') ? 'Warrior'
|
||||
gender = if @selectedHero?.get('slug') in heroGenders.male then 'male' else 'female'
|
||||
didAdd = false
|
||||
if slot is 'gloves'
|
||||
if heroClass is 'Ranger'
|
||||
imageKeys = ["#{gender}#{heroClass}", "#{gender}#{heroClass}Thumb"]
|
||||
else
|
||||
imageKeys = ["#{gender}", "#{gender}Thumb"]
|
||||
else
|
||||
imageKeys = [gender]
|
||||
for imageKey in imageKeys
|
||||
imageURL = dollImages[imageKey]
|
||||
if not imageURL
|
||||
console.log "Hmm, should have #{slot} #{imageKey} paper doll image, but don't have it."
|
||||
else
|
||||
imageEl = $('<img>').attr('src', "/file/#{imageURL}").addClass("doll-image #{slot} #{heroClass} #{gender} #{_.string.underscored(imageKey).replace(/_/g, '-')}").attr('draggable', false)
|
||||
@$el.find('#equipped').append imageEl
|
||||
didAdd = true
|
||||
didAdd
|
||||
|
||||
destroy: ->
|
||||
@$el.find('.unlock-button').popover 'destroy'
|
||||
@stage?.removeAllChildren()
|
||||
super()
|
||||
|
||||
|
||||
|
||||
heroGenders =
|
||||
male: ['knight', 'samurai', 'trapper', 'potion-master']
|
||||
female: ['captain', 'ninja', 'forest-archer', 'librarian', 'sorcerer']
|
||||
|
||||
gear =
|
||||
'simple-boots': '53e237bf53457600003e3f05'
|
||||
|
|
|
@ -319,6 +319,13 @@ playerCreated = [
|
|||
image: '/file/db/level/526711d9add4f8965f000002/hunter_triplets_icon.png'
|
||||
description: 'There is a horde of ogres marching on your village. Stay out of reach and use your bow to take them out! - by Danny Whittaker'
|
||||
}
|
||||
{
|
||||
name: "IFC - Videira"
|
||||
difficulty: 3
|
||||
id: 'ifc-videira'
|
||||
image: '/file/db/level/52602ecb026e8481e7000001/generic_1.png'
|
||||
description: 'A level inspired by IFC Videira. - by Leonardo Meneguzzi.'
|
||||
}
|
||||
]
|
||||
|
||||
campaigns = [
|
||||
|
|
|
@ -10,6 +10,8 @@ MusicPlayer = require 'lib/surface/MusicPlayer'
|
|||
storage = require 'lib/storage'
|
||||
AuthModal = require 'views/modal/AuthModal'
|
||||
|
||||
trackedHourOfCode = false
|
||||
|
||||
class LevelSessionsCollection extends CocoCollection
|
||||
url: ''
|
||||
model: LevelSession
|
||||
|
@ -70,6 +72,12 @@ module.exports = class WorldMapView extends RootView
|
|||
@listenTo me, 'change:spent', -> @renderSelectors('#gems-count')
|
||||
window.tracker?.trackEvent 'World Map', Action: 'Loaded', ['Google Analytics']
|
||||
|
||||
# If it's a new player who didn't appear to come from Hour of Code, we register her here without setting the hourOfCode property.
|
||||
elapsed = (new Date() - new Date(me.get('dateCreated')))
|
||||
if not trackedHourOfCode and not me.get('hourOfCode') and elapsed < 5 * 60 * 1000
|
||||
$('body').append($('<img src="http://code.org/api/hour/begin_codecombat.png" style="visibility: hidden;">'))
|
||||
trackedHourOfCode = true
|
||||
|
||||
destroy: ->
|
||||
@setupManager?.destroy()
|
||||
$(window).off 'resize', @onWindowResize
|
||||
|
|
|
@ -93,8 +93,6 @@ module.exports = class PlayLevelView extends RootView
|
|||
constructor: (options, @levelID) ->
|
||||
console.profile?() if PROFILE_ME
|
||||
super options
|
||||
if not me.get('hourOfCode') and @getQueryVariable 'hour_of_code'
|
||||
@setUpHourOfCode()
|
||||
|
||||
@isEditorPreview = @getQueryVariable 'dev'
|
||||
@sessionID = @getQueryVariable 'session'
|
||||
|
@ -114,12 +112,6 @@ module.exports = class PlayLevelView extends RootView
|
|||
@load()
|
||||
application.tracker?.trackEvent 'Started Level Load', level: @levelID, label: @levelID, ['Google Analytics']
|
||||
|
||||
setUpHourOfCode: ->
|
||||
me.set 'hourOfCode', true
|
||||
me.patch()
|
||||
$('body').append($('<img src="http://code.org/api/hour/begin_codecombat.png" style="visibility: hidden;">'))
|
||||
application.tracker?.trackEvent 'Hour of Code Begin', {}
|
||||
|
||||
setLevel: (@level, givenSupermodel) ->
|
||||
@supermodel.models = givenSupermodel.models
|
||||
@supermodel.collections = givenSupermodel.collections
|
||||
|
@ -152,10 +144,6 @@ module.exports = class PlayLevelView extends RootView
|
|||
getRenderData: ->
|
||||
c = super()
|
||||
c.world = @world
|
||||
if me.get('hourOfCode') and me.get('preferredLanguage', true) is 'en-US'
|
||||
# Show the Hour of Code footer explanation until it's been more than a day
|
||||
elapsed = (new Date() - new Date(me.get('dateCreated')))
|
||||
c.explainHourOfCode = elapsed < 86400 * 1000
|
||||
c
|
||||
|
||||
afterRender: ->
|
||||
|
@ -606,7 +594,7 @@ module.exports = class PlayLevelView extends RootView
|
|||
# Current real-time multiplayer session
|
||||
# Internal multiplayer create/joined/left events
|
||||
#
|
||||
# Real-time state variables.
|
||||
# Real-time state variables.
|
||||
# Each Ref is Firebase reference, and may have a matching Data suffixed variable with the latest data received.
|
||||
# @realTimePlayerRef - User's real-time multiplayer player for this level
|
||||
# @realTimePlayerGameRef - User's current real-time multiplayer player game session
|
||||
|
@ -727,7 +715,7 @@ module.exports = class PlayLevelView extends RootView
|
|||
|
||||
@realTimeSessionRef = new Firebase "#{@multiplayerFireHost}multiplayer_level_sessions/#{@levelID}/#{e.realTimeSessionID}"
|
||||
@realTimePlayersRef = @realTimeSessionRef.child 'players'
|
||||
|
||||
|
||||
# Look for opponent
|
||||
@realTimeSessionRef.once 'value', (multiplayerSessionSnapshot) =>
|
||||
if @realTimeSessionData = multiplayerSessionSnapshot.val()
|
||||
|
@ -751,7 +739,7 @@ module.exports = class PlayLevelView extends RootView
|
|||
console.error 'Could not lookup multiplayer session data.'
|
||||
@realTimeSessionRef.on 'value', @onRealTimeSessionChanged
|
||||
|
||||
@realTimePlayerGameRef = @realTimeSessionRef.child "players/#{me.id}"
|
||||
@realTimePlayerGameRef = @realTimeSessionRef.child "players/#{me.id}"
|
||||
|
||||
# TODO: Follow up in MultiplayerView to see if double joins can be avoided
|
||||
# else
|
||||
|
@ -817,7 +805,7 @@ module.exports = class PlayLevelView extends RootView
|
|||
unless @realTimeSessionRef?
|
||||
console.error 'Real-time multiplayer cast without multiplayer session.'
|
||||
return
|
||||
unless @realTimeSessionData?
|
||||
unless @realTimeSessionData?
|
||||
console.error 'Real-time multiplayer cast without multiplayer data.'
|
||||
return
|
||||
unless @realTimePlayersData?
|
||||
|
|
|
@ -80,7 +80,7 @@ module.exports = class HeroVictoryModal extends ModalView
|
|||
@readyToContinue = true
|
||||
@updateSavingProgressStatus()
|
||||
me.fetch() unless me.loading
|
||||
|
||||
|
||||
@readyToContinue = true if not @achievements.models.length
|
||||
|
||||
getRenderData: ->
|
||||
|
@ -117,6 +117,23 @@ module.exports = class HeroVictoryModal extends ModalView
|
|||
{key: 'continue', link: @continueLevelLink, 'choice-explicit': 'next_level', 'choice-implicit': 'just_right'}
|
||||
{key: 'more_practice', link: @morePracticeLevelLink, 'choice-explicit': 'more_practice', 'choice-implicit': 'too_hard'}
|
||||
]
|
||||
|
||||
elapsed = (new Date() - new Date(me.get('dateCreated')))
|
||||
isHourOfCode = me.get('hourOfCode') or elapsed < 120 * 60 * 1000
|
||||
# Later we should only check me.get('hourOfCode'), but for now so much traffic comes in that we just assume it.
|
||||
if isHourOfCode
|
||||
# Show the Hour of Code "I'm Done" tracking pixel after they played for 20 minutes
|
||||
enough = elapsed >= 20 * 60 * 1000
|
||||
tooMuch = elapsed > 120 * 60 * 1000
|
||||
showDone = elapsed >= 30 * 60 * 1000 and not tooMuch
|
||||
if enough and not tooMuch and not me.get('hourOfCodeComplete')
|
||||
$('body').append($('<img src="http://code.org/api/hour/finish_codecombat.png" style="visibility: hidden;">'))
|
||||
me.set 'hourOfCodeComplete', true # Note that this will track even for players who don't have hourOfCode set.
|
||||
me.patch()
|
||||
window.tracker?.trackEvent 'Hour of Code Finish', {}
|
||||
# Show the "I'm done" button between 30 - 120 minutes if they definitely came from Hour of Code
|
||||
c.showHourOfCodeDoneButton = me.get('hourOfCode') and showDone
|
||||
|
||||
return c
|
||||
|
||||
afterRender: ->
|
||||
|
|
|
@ -35,7 +35,7 @@ module.exports = class PlayHeroesModal extends ModalView
|
|||
@confirmButtonI18N = options.confirmButtonI18N ? "common.save"
|
||||
@heroes = new CocoCollection([], {model: ThangType})
|
||||
@heroes.url = '/db/thang.type?view=heroes'
|
||||
@heroes.setProjection ['original','name','slug','soundTriggers','featureImage','gems','heroClass','description','components','extendedName','unlockLevelName','i18n']
|
||||
@heroes.setProjection ['original','name','slug','soundTriggers','featureImage','featureImageHair','featureImageThumb','gems','heroClass','description','components','extendedName','unlockLevelName','i18n']
|
||||
@heroes.comparator = 'gems'
|
||||
@listenToOnce @heroes, 'sync', @onHeroesLoaded
|
||||
@supermodel.loadCollection(@heroes, 'heroes')
|
||||
|
|
|
@ -23,6 +23,9 @@ ThangTypeHandler = class ThangTypeHandler extends Handler
|
|||
'raster'
|
||||
'rasterIcon'
|
||||
'featureImage'
|
||||
'featureImageHair'
|
||||
'featureImageThumb'
|
||||
'dollImages'
|
||||
'spriteType'
|
||||
'i18nCoverage'
|
||||
'i18n'
|
||||
|
|
|
@ -271,7 +271,7 @@ PaymentHandler = class PaymentHandler extends Handler
|
|||
|
||||
sendPaymentHipChatMessage: (options) ->
|
||||
try
|
||||
message = "#{options.user?.get('name')} bought #{options.payment?.get('amount')} via #{options.payment?.get('service'}."
|
||||
message = "#{options.user?.get('name')} bought #{options.payment?.get('amount')} via #{options.payment?.get('service')}."
|
||||
hipchat.sendHipChatMessage message
|
||||
catch e
|
||||
log.error "Couldn't send HipChat message on payment because of error: #{e}"
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue