mirror of
https://github.com/codeninjasllc/codecombat.git
synced 2024-11-28 01:55:38 -05:00
Merge branch 'master' into production
This commit is contained in:
commit
8c3f4d92d2
18 changed files with 443 additions and 91 deletions
|
@ -78,7 +78,11 @@ module.exports = class Label extends CocoClass
|
||||||
o.fontSize = {D: 25, S: 12, N: 24}[st]
|
o.fontSize = {D: 25, S: 12, N: 24}[st]
|
||||||
fontFamily = {D: 'Arial', S: 'Arial', N: 'Arial'}[st]
|
fontFamily = {D: 'Arial', S: 'Arial', N: 'Arial'}[st]
|
||||||
o.fontDescriptor = "#{o.fontWeight} #{o.fontSize}px #{fontFamily}"
|
o.fontDescriptor = "#{o.fontWeight} #{o.fontSize}px #{fontFamily}"
|
||||||
o.fontColor = {D: '#000', S: '#FFF', N: '#00a'}[st]
|
o.fontColor = {D: '#000', S: '#FFF', N: '#0a0'}[st]
|
||||||
|
if @style is 'name' and @sprite?.thang?.team is 'humans'
|
||||||
|
o.fontColor = '#a00'
|
||||||
|
else if @style is 'name' and @sprite?.thang?.team is 'ogres'
|
||||||
|
o.fontColor = '#00a'
|
||||||
o.backgroundFillColor = {D: 'white', S: 'rgba(0,0,0,0.4)', N: 'rgba(255,255,255,0.5)'}[st]
|
o.backgroundFillColor = {D: 'white', S: 'rgba(0,0,0,0.4)', N: 'rgba(255,255,255,0.5)'}[st]
|
||||||
o.backgroundStrokeColor = {D: 'black', S: 'rgba(0,0,0,0.6)', N: 'rgba(0,0,0,0)'}[st]
|
o.backgroundStrokeColor = {D: 'black', S: 'rgba(0,0,0,0.6)', N: 'rgba(0,0,0,0)'}[st]
|
||||||
o.backgroundStrokeStyle = {D: 2, S: 1, N: 1}[st]
|
o.backgroundStrokeStyle = {D: 2, S: 1, N: 1}[st]
|
||||||
|
|
|
@ -476,8 +476,9 @@ module.exports = Lank = class Lank extends CocoClass
|
||||||
bar.scaleX = healthPct / @options.floatingLayer.resolutionFactor
|
bar.scaleX = healthPct / @options.floatingLayer.resolutionFactor
|
||||||
if @thang.showsName
|
if @thang.showsName
|
||||||
@setNameLabel(if @thang.health <= 0 then '' else @thang.id)
|
@setNameLabel(if @thang.health <= 0 then '' else @thang.id)
|
||||||
else if @options.playerName
|
# Let's try just using the DuelStatsView instead of this.
|
||||||
@setNameLabel @options.playerName
|
#else if @options.playerName
|
||||||
|
# @setNameLabel @options.playerName
|
||||||
|
|
||||||
configureMouse: ->
|
configureMouse: ->
|
||||||
@sprite.cursor = 'pointer' if @thang?.isSelectable
|
@sprite.cursor = 'pointer' if @thang?.isSelectable
|
||||||
|
|
|
@ -234,43 +234,43 @@ module.exports = nativeDescription: "български език", englishDescri
|
||||||
control_bar_join_game: "Присъединяване"
|
control_bar_join_game: "Присъединяване"
|
||||||
reload: "Презареди"
|
reload: "Презареди"
|
||||||
reload_title: "Презареди целият код?"
|
reload_title: "Презареди целият код?"
|
||||||
# reload_really: "Are you sure you want to reload this level back to the beginning?"
|
reload_really: "Сигурен ли сте, че искате да презаредите нивото и да започнете отначало?"
|
||||||
reload_confirm: "Презареди всички"
|
reload_confirm: "Презареди всички"
|
||||||
victory: "Победа"
|
victory: "Победа"
|
||||||
# victory_title_prefix: ""
|
victory_title_prefix: "Ниво "
|
||||||
# victory_title_suffix: " Complete"
|
victory_title_suffix: " завършено!"
|
||||||
victory_sign_up: "Регистрирай се за да запишеш напредъка си"
|
victory_sign_up: "Регистрирай се за да запишеш напредъка си"
|
||||||
# victory_sign_up_poke: "Want to save your code? Create a free account!"
|
victory_sign_up_poke: "Регистрирайте се безплатно за да запазите прогреса си!"
|
||||||
# victory_rate_the_level: "Rate the level: " # Only in old-style levels.
|
victory_rate_the_level: "Оценете нивото: " # Only in old-style levels.
|
||||||
# victory_return_to_ladder: "Return to Ladder"
|
victory_return_to_ladder: "Обратно към Стълбата"
|
||||||
victory_play_continue: "Продължи"
|
victory_play_continue: "Продължи"
|
||||||
victory_saving_progress: "Записване на напредъка"
|
victory_saving_progress: "Записване на напредъка"
|
||||||
# victory_go_home: "Go Home"
|
victory_go_home: "На Главната"
|
||||||
# victory_review: "Tell us more!"
|
victory_review: "Разкажи ни повече!"
|
||||||
# victory_review_placeholder: "How was the level?"
|
victory_review_placeholder: "Как беше нивото?"
|
||||||
victory_hour_of_code_done: "Готов ли си?"
|
victory_hour_of_code_done: "Готов ли си?"
|
||||||
victory_hour_of_code_done_yes: "Да аз съм готов с моят Hour of Code™!"
|
victory_hour_of_code_done_yes: "Да аз съм готов с моят Hour of Code™!"
|
||||||
victory_experience_gained: "Спечелен опит"
|
victory_experience_gained: "Спечелен опит"
|
||||||
victory_gems_gained: "Спечелени скъпоценни камъни"
|
victory_gems_gained: "Спечелени скъпоценни камъни"
|
||||||
# victory_new_item: "New Item"
|
victory_new_item: "Нов Предмет"
|
||||||
# victory_viking_code_school: "Holy smokes, that was a hard level you just beat! If you aren't already a software developer, you should be. You just got fast-tracked for acceptance with Viking Code School, where you can take your skills to the next level and become a professional web developer in 14 weeks."
|
victory_viking_code_school: "О да - това ниво беше наистина тежко! Ти или си програмист, или обезателно трябва да станеш такъв! Току що се доближи до приемането си във Викингското Училище по Програмиране, където ще научиш много нови неща и ще станеш професионален уеб програмист за 14 седмици."
|
||||||
# victory_become_a_viking: "Become a Viking"
|
victory_become_a_viking: "Стани Викинг"
|
||||||
guide_title: "Упътване"
|
guide_title: "Упътване"
|
||||||
# tome_minion_spells: "Your Minions' Spells" # Only in old-style levels.
|
tome_minion_spells: "Заклинания на вашите Миньони' Spells" # Only in old-style levels.
|
||||||
# tome_read_only_spells: "Read-Only Spells" # Only in old-style levels.
|
tome_read_only_spells: "Read-Only Заклинания" # Only in old-style levels.
|
||||||
# tome_other_units: "Other Units" # Only in old-style levels.
|
tome_other_units: "Други Модули" # Only in old-style levels.
|
||||||
# tome_cast_button_run: "Run"
|
tome_cast_button_run: "Стартиране"
|
||||||
# tome_cast_button_running: "Running"
|
tome_cast_button_running: "В Процес..."
|
||||||
# tome_cast_button_ran: "Ran"
|
tome_cast_button_ran: "Стартирано"
|
||||||
# tome_submit_button: "Submit"
|
tome_submit_button: "Изпращане"
|
||||||
# tome_reload_method: "Reload original code for this method" # Title text for individual method reload button.
|
tome_reload_method: "Презареди оригиналния код за този метод" # Title text for individual method reload button.
|
||||||
# tome_select_method: "Select a Method"
|
tome_select_method: "Избери Метод"
|
||||||
# tome_see_all_methods: "See all methods you can edit" # Title text for method list selector (shown when there are multiple programmable methods).
|
tome_see_all_methods: "Виж всички методи, които можеш да редактираш" # Title text for method list selector (shown when there are multiple programmable methods).
|
||||||
# tome_select_a_thang: "Select Someone for "
|
tome_select_a_thang: "Избери някого за "
|
||||||
# tome_available_spells: "Available Spells"
|
tome_available_spells: "Достъпни Заклинания"
|
||||||
tome_your_skills: "Твоите Умения"
|
tome_your_skills: "Твоите Умения"
|
||||||
tome_help: "Помощ"
|
tome_help: "Помощ"
|
||||||
# tome_current_method: "Current Method"
|
tome_current_method: "Текущ Метод"
|
||||||
hud_continue_short: "Продължи"
|
hud_continue_short: "Продължи"
|
||||||
code_saved: "Кодът е записан"
|
code_saved: "Кодът е записан"
|
||||||
skip_tutorial: "Пропусни (esc)"
|
skip_tutorial: "Пропусни (esc)"
|
||||||
|
@ -280,43 +280,43 @@ module.exports = nativeDescription: "български език", englishDescri
|
||||||
problem_alert_title: "Оправи си кода."
|
problem_alert_title: "Оправи си кода."
|
||||||
problem_alert_help: "Помощ"
|
problem_alert_help: "Помощ"
|
||||||
time_current: "Текущо време:"
|
time_current: "Текущо време:"
|
||||||
# time_total: "Max:"
|
time_total: "Максимално:"
|
||||||
# time_goto: "Go to:"
|
time_goto: "Иди на:"
|
||||||
# non_user_code_problem_title: "Unable to Load Level"
|
non_user_code_problem_title: "Нивото не може да се зареди"
|
||||||
# infinite_loop_title: "Infinite Loop Detected"
|
infinite_loop_title: "Открит е безкраен цикъл"
|
||||||
# infinite_loop_description: "The initial code to build the world never finished running. It's probably either really slow or has an infinite loop. Or there might be a bug. You can either try running this code again or reset the code to the default state. If that doesn't fix it, please let us know."
|
infinite_loop_description: "Кодът за сътворение на света никога не свършва. Или е много бавен, или има безкраен цикъл. Или може да има бъг. Можете да опитате да стартирате този код отново, или да нулирате кода до изходното му състояние. Ако нещата не се оправят, моля, съобщете ни."
|
||||||
# check_dev_console: "You can also open the developer console to see what might be going wrong."
|
check_dev_console: "Също така можете да отворите конзолата за разработчици, за да видите какво не е наред."
|
||||||
# check_dev_console_link: "(instructions)"
|
check_dev_console_link: "(инструкции)"
|
||||||
infinite_loop_try_again: "Пробвай отново"
|
infinite_loop_try_again: "Пробвай отново"
|
||||||
infinite_loop_reset_level: "Ресетване на Ниво"
|
infinite_loop_reset_level: "Нулиране на Ниво"
|
||||||
infinite_loop_comment_out: "Коментирай моят Код"
|
infinite_loop_comment_out: "Коментирай моят Код"
|
||||||
# tip_toggle_play: "Toggle play/paused with Ctrl+P."
|
tip_toggle_play: "Превключвайте възпроизвеждане/пауза с Ctrl+P."
|
||||||
# tip_scrub_shortcut: "Use Ctrl+[ and Ctrl+] to rewind and fast-forward."
|
tip_scrub_shortcut: "Използвайте Ctrl+[ и Ctrl+] за бързо превъртане напред и назад."
|
||||||
# tip_guide_exists: "Click the guide, inside game menu (at the top of the page), for useful info."
|
tip_guide_exists: "Кликнете на ръководството в менюто(в горната част на страницата), за полезна информация."
|
||||||
tip_open_source: "CodeCombat e 100% проект с отворен код!"
|
tip_open_source: "CodeCombat e 100% проект с отворен код!"
|
||||||
# tip_tell_friends: "Enjoying CodeCombat? Tell your friends about us!"
|
tip_tell_friends: "Насладихте ли се на CodeCombat? Разкажете на приятелите си за нас!"
|
||||||
tip_beta_launch: "CodeCombat стартира своята beta през Октомври, 2013."
|
tip_beta_launch: "CodeCombat стартира своята beta през Октомври, 2013."
|
||||||
tip_think_solution: "Помисли върху решението,не проблема."
|
tip_think_solution: "Помисли върху решението, не проблема."
|
||||||
# tip_theory_practice: "In theory, there is no difference between theory and practice. But in practice, there is. - Yogi Berra"
|
tip_theory_practice: "На теория няма разлика между теорията и практиката. Но на практика има. - Yogi Berra"
|
||||||
# tip_error_free: "There are two ways to write error-free programs; only the third one works. - Alan Perlis"
|
tip_error_free: "Има само два начина да напишеш безгрешна програма; само третия работи. - Alan Perlis"
|
||||||
# tip_debugging_program: "If debugging is the process of removing bugs, then programming must be the process of putting them in. - Edsger W. Dijkstra"
|
tip_debugging_program: "Ако дебъгването е процес на премахване на бъгове, тогава програмирането трябва да е процес на поставянето им. - Edsger W. Dijkstra"
|
||||||
# tip_forums: "Head over to the forums and tell us what you think!"
|
tip_forums: "Идете на форумите и кажете какво мислите!"
|
||||||
# tip_baby_coders: "In the future, even babies will be Archmages."
|
tip_baby_coders: "В бъдещето дори бебетата ще са Архимагове."
|
||||||
# tip_morale_improves: "Loading will continue until morale improves."
|
tip_morale_improves: "Зареждането ще продължи докато бойният дух не се възстанови."
|
||||||
# tip_all_species: "We believe in equal opportunities to learn programming for all species."
|
tip_all_species: "Ние вярваме в равните възможности на всички видове да се научат да програмират."
|
||||||
# tip_reticulating: "Reticulating spines."
|
tip_reticulating: "Да замрежим бодлите!"
|
||||||
# tip_harry: "Yer a Wizard, "
|
tip_harry: "Ти си Магьосник, "
|
||||||
# tip_great_responsibility: "With great coding skill comes great debug responsibility."
|
tip_great_responsibility: "С големите програмистки умения идват големите отговорности по дебъга."
|
||||||
# tip_munchkin: "If you don't eat your vegetables, a munchkin will come after you while you're asleep."
|
tip_munchkin: "Ако не си изядеш зеленчуците, Торбалан ще дойде и ще те вземе, когато заспиш."
|
||||||
# tip_binary: "There are only 10 types of people in the world: those who understand binary, and those who don't."
|
tip_binary: "Има само 10 типа хора по света - тези, които разбират двоичната система, и тези, които не я разбират."
|
||||||
# tip_commitment_yoda: "A programmer must have the deepest commitment, the most serious mind. ~ Yoda"
|
tip_commitment_yoda: "Програмистът на прининципите верен трябва да е - и със ум сериозен. ~ Йода"
|
||||||
# tip_no_try: "Do. Or do not. There is no try. - Yoda"
|
tip_no_try: "Прави. Или не прави. Недей опитва. - Йода"
|
||||||
# tip_patience: "Patience you must have, young Padawan. - Yoda"
|
tip_patience: "Търпение да имаш трябва, млади Падуане. - Йода"
|
||||||
# tip_documented_bug: "A documented bug is not a bug; it is a feature."
|
tip_documented_bug: "Документирания бъг не е бъг - той е фичър."
|
||||||
# tip_impossible: "It always seems impossible until it's done. - Nelson Mandela"
|
tip_impossible: "Винаги изглежда невъзможно - докато не се направи. - Нелсън Мандела"
|
||||||
# tip_talk_is_cheap: "Talk is cheap. Show me the code. - Linus Torvalds"
|
tip_talk_is_cheap: "Приказките са вятър и мъгла. Покажи ми кода. - Линус Торвалдс"
|
||||||
# tip_first_language: "The most disastrous thing that you can ever learn is your first programming language. - Alan Kay"
|
tip_first_language: "Най-пагубното нещо, което можеш да научиш е първият ти език за програмиране. - Alan Kay"
|
||||||
# tip_hardware_problem: "Q: How many programmers does it take to change a light bulb? A: None, it's a hardware problem."
|
tip_hardware_problem: "Въпр.: Колко програмиста са нужни, за да сменят електрическа крушка? Отг.: Николко, това е хардуерен проблем."
|
||||||
# tip_hofstadters_law: "Hofstadter's Law: It always takes longer than you expect, even when you take into account Hofstadter's Law."
|
# tip_hofstadters_law: "Hofstadter's Law: It always takes longer than you expect, even when you take into account Hofstadter's Law."
|
||||||
# tip_premature_optimization: "Premature optimization is the root of all evil. - Donald Knuth"
|
# tip_premature_optimization: "Premature optimization is the root of all evil. - Donald Knuth"
|
||||||
# tip_brute_force: "When in doubt, use brute force. - Ken Thompson"
|
# tip_brute_force: "When in doubt, use brute force. - Ken Thompson"
|
||||||
|
|
|
@ -634,28 +634,28 @@ module.exports = nativeDescription: "Español (América Latina)", englishDescrip
|
||||||
sys_requirements_2: "CodeCombat no está soportado en iPad aún."
|
sys_requirements_2: "CodeCombat no está soportado en iPad aún."
|
||||||
|
|
||||||
teachers_survey:
|
teachers_survey:
|
||||||
# title: "Teacher Survey"
|
title: "Encuesta para profesores"
|
||||||
# must_be_logged: "You must be logged in first. Please create an account or log in from the menu above."
|
must_be_logged: "Debe iniiciar sesión primero. Por favor cree una cuenta o inicie sesión desde el menú en la parte superior."
|
||||||
# retrieving: "Retrieving information..."
|
retrieving: "Obteniendo información..."
|
||||||
# being_reviewed_1: "Your application for a free trial subscription is being"
|
being_reviewed_1: "Su solicitud para una prueba gratuita de subscripción está siendo"
|
||||||
# being_reviewed_2: "reviewed."
|
being_reviewed_2: "revisada."
|
||||||
# approved_1: "Your application for a free trial subscription was"
|
approved_1: "Su solicitud para una prueba gratuita de subscripción fue" #since about 1993 fué can use no tilde
|
||||||
approved_2: "Aprobada."
|
approved_2: "Aprobada."
|
||||||
# approved_3: "Further instructions have been sent to"
|
approved_3: "Instruccciones posteriores han sido enviadas a"
|
||||||
# denied_1: "Your application for a free trial subscription has been"
|
denied_1: "Su solicitud para una prueba gratuita de subscripción fue"
|
||||||
denied_2: "denegadae."
|
denied_2: "denegada."
|
||||||
contact_1: "Porfavor contactarse"
|
contact_1: "Por favor contáctenos"
|
||||||
# contact_2: "if you have further questions."
|
contact_2: "si tiene más preguntas."
|
||||||
# description_1: "We offer free subscriptions to teachers for evaluation purposes. You can find more information on our"
|
# description_1: "We offer free subscriptions to teachers for evaluation purposes. You can find more information on our"
|
||||||
# description_2: "teachers"
|
description_2: "página"
|
||||||
# description_3: "page."
|
description_3: "de maestros."
|
||||||
# description_4: "Please fill out this quick survey and we’ll email you setup instructions."
|
# description_4: "Please fill out this quick survey and we’ll email you setup instructions."
|
||||||
email: "Dirección de email"
|
email: "Dirección de email"
|
||||||
school: "Nombre del colegio"
|
school: "Nombre del colegio"
|
||||||
location: "Nombre de la ciudad"
|
location: "Nombre de la ciudad"
|
||||||
age_students: "¿Qué edad tienen tus estudiantes?"
|
age_students: "¿Qué edad tienen tus estudiantes?"
|
||||||
# under: "Under"
|
under: "Menor" #under like underage = menor as menor de edad
|
||||||
# other: "Other:"
|
other: "Otro:"
|
||||||
amount_students: "¿A cuantos alumnos les enseñas?"
|
amount_students: "¿A cuantos alumnos les enseñas?"
|
||||||
hear_about: "¿Donde escuchaste sobre CodeCombat?"
|
hear_about: "¿Donde escuchaste sobre CodeCombat?"
|
||||||
fill_fields: "Porfavor llenar todos los campos."
|
fill_fields: "Porfavor llenar todos los campos."
|
||||||
|
@ -707,7 +707,7 @@ module.exports = nativeDescription: "Español (América Latina)", englishDescrip
|
||||||
new_password: "Nueva Contraseña"
|
new_password: "Nueva Contraseña"
|
||||||
new_password_verify: "Verificar"
|
new_password_verify: "Verificar"
|
||||||
type_in_email: "Ingrese su correo electrónico para confirmar la eliminación" # {change}
|
type_in_email: "Ingrese su correo electrónico para confirmar la eliminación" # {change}
|
||||||
# type_in_password: "Also, type in your password."
|
type_in_password: "También, escribe tu password."
|
||||||
email_subscriptions: "Suscripciones de Email"
|
email_subscriptions: "Suscripciones de Email"
|
||||||
email_subscriptions_none: "No tienes suscripciones."
|
email_subscriptions_none: "No tienes suscripciones."
|
||||||
email_announcements: "Noticias"
|
email_announcements: "Noticias"
|
||||||
|
@ -782,7 +782,7 @@ module.exports = nativeDescription: "Español (América Latina)", englishDescrip
|
||||||
make_private: "Hacer clan privado"
|
make_private: "Hacer clan privado"
|
||||||
subs_only: "solo suscriptores"
|
subs_only: "solo suscriptores"
|
||||||
create_clan: "Crear nuevo clan"
|
create_clan: "Crear nuevo clan"
|
||||||
# private_preview: "Preview"
|
private_preview: "Previsualizar"
|
||||||
public_clans: "Clanes publicos"
|
public_clans: "Clanes publicos"
|
||||||
my_clans: "Mis Clanes"
|
my_clans: "Mis Clanes"
|
||||||
clan_name: "Nombre del clan"
|
clan_name: "Nombre del clan"
|
||||||
|
@ -794,7 +794,7 @@ module.exports = nativeDescription: "Español (América Latina)", englishDescrip
|
||||||
edit_name: "editar nombre"
|
edit_name: "editar nombre"
|
||||||
edit_description: "editar descripción"
|
edit_description: "editar descripción"
|
||||||
private: "(privado)"
|
private: "(privado)"
|
||||||
# summary: "Summary"
|
summary: "Resumen"
|
||||||
average_level: "Nivel Promedio"
|
average_level: "Nivel Promedio"
|
||||||
average_achievements: "Logros Promedio"
|
average_achievements: "Logros Promedio"
|
||||||
delete_clan: "Borrar Clan"
|
delete_clan: "Borrar Clan"
|
||||||
|
@ -853,8 +853,8 @@ module.exports = nativeDescription: "Español (América Latina)", englishDescrip
|
||||||
indoor: "Interior"
|
indoor: "Interior"
|
||||||
desert: "Desierto"
|
desert: "Desierto"
|
||||||
grassy: "Herboso"
|
grassy: "Herboso"
|
||||||
# mountain: "Mountain"
|
mountain: "Mountaña"
|
||||||
# glacier: "Glacier"
|
glacier: "Glaciar"
|
||||||
small: "Pequeño"
|
small: "Pequeño"
|
||||||
large: "Grande"
|
large: "Grande"
|
||||||
fork_title: "Fork de Nueva Versión"
|
fork_title: "Fork de Nueva Versión"
|
||||||
|
|
|
@ -47,7 +47,10 @@ $level-resize-transition-time: 0.5s
|
||||||
line-height: 2vw
|
line-height: 2vw
|
||||||
img
|
img
|
||||||
width: 1.8vw
|
width: 1.8vw
|
||||||
heighT: 1.8vw
|
height: 1.8vw
|
||||||
|
#duel-stats-view
|
||||||
|
right: calc(1% + 100px)
|
||||||
|
bottom: 50px
|
||||||
#control-bar-view .title
|
#control-bar-view .title
|
||||||
left: 20%
|
left: 20%
|
||||||
width: 60%
|
width: 60%
|
||||||
|
|
154
app/styles/play/level/duel-stats-view.sass
Normal file
154
app/styles/play/level/duel-stats-view.sass
Normal file
|
@ -0,0 +1,154 @@
|
||||||
|
@import "app/styles/mixins"
|
||||||
|
@import "app/styles/bootstrap/variables"
|
||||||
|
|
||||||
|
#duel-stats-view
|
||||||
|
position: absolute
|
||||||
|
right: 44.3%
|
||||||
|
bottom: 133px
|
||||||
|
z-index: 3
|
||||||
|
@include transition(opacity .2s linear)
|
||||||
|
@include user-select(none)
|
||||||
|
padding: 4px 10px 0 4px
|
||||||
|
background: transparent url(/images/level/hud_background.png) no-repeat
|
||||||
|
background-size: 100% auto
|
||||||
|
border-radius: 4px
|
||||||
|
|
||||||
|
width: 500px
|
||||||
|
height: 60px
|
||||||
|
display: flex
|
||||||
|
flex-direction: row
|
||||||
|
|
||||||
|
&:hover
|
||||||
|
opacity: 0.1
|
||||||
|
|
||||||
|
.player-container
|
||||||
|
width: 50%
|
||||||
|
height: 50px
|
||||||
|
display: flex
|
||||||
|
flex-direction: row
|
||||||
|
align-items: center
|
||||||
|
text-transform: uppercase
|
||||||
|
font-family: $headings-font-family
|
||||||
|
font-weight: bold
|
||||||
|
font-size: 18px
|
||||||
|
color: hsla(4,80%,51%,1)
|
||||||
|
text-shadow: 0px 1px 0px black, 0px -1px 0px black, 1px 0px 0px black, -1px 0px 0px black
|
||||||
|
|
||||||
|
&.team-humans
|
||||||
|
padding-right: 10px
|
||||||
|
|
||||||
|
.player-power
|
||||||
|
margin-right: 5px
|
||||||
|
|
||||||
|
&.team-ogres
|
||||||
|
padding-left: 10px
|
||||||
|
flex-direction: row-reverse
|
||||||
|
color: hsla(205,100%,51%,1)
|
||||||
|
|
||||||
|
.name-and-power
|
||||||
|
flex-direction: row-reverse
|
||||||
|
|
||||||
|
.player-name
|
||||||
|
text-align: right
|
||||||
|
|
||||||
|
.player-power
|
||||||
|
margin-left: 5px
|
||||||
|
flex-direction: row-reverse
|
||||||
|
text-align: right
|
||||||
|
|
||||||
|
.player-health
|
||||||
|
flex-direction: row-reverse
|
||||||
|
|
||||||
|
.health-bar-container .health-bar
|
||||||
|
background: hsla(205,100%,51%,1)
|
||||||
|
|
||||||
|
.name-and-power
|
||||||
|
display: flex
|
||||||
|
flex-direction: row
|
||||||
|
|
||||||
|
.player-portrait
|
||||||
|
margin: 0 12px
|
||||||
|
|
||||||
|
.thang-avatar-view
|
||||||
|
width: 30px
|
||||||
|
|
||||||
|
.player-name
|
||||||
|
height: 50%
|
||||||
|
text-align: left
|
||||||
|
overflow: hidden
|
||||||
|
text-overflow: ellipsis
|
||||||
|
white-space: nowrap
|
||||||
|
max-width: 130px
|
||||||
|
|
||||||
|
$iconSize: 16px
|
||||||
|
.health-icon, .power-icon
|
||||||
|
display: inline-block
|
||||||
|
width: $iconSize
|
||||||
|
height: $iconSize
|
||||||
|
background: transparent url(/images/level/hud_info_icons.png) no-repeat
|
||||||
|
background-size: auto $iconSize
|
||||||
|
|
||||||
|
.player-health, .player-power
|
||||||
|
height: 50%
|
||||||
|
display: flex
|
||||||
|
flex-direction: row
|
||||||
|
height: 18px
|
||||||
|
|
||||||
|
.player-health
|
||||||
|
line-height: 16px
|
||||||
|
|
||||||
|
.health-bar-container
|
||||||
|
width: 100px
|
||||||
|
display: inline-block
|
||||||
|
margin: 1px 5px
|
||||||
|
height: 16px
|
||||||
|
background: rgb(32, 27, 21)
|
||||||
|
padding: 4px
|
||||||
|
border-radius: 8px
|
||||||
|
border: 0
|
||||||
|
overflow: hidden
|
||||||
|
|
||||||
|
.health-bar
|
||||||
|
background: rgb(234, 35, 45)
|
||||||
|
width: 100%
|
||||||
|
height: 8px
|
||||||
|
border-radius: 4px
|
||||||
|
|
||||||
|
.health-value
|
||||||
|
vertical-align: top
|
||||||
|
|
||||||
|
.player-power
|
||||||
|
|
||||||
|
.power-icon
|
||||||
|
margin-top: 4px
|
||||||
|
background-position: (-5 * $iconSize) 0px
|
||||||
|
|
||||||
|
.power-value
|
||||||
|
min-width: 20px
|
||||||
|
margin: 0px 5px
|
||||||
|
|
||||||
|
//&.team-humans .team-gold
|
||||||
|
// color: hsla(4,80%,51%,1)
|
||||||
|
//
|
||||||
|
//&.team-ogres .team-gold
|
||||||
|
// color: hsla(205,100%,51%,1)
|
||||||
|
//
|
||||||
|
//.team-gold
|
||||||
|
// font-size: 1.4vw
|
||||||
|
// line-height: 1.4vw
|
||||||
|
// margin: 0
|
||||||
|
// color: hsla(205,0%,51%,1)
|
||||||
|
// display: inline-block
|
||||||
|
// padding: 0px 4px
|
||||||
|
//
|
||||||
|
// img
|
||||||
|
// width: 1.2vw
|
||||||
|
// height: 1.2vw
|
||||||
|
// border-radius: 2px
|
||||||
|
// padding: 0.1vw
|
||||||
|
// margin-top: -0.2vw
|
||||||
|
// margin-right: 0.1vw
|
||||||
|
//
|
||||||
|
// .gold-amount
|
||||||
|
// display: inline-block
|
||||||
|
// min-width: 20px
|
|
@ -12,6 +12,10 @@
|
||||||
display: none
|
display: none
|
||||||
#gold-view
|
#gold-view
|
||||||
right: 1%
|
right: 1%
|
||||||
|
#duel-stats-view
|
||||||
|
right: 230px
|
||||||
|
bottom: 80px
|
||||||
|
@include scale(2)
|
||||||
|
|
||||||
#control-bar-view
|
#control-bar-view
|
||||||
width: 100%
|
width: 100%
|
||||||
|
|
|
@ -29,6 +29,8 @@
|
||||||
|
|
||||||
#multiplayer-status-view
|
#multiplayer-status-view
|
||||||
|
|
||||||
|
#duel-stats-view
|
||||||
|
|
||||||
#playback-view
|
#playback-view
|
||||||
|
|
||||||
#thang-hud
|
#thang-hud
|
||||||
|
|
21
app/templates/play/level/duel-stats-view.jade
Normal file
21
app/templates/play/level/duel-stats-view.jade
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
for player in players
|
||||||
|
div(class="player-container team-" + player.team)
|
||||||
|
.player-portrait
|
||||||
|
.thang-avatar-placeholder
|
||||||
|
.player-info
|
||||||
|
.name-and-power
|
||||||
|
.player-power
|
||||||
|
.power-icon
|
||||||
|
.power-value
|
||||||
|
.player-name= player.name
|
||||||
|
.player-health
|
||||||
|
.health-icon
|
||||||
|
.health-bar-container
|
||||||
|
.health-bar
|
||||||
|
.health-value
|
||||||
|
//.player-gold
|
||||||
|
// .team-gold
|
||||||
|
// img(src="/images/level/gold_icon.png", alt="", draggable="false")
|
||||||
|
// .gold-amount
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,3 @@
|
||||||
div(class="team-gold team-" + team)
|
div(class="team-gold team-" + team)
|
||||||
img(src="/images/level/gold_icon.png", alt="")
|
img(src="/images/level/gold_icon.png", alt="", draggable="false")
|
||||||
div(class="gold-amount team-" + team)
|
div(class="gold-amount team-" + team)
|
||||||
|
|
|
@ -9,5 +9,6 @@
|
||||||
#canvas-top-gradient.gradient
|
#canvas-top-gradient.gradient
|
||||||
#gold-view.secret.expanded
|
#gold-view.secret.expanded
|
||||||
#level-chat-view
|
#level-chat-view
|
||||||
|
#duel-stats-view
|
||||||
#playback-view
|
#playback-view
|
||||||
#thang-hud
|
#thang-hud
|
||||||
|
|
|
@ -28,6 +28,7 @@ ControlBarView = require './level/ControlBarView'
|
||||||
PlaybackView = require './level/LevelPlaybackView'
|
PlaybackView = require './level/LevelPlaybackView'
|
||||||
GoalsView = require './level/LevelGoalsView'
|
GoalsView = require './level/LevelGoalsView'
|
||||||
GoldView = require './level/LevelGoldView'
|
GoldView = require './level/LevelGoldView'
|
||||||
|
DuelStatsView = require './level/DuelStatsView'
|
||||||
VictoryModal = require './level/modal/VictoryModal'
|
VictoryModal = require './level/modal/VictoryModal'
|
||||||
InfiniteLoopModal = require './level/modal/InfiniteLoopModal'
|
InfiniteLoopModal = require './level/modal/InfiniteLoopModal'
|
||||||
|
|
||||||
|
@ -179,8 +180,8 @@ module.exports = class SpectateLevelView extends RootView
|
||||||
|
|
||||||
@insertSubView new GoldView {}
|
@insertSubView new GoldView {}
|
||||||
@insertSubView new HUDView {level: @level}
|
@insertSubView new HUDView {level: @level}
|
||||||
worldName = utils.i18n @level.attributes, 'name'
|
@insertSubView new DuelStatsView level: @level, session: @session, otherSession: @otherSession, supermodel: @supermodel, thangs: @world.thangs if @level.get('type') in ['hero-ladder', 'course-ladder']
|
||||||
@controlBar = @insertSubView new ControlBarView {worldName: worldName, session: @session, level: @level, supermodel: @supermodel, spectateGame: true}
|
@insertSubView @controlBar = new ControlBarView {worldName: utils.i18n(@level.attributes, 'name'), session: @session, level: @level, supermodel: @supermodel, spectateGame: true}
|
||||||
|
|
||||||
# callbacks
|
# callbacks
|
||||||
|
|
||||||
|
|
120
app/views/play/level/DuelStatsView.coffee
Normal file
120
app/views/play/level/DuelStatsView.coffee
Normal file
|
@ -0,0 +1,120 @@
|
||||||
|
CocoView = require 'views/core/CocoView'
|
||||||
|
template = require 'templates/play/level/duel-stats-view'
|
||||||
|
ThangAvatarView = require 'views/play/level/ThangAvatarView'
|
||||||
|
utils = require 'core/utils'
|
||||||
|
|
||||||
|
# TODO:
|
||||||
|
# - if a hero is dead, a big indication that they are dead
|
||||||
|
# - each hero's current action?
|
||||||
|
# - if one player is you, an indicator that it's you?
|
||||||
|
# - indication of which team won (not always hero dead--ties and other victory conditions)
|
||||||
|
# - army composition or power or attack/defense (for certain levels): experiment with something simple, not like the previous unit list thing
|
||||||
|
|
||||||
|
module.exports = class DuelStatsView extends CocoView
|
||||||
|
id: 'duel-stats-view'
|
||||||
|
template: template
|
||||||
|
|
||||||
|
subscriptions:
|
||||||
|
#'surface:gold-changed': 'onGoldChanged'
|
||||||
|
'god:new-world-created': 'onNewWorld'
|
||||||
|
'god:streaming-world-updated': 'onNewWorld'
|
||||||
|
'surface:frame-changed': 'onFrameChanged'
|
||||||
|
|
||||||
|
constructor: (options) ->
|
||||||
|
super options
|
||||||
|
options.thangs = _.filter options.thangs, 'inThangList'
|
||||||
|
unless options.otherSession
|
||||||
|
options.otherSession = get: (prop) -> {
|
||||||
|
creatorName: $.i18n.t 'ladder.simple_ai'
|
||||||
|
team: if options.session.get('team') is 'humans' then 'ogres' else 'humans'
|
||||||
|
heroConfig: options.session.get('heroConfig')
|
||||||
|
}[prop]
|
||||||
|
#@teamGold = {}
|
||||||
|
#@teamGoldEarned = {}
|
||||||
|
|
||||||
|
getRenderData: (c) ->
|
||||||
|
c = super c
|
||||||
|
c.players = @players = (@formatPlayer team for team in ['humans', 'ogres'])
|
||||||
|
c
|
||||||
|
|
||||||
|
formatPlayer: (team) ->
|
||||||
|
p = team: team
|
||||||
|
session = _.find [@options.session, @options.otherSession], (s) -> s.get('team') is team
|
||||||
|
p.name = session.get 'creatorName'
|
||||||
|
p.heroThangType = (session.get('heroConfig') ? {}).thangType or '529ffbf1cf1818f2be000001'
|
||||||
|
p.heroID = if team is 'ogres' then 'Hero Placeholder 1' else 'Hero Placeholder'
|
||||||
|
p
|
||||||
|
|
||||||
|
afterRender: ->
|
||||||
|
super()
|
||||||
|
for player in @players
|
||||||
|
@buildAvatar player.heroID, player.team
|
||||||
|
|
||||||
|
buildAvatar: (heroID, team) ->
|
||||||
|
@avatars ?= {}
|
||||||
|
return if @avatars[team]
|
||||||
|
thang = _.find @options.thangs, id: heroID
|
||||||
|
@avatars[team] = avatar = new ThangAvatarView thang: thang, includeName: false, supermodel: @supermodel
|
||||||
|
@$find(team, '.thang-avatar-placeholder').replaceWith avatar.$el
|
||||||
|
avatar.render()
|
||||||
|
|
||||||
|
onNewWorld: (e) ->
|
||||||
|
@options.thangs = _.filter e.world.thangs, 'inThangList'
|
||||||
|
|
||||||
|
onFrameChanged: (e) ->
|
||||||
|
@update()
|
||||||
|
|
||||||
|
update: ->
|
||||||
|
for player in @players
|
||||||
|
thang = _.find @options.thangs, id: @avatars[player.team].thang.id
|
||||||
|
@updateHealth thang
|
||||||
|
@updatePower()
|
||||||
|
|
||||||
|
updateHealth: (thang) ->
|
||||||
|
$health = @$find thang.team, '.player-health'
|
||||||
|
$health.find('.health-bar').css 'width', Math.max(0, Math.min(100, 100 * thang.health / thang.maxHealth)) + '%'
|
||||||
|
utils.replaceText $health.find('.health-value'), Math.round thang.health
|
||||||
|
|
||||||
|
updatePower: ->
|
||||||
|
# Right now we just display the army cost of all living units as opposed to doing something more sophisticate to measure power.
|
||||||
|
@costTable ?=
|
||||||
|
soldier: 20
|
||||||
|
archer: 25
|
||||||
|
decoy: 25
|
||||||
|
'griffin-rider': 50
|
||||||
|
paladin: 80
|
||||||
|
artillery: 75
|
||||||
|
'arrow-tower': 75
|
||||||
|
palisade: 10
|
||||||
|
peasant: 50
|
||||||
|
powers = humans: 0, ogres: 0
|
||||||
|
for thang in @options.thangs when thang.health > 0
|
||||||
|
powers[thang.team] += @costTable[thang.type] or 0 if powers[thang.team]?
|
||||||
|
for player in @players
|
||||||
|
utils.replaceText @$find(player.team, '.power-value'), powers[player.team]
|
||||||
|
|
||||||
|
$find: (team, selector) ->
|
||||||
|
@$el.find(".player-container.team-#{team} " + selector)
|
||||||
|
|
||||||
|
destroy: ->
|
||||||
|
avatar.destroy() for team, avatar of @avatars ? {}
|
||||||
|
super()
|
||||||
|
|
||||||
|
#onGoldChanged: (e) ->
|
||||||
|
# return if @teamGold[e.team] is e.gold and @teamGoldEarned[e.team] is e.goldEarned
|
||||||
|
# @teamGold[e.team] = e.gold
|
||||||
|
# @teamGoldEarned[e.team] = e.goldEarned
|
||||||
|
# goldEl = @$find e.team, '.gold-amount'
|
||||||
|
# text = '' + e.gold
|
||||||
|
# if e.goldEarned and e.goldEarned > e.gold
|
||||||
|
# text += " (#{e.goldEarned})"
|
||||||
|
# goldEl.text text
|
||||||
|
# @updateTitle()
|
||||||
|
#
|
||||||
|
#updateTitle: ->
|
||||||
|
# for team, gold of @teamGold
|
||||||
|
# if @teamGoldEarned[team]
|
||||||
|
# title = "Team '#{team}' has #{gold} now of #{@teamGoldEarned[team]} gold earned."
|
||||||
|
# else
|
||||||
|
# title = "Team '#{team}' has #{gold} gold."
|
||||||
|
# @$find(team, '.player-gold').attr 'title', title
|
|
@ -32,6 +32,7 @@ LevelPlaybackView = require './LevelPlaybackView'
|
||||||
GoalsView = require './LevelGoalsView'
|
GoalsView = require './LevelGoalsView'
|
||||||
LevelFlagsView = require './LevelFlagsView'
|
LevelFlagsView = require './LevelFlagsView'
|
||||||
GoldView = require './LevelGoldView'
|
GoldView = require './LevelGoldView'
|
||||||
|
DuelStatsView = require './DuelStatsView'
|
||||||
VictoryModal = require './modal/VictoryModal'
|
VictoryModal = require './modal/VictoryModal'
|
||||||
HeroVictoryModal = require './modal/HeroVictoryModal'
|
HeroVictoryModal = require './modal/HeroVictoryModal'
|
||||||
InfiniteLoopModal = require './modal/InfiniteLoopModal'
|
InfiniteLoopModal = require './modal/InfiniteLoopModal'
|
||||||
|
@ -246,8 +247,8 @@ module.exports = class PlayLevelView extends RootView
|
||||||
@insertSubView new LevelDialogueView {level: @level, sessionID: @session.id}
|
@insertSubView new LevelDialogueView {level: @level, sessionID: @session.id}
|
||||||
@insertSubView new ChatView levelID: @levelID, sessionID: @session.id, session: @session
|
@insertSubView new ChatView levelID: @levelID, sessionID: @session.id, session: @session
|
||||||
@insertSubView new ProblemAlertView session: @session, level: @level, supermodel: @supermodel
|
@insertSubView new ProblemAlertView session: @session, level: @level, supermodel: @supermodel
|
||||||
worldName = utils.i18n @level.attributes, 'name'
|
@insertSubView new DuelStatsView level: @level, session: @session, otherSession: @otherSession, supermodel: @supermodel, thangs: @world.thangs if @level.get('type') in ['hero-ladder', 'course-ladder']
|
||||||
@controlBar = @insertSubView new ControlBarView {worldName: worldName, session: @session, level: @level, supermodel: @supermodel}
|
@insertSubView @controlBar = new ControlBarView {worldName: utils.i18n(@level.attributes, 'name'), session: @session, level: @level, supermodel: @supermodel}
|
||||||
#_.delay (=> Backbone.Mediator.publish('level:set-debug', debug: true)), 5000 if @isIPadApp() # if me.displayName() is 'Nick'
|
#_.delay (=> Backbone.Mediator.publish('level:set-debug', debug: true)), 5000 if @isIPadApp() # if me.displayName() is 'Nick'
|
||||||
|
|
||||||
initVolume: ->
|
initVolume: ->
|
||||||
|
|
|
@ -78,6 +78,7 @@ module.exports = class PlayHeroesModal extends ModalView
|
||||||
afterRender: ->
|
afterRender: ->
|
||||||
super()
|
super()
|
||||||
return unless @supermodel.finished()
|
return unless @supermodel.finished()
|
||||||
|
@playSound 'game-menu-open'
|
||||||
@$el.find('.hero-avatar').addClass 'ie' if @isIE()
|
@$el.find('.hero-avatar').addClass 'ie' if @isIE()
|
||||||
heroes = @heroes.models
|
heroes = @heroes.models
|
||||||
@$el.find('.hero-indicator').each ->
|
@$el.find('.hero-indicator').each ->
|
||||||
|
@ -334,7 +335,7 @@ module.exports = class PlayHeroesModal extends ModalView
|
||||||
|
|
||||||
onHidden: ->
|
onHidden: ->
|
||||||
super()
|
super()
|
||||||
Backbone.Mediator.publish 'audio-player:play-sound', trigger: 'game-menu-close', volume: 1
|
@playSound 'game-menu-close'
|
||||||
|
|
||||||
destroy: ->
|
destroy: ->
|
||||||
clearInterval @heroAnimationInterval
|
clearInterval @heroAnimationInterval
|
||||||
|
|
|
@ -0,0 +1,37 @@
|
||||||
|
// Add clan leagues to sessions
|
||||||
|
// Usage:
|
||||||
|
// mongo <address>:<port>/<database> <script file> -u <username> -p <password>
|
||||||
|
//
|
||||||
|
// It just goes through all users in clans, then adds their clans to all their multiplayer sessions.
|
||||||
|
|
||||||
|
migrateClans();
|
||||||
|
|
||||||
|
function migrateClans() {
|
||||||
|
print("Adding clan leagues to sessions...");
|
||||||
|
var cursor = db.users.find({emailLower: {$exists: true}, clans: {$exists: true}}, {clans: 1, name: 1});
|
||||||
|
print("Users with clans found: " + cursor.count());
|
||||||
|
var users = cursor.toArray();
|
||||||
|
var arenas = [
|
||||||
|
"5442ba0e1e835500007eb1c7",
|
||||||
|
"550363b4ec31df9c691ab629",
|
||||||
|
"5469643c37600b40e0e09c5b",
|
||||||
|
"54b83c2629843994803c838e",
|
||||||
|
"544437e0645c0c0000c3291d"
|
||||||
|
];
|
||||||
|
users.forEach(function (user, userIndex) {
|
||||||
|
var leagues = [];
|
||||||
|
for (var i = 0; i < user.clans.length; ++i) {
|
||||||
|
leagues.push({leagueID: user.clans[i] + '', stats: {standardDeviation: 25 / 3, numberOfWinsAndTies: 0, numberOfLosses: 0, totalScore: 10, meanStrength: 25}});
|
||||||
|
};
|
||||||
|
//var sessions = db.level.sessions.find({creator: user._id + '', 'level.original': {$in: arenas}, submitted: true}, {clans: 1}).toArray();
|
||||||
|
//print("Found sessions", sessions, "for user", user._id, user.name, 'who has clans', user.clans.join(', '));
|
||||||
|
//print("Going to set leagues to...")
|
||||||
|
//printjson(leagues);
|
||||||
|
var conditions = {creator: user._id + '', 'level.original': {$in: arenas}, submitted: true};
|
||||||
|
var operations = {$set: {leagues: leagues}};
|
||||||
|
var result = db.level.sessions.update(conditions, operations, {multi: true});
|
||||||
|
if (userIndex % 1000 === 0)
|
||||||
|
print("Done", userIndex, "\tof", users.length, "users.");
|
||||||
|
});
|
||||||
|
print("Done.");
|
||||||
|
}
|
|
@ -74,6 +74,8 @@ updateSessionToSubmit = (transpiledCode, user, sessionToUpdate, callback) ->
|
||||||
league.stats.standardDeviation = 25 / 3
|
league.stats.standardDeviation = 25 / 3
|
||||||
league.stats.numberOfWinsAndTies = 0
|
league.stats.numberOfWinsAndTies = 0
|
||||||
league.stats.numberOfLosses = 0
|
league.stats.numberOfLosses = 0
|
||||||
|
league.stats.meanStrength ?= 25
|
||||||
|
league.stats.totalScore ?= 10
|
||||||
newLeagues.push(league)
|
newLeagues.push(league)
|
||||||
unless _.isEqual newLeagues, sessionToUpdate.leagues
|
unless _.isEqual newLeagues, sessionToUpdate.leagues
|
||||||
sessionUpdateObject.leagues = sessionToUpdate.leagues = newLeagues
|
sessionUpdateObject.leagues = sessionToUpdate.leagues = newLeagues
|
||||||
|
|
|
@ -42,7 +42,7 @@ getRandomSessions = (user, callback) ->
|
||||||
leagueIDs = (leagueID + '' for leagueID in leagueIDs) # Make sure to fetch them as strings.
|
leagueIDs = (leagueID + '' for leagueID in leagueIDs) # Make sure to fetch them as strings.
|
||||||
return sampleByLevel callback unless leagueIDs.length and Math.random() > 1 / leagueIDs.length
|
return sampleByLevel callback unless leagueIDs.length and Math.random() > 1 / leagueIDs.length
|
||||||
leagueID = _.sample leagueIDs
|
leagueID = _.sample leagueIDs
|
||||||
findRandomSession {'leagues.leagueID': leagueID, favorRecent: true}, (err, session) ->
|
findRandomSession {'leagues.leagueID': leagueID}, (err, session) ->
|
||||||
if err then return callback err
|
if err then return callback err
|
||||||
unless session then return sampleByLevel callback
|
unless session then return sampleByLevel callback
|
||||||
otherTeam = scoringUtils.calculateOpposingTeam session.team
|
otherTeam = scoringUtils.calculateOpposingTeam session.team
|
||||||
|
|
Loading…
Reference in a new issue