diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
new file mode 100644
index 0000000000..c08eace6c0
--- /dev/null
+++ b/CONTRIBUTING.md
@@ -0,0 +1,14 @@
+# Reporting Bugs
+
+1. Go to the [issue queue](https://github.com/lefnire/habitrpg/issues?state=open), and
+1. check first that a ticket doesn't already exist, using the [search bar](https://www.evernote.com/shard/s17/sh/4a159680-a709-4949-9805-d849bc124c1d/6276f24fb1dce8985eec7d5b021edd9c).
+1. If one hasn't been submitted, [create a new ticket](https://github.com/lefnire/habitrpg/issues/new). If at all possible, please include your browser, [user ID](http://habitrpg.wikia.com/wiki/API#UserID) and **most importantly** any JavaScript errors that may be being thrown (see [Chrome Console instructions](https://developers.google.com/chrome-developer-tools/docs/console#opening_the_console) for how to do that).
+
+# Requesting a feature
+
+HabitRPG uses [Trello](https://trello.com/b/EpoYEYod/habitrpg) to track feature requests. [Read more](https://trello.com/c/8gzGlle8/142-how-to-submit-a-new-request).
+
+# Contributing Code
+
+* See [Contributing to HabitRPG](http://habitrpg.wikia.com/wiki/Contributing_to_HabitRPG)
+* See [Tips](http://habitrpg.wikia.com/wiki/Tips)
diff --git a/Gruntfile.js b/Gruntfile.js
index c1bf9a461a..3ea64fbf1f 100644
--- a/Gruntfile.js
+++ b/Gruntfile.js
@@ -99,6 +99,7 @@ module.exports = function(grunt) {
});
});
grunt.config.set('uglify.build.files', uglify);
+ grunt.config.set('uglify.build.options', {compress: false})
grunt.config.set('cssmin.build.files', cssmin);
});
diff --git a/bower.json b/bower.json
index ff1b5bde1d..4794009d1f 100644
--- a/bower.json
+++ b/bower.json
@@ -17,14 +17,15 @@
"jquery": "~2.0.3",
"jquery.cookie": "~1.4.0",
"jquery-ui": "~1.10.3",
- "angular": "1.2.0-rc.3",
- "angular-sanitize": "1.2.0-rc.3",
- "angular-resource": "1.2.0-rc.3",
+ "angular": "~1.2.1",
+ "angular-sanitize": "~1.2.1",
+ "angular-resource": "~1.2.1",
"angular-ui": "~0.4.0",
"angular-ui-utils": "~0.0.4",
"angular-bootstrap": "~0.5.0",
"angular-ui-router": "ca3b4777a603df8f86cfd653c8f6c38b2ae05d89",
"angular-loading-bar": "~0.0.5",
+ "angular-bindonce": "~0.2.1",
"bootstrap": "v2.3.2",
"bootstrap-datepicker": "~1.2.0",
"bootstrap-tour": "0.5.0",
@@ -34,14 +35,16 @@
"github-buttons": "git://github.com/mdo/github-buttons.git",
"marked": "~0.2.9",
"JavaScriptButtons": "git://github.com/paypal/JavaScriptButtons.git#master",
- "Angular-At-Directive": "git://github.com/snicker/Angular-At-Directive#master"
+ "Angular-At-Directive": "git://github.com/snicker/Angular-At-Directive#master",
+ "js-emoji": "git://github.com/snicker/js-emoji#master",
+ "gemoji": "git://github.com/github/gemoji"
},
"resolutions": {
"jquery": "~2.0.3",
"bootstrap": "v2.3.2",
- "angular": "1.2.0-rc.3"
+ "angular": "~1.2.1"
},
"devDependencies": {
- "angular-mocks": "1.2.0-rc.3"
+ "angular-mocks": "~1.2.1"
}
}
diff --git a/karma.conf.js b/karma.conf.js
index 0e1761b402..ffba336587 100644
--- a/karma.conf.js
+++ b/karma.conf.js
@@ -16,6 +16,7 @@ module.exports = function(config) {
'public/bower_components/angular-resource/angular-resource.min.js',
'public/bower_components/angular-mocks/angular-mocks.js',
'public/bower_components/marked/lib/marked.js',
+ 'public/bower_components/js-emoji/emoji.js',
'public/bower_components/habitrpg-shared/dist/habitrpg-shared.js',
'public/js/*.js',
'public/js/**/*.js',
diff --git a/locales/bg/app.json b/locales/bg/app.json
index d4a0b0aafb..f8805bbf7a 100644
--- a/locales/bg/app.json
+++ b/locales/bg/app.json
@@ -130,6 +130,10 @@
"hair": "Hair",
"skin": "Skin",
"clothing" : "Clothing",
+ "showArmor": "Show Armor",
+ "other": "Other",
+ "showWeapon": "Show Weapon",
+ "showShield": "Show Shield",
"photoUrl": "Photo Url",
"fullName": "Full Name",
"blurb": "Blurb",
diff --git a/locales/cs/app.json b/locales/cs/app.json
index b29382a176..d3c776157a 100644
--- a/locales/cs/app.json
+++ b/locales/cs/app.json
@@ -131,6 +131,10 @@
"hair": "Hair",
"skin": "Skin",
"clothing" : "Clothing",
+ "showArmor": "Show Armor",
+ "other": "Other",
+ "showWeapon": "Show Weapon",
+ "showShield": "Show Shield",
"photoUrl": "Photo Url",
"fullName": "Full Name",
"blurb": "Blurb",
diff --git a/locales/cu/app.json b/locales/cu/app.json
index 37b003b75c..d69a2a23d0 100644
--- a/locales/cu/app.json
+++ b/locales/cu/app.json
@@ -132,6 +132,10 @@
"hair": "Hair",
"skin": "Skin",
"clothing" : "Clothing",
+ "showArmor": "Show Armor",
+ "other": "Other",
+ "showWeapon": "Show Weapon",
+ "showShield": "Show Shield",
"photoUrl": "Photo Url",
"fullName": "Full Name",
"blurb": "Blurb",
diff --git a/locales/de/app.json b/locales/de/app.json
index 90d862c503..26a139867e 100644
--- a/locales/de/app.json
+++ b/locales/de/app.json
@@ -131,6 +131,10 @@
"hair": "Haare",
"skin": "Haut",
"clothing" : "Kleidung",
+ "showArmor": "Show Armor",
+ "other": "Other",
+ "showWeapon": "Show Weapon",
+ "showShield": "Show Shield",
"photoUrl": "Bild-Url",
"fullName": "Name",
"blurb": "über dich",
diff --git a/locales/el/app.json b/locales/el/app.json
index f89ce2a0bc..349009af8c 100644
--- a/locales/el/app.json
+++ b/locales/el/app.json
@@ -135,6 +135,10 @@
"hair": "Μαλλιά",
"skin": "Δέρμα",
"clothing" : "Ρούχα",
+ "showArmor": "Show Armor",
+ "other": "Other",
+ "showWeapon": "Show Weapon",
+ "showShield": "Show Shield",
"photoUrl": "Url Φωτογραφίας",
"fullName": "Πλήρες Όνομα",
"blurb": "Κείμενο",
diff --git a/locales/en/app.json b/locales/en/app.json
index cd12c0bf54..38d94fa446 100644
--- a/locales/en/app.json
+++ b/locales/en/app.json
@@ -47,7 +47,7 @@
"reward1" : "1 Episode of Game of Thrones",
"reward1comment": "-- Rewards: Treat Yourself! -- As you complete goals, you earn gold to buy rewards. Buy them liberally - rewards are integral in forming good habits.",
"reward2" : "Cake",
- "reward2comment" : "But only buy if you have enough gold - you lose HP otherwise.",
+ "reward2comment" : "But only buy if you have enough gold!",
"_commentdefaulttags" : "DEFAULT TAGS",
"morning" : "morning",
@@ -104,7 +104,7 @@
"S": "S",
"todos": "To-Dos",
"Todos": "To-Dos",
- "newTodo": "New Todo",
+ "newTodo": "New To-Do",
"dueDate": "Due Date",
"remaining": "Remaining",
"complete": "Complete",
@@ -124,7 +124,7 @@
"dropsEnabled" : "Drops Enabled!",
"dropsEnabledText1" : "You've unlocked the Drop System! Now when you complete tasks, you have a small chance of finding an item. And guess what, you just found a",
"dropsEnabledText2" : "egg",
- "itemDropped" : "An items has dropped",
+ "itemDropped" : "An item has dropped",
@@ -137,6 +137,10 @@
"hair": "Hair",
"skin": "Skin",
"clothing" : "Clothing",
+ "showWeapon": "Show Weapon",
+ "other" : "Other",
+ "showShield": "Show Shield",
+ "showArmor": "Show Armor",
"photoUrl": "Photo Url",
"fullName": "Full Name",
"blurb": "Blurb",
@@ -353,7 +357,7 @@
"_commentdeathstuff" : "DEATH",
"deathTitle" : "You Died!",
- "deathText" : "You've lost your GP, 1 level and 1 gear piece. Be sure to complete your dailies to prevent this from happening again!",
+ "deathText" : "You've lost your Gold, 1 Level, and 1 piece of Equipment. Be sure to complete your Dailies to prevent this from happening again!",
"_commentgems" : "GEMS",
"gems" : "Gems",
@@ -375,7 +379,7 @@
"legalTerms" : "Terms",
"footerCommunity" : "Community",
"communityBugs" : "Submit Bugs",
- "communityFeatures" : "Request Feautres",
+ "communityFeatures" : "Request Features",
"communityExtensions" : "Add-ons / Extensions",
"communityForum" : "Community Forum",
"footerSocial" : "Social",
diff --git a/locales/es/app.json b/locales/es/app.json
index fdddf5d73b..a9da398211 100644
--- a/locales/es/app.json
+++ b/locales/es/app.json
@@ -3,49 +3,49 @@
"_commentfrontpage":"HABITRPG PORTADA",
- "synopsis" : "Un programa para construir hábitos que convierte tu vida en un Juego de Rol. Aumenta de nivel a medida que triunfas, pierde HP al fracasar, gana dinero para comprar armas y armaduras.",
+ "synopsis" : "Un programa para construir hábitos que convierte tu vida en un juego de rol. Aumenta de nivel a medida que triunfas, pierde HP al fracasar, gana dinero para comprar armas y armaduras.",
"playButton" : "Jugar",
"_commenttut": "TUTORIAL/VISITA",
- "endTourButton": "Finalizar visita",
+ "endTourButton": "Finalizar tour",
"nextButton" : "Siguiente",
"prevButton" : "Volver",
"tour1Title" : "Bienvenido a HabitRPG",
- "tour1Text" : "Bienvenido a HabitRPG, un seguidor de hábitos que convierte tus objetivos en un Juego de Rol.",
+ "tour1Text" : "Bienvenido a HabitRPG, un seguidor de hábitos que convierte tus objetivos en un juego de rol.",
"tour2Title" : "Hábitos",
"tour2Text" : "Los hábitos son objetivos buenos o malos de los que estás pendiente constantemente.",
"tour3Title" : "Diarios",
"tour3Text" : "Los diarios son objetivos que quieres completar una vez al día.",
"tour4Title" : "Quehaceres",
"tour4Text" : "Los quehaceres son objetivos únicos que deben ser completados en algún momento.",
- "tour5Title" : "Premios",
- "tour5Text" : "Al completar objetivos, ganas dinero para comprar premios. Cómpralos generosamente - las recompensas son fundamentales para formar buenos hábitos. ",
+ "tour5Title" : "Recompensas",
+ "tour5Text" : "Al completar objetivos, ganas dinero para comprar recompensas. Cómpralas generosamente - las recompensas son fundamentales para formar buenos hábitos. ",
"tour6Title" : "Sitúa el cursor sobre los comentarios",
"tour6Text" : "Diferentes tipos de tareas tienen propiedades especiales. Mueve el cursor sobre el comentario de cada tarea para más información. Cuando estés listo para empezar, borra las tareas existentes y agrega las tuyas.",
"_commentdefaulttasks":"TAREAS POR DEFECTO",
- "habit1" : "1h de Trabajo Productivo",
- "habit1comment": "-- Hábitos: Sigue Constantemente -- Para algunos Hábitos, sólo tiene sentido *ganar* puntos (como éste)",
- "habit2" : "Comer Comida Basura",
+ "habit1" : "1h de trabajo productivo",
+ "habit1comment": "-- Hábitos: Sigue Constantemente -- Para algunos hábitos, sólo tiene sentido *ganar* puntos (como éste)",
+ "habit2" : "Comer comida basura",
"habit2comment" : "Para otros, sólo tiene sentido *perder* puntos",
- "habit3" : "Usar las Escaleras",
+ "habit3" : "Usar las escaleras",
"habit3comment" : "Para el resto, tanto + como - tiene sentido (escaleras = ganar, elevador = perder)",
- "daily1" : "1h de Proyecto Personal",
- "daily1comment" : "-- Diarios: Completa Una Vez al Día -- Al final de cada día, los Diarios no cumplidos te descuentan puntos.",
+ "daily1" : "1h de proyecto personal",
+ "daily1comment" : "-- Diarios: Completa Una Vez al Día -- Al final de cada día, los diarios sin completar te descuentan puntos.",
"daily2" : "Hacer Ejercicio",
- "daily2comment" : "Si te está yendo bien, se vuelven verdes y son menos valiosos (experiencia, oro) y menos dañinos (PV). Esto significa que puedes darte un descanso de ellos por un rato.",
- "daily3" : "45m de Lectura",
- "daily3comment" : "Pero si te está yendo mal, se vuelven rojos. Peor te va, más valiosos (experiencia, oro) y más dañinos (PV) se vuelven estos objetivos. Esto te alienta a enfocarte en tus fallas, los rojos.",
- "todo1" : "Llamar a Mamá",
- "todo1comment" : "-- Quehaceres: Completa en Algún Momento -- Los Quehaceres no cumplidos no te harán daño, pero se volverán más valiosos con el tiempo. Esto te alentará a completar los Quehaceres obsoletos.",
- "reward1" : "1 Episodio de Game of Thrones",
- "reward1comment": "-- Premios: Hazte Un Obsequio! -- Al completar objetivos, ganas dinero para comprar premios. Cómpralos generosamente - las recompensas son fundamentales para formar buenos hábitos.",
+ "daily2comment" : "Si te está yendo bien, se vuelven verdes y son menos valiosos (experiencia, oro) y menos dañinos (HP). Esto significa que puedes darte un descanso de ellos por un rato.",
+ "daily3" : "45m de lectura",
+ "daily3comment" : "Pero si te está yendo mal, se vuelven rojos. Peor te va, más valiosos (experiencia, oro) y más dañinos (HP) se vuelven estos objetivos. Esto te alienta a enfocarte en tus fallas, los rojos.",
+ "todo1" : "Llamar a mamá",
+ "todo1comment" : "-- Quehaceres: Completa en Algún Momento -- Los quehaceres sin completar no te harán daño, pero se volverán más valiosos con el tiempo. Esto te alentará a completar los quehaceres obsoletos.",
+ "reward1" : "1 Episodio de Juego de Tronos",
+ "reward1comment": "-- Recompensas: Hazte Un Obsequio! -- Al completar objetivos, ganas dinero para comprar recompensas. Cómpralas generosamente - las recompensas son fundamentales para formar buenos hábitos.",
"reward2" : "Torta",
- "reward2comment" : "Pero sólo compra si tienes suficiente oro - de lo contrario perderás PV.",
+ "reward2comment" : "Pero sólo compra si tienes suficiente oro - de lo contrario perderás HP.",
"_commentdefaulttags" : "ETIQUETA DE DEFECTO",
"morning" : "mañana",
@@ -53,7 +53,7 @@
"evening" : "noche",
"_commenthead": "ENCABEZAMIENTO",
- "health": "Vida",
+ "health": "Salud",
"experience": "Experiencia",
"history": "Historial",
"anonymous": "Anónimo",
@@ -81,7 +81,7 @@
"advancedOptions": "Opciones Avanzadas",
"difficulty": "Dificultad",
"difficultyHelpTitle": "¿Qué tan difícil es esta tarea?",
- "difficultyHelpContent": "Esto multiplica su valor respecto al puntaje. Úsalo con moderación y depende más bien de nuestros algoritmos orgánicos de ajuste de valor. Pero algunas tareas son extremadamente más valiosas (Escribir una Tesis vs. Lavarme los Dientes). Haz clic para más información.",
+ "difficultyHelpContent": "Esto multiplica su valor respecto al puntaje. Úsalo con moderación; en lugar de eso depende de nuestros algoritmos orgánicos de ajuste de valor. Pero algunas tareas son extremadamente más valiosas (Escribir una tesis vs. Lavarme los dientes). Haz clic para más información.",
"easy": "Fácil",
"medium": "Medio",
"hard": "Difícil",
@@ -103,10 +103,10 @@
"dueDate": "Fecha de Vencimiento",
"remaining": "Pendientes",
"complete": "Completos",
- "rewards": "Premios",
+ "rewards": "Recompensas",
"gold": "Oro",
"silver": "Plata",
- "newReward": "Nuevo Premio",
+ "newReward": "Nueva Recompensa",
"price": "Precio",
"tags" : "Etiquetas",
"editTags" : "Editar Etiquetas",
@@ -115,8 +115,8 @@
"_commentdrops" : "SYSTEMA DE DROPS",
- "dropsEnabled" : "¡Drops Habilitados!",
- "dropsEnabledText1" : "¡Has activado el Sistema de drops! Ahora cuando completas tareas, tienes una pequeña azar de encontrar un ítem. Y adivina qué, has encontrado un",
+ "dropsEnabled" : "¡Caídas Habilitadas!",
+ "dropsEnabledText1" : "¡Has desbloqueado el Sistema de Caídas! Ahora cuando completas tareas, tienes una pequeña chance de encontrar un ítem. Y adivina qué, has encontrado un",
"dropsEnabledText2" : "huevo",
"itemDropped" : "Ha caído un ítem",
@@ -131,7 +131,11 @@
"hair": "Cabello",
"skin": "Piel",
"clothing" : "Ropa",
- "photoUrl": "Url de la Imagen",
+ "showArmor": "Mostrar Armadura",
+ "other": "Más",
+ "showWeapon": "Mostrar Arma",
+ "showShield": "Mostrar Escudo",
+ "photoUrl": "Url de Imagen",
"fullName": "Nombre Completo",
"blurb": "Descripción",
"websites": "Sitios Web",
@@ -151,10 +155,10 @@
"party": "Grupo",
"createAParty":"Crear un Grupo",
- "noPartyText": "No estás en un grupo. Puedes crear uno e invitar amigos, o si te quieres incorporarse a un grupo existente, haz que ingresen:",
+ "noPartyText": "No estás en un grupo. Puedes crear uno e invitar amigos, o si te quieres unir a un grupo existente, haz que ingresen:",
"partyName": "Nombre del Grupo",
"create":"Crear",
- "userId":"Id del Usuario",
+ "userId":"Id de Usuario",
"invite":"Invitar",
"leave": "Salir",
"invitedTo" : "Estás Invitado A",
@@ -177,12 +181,12 @@
"rarePets": "Mascotas Raras",
"tavern": "Taberna",
- "restButton":"Descansar En La Posada",
- "checkoutButton": "Salir De La Posada",
- "tavernTalkTitle":"Charla de Taberna & Busqueda de grupos",
- "tavernRestingInfo" : "Mientras descansas, tus Diarios son guardados y no son afectados por el cambio de día. Salgas mañana de la posada o en una semana, continuarás en el mismo estado en que estabas cuando entraste.",
+ "restButton":"Descansar en la Posada",
+ "checkoutButton": "Salir de la Posada",
+ "tavernTalkTitle":"Charla de Taberna & Búsqueda de Grupos",
+ "tavernRestingInfo" : "Mientras descansas, tus diarios son guardados y no son afectados por el cambio de día. Salgas mañana de la posada o en una semana, continuarás en el mismo estado en que estabas cuando entraste.",
"resources" : "Recursos",
- "LFGPosts" : "Publicaciones de busca de grupos",
+ "LFGPosts" : "Publicaciones de búsqueda de grupos",
"tutorials" : "Tutoriales",
"achievements":"Logros",
@@ -195,7 +199,7 @@
"kickstartText" : "Apoyó el proyecto en Kickstarter",
"streakName" : " Logro(s) en Cadena",
"streakText1" : "Ha completado ",
- "stureakText2" : "Diarios durante 21 días consecutivos",
+ "stureakText2" : "diarios durante 21 días consecutivos",
"origUserName" : "Usuario Original",
"origUserText" : "Se remonta a los antiguos días de Habit (¡benditos sean por lidiar con los errores!)",
"ultimGearName" : "Máximo Equipamiento",
@@ -208,7 +212,7 @@
"settings":"Configuración",
"customDayStart":"Personalizar Inicio del Día",
"24HrClock": "Reloj 24h",
- "clockInfo":"Por defecto HabitRPG chequea y reinicia tus Diarios cada día a medianoche. Puedes personalizar esto aquí (Ingresa un número entre 0 y 24).",
+ "clockInfo":"Por defecto HabitRPG chequea y reinicia tus diarios cada día a medianoche. Puedes personalizar esto aquí (Ingresa un número entre 0 y 24).",
"misc":"Miscelánea",
"hideHeader":"Ocultar Encabezado",
"showHeader":"Mostrar Encabezado",
@@ -227,7 +231,7 @@
"delete":"Eliminar",
"deleteAltText":"Eliminar tu cuenta",
"deleteHeader" : "Eliminar Cuenta",
- "deleteText1":"¡Woa woa woa! ¿Estás seguro? Esto realmente eliminará tu cuenta para siempre, y nunca podrá ser recuperada. Si estás absolutamente seguro, escribe",
+ "deleteText1":"¡Wow wow wow! ¿Estás seguro? Esto realmente eliminará tu cuenta para siempre, y nunca podrá ser recuperada. Si estás absolutamente seguro, escribe",
"deleteText2":" DELETE ",
"deleteText3":"en el cuadro de texto",
"API":"API",
@@ -284,7 +288,7 @@
"sheild1Text": "Reduce la pérdida de HP en un 3%",
"sheild2Name" : "Broquel",
"sheild2Text": "Reduce la pérdida de HP en un 4%",
- "sheild3Name" : "Escudo Fuerte",
+ "sheild3Name" : "Escudo Reforzado",
"sheild3Text": "Reduce la pérdida de HP en un 5%",
"sheild4Name" : "Escudo Rojo",
"sheild4Text": "Reduce la pérdida de HP en un 7%",
@@ -343,21 +347,21 @@
"NPCAugustinText1" : "¡Bienvenido al Mercado! Soy el comerciante;",
"NPCAugustinText2" : "¿Mueres por conseguir esa mascota particular que buscas, pero no quieres esperar que caiga? ¡Cómprala aquí!",
"NPCJohanssonText1" : "¡Bienvenido a la Taberna! Soy",
- "NPCJohanssonText2": "el camarero. Si quieres descansar por un tiempo (¿te vas de vacaciones? ¿enfermedad repentina?), te instalaré en la posada - los Diarios no te dañarán mientras descansas. Quédate por un tiempo y conoce a los lugareños.",
+ "NPCJohanssonText2": "el camarero. Si quieres descansar por un tiempo (¿te vas de vacaciones? ¿enfermedad repentina?), te instalaré en la posada - los diarios no te dañarán mientras descansas. Quédate por un tiempo y conoce a los lugareños.",
"NPCMelchiorText1" : "",
"NPCBowenText1" : "",
"NPCBochText1" : "",
"_commentdeathstuff" : "DEATH",
"deathTitle" : "¡Has Muerto!",
- "deathText" : "Has perdido tu oro, 1 nivel y 1 pieza de equipamiento. ¡Asegúrate de completar tus Diarios para prevenir que esto pase de nuevo!",
+ "deathText" : "Has perdido tu oro, 1 nivel y 1 pieza de equipamiento. ¡Asegúrate de completar tus diarios para prevenir que esto pase de nuevo!",
"_commentgems" : "GEMS",
"gems" : "Gemas",
"outOfGems" : "Sin Gemas",
"buyMoreGems" : "Compra Más Gemas",
"notEnoughGems" : "No hay suficientes Gemas",
- "petsOutOfGems" : "¡Oops, te has quedado sin Gemas, las cuales sirven para comprar ítems especiales! Habit es un proyecto de código abierto, y le viene bien toda la ayuda que pueda conseguir - compra más Gemas para recibir esta mascota, y considéralo como una donación a los colaboradores",
+ "petsOutOfGems" : "¡Ups, te has quedado sin Gemas, las cuales sirven para comprar ítems especiales! Habit es un proyecto de código abierto, y le viene bien toda la ayuda que pueda conseguir - compra más Gemas para recibir esta mascota, y considéralo como una donación a los colaboradores",
"gemsWhatFor" : "Se usan para comprar ítems especiales (reroll, huevos, pociones eclosionadoras, etc). Necesitarás desbloquear estas características para poder usar Gemas.",
"_commentfooter": "FOOTER",
diff --git a/locales/fr/app.json b/locales/fr/app.json
index ce61a15538..80e646e8e6 100644
--- a/locales/fr/app.json
+++ b/locales/fr/app.json
@@ -128,10 +128,14 @@
"avatar": "Avatar",
"head": "Tête",
- "showHelm": "Afficher le casque",
+ "showHelm": "Montrer le casque",
"hair": "Cheveux",
"skin": "Peau",
"clothing" : "Vêtements",
+ "showArmor": "Montrer l'armure",
+ "other": "Autres",
+ "showWeapon": "Montrer l'arme",
+ "showShield": "Montrer le bouclier",
"photoUrl": "Lien vers la photo",
"fullName": "Nom complet",
"blurb": "Bio",
diff --git a/locales/he/app.json b/locales/he/app.json
index db0f32e1d2..6a5aa7e8b4 100644
--- a/locales/he/app.json
+++ b/locales/he/app.json
@@ -1,98 +1,98 @@
{
- "languageName": "Hebrew",
+ "languageName": "עברית",
-"_commentfrontpage":"HABITRPG FRONT PAGE",
- "synopsis" : "תוכנית שמהפך את ההיים שלך למשחק תפקידים. ההצלחה מעלה את המדרגה, הכשלון מונע את נקודות החיים, תרוויחו כסף לאסף נשקת שריון ופריטים.",
+"_commentfrontpage":"HABITRPG עמוד ראשי",
+ "synopsis" : "תוכנה לפיתוח הרגלים שמתייחסת לחיים כמו משחק תפקידים. עלה שלב בהצלחות, הפסד בריאות בכשלונות, הרווח כסף לרכישת נשק ושריון.",
"playButton" : "שחק",
-"_commenttut": "TUTORIAL/TOUR",
- "endTourButton": "גמר הסיור",
+"_commenttut": "הדרכה/סיור",
+ "endTourButton": "סיים סיור",
"nextButton" : "הבא",
- "prevButton" : "אחרון",
+ "prevButton" : "הקודם",
"tour1Title" : "ברוכים הבאים ל-HabitRPG",
- "tour1Text" : "ברוכים הבאים ל-HabitRPG, גשש הרגלים שמטפל בך כאילו היית דמות במשחק תפקידים.",
+ "tour1Text" : "ברוכים הבאים ל-HabitRPG, מתעד-ההרגלים שמטפל בך כאילו היית דמות במשחק תפקידים.",
"tour2Title" : "הרגלים",
- "tour2Text" : "הרגלים הם מידות או מטרות לטוב או לרע שאתם גוששים.",
- "tour3Title" : "יומיומיות",
- "tour3Text" : "יומיומיות הן מטלות שרוצים למלאות בקצב יומיומי.",
+ "tour2Text" : "הרגלים יכולים להיות מטרות טובות או רעות אחריהם אתם עוקבים ברציפות.",
+ "tour3Title" : "יומיות",
+ "tour3Text" : "יומיות הן מטרות שרוצים להשיג פעם ביום.",
"tour4Title" : "מטלות",
- "tour4Text" : "מטלות הם משימות חד-פעמיות שצריכים למלאות באיזה זמן. ",
+ "tour4Text" : "מטלות הן משימות חד-פעמיות שיש להשלים מתישהו.",
"tour5Title" : "פרסים",
- "tour5Text" : "כשתמלאו המטרות, תרוויחו זהב לקנות פרסים. קנו אותם חופשי - חייבים פרסים כדי לבנות הרגלים טובים ומידות טובות. ",
- "tour6Title" : "העבר את העכבר על הערות",
- "tour6Text" : "יש לסוגי המטרות השונות מאפיינים שונים. העבר את העכבר על הערה של כל מטרה לצפייה במידע מושלמת. כשאתם מוכניםת מחקו את המטרות המחדלים וקדימה!.",
+ "tour5Text" : "עם השגת המטרות, תרוויחו זהב שישמש אתכם לרכישת פרסים. רכשו פרסים בחופשיות - תמריצים חיוביים הם חיוניים לביסוס הרגלים טובים.",
+ "tour6Title" : "עבור על ההערות",
+ "tour6Text" : "למטרות מסוגים שונים יש מאפיינים מיוחדים. הצביעו עם העכבר על סמל ההערה של כל מטרה למידע נוסף. כשאתם מוכנים, מחקו את המטרות הקיימות והוסיפו את שלכם.",
-"_commentdefaulttasks":"DEFAULT TASKS",
- "habit1" : "1h Productive Work",
- "habit1comment": "-- Habits: Constantly Track -- For some habits, it only makes sense to *gain* points (like this one)",
- "habit2" : "Eat Junk Food",
- "habit2comment" : "For others, it only makes sense to *lose* points",
- "habit3" : "Take The Stairs",
- "habit3comment" : "For the rest, both + and - make sense (stairs = gain, elevator = lose)",
- "daily1" : "1h Personal Project",
- "daily1comment" : "-- Dailies: Complete Once a Day -- At the end of each day, non-completed Dailies dock you points.",
- "daily2" : "Exercise",
- "daily2comment" : "If you are doing well, they turn green and are less valuable (experience, gold) and less damaging (HP). This means you can ease up on them for a bit.",
- "daily3" : "45m Reading",
- "daily3comment" : "But if you are doing poorly, they turn red. The worse you do, the more valuable (exp, gold) and more damaging (HP) these goals become. This encourages you to focus on your shortcomings, the reds.",
- "todo1" : "Call Mom",
- "todo1comment" : "-- Todos: Complete Eventually -- Non-completed Todos won't hurt you, but they will become more valuable over time. This will encourage you to wrap up stale Todos.",
- "reward1" : "1 Episode of Game of Thrones",
- "reward1comment": "-- Rewards: Treat Yourself! -- As you complete goals, you earn gold to buy rewards. Buy them liberally - rewards are integral in forming good habits.",
- "reward2" : "Cake",
- "reward2comment" : "But only buy if you have enough gold - you lose HP otherwise.",
+"_commentdefaulttasks":"משימות ברירת מחדל",
+ "habit1" : "שעת עבודה פרודוקטיבית",
+ "habit1comment": "-- הרגלים: במעקב רציף -- עבור הרגלים מסויימים, הגיוני רק *לצבור* נקודות (כמו זה) --",
+ "habit2" : "לאכול ג'אנק פוד",
+ "habit2comment" : "עבור אחרים, זה רק הגיוני *להפסיד* נקודות",
+ "habit3" : "עלה במדרגות",
+ "habit3comment" : "עבור השאר, גם + וגם - הגיוניים (מדרגות = צבירה, מעלית = הפסד)",
+ "daily1" : "שעה פרוייקט אישי",
+ "daily1comment" : "יומיות: השלימו אחת ליום -- בסוף כל יום, יומיות שלא הושלמו מעכבות את קצב צבירת הנקודות שלך.",
+ "daily2" : "אימון כושר",
+ "daily2comment" : "אם אתם עומדים ביעדים, הם הופכים לירוקים ושווים פחות (נסיון, זהב) ופחות מזיקים (בריאות). זה אומר שאתם יכולים להתייחס אליהם יותר בקלות.",
+ "daily3" : "45 דקות קריאה",
+ "daily3comment" : "אבל אם אתם לא עומדים בקצב, הם נהיים אדומים. ככל שתכשלו יותר, ערכם (נסיון, זהב) יעלה והם יעלו לכם ביותר בריאות. זה יעודד אתכם להתמקד במכשולים שלכם, הצבועים באדום.",
+ "todo1" : "להתקשר לאמא",
+ "todo1comment" : "מטלות: להשלים מתישהו -- מטלות שלא הושלמו לא יפגעו בך, אבל ערכן יגדל עם הזמן. זה יעודד אתכם להשלים מטלות מעוכבות.",
+ "reward1" : "פרק אחד של משחקי הכס",
+ "reward1comment": "פרסים: פנקו את עצמכם! -- ככל שתשיגו יעדים, תרוויחו זהב לרכוש פרסים. ריכשו אותם בנדיבות - תמריצים חיוביים חיוניים לאימוץ הרגלים טובים.",
+ "reward2" : "עוגה",
+ "reward2comment" : "אבל ריכשו אותם רק אם יש לכם מספיק זהב - אחרת תאבדו נקודות בריאות.",
-"_commentdefaulttags" : "DEFAULT TAGS",
+"_commentdefaulttags" : "תגיות ברירת מחדל",
"morning" : "בוקר",
- "afternoon" : "אחה״צ",
+ "afternoon" : "צהריים",
"evening" : "ערב",
-"_commenthead": "HEADER",
+"_commenthead": "כותרת",
"health": "בריאות",
"experience": "נסיון",
"history": "היסטוריה",
"anonymous": "אלמוני",
- "level": "דרגה",
+ "level": "שלב",
"tasks": "משימות",
"loginAndReg" : "כניסה / הרשמה",
"loginFacebookAlt" : "כניסה / הרשמה דרך פייסבוק",
- "login" : "כביסה",
+ "login" : "כניסה",
"register" : "הרשמה",
"options": "אפשרויות",
"logout": "יציאה",
-"_commentnotifcations" : "NOTIFICATIONS",
- "partyNotification" : "הודעות חברה חדשות",
+"_commentnotifcations" : "עדכונים",
+ "partyNotification" : "הצעת חברות חדשה",
-"_commenttaskview": "TASK VIEW",
+"_commenttaskview": "תצוגת משימה",
"habits": "הרגלים",
"Habits": "הרגלים",
"newHabit": "הרגל חדש",
- "edit": "ערך",
+ "edit": "ערוך",
"text": "טקסט",
"extraNotes": "הארות",
"directions/Actions": "כיוון/פעולות",
"advancedOptions": "אפשרויות מתקדמות",
"difficulty": "קושי",
"difficultyHelpTitle": "כמה קשה המשימה הזאת?",
- "difficultyHelpContent": "זאת מכפילה את ערך המשימה. תשתמשו בזאת מעטת אלא סמכו על אלגוריתם הההתאמה האורגני. אבל כמה משימות ערכן משונה באופן משמעותי כמו ציחצוח שניים מול כתיבת התזה. תלחצו למידע מושלמת.",
+ "difficultyHelpContent": "זה מכפיל את ערך הנקודות. השתמשו בחסכנות, עדיף כמובן שתסמכו על אלגוריתם שקלול הערך האורגני שלנו, אבל לפעמים מטלות מסויימות שוות יותר (לכתוב תזה מול להשתמש בחוט דנטלי). לחצו למידע נוסף",
"easy": "קל",
"medium": "בינוני",
"hard": "קשה",
- "delete": "מחוק",
- "progress": "פרוגרס",
- "score": "ציון",
- "dailies": "יומיומיות",
- "Dailies": "יומיומיות",
- "newDaily": "יומיומית חדשה",
+ "delete": "מחיקה",
+ "progress": "התקדמות",
+ "score": "ניקוד",
+ "dailies": "יומיות",
+ "Dailies": "יומיות",
+ "newDaily": "יומית חדשה",
"repeat": "חזרה",
"Su": "א'",
"M": "ב'",
@@ -105,159 +105,163 @@
"Todos": "מטלות",
"newTodo": "מטלה חדשה",
"dueDate": "תעריך יעד",
- "remaining": "נשארות",
- "complete": "נשלמות",
+ "remaining": "נשאר",
+ "complete": "הושלם",
"rewards": "פרסים",
"Rewards": "פרסים",
"gold": "זהב",
"silver": "כסף",
"newReward": "פרס חדש",
- "price": "מכיר",
- "tags" : "תגים",
- "editTags" : "ערוך תגים",
- "newTag" : "תג חדש",
- "clearFilters" : "מחוק מסננות",
+ "price": "מחיר",
+ "tags" : "תגיות",
+ "editTags" : "ערוך תגיות",
+ "newTag" : "תגית חדשה",
+ "clearFilters" : "נקה סינון",
-"_commentdrops" : "DROP SYSTEM",
- "dropsEnabled" : "ירידות מופעלות!",
- "dropsEnabledText1" : "פתחת מערכת הירידות! עכשיו, כשתגמרו משימות, יש לכם צ׳נס קטן למצוא משהו יפה. מאמינים? בדיוק מצאתם",
+"_commentdrops" : "מערכת הליקוט",
+ "dropsEnabled" : "ליקוט מופעל!",
+ "dropsEnabledText1" : "שחררתם את מערכת הליקוט! מעתה כשתשלימו משימות, יש סיכוי קטן שתמצאו משהו מעניין. ונחשו מה, בדיוק מצאתם",
"dropsEnabledText2" : "ביצה",
- "itemDropped" : "ירד פריט!!",
+ "itemDropped" : "הפריט לוקט!!",
-"_commentoptionsview": "OPTIONS VIEW",
+"_commentoptionsview": "תצוגת אפשרויות",
"profile": "פרופיל",
- "avatar": "אוואתר",
+ "avatar": "דמות",
"head": "ראש",
"showHelm": "הראה קסדה",
- "hair": "שער",
+ "hair": "שיער",
"skin": "עור",
"clothing" : "לבוש",
- "photoUrl": "URL תמונה",
+ "showArmor": "Show Armor",
+ "other": "Other",
+ "showWeapon": "Show Weapon",
+ "showShield": "Show Shield",
+ "photoUrl": "כתובת תמונה",
"fullName": "שם מלא",
"blurb": "קצת על עצמך",
"websites": "אתרי אינטרנט",
- "addWebsites": "הוסיף אתרים",
+ "addWebsites": "הוסף אתרים",
"items" : "פריטים",
"weapon" : "נשק",
"armor" : "שריון",
"helm" : "קסדה",
"shield" : "מגן",
- "stats" : "סטטיסטיקות",
+ "stats" : "נתונים",
"strength" : "עוצמה",
"defense" : "הגנה",
"totalStrength" : "סך עוצמה",
"totalDefense" : "סך הגנה",
- "party": "Party",
- "createAParty":"יצר מפלגה",
- "noPartyText": "אתה לא במפלגה. או שאתה יכול ליצור אותו ולהזמין את החברים, או אם אתה רוצה להצטרף למפלגה קיימת, יש להם להכניס:",
- "partyName": "שם מפלגה",
- "create":"יצר",
+ "party": "חמולה",
+ "createAParty":"צור חמולה",
+ "noPartyText": "אינכם בחמולה. באפשרותכם ליצור חמולה ולהזמין חברים, או על מנת להצטרף לחמולה קיימת, עליהם להכניס:",
+ "partyName": "שם החמולה",
+ "create":"צור",
"userId":"מספר משתמש",
- "invite":"הזמין",
- "leave": "יצא",
+ "invite":"הזמן",
+ "leave": "עזוב",
"invitedTo" : "אתם מוזמנים ל-",
"chat": "שיחה",
"inventory": "מלאי",
"eggs": "ביצים",
- "noEggs": "אין לך ביצים במלאי שלך",
- "hatchingPotions": "שיקויי בקיעה",
- "noHatchingPotions": "עדיין אין לך שיקויי בקיעה",
- "hatchYourEgg" : "בוקע את הביצה שלך",
- "whichHatchingPotion1" : "איזה שיקוי בקיעה לשפוך על ביצת ה",
+ "noEggs": "אין לך ביצים במלאי",
+ "hatchingPotions": "שיקויים",
+ "noHatchingPotions": "עדיין אין לך שיקוי",
+ "hatchYourEgg" : "הפוך ביצה לחיית מחמד",
+ "whichHatchingPotion1" : "איזה שיקוי לשפוך על ביצת ה",
"whichHatchingPotion2" : "שלך?",
"pour" : "שפוך",
"rarePets" : "חיות נדירות",
- "market": "השוק",
+ "market": "שוק",
- "stable": "אורוה",
+ "stable": "אורווה",
"petsFound":"חיות שנמצאות",
"rarePets": "חיות נדירות",
- "tavern": "בית מרזח",
- "restButton":"תנוח בבית מלון",
- "checkoutButton": "יציאה מהמלון",
- "tavernTalkTitle":"שיחה ו-LFG בבית המרזח",
- "tavernRestingInfo" : "תוך כדי לינה היומימיות שלך נשמרות ואין הליכת הזמן מפריע לנקודות שלך. מתי שאתם רוצים, תצאו מהמלון והדמות שלכם יהיה בדיוק כמו ששמתם פה.",
+ "tavern": "טברנה",
+ "restButton":"נוח בצימר",
+ "checkoutButton": "צא מהצימר",
+ "tavernTalkTitle":"שיח בטברנה",
+ "tavernRestingInfo" : "כל עוד הדמות שלכם לנה בצימר היומיות שלכם נשמרות והזמן שחולף לא מוריד נקודות. כשתרצו, צאו מהצימר והדמות שלכם תשוב בדיוק פי שהייתה כשבאה.",
"resources" : "משאבים",
- "LFGPosts" : "הודעות LGF",
+ "LFGPosts" : "הודעות",
"tutorials" : "הדרכות",
- "achievements":"Achievements",
- "achievementUnlocked" : "השג פתוח!",
+ "achievements":"הישגים",
+ "achievementUnlocked" : "הישג שוחרר!",
"npcText" : "תמך בפרוייקט ה-Kickstarter ברמה הגבוהה ביותר",
"contribName" : "מתנדב",
- "contribText" : "התנדב ל-HabitRPG (קוד, עיצוב, אומנות, עצה חוקי, משמכים, וכו׳). רוצה? תקן משהו!",
+ "contribText" : "תרמו ל-HabitRPG (קוד, עיצוב, אומנות, יעוץ משפטי, כתיבה, וכו׳). רוצים? תקנו משהו!",
"kickstartName1" : "תומך Kickstarter - ",
"kickstartName2" : "מדרגה",
"kickstartText" : "תמך בפרוייקט ה-Kickstarter",
- "streakName" : "השגות התמדה",
- "streakText1" : "התמד",
- "stureakText2" : "פעמים של 21 ימים ביומיומיות",
+ "streakName" : "הישג רצף התמדה",
+ "streakText1" : "התמיד",
+ "stureakText2" : "פעמים 21 ימים ברצף ביומיות",
"origUserName" : "משתמש מקורי",
"origUserText" : "היו היה פעם שכל אחד לחם בבאגים. איך שעשו חיל!",
- "ultimGearName" : "סוף הציוד",
- "ultimGearText" : "השג סט השיון וכלי זיין המקסימלי",
- "ultimGearUnlocked" : "השגת השג 'סוף הציוד' שקנית הציוד המקסימלי",
- "beastMastName" : "בעל החייות",
- "beastMastText" : "מצא כל 90 חיות. קשה נורה! תנו כבוד!",
- "beastMastUnlocked" : "השגת השג 'בעל החיות' שמצאת כל החיות!",
+ "ultimGearName" : "מעצמה צבאית",
+ "ultimGearText" : "השיג את כל כלי השריון והנשק",
+ "ultimGearUnlocked" : "השגת סטטוס 'מעצמה צבאית' - יש לך את כל כלי השריון והנשק",
+ "beastMastName" : "מלך החיות",
+ "beastMastText" : "מצא את כל 90 החיות. קשה נורא! תנו כבוד!",
+ "beastMastUnlocked" : "השגת את סטטוס 'מלך החיות' על שמצאת כל החיות!",
- "settings":"Settings",
- "customDayStart":"Custom Day Start",
- "24HrClock": "24Hr Clock",
- "clockInfo":"HabitRPG defaults to check and reset your dailies at midnight each day. You can customize that here (Enter number between 0 and 24).",
- "misc":"Misc",
- "hideHeader":"Hide Header",
- "showHeader":"Show Header",
- "changePass":"Change Password",
- "oldPass":"Old Password",
- "newPass":"New Password",
- "confirmPass":"Confirm New Password",
- "dangerZone": "Danger Zone",
- "reset":"Reset",
- "resetAltText":"Resets your entire account (dangerous)",
- "resetText1":"This resets your entire account - your tasks will be deleted and your character will start over.",
- "resetText2":"This is highly discouraged because you'll lose historical data, which is useful for graphing your progress over time. However, some people find it useful in the beginning after playing with the app for a while.",
- "restore":"Restore",
- "restoreAltText":"Restores attributes to your character",
+ "settings":"הגדרות",
+ "customDayStart":"שעת תחילת יום",
+ "24HrClock": "שעון 24 שעות",
+ "clockInfo":"HabitRPG מעדכן את הנתונים שלך בחצות כל יום כברירת מחדל. תוכלו להתאים אישית כאן את השעה (הזינו מספר בין 0 ל24)",
+ "misc":"שונות",
+ "hideHeader":"הסתר כותרת",
+ "showHeader":"הצג כותרת",
+ "changePass":"שינוי סיסמה",
+ "oldPass":"סיסמה ישנה",
+ "newPass":"סיסמה חדשה",
+ "confirmPass":"אשר סיסמה חדשה",
+ "dangerZone": "איזור סכנה",
+ "reset":"איפוס",
+ "resetAltText":"איפוס כל החשבון (מסוכן)",
+ "resetText1":"זה מאפס את כל החשבון - המטלות שלך ימחקו והדמות תתחיל מחדש. ",
+ "resetText2":"זה מאוד לא מומלץ כי תאבדו מידע היסטורי ששימושי מאוד להציג את התקדמותכם לאורך זמן. עם זאת, אנשים מסויימים מעוניינים באפשרות זו בהתחלה לאחר ששיחקו קצת בתוכנה. ",
+ "restore":"שחזר",
+ "restoreAltText":"שחזר מאפיינים של הדמות",
"restoreText1":"HabitRPG is quite Beta-quality at present, and many find they need to restore character attributes as a result. Enter your numbers here and it will be applied automatically to your character. This will be removed once Habit is more stable.",
- "delete":"Delete",
- "deleteAltText":"Delete your account",
- "deleteHeader" : "Delete Account",
- "deleteText1":"Woa woa woa! Are you sure? This will seriously delete your account forever, and it can never be restored. If you're absolutely certain, type",
+ "delete":"מחיקה",
+ "deleteAltText":"מחק את החשבון",
+ "deleteHeader" : "מחק חשבון",
+ "deleteText1":"ווא ווא ווי ווא! בטוחים? רוצים לחשוב על זה לשניה? זה לגמרי ברצינות ימחק את החשבון שלכם לתמיד, אף פעם לא תוכלו לשחזר אותו. אם אתם בטוחים לגמרי, הקלידו",
"deleteText2":" DELETE ",
- "deleteText3":"into the text-box",
+ "deleteText3":"לתוך תיבת הטקסט",
"API":"API",
- "APIText":"Copy these for use in third party applications.",
+ "APIText":"העתיקו את אלה לשימוש באפליקציות צד-ג.",
"APIToken":"Api Token",
-"_commentitems": "ITEMS",
- "_commentitemsweps": "WEAPONS",
- "sword0name" : "חרב תרגיל",
+"_commentitems": "פריטים",
+ "_commentitemsweps": "כלי נשק",
+ "sword0name" : "חרב אימון",
"sword1Name" : "חרב",
"sword1Text" : "מגדיל את רווח ניסיון של 3%.",
"sword2Name" : "גרזן",
"sword2Text" : "מגדיל את רווח ניסיון של 6%.",
"sword3Name" : "כוכב השחר",
"sword3Text" : "מגדיל את רווח ניסיון של 9%.",
- "sword4Name" : "חרב כחול",
+ "sword4Name" : "חרב כחולה",
"sword4Text" : "מגדיל את רווח ניסיון של 12%.",
- "sword5Name" : "חרב אדום",
+ "sword5Name" : "חרב אדומה",
"sword5Text" : "מגדיל את רווח ניסיון של 15%.",
"sword6Name" : "חרב זהב",
"sword6Text" : "מגדיל את רווח ניסיון של 18%.",
- "_commentitemsarmor": "ARMOR",
+ "_commentitemsarmor": "שריון",
"armor0Name" : "שריון בד",
"armor1Name" : "שריון עור" ,
"armor1Text": "מקטין הפסד של HP ב -4%",
@@ -270,7 +274,7 @@
"armor5Name" : "שריון זהב",
"armor5Text": "מקטין הפסד של HP ב -10%",
- "_commentitemshead" : "HEADGEAR",
+ "_commentitemshead" : "קסדה",
"head0Name" : "בלי קסדה",
"head1Name" : "קסדת עור" ,
"head1Text": "מקטין הפסד של HP ב-2%",
@@ -283,7 +287,7 @@
"head5Name" : "קסדת זהב",
"head5Text": "מקטין הפסד של HP ב-6%",
- "_commentitemsshield" : "SHIELDS",
+ "_commentitemsshield" : "מגנים",
"sheild0Name" : "בלי מגן",
"sheild1Name" : "מגן עץ",
"sheild1Text": "מקטין הפסד של HP ב-3%",
@@ -296,8 +300,8 @@
"sheild5Name" : "מגן זהב",
"sheild5Text": "מקטין הפסד של HP ב-8%",
- "_commentitemsother" : "OTHER ITEMS",
- "healthPotionName" : "שקוי בריאות",
+ "_commentitemsother" : "פריטים אחרים",
+ "healthPotionName" : "שיקוי בריאות",
"healthPotionNotes" : "לשחזר 15 HP באופן מיידי",
"rerollName" : "אתחול",
"rerollNotes" : "מאפס את ערכי המשימות שלך לצהוב. טוב כשאתה באדום וקשה להשתייר בחיים.",
@@ -306,7 +310,7 @@
"rerollModelText2" : "קרא יותר",
"rerollModelText3" : "אמנם, הכרחי אחרי תקופות ממושכות של הרגלים רעים.",
- "_commentitemspeteggs": "PET EGGS",
+ "_commentitemspeteggs": "ביצי חיות מחמד",
"wolfEgg": "גור זאב",
"tigerEgg": "גור נמרים",
"pandaEgg": "גור פנדה",
@@ -318,7 +322,7 @@
"bearEgg": "גור דובים",
"wolfEgg": "גור זאב",
- "_commentitemshatchingpotions": "HATCHING POTIONS",
+ "_commentitemshatchingpotions": "שיקויים",
"basePotName": "בסיסי",
"basePotText" : ".בוקעים חיית המחמד שלך לצורתה הבסיסי",
"whitePotName": "לבן",
@@ -353,7 +357,7 @@
"NPCBowenText1" : "",
"NPCBochText1" : "",
-"_commentdeathstuff" : "DEATH",
+"_commentdeathstuff" : "מוות",
"deathTitle" : "אתה מת!",
"deathText" : "הפסדת כל הכסף, מדרגה אחד וכלי אחת. הקפד להשלים את היומונים שלך כדי למנוע את זה מלקרות שוב!",
@@ -385,22 +389,22 @@
"_commentmisc": "MISC & GLOBAL",
- "removeAds": "הסרת פרסומים",
- "whyAds": "למה פירסומים?",
+ "removeAds": "הסרת פרסומות",
+ "whyAds": "למה פרסומות?",
"whyAdsContent1": "Habit היא פרויקט Open Source, וזקוק לכל עזרה - רואים את זה כתרומה למפתחים. גם מקבלים 20 אבני חן כדי לקנות פריטים מיוחדים.",
"whyAdsContent2": "'היי, אני תמכתי ה-Kickstarter!' - עקוב אחרי",
"whyAdsContent3": "ההוראות הבאות",
- "_commentbuttons": "BUTTONS",
+ "_commentbuttons": "כפתורים",
"submit":"שלח",
"close":"סגור",
"saveAndClose": "שמור וסגור",
"cancel":"בטל",
"ok" : "בסדר",
- "add" : "הוסיף",
+ "add" : "הוסף",
"undo" : "החזר",
"continue" : "המשך",
"accept" : "קבל",
- "reject" : "דוחה",
+ "reject" : "דחה",
"or" : "או",
"_commenttimestamps":"TIME STAMPS",
"justNow":"בדיוק עכשיו",
diff --git a/locales/id/app.json b/locales/id/app.json
index 6e96308bb3..8e58a655a6 100644
--- a/locales/id/app.json
+++ b/locales/id/app.json
@@ -132,6 +132,10 @@
"hair": "Hair",
"skin": "Skin",
"clothing" : "Clothing",
+ "showArmor": "Show Armor",
+ "other": "Other",
+ "showWeapon": "Show Weapon",
+ "showShield": "Show Shield",
"photoUrl": "Photo Url",
"fullName": "Full Name",
"blurb": "Blurb",
diff --git a/locales/it/app.json b/locales/it/app.json
index d7b97197a0..df1577ede0 100644
--- a/locales/it/app.json
+++ b/locales/it/app.json
@@ -4,7 +4,7 @@
"_commentfrontpage":"HABITRPG FRONT PAGE",
- "synopsis" : "Un programma per trattare le proprie abitudini come in un Gioco di Ruolo. Sali di livello se ci riesci, perdi HP se fallisci, guadagna soldi per comprare armi ed armature.",
+ "synopsis" : "Un programma per gestire le proprie abitudini come in un Gioco di Ruolo. Sali di livello se ci riesci, perdi HP se fallisci, guadagna soldi per comprare armi ed armature.",
"playButton" : "Gioca",
@@ -20,11 +20,11 @@
"tour3Title" : "Dailies",
"tour3Text" : "Le Dailies sono le attività che vuoi completare una volta al giorno.",
"tour4Title" : "Todos",
- "tour4Text" : "I Todos sono obiettivi unici che devono essere completati alla fine.",
+ "tour4Text" : "I Todos sono gli obiettivi personali che vuoi completare.",
"tour5Title" : "Ricompense",
"tour5Text" : "Quando completi i tuoi obiettivi, guadagni oro per comprare ricompense. Comprale liberamente - le ricompense sono fondamentali per formare buone abitudini.",
"tour6Title" : "Passa il mouse sopra i commenti",
- "tour6Text" : "Diversi tipi di attività hanno proprietà sperciali. Passa il mouse sopra i commenti per maggiori informazioni. Quando sei pronto per cominciare, cancella le attività esistenti ed aggiungine di nuove.",
+ "tour6Text" : "Diversi tipi di attività hanno proprietà speciali. Passa il mouse sopra i commenti per maggiori informazioni. Quando sei pronto per cominciare, cancella le attività esistenti ed aggiungine di nuove.",
@@ -132,6 +132,10 @@
"hair": "Capelli",
"skin": "Pelle",
"clothing" : "Abbigliamento",
+ "showArmor": "Mostra Armatura",
+ "other": "Altro",
+ "showWeapon": "Mostra Arma",
+ "showShield": "Mostra Scudo",
"photoUrl": "Url Foto",
"fullName": "Nome Completo",
"blurb": "Firma",
@@ -183,7 +187,7 @@
"tavernTalkTitle":"Chiacchiera nella Taverna & LFG",
"tavernRestingInfo" : "Mentre riposi le tue dailies sono salvate e non verranno modificate dal cambio di giorno. Puoi tornare domani o in una settimana, troverai tutto come l'hai lasciato.",
"resources" : "Risorse",
- "LFGPosts" : "Messaggi LGF",
+ "LFGPosts" : "Messaggi LFG",
"tutorials" : "Tutorials",
"achievements":"Obiettivi",
@@ -280,7 +284,7 @@
"head5Text": "Riduce gli HP persi del 6%",
"_commentitemsshield" : "SHIELDS",
- "sheild0Name" : "Nessuno Scuso",
+ "sheild0Name" : "Nessuno Scudo",
"sheild1Name" : "Scudo di Legno",
"sheild1Text": "Riduce gli HP persi del 3%",
"sheild2Name" : "Brocchiero",
@@ -344,7 +348,7 @@
"NPCAugustinText1" : "Benvenuti al mercato! Io sono il mercante;",
"NPCAugustinText2" : "Morite dalla voglia di avere quel particolare animale, ma non volete aspettare di trovarlo ? Compratelo qui!",
"NPCJohanssonText1" : "Benvenuti alla Locanda! Io sono",
- "NPCJohanssonText2": "l'oste. Se vuoi riposare per un po' (vai in vacanca? malattia improvvisa?), ti sistemo in locanda - le dailies non ti faranno male mentre riposi. Rimani un po' & incontra la gente del posto.",
+ "NPCJohanssonText2": "l'oste. Se vuoi riposare per un po' (vai in vacanca? malattia improvvisa?), ti sistemo in locanda - le dailies non ti faranno male mentre riposi. Rimani un po' e incontra la gente del posto.",
"NPCMelchiorText1" : "",
"NPCBowenText1" : "",
"NPCBochText1" : "",
@@ -384,7 +388,7 @@
"removeAds": "Rimuovi gli Ads",
"whyAds": "Perché gli Ads?",
"whyAdsContent1": "Habit è un progetto open source, e può usare tutto l'aiuto che può ottenere - considerala una donazione ai collaboratori. Riceverai anche 20 Gemme dall'acquisto, con le quali puoi comprare oggetti speciali.",
- "whyAdsContent2": "'Hey, Ho sostenuto il progetto su Kickstarter!' - segui",
+ "whyAdsContent2": "'Hey, ho sostenuto il progetto su Kickstarter!' - segui",
"whyAdsContent3": "queste istruzioni",
"_commentbuttons": "BUTTONS",
"submit":"Invia",
diff --git a/locales/ja/app.json b/locales/ja/app.json
index 81f190efd2..f96333525f 100644
--- a/locales/ja/app.json
+++ b/locales/ja/app.json
@@ -80,7 +80,7 @@
"extraNotes": "Extra Notes",
"directions/Actions": "Directions/Actions",
"advancedOptions": "Advanced Options",
- "difficulty": "Difficulty",
+ "difficulty": "難易度",
"difficultyHelpTitle": "How difficult is this task?",
"difficultyHelpContent": "This multiplies its point value. Use sparingly, rely instead on our organic value-adjustment algorithms. But some tasks are grossly more valuable (Write Thesis vs Floss Teeth). Click for more info.",
"easy": "簡単",
@@ -129,9 +129,13 @@
"head": "頭",
"showHelm": "Show 兜",
- "hair": "Hair",
+ "hair": "毛",
"skin": "皮膚",
"clothing" : "衣料",
+ "showArmor": "Show Armor",
+ "other": "他の",
+ "showWeapon": "Show Weapon",
+ "showShield": "Show Shield",
"photoUrl": "写真 URL",
"fullName": "名前",
"blurb": "自己紹介",
@@ -171,13 +175,13 @@
"whichHatchingPotion2" : "卵?",
"pour" : "pour",
"rarePets" : "Rare Pets",
- "market": "Market",
+ "market": "マーケット",
"stable": "Stable",
"petsFound":"Pets Found",
"rarePets": "Rare Pets",
- "tavern": "Tavern",
+ "tavern": "居酒屋",
"restButton":"Rest In The Inn",
"checkoutButton": "Check Out Of Inn",
"tavernTalkTitle":"Tavern Talk & LFG",
@@ -186,7 +190,7 @@
"LFGPosts" : "LGF Posts",
"tutorials" : "チュートリアル",
- "achievements":"Achievements",
+ "achievements":"功績",
"achievementUnlocked" : "Achievement Unlocked!",
"npcText" : "Backed the Kickstarter project at the maximum level!",
"contribName" : "Contributor",
@@ -353,7 +357,7 @@
"deathText" : "You've lost your GP, 1 level and 1 gear piece. Be sure to complete your dailies to prevent this from happening again!",
"_commentgems" : "GEMS",
- "gems" : "Gems",
+ "gems" : "宝石",
"outOfGems" : "Out Of Gems",
"buyMoreGems" : "Buy More Gems",
"notEnoughGems" : "Not enough Gems",
@@ -390,7 +394,7 @@
"close":"締める",
"saveAndClose": "保存して閉じる",
"cancel":"キャンセル",
- "ok" : "Ok",
+ "ok" : "はい",
"add" : "加える",
"undo" : "キャンセル",
"continue" : "続ける",
diff --git a/locales/nl/app.json b/locales/nl/app.json
index 812296ef2a..90093b7574 100644
--- a/locales/nl/app.json
+++ b/locales/nl/app.json
@@ -132,6 +132,10 @@
"hair": "Haar",
"skin": "Huid",
"clothing" : "Kleding",
+ "showArmor": "Show Armor",
+ "other": "Other",
+ "showWeapon": "Show Weapon",
+ "showShield": "Show Shield",
"photoUrl": "Foto URL",
"fullName": "Volledige Naam",
"blurb": "Blurp",
diff --git a/locales/no/app.json b/locales/no/app.json
index 8e837fec62..b668b942bb 100644
--- a/locales/no/app.json
+++ b/locales/no/app.json
@@ -137,6 +137,10 @@
"skin": "Hudfarge",
"clothing" : "Klær",
"photoUrl": "Bilde-URL",
+ "showArmor": "Show Armor",
+ "other": "Other",
+ "showWeapon": "Show Weapon",
+ "showShield": "Show Shield",
"fullName": "Fullt navn",
"blurb": "Kort om deg",
"websites": "Nettsider",
diff --git a/locales/pl/app.json b/locales/pl/app.json
index a24f2b8c5e..ee97d430b3 100644
--- a/locales/pl/app.json
+++ b/locales/pl/app.json
@@ -132,6 +132,10 @@
"hair": "Włosy",
"skin": "Karnacja",
"clothing" : "Ubranie",
+ "showArmor": "Show Armor",
+ "other": "Other",
+ "showWeapon": "Show Weapon",
+ "showShield": "Show Shield",
"photoUrl": "URL obrazka",
"fullName": "Imię i nazwisko",
"blurb": "Krótki opis",
diff --git a/locales/pt/app.json b/locales/pt/app.json
index 1e81ab6a67..669488790c 100644
--- a/locales/pt/app.json
+++ b/locales/pt/app.json
@@ -132,6 +132,10 @@
"hair": "Cabelo",
"skin": "Pele",
"clothing" : "Vestimentas",
+ "showArmor": "Show Armor",
+ "other": "Other",
+ "showWeapon": "Show Weapon",
+ "showShield": "Show Shield",
"photoUrl": "Url da Foto",
"fullName": "Nome Completo",
"blurb": "Sinopse",
diff --git a/locales/ru/app.json b/locales/ru/app.json
index 7d46037ed6..1e13f69762 100644
--- a/locales/ru/app.json
+++ b/locales/ru/app.json
@@ -132,6 +132,10 @@
"hair": "Волосы",
"skin": "Кожа",
"clothing" : "Одежда",
+ "showArmor": "Show Armor",
+ "other": "Other",
+ "showWeapon": "Show Weapon",
+ "showShield": "Show Shield",
"photoUrl": "Ссылка на фото",
"fullName": "Полное имя",
"blurb": "О себе",
diff --git a/locales/sl/app.json b/locales/sl/app.json
new file mode 100644
index 0000000000..ef5783c5e9
--- /dev/null
+++ b/locales/sl/app.json
@@ -0,0 +1,417 @@
+{
+
+ "languageName": "Slovene",
+ "stringNotFound": "String not found.",
+
+
+"_commentfrontpage":"HABITRPG FRONT PAGE",
+ "synopsis" : "Program za pridobivanje navad, s katerim tvoje življenje postane igra igranja vlog. Z uspehi tvoj lik raste, z neuspehi izgubi del zdravja, s prisluženim denarjem pa lahko kupiš orožje in oklep.",
+ "playButton" : "Igraj",
+
+
+
+"_commenttut": "TUTORIAL/TOUR",
+ "endTourButton": "Končaj predstavitev",
+ "nextButton" : "Naprej",
+ "prevButton" : "Nazaj",
+ "tour1Title" : "Dobrodošel pri HabitRPG",
+ "tour1Text" : "Dobrodošel pri HabitRPG, programu, ki spremlja tvoje navade v stilu igre igranja vlog.",
+ "tour2Title" : "Navade",
+ "tour2Text" : "S programom ves čas spremljaš dobre in slabe navade.",
+ "tour3Title" : "Dnevne naloge",
+ "tour3Text" : "Dnevne naloge moraš opraviti vsak dan enkrat.",
+ "tour4Title" : "Opravki",
+ "tour4Text" : "Opravki so naloge, ki jih moraš opraviti samo enkrat. ",
+ "tour5Title" : "Nagrade",
+ "tour5Text" : "Z opravljenimi nalogami si prislužiš zlato, s katerim lahko kupiš nagrade. Kupuj jih pogosto, saj so pomembne pri pridobivanju novih navad. ",
+ "tour6Title" : "Poglej komentarje",
+ "tour6Text" : "Določene vrste nalog imajo posebne lastnosti. Ogledaš si jih tako, da kazalec miške postaviš nad njihov komentar. Ko želiš začeti, izbriši obstoječe naloge in dodaj svoje.",
+
+
+
+"_commentdefaulttasks":"DEFAULT TASKS",
+ "habit1" : "1h produktivno delo",
+ "habit1comment": "-- Navade program spremlja ves čas -- Pri določenih nalogah je smiselno samo *pridobivanje* točk (kot pri tej)",
+ "habit2" : "Jedel nezdravo hrano",
+ "habit2comment" : "Pri drugih je smiselno samo *izgubljanje* točk",
+ "habit3" : "Šel po stopnicah",
+ "habit3comment" : "Pri ostalih lahko uporabiš tako + kot tudi - (stopnice = pridobiš, dvigalo = izgubiš)",
+ "daily1" : "1h osebni projekt",
+ "daily1comment" : "-- Dnevne naloge je treba opraviti enkrat na dan -- Ko se dan konča, izgubiš točke za vse neopravljene dnevne naloge.",
+ "daily2" : "Telovadba",
+ "daily2comment" : "Če jih opravljaš vestno, postanejo zelene, prinesejo manj denarja in izkušenj ter odvzamejo manj zdravja, ko jih ne opraviš.",
+ "daily3" : "45min branje",
+ "daily3comment" : "Če pa jih opravljaš neredno, postanejo rdeče. Čim manjkrat jih opraviš, tem več zlata in izkušenj prinesejo, vendar pa so tudi bolj nevarne za zdravje lika. To te spodbudi, da jih opravljaš bolj redno.",
+ "todo1" : "Pokliči mamo",
+ "todo1comment" : "-- Opravke je treba opraviti enkrat -- Neopravljeni opravki ne škodujejo zdravju lika, sčasoma pa postanejo vredni vedno več, kar te spodbudi, da opraviš te zapoznele naloge.",
+ "reward1" : "1 epizoda Igre prestolov",
+ "reward1comment": "-- Privošči si nagrado! -- Z opravljenimi nalogami si prislužiš zlato, s katerim lahko kupiš nagrade. Kupuj jih pogosto, saj so pomembne pri pridobivanju novih navad.",
+ "reward2" : "Torta",
+ "reward2comment" : "Ampak samo, če imaš dovolj zlata, saj boš drugače izgubil točke pri zdravju.",
+
+"_commentdefaulttags" : "DEFAULT TAGS",
+ "morning" : "jutro",
+ "afternoon" : "popoldne",
+ "evening" : "večer",
+
+"_commenthead": "HEADER",
+ "health": "Zdravje",
+ "experience": "Izkušnje",
+ "history": "Zgodovina",
+ "anonymous": "Neimenovan",
+ "level": "Level",
+ "tasks": "Naloge",
+ "loginAndReg" : "Prijava / Registracija",
+ "loginFacebookAlt" : "Prijava / Registracija preko Facebooka",
+ "login" : "Prijava",
+ "register" : "Registracija",
+ "options": "Možnosti",
+ "logout": "Odjava",
+
+"_commentnotifcations" : "NOTIFICATIONS",
+ "partyNotification" : "Novo sporočilo skupine",
+
+
+
+"_commenttaskview": "TASK VIEW",
+ "habits": "Navade",
+ "Habits": "Navade",
+ "newHabit": "Nova navada",
+ "edit": "Uredi",
+ "text": "Besedilo",
+ "extraNotes": "Opomba",
+ "directions/Actions": "Navodilo/Dejanje",
+ "advancedOptions": "Dodatne možnosti",
+ "difficulty": "Težavnost",
+ "difficultyHelpTitle": "Kako težavna je naloga?",
+ "difficultyHelpContent": "Težavnost pomnoži osnovno vrednost. Priporočamo, da večinoma uporabljaš vgrajeni algoritem, ki prilagodi vrednost. A nekatere naloge so veliko pomembnejše od drugih (pisanje diplome proti nitkanju zob). Klikni za več informacij.",
+ "easy": "Enostavno",
+ "medium": "Srednje",
+ "hard": "Težko",
+ "delete": "Zbriši",
+ "progress": "Napredek",
+ "score": "Točke",
+ "dailies": "Dnevne naloge",
+ "Dailies": "Dnevne naloge",
+ "newDaily": "Nova dnevna naloga",
+ "repeat": "Ponovi",
+ "Su": "Ne",
+ "M": "Po",
+ "T": "To",
+ "We": "Sr",
+ "Th": "Če",
+ "F": "Pe",
+ "S": "So",
+ "todos": "Opravki",
+ "Todos": "Opravki",
+ "newTodo": "Nov opravek",
+ "dueDate": "Opraviti do",
+ "remaining": "Preostalo",
+ "complete": "Opravljeno",
+ "rewards": "Nagrade",
+ "Rewards": "Nagrade",
+ "gold": "Zlato",
+ "silver": "Srebro",
+ "newReward": "Nova nagrada",
+ "price": "Cena",
+ "tags" : "Oznake",
+ "editTags" : "Uredi oznake",
+ "newTag" : "Nova oznaka",
+ "clearFilters" : "Počisti filtre",
+
+
+"_commentdrops" : "DROP SYSTEM",
+ "dropsEnabled" : "Najdbe vključene!",
+ "dropsEnabledText1" : "Odklenil si sistem najdb! Ko zdaj opraviš nalogo, imaš majhno možnost, da naletiš na najdbo. Ne boš verjel, ravnokar si našel",
+ "dropsEnabledText2" : "jajce",
+ "itemDropped" : "Nova najdba",
+
+
+
+"_commentoptionsview": "OPTIONS VIEW",
+ "profile": "Profil",
+ "avatar": "Avatar",
+
+ "head": "Glava",
+ "showHelm": "Pokaži čelado",
+ "hair": "Lasje",
+ "skin": "Polt",
+ "clothing" : "OblaËila",
+ "showArmor": "Show Armor",
+ "other": "Other",
+ "showWeapon": "Show Weapon",
+ "showShield": "Show Shield",
+ "photoUrl": "Spletni naslov slike",
+ "fullName": "Polno ime",
+ "blurb": "O tebi",
+ "items" : "Oprema",
+ "weapon" : "Orožje",
+ "armor" : "Oklep",
+ "helm" : "Čelada",
+ "shield" : "Ščit",
+
+ "stats" : "Podatki",
+ "strength" : "Moč",
+ "defense" : "Obramba",
+ "totalStrength" : "Skupna moč",
+ "totalDefense" : "Skupna obramba",
+
+
+ "party": "Skupina",
+ "createAParty":"Ustvari skupino",
+ "noPartyText": "Nisi del skupine. Lahko ustvariš svojo in povabiš prijatelje ali pa se pridružiš že obstoječi skupini. Naj uporabijo to številko:",
+ "partyName": "Ime skupine",
+ "create":"Ustvari",
+ "userId":"Številka uporabnika",
+ "invite":"Povabi",
+ "leave": "Zapusti",
+ "invitedTo" : "Povabljen si k skupini",
+ "chat": "Klepet",
+
+ "inventory": "Inventar",
+ "eggs": "Jajca",
+ "noEggs": "Našel nisi še nobenega jajca.",
+ "hatchingPotions": "Valilni napoji",
+ "noHatchingPotions": "Našel nisi še nobenega valilnega napoja.",
+ "hatchYourEgg" : "Naj se zverinica izvali",
+ "whichHatchingPotion1" : "Kateri valilni napoj želiš politi po",
+ "whichHatchingPotion2" : "jajcu?",
+ "pour" : "polij",
+ "rarePets" : "Redke zverinice",
+ "market": "Trgovina",
+
+ "stable": "Hlev",
+ "petsFound":"najdenih zverinic",
+ "rarePets": "Redke zverinice",
+
+ "tavern": "Gostilna",
+ "restButton":"Počivaj v gostilni",
+ "checkoutButton": "Odjavi se iz gostilne",
+ "tavernTalkTitle":"Gostilniški klepet in iskanje skupin",
+ "tavernRestingInfo" : "Medtem ko počivaš, se dnevne naloge shranijo in ne škodujejo zdravju lika. Lahko se odjaviš jutri ali čez en teden in lik bo v istem stanju kot na začetku počitka.",
+ "resources" : "Viri",
+ "LFGPosts" : "Objave glede iskanja skupin",
+ "tutorials" : "Vodiči",
+
+ "achievements":"Dosežki",
+ "achievementUnlocked" : "Nov dosežek!",
+ "npcText" : "Med največjimi podporniki pri Kickstarter projektu!",
+ "contribName" : "Sodelavec",
+ "contribText" : "Prispeval k razvoju HabitRPG-ja (programiranje, dizajn, pikslaste grafike, pravni nasveti, dokumenti itd.). Želiš to značko? Popravi kakšnega hrošča",
+ "kickstartName1" : "Podpornik pri Kickstarterju - ",
+ "kickstartName2" : "donacije",
+ "kickstartText" : "Podprl Kickstarter projekt",
+ "streakName" : " Niz(i) uspehov",
+ "streakText1" : "Dosegel ",
+ "stureakText2" : " 21-dnevnih nizov uspehov pri dnevnih nalogah",
+ "origUserName" : "Prvotni uporabnik",
+ "origUserText" : "Bil z nami od samega začetka HabitRPG-ja (kapo dol za uspešno prebijanje skozi te hroščaste čase!)",
+ "ultimGearName" : "Vrhunska oprema",
+ "ultimGearText" : "Prišel do najboljšega orožja in oklepa",
+ "ultimGearUnlocked" : "Dobil si značko 'Vrhunska oprema', saj imaš najboljšo opremo, kar jo lahko kupi zlato!",
+ "beastMastName" : "Šef zverinjaka",
+ "beastMastText" : "Našel si vseh 90 zverinic (kar je izjemno težko, vsa čast!)",
+ "beastMastUnlocked" : "Dobil si značko 'Šef zverinjaka', saj si našel vse zverinice!",
+
+ "settings":"Nastavitve",
+ "customDayStart":"Določi začetek dneva",
+ "24HrClock": "24-urni način",
+ "clockInfo":"HabitRPG preveri in ponastavi tvoje dnevne naloge vsak dan opolnoči. To uro lahko spremeniš tukaj (vpiši številko med 0 in 24).",
+ "misc":"Ostalo",
+ "hideHeader":"Skrij glavo",
+ "showHeader":"Pokaži glavo",
+ "changePass":"Sprememba gesla",
+ "oldPass":"Staro geslo",
+ "newPass":"Novo geslo",
+ "confirmPass":"Potrditev novega gesla",
+ "dangerZone": "Nevarno območje",
+ "reset":"Ponastavitev",
+ "resetAltText":"Ponastavitev tvojega računa (nevarno)",
+ "resetText1":"S tem gumbom ponastaviš celoten račun - naloge bodo izbrisane, tvoj lik pa bo moral začeti znova.",
+ "resetText2":"Tega ne priporočamo, saj boš izgubil pretekle informacije, ki ti lahko pomagajo pri spremljanju napredka. Izbris računa je uporaben predvsem za ljudi, ki želijo program najprej preizkusiti, potem pa začeti na novo.",
+ "restore":"Povrnitev",
+ "restoreAltText":"Povrne liku podatke",
+ "restoreText1":"HabitRPG je še v fazi razvoja, zato bodo nekateri uporabniki morda primorani liku povrniti podatke. Tukaj vpiši podatke in avtomatično bodo dodani tvojemu liku. Ko bo program bolj stabilen, bo ta funkcija odstranjena.",
+ "delete":"Brisanje",
+ "deleteAltText":"Brisanje računa",
+ "deleteHeader" : "Izbriši račun",
+ "deleteText1":"Počasi! Si prepričan? S tem boš za vedno izbrisal račun in ne bo se ga dalo povrniti. Če si popolnoma prepričan, vpiši",
+ "deleteText2":" IZBRIŠI ",
+ "deleteText3":"v okence",
+ "API":"API",
+ "APIText":"Kopiraj te podatke za uporabo pri aplikacijah drugih proizvajalcev.",
+ "APIToken":"Api žeton",
+
+
+
+"_commentitems": "ITEMS",
+ "_commentitemsweps": "WEAPONS",
+ "sword0name" : "Vadbeni meč",
+ "sword1Name" : "Meč",
+ "sword1Text" : "Poveča pridobivanje izkušenj za 3%.",
+ "sword2Name" : "Sekira",
+ "sword2Text" : "Poveča pridobivanje izkušenj za 6%.",
+ "sword3Name" : "Buzdovan",
+ "sword3Text" : "Poveča pridobivanje izkušenj za 9%.",
+ "sword4Name" : "Modri meč",
+ "sword4Text" : "Poveča pridobivanje izkušenj za 12%.",
+ "sword5Name" : "Rdeči meč",
+ "sword5Text" : "Poveča pridobivanje izkušenj za 15%.",
+ "sword6Name" : "Zlati meč",
+ "sword6Text" : "Poveča pridobivanje izkušenj za 18%.",
+
+ "_commentitemsarmor": "ARMOR",
+ "armor0Name" : "Oklep iz blaga",
+ "armor1Name" : "Usnjeni oklep" ,
+ "armor1Text": "Zmanjša izgubo zdravja za 4%",
+ "armor2Name" : "Verižna srajca",
+ "armor2Text": "Zmanjša izgubo zdravja za 6%",
+ "armor3Name" : "Ploščni oklep",
+ "armor3Text": "Zmanjša izgubo zdravja za 7%",
+ "armor4Name" : "Rdeči oklep",
+ "armor4Text": "Zmanjša izgubo zdravja za 8%",
+ "armor5Name" : "Zlati oklep",
+ "armor5Text": "manjša izgubo zdravja za 10%",
+
+ "_commentitemshead" : "HEADGEAR",
+ "head0Name" : "Brez čelade",
+ "head1Name" : "Usnjena čelada" ,
+ "head1Text": "Zmanjša izgubo zdravja za 2%",
+ "head2Name" : "Verižna kapuca",
+ "head2Text": "Zmanjša izgubo zdravja za 3%",
+ "head3Name" : "Ploščna čelada",
+ "head3Text": "Zmanjša izgubo zdravja za 4%",
+ "head4Name" : "Rdeča čelada",
+ "head4Text": "Zmanjša izgubo zdravja za 5%",
+ "head5Name" : "Zlata čelada",
+ "head5Text": "Zmanjša izgubo zdravja za 6%",
+
+ "_commentitemsshield" : "SHIELDS",
+ "sheild0Name" : "Brez ščita",
+ "sheild1Name" : "Leseni ščit",
+ "sheild1Text": "Zmanjša izgubo zdravja za 3%",
+ "sheild2Name" : "Mali ščit",
+ "sheild2Text": "Zmanjša izgubo zdravja za 4%",
+ "sheild3Name" : "Okrepljeni ščit",
+ "sheild3Text": "Zmanjša izgubo zdravja za 5%",
+ "sheild4Name" : "Rdeči ščit",
+ "sheild4Text": "Zmanjša izgubo zdravja za 7%",
+ "sheild5Name" : "Zlati ščit",
+ "sheild5Text": "Zmanjša izgubo zdravja za 8%",
+
+ "_commentitemsother" : "OTHER ITEMS",
+ "healthPotionName" : "Zdravilni napoj",
+ "healthPotionNotes" : "Takoj povrne 15 točk pri zdravju",
+ "rerollName" : "Ponastavitev nalog",
+ "rerollNotes" : "Naloge spet postanejo rumene. To je uporabno, ko so vse naloge rdeče in je težko ostati živ.",
+ "rerollModelHeader" : "Ponastavi naloge",
+ "rerollModelText1" : "To močno odsvetujemo, saj rdeče naloge spodbujajo k izboljšavanju",
+ "rerollModelText2" : "beri naprej",
+ "rerollModelText3" : "Vendar pa to postane nujno po daljšem obdobju slabih navad.",
+
+ "_commentitemspeteggs": "PET EGGS",
+ "wolfEgg": "Mladi volk",
+ "tigerEgg": "Mladi tiger",
+ "pandaEgg": "Mladi panda",
+ "lionEgg": "Mladi lev",
+ "foxEgg": "Lisjak",
+ "pigEgg": "Leteči pujs",
+ "dragonEgg": "Zmaj",
+ "cactusEgg": "Kaktus",
+ "bearEgg": "Mladi medved",
+
+ "_commentitemshatchingpotions": "HATCHING POTIONS",
+ "basePotName": "Osnovni",
+ "basePotText" : "Iz jajca se izvali osnovna zverinica.",
+ "whitePotName": "Beli",
+ "whitePotText" : "Iz jajca se izvali bela zverinica.",
+ "desertPotName": "Puščavski",
+ "desertPotText" : "Iz jajca se izvali puščavska zverinica.",
+ "redPotName": "Rdeči",
+ "redPotText" : "Iz jajca se izvali rdeča zverinica.",
+ "shadePotName": "Senčni",
+ "shadePotText" : "Iz jajca se izvali senčna zverinica.",
+ "skeletonPotName": "Skeletni",
+ "skeletonPotText" : "Iz jajca se izvali skeletna zverinica.",
+ "zombiePotName": "Zombijski",
+ "zombiePotText" : "Iz jajca se izvali zombijska zverinica.",
+ "cottonPinkPotName": "Svetlo roza",
+ "cottonPinkPotText" : "Iz jajca se izvali svetlo roza zverinica.",
+ "cottonBluePotName": "Svetlo modri",
+ "cottonBluePotText" : "Iz jajca se izvali svetlo modra zverinica.",
+ "goldenPotName": "Zlati",
+ "goldenPotText" : "Iz jajca se izvali zlata zverinica.",
+
+
+
+"_commentnpcsandchars": "NPCS & CHARACTERS",
+ "_commentNPCS" : "NPCS",
+ "NPCBaileyText1" : "mestna klicarka tukaj! Oznanjam nekaj novosti!",
+ "NPCAugustinText1" : "Dobrodošel v trgovini! Jaz sem trgovec;",
+ "NPCAugustinText2" : "Če si neznansko želiš neke zverinice, a nočeš čakati, da jo najdeš, jo lahko kupiš tukaj.",
+ "NPCJohanssonText1" : "Dobrodošel v gostilni! Jaz sem",
+ "NPCJohanssonText2": "točaj. Če hočeš malo počiti (Greš na počitnice? Si zbolel?), ti bom pripravil posteljo - v tem času ti neopravljene dnevne naloge ne bodo škodovale. Usedi se in spoznaj domačine.",
+ "NPCMelchiorText1" : "",
+ "NPCBowenText1" : "",
+ "NPCBochText1" : "",
+
+"_commentdeathstuff" : "DEATH",
+ "deathTitle" : "Umrl si!",
+ "deathText" : "Izgubil si vso zlato, en level in en kos opreme. Pridno opravljaj dnevne naloge, da se to ne bo ponovilo!",
+
+"_commentgems" : "GEMS",
+ "gems" : "Dragulji",
+ "outOfGems" : "Zmanjkalo dragljev",
+ "buyMoreGems" : "Kupi več draguljev",
+ "notEnoughGems" : "Nimaš dovolj draguljev",
+ "petsOutOfGems" : "Zmanjkalo ti je draguljev, s katerimi lahko kupiš posebne predmete! HabitRPG je odprtokodni projekt in tvoja pomoč je zelo dobrodošla - kupi več draguljev, da lahko dobiš to zverinico, s tem pa tudi pomagaš ustvarjalcem",
+ "gemsWhatFor" : "Z njimi lahko kupiš posebne predmete (ponastavitev nalog, jajca, valilni napoji itd.). Vendar pa moraš te funkcije najprej odkleniti.",
+
+"_commentfooter": "FOOTER",
+ "footerCompany" : "Podjetje",
+ "companyAbout" : "O nas",
+ "companyBlog" : "Blog",
+ "companyTeam" : "Ekipa",
+ "companyExtensions" : "Podaljški",
+ "companyFAQ" : "Pogosta vprašanja",
+ "footerLegal" : "Pravno obvestilo",
+ "legalPrivacy" : "Varovanje podatkov",
+ "legalTerms" : "Pravni pogoji",
+ "footerCommunity" : "Skupnost",
+ "communityBugs" : "Oddaj poročilo o hrošču",
+ "communityFeatures" : "Zahtevaj novo funkcijo",
+ "communityExtensions" : "Dodatki / Podaljški",
+ "communityForum" : "Forum",
+ "footerSocial" : "Družbena omrežja",
+
+
+
+"_commentmisc": "MISC & GLOBAL",
+ "removeAds": "Odstrani reklame",
+ "whyAds": "Zakaj reklame?",
+ "whyAdsContent1": "HabitRPG je odprtokodni projekt in tvoja pomoč je zelo dobrodošla - z donacijo pomagaš ustvarjalcem, prejmeš pa tudi 20 draguljev, s katerimi lahko kupiš posebne predmete.",
+
+ "whyAdsContent2": "'Podprl sem vas pri Kickstarterju!' - sledi",
+ "whyAdsContent3": "tem navodilom",
+ "_commentbuttons": "BUTTONS",
+ "submit":"Pošlji",
+ "close":"Zapri",
+ "saveAndClose": "Shrani in zapri",
+ "cancel":"Prekliči",
+ "ok" : "V redu",
+ "add" : "Dodaj",
+ "undo" : "Razveljavi",
+ "continue" : "Nadaljuj",
+ "accept" : "Sprejmi",
+ "reject" : "Prekliči",
+ "or" : "Ali",
+ "_commenttimestamps":"TIME STAMPS",
+ "justNow":"Pravkar",
+ "aMinuteAgo":"Pred eno minuto",
+ "minutesAgo":"minut nazaj",
+ "anHourAgo": "Pred eno uro",
+ "hoursAgo": "ur nazaj",
+ "yesterday":"Včeraj",
+ "daysAgo":"dni nazaj"
+
+}
diff --git a/locales/uk/app.json b/locales/uk/app.json
index ac63261901..2dbe2ecedc 100644
--- a/locales/uk/app.json
+++ b/locales/uk/app.json
@@ -132,6 +132,10 @@
"hair": "Волосся",
"skin": "Кожа",
"clothing" : "Одяг",
+ "showArmor": "Show Armor",
+ "other": "Other",
+ "showWeapon": "Show Weapon",
+ "showShield": "Show Shield",
"photoUrl": "Посилання на фото",
"fullName": "Повне ім'я",
"blurb": "Про себе",
diff --git a/locales/ur/app.json b/locales/ur/app.json
index d108b425bc..25129f1f72 100644
--- a/locales/ur/app.json
+++ b/locales/ur/app.json
@@ -131,6 +131,10 @@
"hair": "بال",
"skin": "Skin",
"clothing" : "Clothing",
+ "showArmor": "Show Armor",
+ "other": "Other",
+ "showWeapon": "Show Weapon",
+ "showShield": "Show Shield",
"photoUrl": "Photo Url",
"fullName": "Full Name",
"blurb": "Blurb",
diff --git a/migrations/20131109_refactor_pets.js b/migrations/20131109_refactor_pets.js
index 1e85ff8fb2..f5d9f7d567 100644
--- a/migrations/20131109_refactor_pets.js
+++ b/migrations/20131109_refactor_pets.js
@@ -1,31 +1,36 @@
-db.users.find({},{backer: 1, items:1}).forEach(function(user){
- user.items = {
- armor: +user.items.armor || 0,
- weapon: +user.items.weapon || 0,
- head: +user.items.head || 0,
- shield: +user.items.shield || 0,
+db.users.find(
+ {$where: "Array.isArray(this.items.pets) || Array.isArray(this.items.eggs) || Array.isArray(this.items.hatchingPotions)"},
+ {backer: 1, items:1}
+).forEach(function(user){
- pets: _.reduce(user.items.pets, function(m,v){ m[v] = 5; return m;}, {}),
- currentPet: user.items.currentPet ? user.items.currentPet.str : '',
- eggs: _.reduce(user.items.eggs, function(m,v){
+ if (_.isArray(user.items.pets)) {
+ user.items.pets = _.reduce(user.items.pets, function(m,v){ m[v] = 5; return m;}, {});
+ }
+
+ if (!_.isString(user.items.currentPet)) {
+ user.items.currentPet = user.items.currentPet ? user.items.currentPet.str : '';
+ }
+
+ if (_.isArray(user.items.eggs)) {
+ user.items.eggs = _.reduce(user.items.eggs, function(m,v){
if (!m[v.name]) m[v.name] = 0;
m[v.name]++;
return m;
- }, {}),
+ }, {});
+ }
- hatchingPotions: _.reduce(user.items.hatchingPotions, function(m,v){
+ if (_.isArray(user.items.hatchingPotions)) {
+ user.items.hatchingPotions = _.reduce(user.items.hatchingPotions, function(m,v){
if (!m[v]) m[v] = 0;
m[v]++;
return m;
- }, {}),
+ }, {});
+ }
- food: {},
+ user.items.food = {};
+ user.items.mounts = {};
+ user.items.currentMount = '';
- mounts: {},
- currentMount: '',
-
- lastDrop: user.items.lastDrop || {date: new Date(), count: 0}
- };
if (user.backer && user.backer.tier && user.backer.tier >= 90) {
user.items.mounts['LionCub-Ethereal'] = true;
}
diff --git a/migrations/20131115_update_gear_preferences.js b/migrations/20131115_update_gear_preferences.js
new file mode 100644
index 0000000000..9ec1264b2f
--- /dev/null
+++ b/migrations/20131115_update_gear_preferences.js
@@ -0,0 +1,10 @@
+//Add defaults to show gears in all users
+db.users.update(
+ {},
+ {$set:{
+ 'preferences.showWeapon': true,
+ 'preferences.showShield': true,
+ 'preferences.showArmor': true,
+ }},
+ {multi:true}
+)
diff --git a/migrations/20131117_fix_task_types.js b/migrations/20131117_fix_task_types.js
new file mode 100644
index 0000000000..14d86cb55f
--- /dev/null
+++ b/migrations/20131117_fix_task_types.js
@@ -0,0 +1,18 @@
+// TODO figure out why this is happening in the first place
+
+db.users.find({},{habits:1, dailys:1, todos:1, rewards:1}).forEach(function(user){
+ _.each(user.habits, function(task){
+ task.type = 'habit';
+ })
+ _.each(user.dailys, function(task){
+ task.type = 'daily';
+ })
+ _.each(user.todos, function(task){
+ task.type = 'todo';
+ })
+ _.each(user.rewards, function(task){
+ task.type = 'reward';
+ })
+
+ db.users.update({_id:user._id}, {$set:{habits: user.habits, dailys: user.dailys, todos: user.todos, rewards: user.rewards}});
+});
diff --git a/migrations/20131117_remove_undefined_pets.js b/migrations/20131117_remove_undefined_pets.js
new file mode 100644
index 0000000000..f908621a75
--- /dev/null
+++ b/migrations/20131117_remove_undefined_pets.js
@@ -0,0 +1,12 @@
+// once and for all!
+
+db.users.find({'items.pets':{$exists:1}},{'items.pets':1}).forEach(function(user){
+ _.reduce(user.items.pets, function(m,v,k){
+ if (!k.indexOf('undefined')) m.push(k);
+ return m;
+ }, []).forEach(function(key){
+ delete user.items.pets[key];
+ })
+
+ db.users.update({_id:user._id}, { $set:{'items.pets':user.items.pets} });
+});
diff --git a/migrations/20131122_deleted_tags.js b/migrations/20131122_deleted_tags.js
new file mode 100644
index 0000000000..e915390041
--- /dev/null
+++ b/migrations/20131122_deleted_tags.js
@@ -0,0 +1,13 @@
+// Cleanup broken tags
+// -------------------------
+db.users.find().forEach(function(user){
+ var tasks = user.habits.concat(user.dailys).concat(user.todos).concat(user.rewards);
+
+ _.each(tasks, function(task){
+ _.each(task.tags, function(value, key){ //value is true, key is tag.id
+ if (!_.find(user.tags,{id:key})) delete task.tags[key];
+ });
+ });
+
+ db.users.update({_id:user._id}, user);
+});
\ No newline at end of file
diff --git a/migrations/20131123_set_default_party_order.js b/migrations/20131123_set_default_party_order.js
new file mode 100644
index 0000000000..970e37e05b
--- /dev/null
+++ b/migrations/20131123_set_default_party_order.js
@@ -0,0 +1,8 @@
+//Add default to randomize party members list
+db.users.update(
+ {},
+ {$set:{
+ 'party.order': 'random',
+ }},
+ {multi:true}
+)
diff --git a/migrations/20131126_clean_dayStart.js b/migrations/20131126_clean_dayStart.js
new file mode 100644
index 0000000000..b2001ec7c2
--- /dev/null
+++ b/migrations/20131126_clean_dayStart.js
@@ -0,0 +1,5 @@
+db.users.find({'preferences.dayStart':{$exists:1}},{'preferences.dayStart':1}).forEach(function(user){
+ var dayStart = +user.preferences.dayStart;
+ dayStart = (_.isNaN(dayStart) || dayStart < 0 || dayStart > 24) ? 0 : dayStart;
+ db.users.update({_id:user._id}, {$set:{'preferences.dayStart':dayStart}});
+});
diff --git a/migrations/20131126_turkey_pet.js b/migrations/20131126_turkey_pet.js
new file mode 100644
index 0000000000..568e38b237
--- /dev/null
+++ b/migrations/20131126_turkey_pet.js
@@ -0,0 +1 @@
+db.users.update({},{$set:{'items.pets.Turkey-Base':5, 'flags.newStuff':true}}, {multi:true});
\ No newline at end of file
diff --git a/migrations/20131127_restore_dayStart.js b/migrations/20131127_restore_dayStart.js
new file mode 100644
index 0000000000..41b3774eed
--- /dev/null
+++ b/migrations/20131127_restore_dayStart.js
@@ -0,0 +1,32 @@
+// node .migrations/20131127_restore_dayStart.js
+
+var mongo = require('mongoskin');
+var _ = require('lodash');
+
+var backupUsers = mongo.db('localhost:27017/habitrpg_old?auto_reconnect').collection('users');
+var liveUsers = mongo.db('localhost:27017/habitrpg_new?auto_reconnect').collection('users');
+
+var query = {'preferences.dayStart':{$exists:1,$ne:0}};
+var select = {'preferences.dayStart': 1};
+
+backupUsers.count(query, function(err, count){
+ if (err) return console.error(err);
+ backupUsers.findEach(query, select, {batchSize:20}, function(err, before){
+ if (err) return console.error(err);
+ if (!before) { count--; return console.log('!before'); }
+ liveUsers.findById(before._id, function(err, after){
+ if (err) return console.error(err);
+ if (!after) { count--; return console.log(before._id + ' deleted?'); }
+
+ var dayStart = +before.preferences.dayStart;
+ if (after.preferences.dayStart == 0 && dayStart != 0){
+ dayStart = (_.isNaN(dayStart) || dayStart < 0 || dayStart > 24) ? 0 : dayStart;
+ } else {
+ dayStart = after.preferences.dayStart;
+ }
+
+ liveUsers.update({_id:after._id}, {$inc:{_v:1}, $set:{'preferences.dayStart':dayStart}});
+ if (--count <= 0) console.log("DONE!");
+ })
+ });
+});
\ No newline at end of file
diff --git a/package.json b/package.json
index f1f5636c67..7350c05643 100644
--- a/package.json
+++ b/package.json
@@ -11,7 +11,7 @@
"express": "*",
"gzippo": "*",
"guid": "*",
- "moment": "*",
+ "moment": "~2.4.0",
"stripe": "*",
"coffee-script": "*",
"nconf": "*",
@@ -19,7 +19,6 @@
"superagent": "~0.12.4",
"resolve": "~0.2.3",
"expect.js": "~0.2.0",
- "relative-date": "~1.1.1",
"lodash": "~2.2.1",
"async": "~0.2.9",
"optimist": "~0.5.2",
@@ -43,7 +42,9 @@
"nodemailer": "~0.5.2",
"grunt-cli": "~0.1.9",
"paypal-ipn": "~1.0.1",
- "express-csv": "~0.6.0"
+ "express-csv": "~0.6.0",
+ "pretty-data": "git://github.com/vkiryukhin/pretty-data#master",
+ "js2xmlparser": "~0.1.2"
},
"private": true,
"subdomain": "habitrpg",
@@ -76,6 +77,7 @@
"karma-chai-plugins": "~0.1.0",
"mocha": "~1.12.1",
"karma-mocha": "~0.1.0",
- "csv": "~0.3.6"
+ "csv": "~0.3.6",
+ "mongoskin": "~0.6.1"
}
}
diff --git a/public/css/avatar.styl b/public/css/avatar.styl
index 9a346da167..bb81bb6327 100644
--- a/public/css/avatar.styl
+++ b/public/css/avatar.styl
@@ -90,4 +90,7 @@ future re: pets and whatnot, this is just temporary.
margin: 0 auto
.character-sprites span, .pet
- position: absolute
\ No newline at end of file
+ position: absolute
+
+.herobox.isLeader
+ background: $better
diff --git a/public/css/customizer.styl b/public/css/customizer.styl
index fd9391fa9d..021048869c 100644
--- a/public/css/customizer.styl
+++ b/public/css/customizer.styl
@@ -22,7 +22,7 @@ menu
line-height: 2
.customize-option
- border: 1px solid grey;
+ border: 0px solid grey;
background-color: hsl(0, 0%, 93%);
margin-bottom: 10px
diff --git a/public/css/filters.styl b/public/css/filters.styl
index 2af0e4a623..1c68eb6470 100644
--- a/public/css/filters.styl
+++ b/public/css/filters.styl
@@ -22,4 +22,15 @@
padding 2px 0 0 2px
.tag-editing .tag-editing-pill
- height:auto
\ No newline at end of file
+ height:auto
+
+.tag-list
+ overflow-y: auto
+ white-space: nowrap
+
+ .nav-pills
+ height: 43px
+
+ li
+ display: inline-block
+ float: none
\ No newline at end of file
diff --git a/public/css/game-pane.styl b/public/css/game-pane.styl
index 34ad09f5f9..124cc33030 100644
--- a/public/css/game-pane.styl
+++ b/public/css/game-pane.styl
@@ -11,6 +11,10 @@
.tavern-pane
position relative
height 250px
+
+.chat-form
+ position: relative
+ z-index: 10
.tavern-chat, .party-chat
@@ -19,16 +23,50 @@
padding-bottom:15px
border-bottom 1px solid #ddd
word-wrap:break-word
+ position:relative
&.highlight
background #EEE
label
margin-right:5px
+
+ .float-label
+ float:left
+ position:absolute
+ top:17px;
+
+ .hidden-label
+ visibility:hidden
+
+ .scrollable-message
+ max-height:80px
+ overflow-y:auto
+
+ .expander
+ float: right
+ position: absolute
+ bottom: 18px
+ right: 20px
+ background: white
+ max-width: 20px
+ max-height: 20px
+ width: 100%
+ height: 100%
+ text-align: center
.own-message
border-left: 4px solid #333
padding-left: 2px
+
+ markdown
+
+ p:first-child
+ display:inline
+
+ img
+ max-height:50px
+ vertical-align:top
// Name tags
.label-contributor-1, .label-contributor-2
diff --git a/public/css/index.styl b/public/css/index.styl
index c8af436a16..3d30dfca9a 100644
--- a/public/css/index.styl
+++ b/public/css/index.styl
@@ -7,6 +7,7 @@
@import "../bower_components/bootstrap/docs/assets/css/bootstrap-responsive.css"
@import "../bower_components/bootstrap-tour/build/css/bootstrap-tour.min.css"
@import "../bower_components/angular-loading-bar/build/loading-bar.css"
+@import "../bower_components/js-emoji/emoji.css"
// Custom includes
@import "./tasks.styl"
@@ -66,6 +67,11 @@ hr
margin-right: 10px;
}
+/* Bootstrap overrides */
+div.tooltip-inner {
+ max-width: 300px;
+}
+
/* Customizations to make footer sticky */
/*html, body {height: 100%;}*/
#wrap
@@ -159,7 +165,6 @@ hr
position absolute
bottom 0px
right 0px
- background-color #dfe9ea
padding 1px 3px 1px 3px
a
diff --git a/public/css/inventory.styl b/public/css/inventory.styl
index f9ed52f076..6f1cfc98e3 100644
--- a/public/css/inventory.styl
+++ b/public/css/inventory.styl
@@ -109,6 +109,8 @@ menu button[class*="Pet_Food_"]
// This adds feeding progress bars to pets. If we have any issues with `menu.pets > button`, revisit
menu.pets .customize-menu
+ width: 100%
+
button
position: relative
.progress
diff --git a/public/css/npcs.styl b/public/css/npcs.styl
index 084a5c19d4..2c2370808c 100644
--- a/public/css/npcs.styl
+++ b/public/css/npcs.styl
@@ -14,8 +14,8 @@
height: 72px
float:left
.NPC-Bailey-Head
- background-position: -168px -42px
- width: 54px
+ background-position: -162px -42px
+ width: 60px
height: 30px
position: absolute
top: 117px // 147 (header-height) - 30 (bailey height)
diff --git a/public/js/app.js b/public/js/app.js
index 1b4d1d5d18..ded963b44e 100644
--- a/public/js/app.js
+++ b/public/js/app.js
@@ -2,6 +2,15 @@
window.env = window.env || {}; //FIX tests
+if(window.env.language && window.env.language.momentLang && window.env.language.momentLangCode){
+ var head = document.getElementsByTagName('head')[0];
+ var script = document.createElement('script');
+ script.type = 'text/javascript';
+ script.text = window.env.language.momentLang;
+ head.appendChild(script);
+ moment.lang(window.env.language.momentLangCode);
+}
+
window.env.t = function(string){
return (window.env.translations[string] || window.env.translations.stringNotFound);
}
@@ -9,7 +18,7 @@ window.env.t = function(string){
window.habitrpg = angular.module('habitrpg',
['ngResource', 'ngSanitize', 'userServices', 'groupServices', 'memberServices', 'challengeServices',
'sharedServices', 'authServices', 'notificationServices', 'guideServices',
- 'ui.bootstrap', 'ui.keypress', 'ui.router', 'chieffancypants.loadingBar', 'At'])
+ 'ui.bootstrap', 'ui.keypress', 'ui.router', 'chieffancypants.loadingBar', 'At', 'pasvaz.bindonce'])
// @see https://github.com/angular-ui/ui-router/issues/110 and https://github.com/HabitRPG/habitrpg/issues/1705
// temporary hack until they have a better solution
diff --git a/public/js/controllers/groupsCtrl.js b/public/js/controllers/groupsCtrl.js
index ab7c90e1c0..09133c3738 100644
--- a/public/js/controllers/groupsCtrl.js
+++ b/public/js/controllers/groupsCtrl.js
@@ -65,6 +65,8 @@ habitrpg.controller("GroupsCtrl", ['$scope', '$rootScope', 'Groups', '$http', 'A
}
// We watch Members.selectedMember because it's asynchronously set, so would be a hassle to handle updates here
$scope.$watch( function() { return Members.selectedMember; }, function (member) {
+ if(member)
+ member.petCount = window.habitrpgShared.helpers.countPets(null, member.items.pets);
$scope.profile = member;
});
}
@@ -128,6 +130,24 @@ habitrpg.controller("GroupsCtrl", ['$scope', '$rootScope', 'Groups', '$http', 'A
.controller('ChatCtrl', ['$scope', 'Groups', 'User', function($scope, Groups, User){
$scope.message = {content:''};
$scope._sending = false;
+
+ $scope.isUserMentioned = function(user, message) {
+ if(message.hasOwnProperty("highlight"))
+ return message.highlight;
+ message.highlight = false;
+ var messagetext = message.text.toLowerCase();
+ var username = user.profile.name;
+ var mentioned = messagetext.indexOf(username.toLowerCase());
+ var pattern = username+"([^\w]|$){1}";
+ if(mentioned > -1) {
+ var preceedingchar = messagetext.substring(mentioned-1,mentioned);
+ if(mentioned == 0 || preceedingchar.trim() == '' || preceedingchar == '@'){
+ var regex = new RegExp(pattern,'i');
+ message.highlight = regex.test(messagetext);
+ }
+ }
+ return message.highlight;
+ }
$scope.postChat = function(group, message){
if (_.isEmpty(message) || $scope._sending) return;
@@ -162,6 +182,14 @@ habitrpg.controller("GroupsCtrl", ['$scope', '$rootScope', 'Groups', '$http', 'A
group.$get();
}
+ // List of Ordering options for the party members list
+ $scope.partyOrderChoices = {
+ 'level': 'Sort by Level',
+ 'random': 'Sort randomly',
+ 'pets': 'Sort by number of pets',
+ 'party_date_joined': 'Sort by Party date joined',
+ };
+
}])
.controller("GuildsCtrl", ['$scope', 'Groups', 'User', '$rootScope', '$state', '$location',
@@ -172,8 +200,10 @@ habitrpg.controller("GroupsCtrl", ['$scope', '$rootScope', 'Groups', '$http', 'A
}
$scope.type = 'guild';
$scope.text = 'Guild';
- $scope.newGroup = new Groups.Group({type:'guild', privacy:'private', leader: User.user._id, members: [User.user._id]});
-
+ var newGroup = function(){
+ return new Groups.Group({type:'guild', privacy:'private', leader: User.user._id, members: [User.user._id]});
+ }
+ $scope.newGroup = newGroup()
$scope.create = function(group){
if (User.user.balance < 1) return $rootScope.modals.buyGems = true;
@@ -183,6 +213,7 @@ habitrpg.controller("GroupsCtrl", ['$scope', '$rootScope', 'Groups', '$http', 'A
$scope.groups.guilds.push(saved);
if(saved.privacy === 'public') $scope.groups.public.push(saved);
$state.go('options.social.guilds.detail', {gid: saved._id});
+ $scope.newGroup = newGroup();
});
}
}
diff --git a/public/js/controllers/headerCtrl.js b/public/js/controllers/headerCtrl.js
index 65da48b89e..369f0bfc85 100644
--- a/public/js/controllers/headerCtrl.js
+++ b/public/js/controllers/headerCtrl.js
@@ -2,10 +2,31 @@
habitrpg.controller("HeaderCtrl", ['$scope', 'Groups', 'User',
function($scope, Groups, User) {
+
+
$scope.party = Groups.party(function(){
- $scope.partyMinusSelf = _.filter($scope.party.members, function(member){
- return member._id !== User.user._id;
- });
+ $scope.partyMinusSelf = _.sortBy(
+ _.filter($scope.party.members, function(member){
+ return member._id !== User.user._id;
+ }),
+ function (member) {
+ switch(User.user.party.order)
+ {
+ case 'level':
+ return member.stats.lvl;
+ break;
+ case 'random':
+ return Math.random();
+ break;
+ case 'pets':
+ return member.items.pets.length;
+ break;
+ default:
+ // party date joined
+ return true;
+ }
+ }
+ ).reverse()
});
}
]);
diff --git a/public/js/controllers/inventoryCtrl.js b/public/js/controllers/inventoryCtrl.js
index 2d60a5d9dd..28deb61463 100644
--- a/public/js/controllers/inventoryCtrl.js
+++ b/public/js/controllers/inventoryCtrl.js
@@ -7,13 +7,11 @@ habitrpg.controller("InventoryCtrl", ['$rootScope', '$scope', 'User', 'API_URL',
$scope.selectedEgg = null; // {index: 1, name: "Tiger", value: 5}
$scope.selectedPotion = null; // {index: 5, name: "Red", value: 3}
- $scope.petCount = _.size(User.user.items.pets);
$scope.totalPets = _.size($scope.Items.eggs) * _.size($scope.Items.hatchingPotions);
// count egg, food, hatchingPotion stack totals
var countStacks = function(items) { return _.reduce(items,function(m,v){return m+v;},0);}
- $scope.$watch('user.items.pets', function(pets){ $scope.petCount = $rootScope.countExists(pets); }, true);
$scope.$watch('user.items.mounts', function(mounts){ $scope.mountCount = $rootScope.countExists(mounts); }, true);
$scope.$watch('user.items.eggs', function(eggs){ $scope.eggCount = countStacks(eggs); }, true);
$scope.$watch('user.items.hatchingPotions', function(pots){ $scope.potCount = countStacks(pots); }, true);
diff --git a/public/js/controllers/notificationCtrl.js b/public/js/controllers/notificationCtrl.js
index 4eb64caa9b..759fd267b5 100644
--- a/public/js/controllers/notificationCtrl.js
+++ b/public/js/controllers/notificationCtrl.js
@@ -29,7 +29,13 @@ habitrpg.controller('NotificationCtrl',
});
$rootScope.$watch('user._tmp.drop', function(after, before){
+ // won't work when getting the same item twice?
if (after == before || !after) return;
+ var type = after.type === 'HatchingPotion' ? 'hatchingPotions' : (after.type.toLowerCase() + 's')
+ if(!User.user.items[type][after.name]){
+ User.user.items[type][after.name] = 0;
+ }
+ User.user.items[type][after.name]++;
$rootScope.modals.drop = true;
});
@@ -44,10 +50,11 @@ habitrpg.controller('NotificationCtrl',
});
$rootScope.$watch('user.items.pets', function(after, before){
- if(_.size(after) === _.size(before) || _.size(after) < 90) return;
+ if(_.size(after) === _.size(before) ||
+ window.habitrpgShared.helpers.countPets(null, after) < 90) return;
User.user.achievements.beastMaster = true;
$rootScope.modals.achievements.beastMaster = true;
- })
+ }, true);
/*_.each(['weapon', 'head', 'chest', 'shield'], function(watched){
$rootScope.$watch('user.items.' + watched, function(before, after){
diff --git a/public/js/controllers/rootCtrl.js b/public/js/controllers/rootCtrl.js
index bbf43d1a84..fdbacd9ceb 100644
--- a/public/js/controllers/rootCtrl.js
+++ b/public/js/controllers/rootCtrl.js
@@ -21,9 +21,25 @@ habitrpg.controller("RootCtrl", ['$scope', '$rootScope', '$location', 'User', '$
return haystack && ~haystack.indexOf(needle);
}
+ // styling helpers
+ $scope.userLevelStyle = function(user,style){
+ style = style || '';
+ if(user && user.backer && user.backer.npc)
+ style += ' label-npc';
+ if(user && user.contributor && user.contributor.level)
+ style += ' label-contributor-'+user.contributor.level;
+ return style;
+ }
+
// count pets, mounts collected totals, etc
$rootScope.countExists = function(items) {return _.reduce(items,function(m,v){return m+(v?1:0)},0)}
+ $rootScope.petCount = window.habitrpgShared.helpers.countPets(null, User.user.items.pets);
+
+ $rootScope.$watch('user.items.pets', function(pets){
+ $rootScope.petCount = window.habitrpgShared.helpers.countPets($rootScope.countExists(pets), User.user.items.pets);
+ }, true);
+
$scope.safeApply = function(fn) {
var phase = this.$root.$$phase;
if(phase == '$apply' || phase == '$digest') {
diff --git a/public/js/controllers/settingsCtrl.js b/public/js/controllers/settingsCtrl.js
index 2d4574d493..6d10e0d758 100644
--- a/public/js/controllers/settingsCtrl.js
+++ b/public/js/controllers/settingsCtrl.js
@@ -27,10 +27,11 @@ habitrpg.controller('SettingsCtrl',
$scope.saveDayStart = function(){
var dayStart = +User.user.preferences.dayStart;
- if (dayStart < 0 || dayStart > 24) {
+ if (_.isNaN(dayStart) || dayStart < 0 || dayStart > 24) {
dayStart = 0;
+ return alert('Please enter a number between 0 and 24');
}
- User.log({'op':'set', data:{'preferences.dayStart': dayStart}});
+ User.set('preferences.dayStart', dayStart);
}
$scope.language = window.env.language;
@@ -40,7 +41,7 @@ habitrpg.controller('SettingsCtrl',
$rootScope.$on('userSynced', function(){
location.reload();
});
- User.set('preferences.language', $scope.language);
+ User.set('preferences.language', $scope.language.code);
}
$scope.reroll = function(){
diff --git a/public/js/controllers/tasksCtrl.js b/public/js/controllers/tasksCtrl.js
index fb6c35b89c..399899d911 100644
--- a/public/js/controllers/tasksCtrl.js
+++ b/public/js/controllers/tasksCtrl.js
@@ -6,7 +6,7 @@ habitrpg.controller("TasksCtrl", ['$scope', '$rootScope', '$location', 'User', '
$scope.score = function(task, direction) {
if (task.type === "reward" && User.user.stats.gp < task.value){
- return Notification.text('Not enough GP.');
+ return Notification.text('Not enough Gold!');
}
Algos.score(User.user, task, direction);
User.log({op: "score",data: task, dir: direction});
@@ -120,7 +120,7 @@ habitrpg.controller("TasksCtrl", ['$scope', '$rootScope', '$location', 'User', '
Notification.text("Item purchased.");
updateStore();
} else {
- Notification.text("Not enough GP.");
+ Notification.text("Not enough Gold!");
}
};
diff --git a/public/js/controllers/userCtrl.js b/public/js/controllers/userCtrl.js
index ab5f3bea1c..c9336e8525 100644
--- a/public/js/controllers/userCtrl.js
+++ b/public/js/controllers/userCtrl.js
@@ -6,9 +6,6 @@ habitrpg.controller("UserCtrl", ['$rootScope', '$scope', '$location', 'User', '$
$scope.hideUserAvatar = function() {
$(".userAvatar").hide();
};
- $scope.toggleHelm = function(val){
- User.log({op:'set', data:{'preferences.showHelm':val}});
- }
$scope.$watch('_editing.profile', function(value){
if(value === true) $scope.editingProfile = angular.copy(User.user.profile);
diff --git a/public/js/directives/directives.js b/public/js/directives/directives.js
index 95e136a997..be8982f076 100644
--- a/public/js/directives/directives.js
+++ b/public/js/directives/directives.js
@@ -81,14 +81,65 @@ habitrpg.directive('habitrpgSortable', ['User', function(User) {
// return hljs.highlightAuto(code).value;
// }
});
+
+ emoji.img_path = 'bower_components/habitrpg-shared/img/emoji/unicode/';
var toHtml = function (markdown) {
if (markdown == undefined)
return '';
-
- return marked(markdown);
+
+ markdown = marked(markdown);
+ markdown = emoji.replace_colons(markdown);
+ markdown = emoji.replace_unified(markdown);
+
+ return markdown;
};
-
+
+ // [nickgordon20131123] this hacky override wraps images with a link to the image in a new window, and also adds some classes in case we want to style
+ marked.InlineLexer.prototype.outputLink = function(cap, link) {
+ var escape = function(html, encode) {
+ return html
+ .replace(!encode ? /&(?!#?\w+;)/g : /&/g, '&')
+ .replace(//g, '>')
+ .replace(/"/g, '"')
+ .replace(/'/g, ''');
+ };
+ if (cap[0].charAt(0) !== '!') {
+ return ''
+ + this.output(cap[1])
+ + '';
+ } else {
+ return '';
+ }
+ }
+
//hljs.tabReplace = ' ';
return {
@@ -102,7 +153,9 @@ habitrpg.directive('habitrpgSortable', ['User', function(User) {
link: function(scope, element, attrs) {
scope.$watch(attrs.ngModel, function(value, oldValue) {
var markdown = value;
+ var linktarget = attrs.target || '_self';
var html = md.toHtml(markdown);
+ html = html.replace(' href','target="'+linktarget+'" href');
element.html(html);
});
}
@@ -153,3 +206,16 @@ habitrpg
}
}]);
+habitrpg.directive('fromNow', ['$interval', function($interval){
+ return function(scope, element, attr){
+ var updateText = function(){ element.text(moment(scope.message.timestamp).fromNow()) };
+ updateText();
+ // Update the counter every 60secs if was sent less than one hour ago otherwise every hour
+ // OPTIMIZATION, every time the interval is run, update the interval time
+ var intervalTime = moment().diff(scope.message.timestamp, 'minute') < 60 ? 60000 : 3600000;
+ var interval = $interval(function(){ updateText() }, intervalTime, false);
+ scope.$on('$destroy', function() {
+ $interval.cancel(interval);
+ });
+ }
+}]);
diff --git a/public/js/services/userServices.js b/public/js/services/userServices.js
index 187f65761a..bf9b605a87 100644
--- a/public/js/services/userServices.js
+++ b/public/js/services/userServices.js
@@ -65,13 +65,14 @@ angular.module('userServices', []).
// the user has been modified from another application, sync up
if(data.wasModified) {
delete data.wasModified;
- _.extend(user, data);
$rootScope.$emit('userUpdated', user);
}
+ // Update user
+ _.extend(user, data);
+
// Emit event when user is synced
$rootScope.$emit('userSynced');
- user._v = data._v;
}
sent.length = 0;
settings.fetching = false;
diff --git a/public/manifest.json b/public/manifest.json
index 4cd6bdf6cd..f14e5b3d97 100644
--- a/public/manifest.json
+++ b/public/manifest.json
@@ -15,6 +15,8 @@
"bower_components/angular-loading-bar/build/loading-bar.js",
"bower_components/Angular-At-Directive/src/at.js",
"bower_components/Angular-At-Directive/src/caret.js",
+ "bower_components/angular-bindonce/bindonce.js",
+ "bower_components/js-emoji/emoji.js",
"bower_components/bootstrap/docs/assets/js/bootstrap.js",
"bower_components/angular-bootstrap/ui-bootstrap.js",
diff --git a/src/controllers/dataexport.js b/src/controllers/dataexport.js
index 817e20791a..6e5f6703b2 100644
--- a/src/controllers/dataexport.js
+++ b/src/controllers/dataexport.js
@@ -1,8 +1,12 @@
var _ = require('lodash');
var csv = require('express-csv');
+var express = require('express');
var nconf = require('nconf');
var moment = require('moment');
var dataexport = module.exports;
+var js2xmlparser = require("js2xmlparser");
+var pd = require('pretty-data').pd;
+var User = require('../models/user').model;
/*
@@ -25,3 +29,58 @@ dataexport.history = function(req, res) {
});
return res.csv(output);
}
+
+var userdata = function(user) {
+ if(user.auth && user.auth.local) {
+ delete user.auth.local.salt;
+ delete user.auth.local.hashed_password;
+ }
+ return user;
+}
+
+dataexport.leanuser = function(req, res, next) {
+ var user = res.locals.user;
+ User.findOne({_id: user._id,}).lean().exec(function(err, user) {
+ if (err) return res.json(500, {err: err});
+ if (_.isEmpty(user)) return res.json(401, NO_USER_FOUND);
+ res.locals.user = user;
+ return next();
+ });
+};
+
+dataexport.userdata = {
+ xml: function(req, res) {
+ var user = userdata(res.locals.user);
+ return res.xml({data: JSON.stringify(user), rootname: 'user'});
+ },
+ json: function(req, res) {
+ var user = userdata(res.locals.user);
+ return res.jsonstring(user);
+ },
+}
+
+/*
+ ------------------------------------------------------------------------
+ Express Extensions (should be refactored into a module)
+ ------------------------------------------------------------------------
+*/
+
+var expressres = express.response || http.ServerResponse.prototype;
+
+expressres.xml = function(obj, headers, status) {
+ var body = '';
+ this.charset = this.charset || 'utf-8';
+ this.header('Content-Type', 'text/xml');
+ this.header('Content-Disposition', 'attachment');
+ body = pd.xml(js2xmlparser(obj.rootname,obj.data));
+ return this.send(body, headers, status);
+};
+
+expressres.jsonstring = function(obj, headers, status) {
+ var body = '';
+ this.charset = this.charset || 'utf-8';
+ this.header('Content-Type', 'application/json');
+ this.header('Content-Disposition', 'attachment');
+ body = pd.json(JSON.stringify(obj));
+ return this.send(body, headers, status);
+};
diff --git a/src/controllers/user.js b/src/controllers/user.js
index 8c875dc1dc..b453d2c914 100644
--- a/src/controllers/user.js
+++ b/src/controllers/user.js
@@ -470,11 +470,13 @@ api.deleteTag = function(req, res){
delete task.tags[tag.id];
})
})
+ user.markModified('habits');
+ user.markModified('dailys');
+ user.markModified('todos');
+ user.markModified('rewards');
user.save(function(err,saved){
if (err) return res.json(500, {err: err});
- // Need to use this until we found a way to update the ui for tasks when a tag is deleted
- res.locals.wasModified = true;
- res.send(200);
+ res.send(204);
});
} else {
res.json(400, {err:'Tag not found'});
@@ -628,10 +630,9 @@ api.batchUpdate = function(req, res, next) {
if (err) return res.json(500, {err: err});
var response = user.toJSON();
response.wasModified = res.locals.wasModified;
- if (response._tmp && response._tmp.drop) response.wasModified = true;
-
- // Send the response to the server
- if(response.wasModified){
+ if (response._tmp && response._tmp.drop){
+ res.json(200, {_tmp: {drop: response._tmp.drop}, _v: response._v});
+ }else if(response.wasModified){
res.json(200, response);
}else{
res.json(200, {_v: response._v});
diff --git a/src/middleware.js b/src/middleware.js
index 4849fee58a..8fe5d8a19e 100644
--- a/src/middleware.js
+++ b/src/middleware.js
@@ -106,6 +106,26 @@ var avalaibleLanguages = _.map(langCodes, function(langCode){
}
});
+// Load MomentJS localization files
+var momentLangs = {};
+
+// Handle different language codes from MomentJS and /locales
+var momentLangsMapping = {
+ 'en': 'en-gb',
+ 'no': 'nn'
+};
+
+_.each(langCodes, function(code){
+ var lang = _.find(avalaibleLanguages, {code: code});
+ lang.momentLangCode = (momentLangsMapping[code] || code);
+ try{
+ var momentLang = momentLangsMapping[code] ? momentLangsMapping[code] : code;
+ // MomentJS lang files are JS files that has to be executed in the browser so we load them as plain text files
+ var f = fs.readFileSync(path.join(__dirname, '/../node_modules/moment/lang/' + lang.momentLangCode + '.js'), 'utf8');
+ lang.momentLang = f;
+ }catch (e){}
+});
+
var getUserLanguage = function(req, callback){
var getFromBrowser = function(){
var acceptable = _(req.acceptedLanguages).map(function(lang){
diff --git a/src/models/user.js b/src/models/user.js
index d13dd60360..7c07306478 100644
--- a/src/models/user.js
+++ b/src/models/user.js
@@ -21,6 +21,8 @@ var eggPotionMapping = _.transform(items.items.eggs, function(m, egg){
}));
})
+var specialPetsMapping = items.items.specialPets; // may need to revisit if we add additional information about the special pets
+
var UserSchema = new Schema({
// ### UUID and API Token
_id: {
@@ -120,8 +122,7 @@ var UserSchema = new Schema({
}
},
- // -------------- Animals -------------------
-
+ // -------------- Animals -------------------
// Complex bit here. The result looks like:
// pets: {
// 'Wolf-Desert': 0, // 0 means does not own
@@ -133,11 +134,7 @@ var UserSchema = new Schema({
// First transform to a 1D eggs/potions mapping
_.transform(eggPotionMapping, function(m,v,k){ m[k] = Number; }),
// Then add additional pets (backer, contributor)
- {
- 'Wolf-Veteran': Number,
- 'Wolf-Cerberus': Number,
- 'Dragon-Hydra': Number
- }
+ _.transform(specialPetsMapping, function(m,v,k){ m[k] = Number; })
),
currentPet: String, // Cactus-Desert
@@ -192,7 +189,8 @@ var UserSchema = new Schema({
current: String, // party._id
invitation: String, // party._id
lastMessageSeen: String,
- leader: Boolean
+ leader: Boolean,
+ order: {type:String, 'default':'level'}
},
preferences: {
armorSet: String,
@@ -205,6 +203,9 @@ var UserSchema = new Schema({
},
hideHeader: {type:Boolean, 'default':false},
showHelm: {type:Boolean, 'default':true},
+ showWeapon: {type:Boolean, 'default':true},
+ showShield: {type:Boolean, 'default':true},
+ showArmor: {type:Boolean, 'default':true},
skin: {type:String, 'default':'white'},
timezoneOffset: Number,
language: String,
@@ -286,6 +287,9 @@ UserSchema.virtual('tasks').get(function () {
UserSchema.pre('save', function(next) {
//this.markModified('tasks');
+ if (_.isNaN(this.preferences.dayStart) || this.preferences.dayStart < 0 || this.preferences.dayStart > 24) {
+ this.preferences.dayStart = 0;
+ }
if (!this.profile.name) {
var fb = this.auth.facebook;
@@ -299,7 +303,11 @@ UserSchema.pre('save', function(next) {
// Actually, can this be used as an attr default? (schema {type: ..., 'default': function(){}})
this.stats.points = this.stats.lvl - (this.stats.def + this.stats.str + this.stats.per + this.stats.int);
- var petCount = _.reduce(this.items.pets,function(m,v){return m+(v ? 1 : 0);},0);
+ var petCount = helpers.countPets(_.reduce(this.items.pets,function(m,v){
+ //HOTFIX - Remove when solution is found, the first argument passed to reduce is a function
+ if(_.isFunction(v)) return m;
+ return m+(v?1:0)},0), this.items.pets);
+
this.achievements.beastMaster = petCount >= 90;
//our own version incrementer
@@ -316,7 +324,9 @@ UserSchema.methods.syncScoreToChallenge = function(task, delta){
var t = chal.tasks[task.id];
if (!t) return chal.syncToUser(self); // this task was removed from the challenge, notify user
t.value += delta;
- t.history.push({value: t.value, date: +new Date});
+ if (t.type == 'habit' || t.type == 'daily') {
+ t.history.push({value: t.value, date: +new Date});
+ }
chal.save();
});
}
diff --git a/src/routes/dataexport.js b/src/routes/dataexport.js
index 090961fd99..b84fe09bd3 100644
--- a/src/routes/dataexport.js
+++ b/src/routes/dataexport.js
@@ -6,5 +6,7 @@ var nconf = require('nconf');
/* Data export */
router.get('/history.csv',auth.authWithSession,dataexport.history); //[todo] encode data output options in the data controller and use these to build routes
+router.get('/userdata.xml',auth.authWithSession,dataexport.leanuser,dataexport.userdata.xml);
+router.get('/userdata.json',auth.authWithSession,dataexport.leanuser,dataexport.userdata.json);
module.exports = router;
diff --git a/views/index.jade b/views/index.jade
index b28e87b716..637586e75b 100644
--- a/views/index.jade
+++ b/views/index.jade
@@ -5,7 +5,7 @@ html(ng-app="habitrpg", ng-controller="RootCtrl", ng-class='{"applying-action":a
title HabitRPG | Your Life The Role Playing Game
// ?v=1 needed to force refresh
- link(rel='shortcut icon' href='#{env.getBuildUrl("favicon.ico")}?v=2')
+ link(rel='shortcut icon', href='#{env.getBuildUrl("favicon.ico")}?v=2')
script(type='text/javascript').
window.env = !{JSON.stringify(env)};
diff --git a/views/main/filters.jade b/views/main/filters.jade
index 746606e2ae..200dc64b52 100644
--- a/views/main/filters.jade
+++ b/views/main/filters.jade
@@ -1,18 +1,18 @@
-.filters(ng-controller='FiltersCtrl')
+.filters.tag-list(ng-controller='FiltersCtrl')
.pull-left.filter-description
| Tags:
ul.nav.nav-pills
li
a(rel='tooltip', title='Edit Tags', ng-click='saveOrEdit()')
i(ng-class='{"icon-ok": _editing, "icon-pencil": !_editing}')
- li(ng-class='{active: user.filters[tag.id]}', ng-repeat='tag in user.tags', style='position: relative;')
+ li(bindonce='user.tags', ng-class='{active: user.filters[tag.id]}', ng-repeat='tag in user.tags', style='position: relative;')
.input-append.option-group.tag-editing(ng-show='_editing')
input.input.input-small.option-content.tag-editing-pill(type='text', ng-model='tag.name')
span.add-on.tag-editing-pill
a.pull-right(ng-click='delete(tag,$index)')
i.icon-trash
a(ng-hide='_editing', ng-click='toggleFilter(tag)')
- i.icon-bullhorn(ng-if="tag.challenge")
+ i.icon-bullhorn(bo-if="tag.challenge")
| {{tag.name}}
li
form.form-inline(ng-show='_editing', ng-submit='createTag(_newTag)')
diff --git a/views/options/inventory/inventory.jade b/views/options/inventory/inventory.jade
index 5513af5b37..90a57f379c 100644
--- a/views/options/inventory/inventory.jade
+++ b/views/options/inventory/inventory.jade
@@ -12,7 +12,7 @@ script(type='text/ng-template', id='partials/options.inventory.inventory.html')
li.customize-menu
menu.pets-menu(label='Eggs ({{eggCount}})')
- p(ng-show='eggCount < 1') You don't have any eggs yet.
+ p(ng-show='eggCount < 1') You don't have any eggs.
div(ng-repeat='(egg,points) in ownedItems(user.items.eggs)')
//TODO move positioning this styling to css
button.customize-option(popover='{{Items.eggs[egg].notes}}', popover-title='{{Items.eggs[egg].text}} Egg', popover-trigger='mouseenter', popover-placement='right', ng-click='chooseEgg(egg)', class='Pet_Egg_{{egg}}', ng-class='{selectableInventory: selectedPotion && !user.items.pets[egg+"-"+selectedPotion.name]}')
@@ -21,7 +21,7 @@ script(type='text/ng-template', id='partials/options.inventory.inventory.html')
li.customize-menu
menu.hatchingPotion-menu(label='Hatching Potions ({{potCount}})')
- p(ng-show='potCount < 1') You don't have any hatching potions yet.
+ p(ng-show='potCount < 1') You don't have any hatching potions.
div(ng-repeat='(pot,points) in ownedItems(user.items.hatchingPotions)')
button.customize-option(popover='{{Items.hatchingPotions[pot].notes}}', popover-title='{{Items.hatchingPotions[pot].text}} Potion', popover-trigger='mouseenter', popover-placement='right', ng-click='choosePotion(pot)', class='Pet_HatchingPotion_{{pot}}', ng-class='{selectableInventory: selectedEgg && !user.items.pets[selectedEgg.name+"-"+pot]}')
.badge.badge-info.stack-count {{points}}
@@ -29,7 +29,7 @@ script(type='text/ng-template', id='partials/options.inventory.inventory.html')
//-li.customize-menu
menu.pets-menu(label='Food ({{foodCount}})')
- p(ng-show='foodCount < 1') You don't have any food yet.
+ p(ng-show='foodCount < 1') You don't have any food.
div(ng-repeat='(food,points) in ownedItems(user.items.food)')
button.customize-option(popover='{{Items.food[food].notes}}', popover-title='{{Items.food[food].text}}', popover-trigger='mouseenter', popover-placement='right', ng-click='chooseFood(food)', class='Pet_Food_{{food}}')
.badge.badge-info.stack-count {{points}}
@@ -52,11 +52,11 @@ script(type='text/ng-template', id='partials/options.inventory.inventory.html')
| Welcome to the Market. Dying to get that particular pet you're after, but don't want to wait for it to drop? Buy it here! If you have unwanted drops, sell them to me.
p
button.btn.btn-primary(ng-show='selectedEgg', ng-click='sellInventory()')
- | Sell {{selectedEgg.name}} for {{selectedEgg.value}} GP
+ | Sell {{selectedEgg.name}} for {{selectedEgg.value}} Gold
button.btn.btn-primary(ng-show='selectedPotion', ng-click='sellInventory()')
- | Sell {{selectedPotion.name}} for {{selectedPotion.value}} GP
+ | Sell {{selectedPotion.name}} for {{selectedPotion.value}} Gold
button.btn.btn-primary(ng-show='selectedFood', ng-click='sellInventory()')
- | Sell {{selectedFood.name}} for {{selectedFood.value}} GP
+ | Sell {{selectedFood.name}} for {{selectedFood.value}} Gold
menu.inventory-list(type='list')
li.customize-menu
diff --git a/views/options/inventory/stable.jade b/views/options/inventory/stable.jade
index 33304e9d59..82f719e6d5 100644
--- a/views/options/inventory/stable.jade
+++ b/views/options/inventory/stable.jade
@@ -67,7 +67,8 @@ script(type='text/ng-template', id='partials/options.inventory.stable.pets.html'
div
button(ng-if='user.items.pets["Wolf-Veteran"]', class="pet-button Pet-Wolf-Veteran", ng-class='{active: user.items.currentPet == "Wolf-Veteran"}', ng-click='choosePet("Wolf", "Veteran")', popover='Veteran Wolf', popover-trigger='mouseenter', popover-placement='bottom')
button(ng-if='user.items.pets["Wolf-Cerberus"]', class="pet-button Pet-Wolf-Cerberus", ng-class='{active: user.items.currentPet == "Wolf-Cerberus"}', ng-click='choosePet("Wolf", "Cerberus")', popover='Cerberus Pup', popover-trigger='mouseenter', popover-placement='bottom')
- button(ng-if='user.items.pets["Dragon-Hydra"]', class="pet-button Pet-Dragon-Hydra", ng-class='{active: user.items.currentPet == "Dragon-Hydra"}', ng-click='choosePet("Dragon", "Hydra")', popover='Hydra Pet', popover-trigger='mouseenter', popover-placement='bottom')
+ button(ng-if='user.items.pets["Dragon-Hydra"]', class="pet-button Pet-Dragon-Hydra", ng-class='{active: user.items.currentPet == "Dragon-Hydra"}', ng-click='choosePet("Dragon", "Hydra")', popover='Hydra', popover-trigger='mouseenter', popover-placement='bottom')
+ button(ng-if='user.items.pets["Turkey-Base"]', class="pet-button Pet-Turkey-Base", ng-class='{active: user.items.currentPet == "Turkey-Base"}', ng-click='choosePet("Turkey", "Base")', popover='Turkey', popover-trigger='mouseenter', popover-placement='bottom')
a(target='_blank', href='http://habitrpg.wikia.com/wiki/Contributing_to_HabitRPG')
button(ng-if='!user.items.pets["Dragon-Hydra"]', class="pet-button pet-not-owned", popover-trigger='mouseenter', popover-placement='right', popover="Click the gold paw to learn more about how you can obtain this rare pet through contributing to HabitRPG!", popover-title='How to Get this Pet!')
img(src='/bower_components/habitrpg-shared/img/PixelPaw-Gold.png')
diff --git a/views/options/profile.jade b/views/options/profile.jade
index 470cf8758d..7bb502e321 100644
--- a/views/options/profile.jade
+++ b/views/options/profile.jade
@@ -9,14 +9,26 @@ script(id='partials/options.profile.avatar.html', type='text/ng-template')
button.m_head_0.customize-option(type='button', ng-click='set("preferences.gender","m")')
button.f_head_0.customize-option(type='button', ng-click='set("preferences.gender","f")')
label.checkbox
- input(type='checkbox', ng-model='user.preferences.showHelm', ng-change='toggleHelm(user.preferences.showHelm)')
+ input(type='checkbox', ng-model='user.preferences.showHelm', ng-change='set("preferences.showHelm", user.preferences.showHelm?true: false)')
| Show Helm
+ menu(type='list')
+ li.customize-menu
+ menu(label='Clothing')
+ button.f_armor_0_v1.customize-option(ng-show='user.preferences.gender=="f"', type='button', ng-click='set("preferences.armorSet","v1")')
+ button.f_armor_0_v2.customize-option(ng-show='user.preferences.gender=="f"', type='button', ng-click='set("preferences.armorSet","v2")')
+ label.checkbox
+ input(type='checkbox', ng-model='user.preferences.showArmor', ng-change='set("preferences.showArmor", user.preferences.showArmor?true: false)')
+ | Show Armor
+ menu(type='list')
+ li.customize-menu
+ menu(label='Other')
+ label.checkbox
+ input(type='checkbox', ng-model='user.preferences.showWeapon', ng-change='set("preferences.showWeapon", user.preferences.showWeapon?true: false)')
+ | Show Weapon
+ label.checkbox
+ input(type='checkbox', ng-model='user.preferences.showShield', ng-change='set("preferences.showShield", user.preferences.showShield?true: false)')
+ | Show Shield
- menu(ng-show='user.preferences.gender=="f"', type='list')
- li.customize-menu
- menu(label='Clothing')
- button.f_armor_0_v1.customize-option(type='button', ng-click='set("preferences.armorSet","v1")')
- button.f_armor_0_v2.customize-option(type='button', ng-click='set("preferences.armorSet","v2")')
.span4
h3 Hair
diff --git a/views/options/settings.jade b/views/options/settings.jade
index e5dd0b2cee..df14bc3b22 100644
--- a/views/options/settings.jade
+++ b/views/options/settings.jade
@@ -71,4 +71,9 @@ script(id='partials/options.settings.export.html', type="text/ng-template")
h2 Data Export
small Here are a few options for saving your Habit data.
h4 Habit History
- a(href="/export/history.csv") Export History (CSV)
+ Export History:
+ a(href="/export/history.csv") (CSV)
+ h4 User Data
+ Export User Data:
+ a(href="/export/userdata.xml") (XML)
+ a(href="/export/userdata.json") (JSON)
diff --git a/views/options/social/challenge-box.jade b/views/options/social/challenge-box.jade
index 213e61b724..09d545635b 100644
--- a/views/options/social/challenge-box.jade
+++ b/views/options/social/challenge-box.jade
@@ -5,7 +5,7 @@
| Challenges
a.pull-right(target='_blank', href='https://trello.com/card/challenges-individual-party-guild-public/50e5d3684fe3a7266b0036d6/58')
i.icon-question-sign
- .modal-body
+ .modal-body(bindonce='group.challenges')
div(ng-if='group.challenges.length > 0')
table.table.table-striped
tr(ng-repeat='challenge in group.challenges')
diff --git a/views/options/social/challenges.jade b/views/options/social/challenges.jade
index ba5a8f9df4..c15d36b32f 100644
--- a/views/options/social/challenges.jade
+++ b/views/options/social/challenges.jade
@@ -18,7 +18,7 @@ script(type='text/ng-template', id='partials/options.social.challenges.detail.me
script(type='text/ng-template', id='partials/options.social.challenges.detail.html')
// Edit button
- div(ng-if='challenge.leader==user._id')
+ div(bindonce='challenge', ng-if='challenge.leader==user._id')
ul.unstyled
li(ng-hide='challenge._locked==false')
button.btn.btn-small.btn-default(ng-click='challenge._locked = false') Edit
@@ -35,12 +35,12 @@ script(type='text/ng-template', id='partials/options.social.challenges.detail.ht
textarea.option-content(cols='3', placeholder='Description', ng-model='challenge.description')
hr
- .well(ng-if='challenge.description') {{challenge.description}}
+ .well(bindonce='challenge', ng-if='challenge.description') {{challenge.description}}
i.icon-question-sign(popover="These are the challenge's tasks. As users participate, they will change color and gain graphs to show you the overall progress of the group.", popover-trigger='mouseenter', popover-placement='right')
habitrpg-tasks(obj='challenge', main=false)
// Member List
- div(ng-if='challenge.members.length > 0')
+ div(bindonce='challenge', ng-if='challenge.members.length > 0')
h3 How's Everyone Doing?
menu
button.customize-option(ng-repeat='member in challenge.members', ng-click='toggleMember(challenge._id, member._id)') {{member.profile.name}}
@@ -49,7 +49,7 @@ script(type='text/ng-template', id='partials/options.social.challenges.detail.ht
// Accordion version if we choose that instead
//- div(ng-if='challenge.members')
h4 How's Everyone Doing?
- .accordion-group(ng-repeat='member in challenge.members')
+ .accordion-group(bindonce='challenge.members', ng-repeat='member in challenge.members')
.accordion-heading
a.accordion-toggle(ng-click='toggleMember(challenge._id, member._id)') {{member.profile.name}}
.accordion-body(ng-class='{collapse: $stateParams.uid != member._id}')
@@ -92,7 +92,8 @@ script(type='text/ng-template', id='partials/options.social.challenges.html')
.option-medium
input.option-content(type='text', minlength="3", maxlength="16", ng-model='newChallenge.shortName', placeholder='Tag Name', required)
- i.icon-question-sign(popover="Challenges appear on tag-lists & task-tooltips. So while you'll want a descriptive title above, you'll also need a 'short name'. Eg, 'Lose 10 pounds in 3 months' might become '-10lb'", popover-trigger='mouseenter', popover-placement='right')
+ a(target='_blank', href='http://habitrpg.wikia.com/wiki/Tags')
+ i.icon-question-sign(popover="Challenges appear on tag-lists & task-tooltips. So while you'll want a descriptive title above, you'll also need a 'short name'. Eg, 'Lose 10 pounds in 3 months' might become '-10lb' (Click the '?' for more info).", popover-trigger='mouseenter', popover-placement='right')
textarea.option-content(cols='3', placeholder='Description', ng-model='newChallenge.description')
diff --git a/views/options/social/chat-box.jade b/views/options/social/chat-box.jade
index 871c165464..7a89b7010e 100644
--- a/views/options/social/chat-box.jade
+++ b/views/options/social/chat-box.jade
@@ -1,11 +1,11 @@
-form(ng-submit='postChat(group,message.content)')
+form.chat-form(ng-submit='postChat(group,message.content)')
.-options
//FIXME ng-model makes this painfully slow! using jquery for now, which is really non-angular-like
.control-group.option-large(ng-controller='AutocompleteCtrl')
textarea.chat-textarea.option-content(style='height:6em;', ui-keypress='{13:"postChat(group,message.content)"}', ng-model='message.content', updateinterval='250', flag='@', at-user, auto-complete)
span.user-list(ng-show='!isAtListHidden')
ul.list-at-user
- li(ng-repeat='user in users | filter:query.text | limitTo: 5', ng-click='autoComplete(user)')
+ li(bindonce='users', ng-repeat='user in users | filter:query.text | limitTo: 5', ng-click='autoComplete(user)')
span.username.label(class='label-contributor-{{user.contributor.level}}', ng-class='{"label-npc": user.backer.npc}') {{user.user}}
table.pull-right
tr
diff --git a/views/options/social/chat-message.jade b/views/options/social/chat-message.jade
index 95f94a8678..0baa423a6e 100644
--- a/views/options/social/chat-message.jade
+++ b/views/options/social/chat-message.jade
@@ -1,10 +1,13 @@
-li(ng-repeat='message in group.chat', ng-class='{highlight: indexOf(message.text.toLowerCase(), user.profile.name.toLowerCase()), "own-message": user._id == message.uuid}')
- a.label.chat-message(class='label-contributor-{{message.contributor.level}}', ng-class='{"label-npc": message.backer.npc}', ng-click='clickMember(message.uuid, true)')
- span(tooltip='{{contribText(message.contributor, message.backer)}}') {{message.user}}
- |
- span(ng-bind-html="message.text | linky:'_blank'")
- | -
- span.muted.time
- | {{relativeDate(message.timestamp, _currentTime) + ' '}}
- a(ng-show='user.contributor.admin || message.uuid == user.id', ng-click='deleteChatMessage(group, message)')
- i.icon-remove(tooltip='Delete')
+li(bindonce='group.chat', ng-repeat='message in group.chat', bo-class='{highlight: isUserMentioned(user,message), "own-message": user._id == message.uuid}')
+ div(class='scrollable-message')
+ a.label.chat-message(class='hidden-label')
+ span {{message.user}}
+ |
+ markdown(ng-model='message.text',target='_blank')
+ | -
+ span.muted.time(from-now='message.timestamp')
+ a(bo-show='user.contributor.admin || message.uuid == user.id', ng-click='deleteChatMessage(group, message)')
+ |
+ i.icon-remove(tooltip='Delete')
+ a.label.chat-message(class='float-label', bo-class='{"label-npc": message.backer.npc, "label-contributor-{{message.contributor.level}}":message.contributor.level}', ng-click='clickMember(message.uuid, true)')
+ span(tooltip='{{contribText(message.contributor, message.backer)}}') {{message.user}}
diff --git a/views/options/social/group.jade b/views/options/social/group.jade
index 1c8e0cd884..9371e3567d 100644
--- a/views/options/social/group.jade
+++ b/views/options/social/group.jade
@@ -8,7 +8,7 @@ a.pull-right.gem-wallet(popover-trigger='mouseenter', popover-title='Guild Bank'
// ------ Information -------
.modal(style='position: relative;top: auto;left: auto;right: auto;margin: 0 auto 20px;z-index: 1;max-width: 100%;')
- .modal-header
+ .modal-header(bindonce='group')
span(ng-if='group.leader == user.id')
button.btn.btn-primary.pull-right(ng-click='save(group)', ng-show='group._editing') Save
button.btn.btn-default.pull-right(ng-click='group._editing = true', ng-hide='group._editing') Edit Group
@@ -20,8 +20,7 @@ a.pull-right.gem-wallet(popover-trigger='mouseenter', popover-title='Guild Bank'
input.option-content(type='text', ng-model='group.name', placeholder='Group Name')
.control-group.option-large
label.control-label Description
- textarea.option-content(style='height:15em;', placeholder='Description', ng-model='group.description')
- include ../../shared/formatting-help
+ textarea.option-content(style='height:15em;', placeholder='Description shown in public Guilds list (Markdown OK)', ng-model='group.description')
.control-group.option-large
label.control-label Logo URL
input.option-content(type='url', placeholder='Logo URL', ng-model='group.logo')
@@ -40,7 +39,16 @@ a.pull-right.gem-wallet(popover-trigger='mouseenter', popover-title='Guild Bank'
.modal-header
h3 Members
.modal-body
- table.table.table-striped
+ span
+ | Party Members list ordering
+ select#partyOrder(
+ style='width:140px',
+ ng-model='user.party.order',
+ ng-controller='ChatCtrl',
+ ng-options='k as v for (k , v) in partyOrderChoices',
+ ng-change='set("party.order", user.party.order)'
+ )
+ table.table.table-striped(bindonce='group')
tr(ng-repeat='member in group.members')
td
// allow leaders to ban members
@@ -78,8 +86,7 @@ a.pull-right.gem-wallet(popover-trigger='mouseenter', popover-title='Guild Bank'
.span8
div.blah-options(ng-show='group._editing')
.option-large
- textarea.option-content(style='height:15em;', placeholder='Message from group leader', ng-model='group.leaderMessage')
- include ../../shared/formatting-help
+ textarea.option-content(style='height:15em;', placeholder='Message from group leader (Markdown OK)', ng-model='group.leaderMessage')
table(ng-show='group.leaderMessage')
tr
td
@@ -91,6 +98,7 @@ a.pull-right.gem-wallet(popover-trigger='mouseenter', popover-title='Guild Bank'
div(ng-controller='ChatCtrl')
h3 Chat
include ./chat-box
+ include ../../shared/formatting-help
ul.unstyled.tavern-chat
include ./chat-message
diff --git a/views/options/social/tavern.jade b/views/options/social/tavern.jade
index 0fad9b0fe0..46a773f8f4 100644
--- a/views/options/social/tavern.jade
+++ b/views/options/social/tavern.jade
@@ -47,20 +47,22 @@
// Player Tiers
.modal(style='position: relative;top: auto;left: auto;right: auto;margin: 0 auto 20px;z-index: 1;max-width: 100%;')
.modal-header
- h3 Player Tier Legend
+ h3 Player Tiers
.modal-body
small.
- Click labels to expand. See contribution details.
+ Click tier labels below for more information.
+ Learn more about contributor rewards
+ Learn how to contribute to HabitRPG
table.table.table-striped
tr
td
a.label.label-contributor-1(ng-click='toggleUserTier($event)') Friend (1-2)
div(style='display:none;')
p.
- When your first submission is deployed, you will receive the HabitRPG Contributor's badge. Your name in Tavern chat will proudly display that you are a contributor.
+ When your first submission is deployed, you will receive the HabitRPG Contributor's badge. Your name in Tavern chat will proudly display that you are a contributor. As a bounty for your work, you will also receive 2 Gems.
hr
p.
- When your second submission is deployed, the Crystal Armor will be available for purchase in the Rewards shop after the Golden Armor. As a bounty for your great work, you will also receive 2 Gems.
+ When your second submission is deployed, the Crystal Armor will be available for purchase in the Rewards shop after the Golden Armor. As a bounty for your continued work, you will also receive 2 Gems.
tr
td
a.label.label-contributor-3(ng-click='toggleUserTier($event)') Elite (3-4)
@@ -69,23 +71,23 @@
When your third submission is deployed, the Crystal Helmet will be available for purchase in the Rewards shop after the Golden Helmet. As a bounty for your great work, you will also receive 2 Gems.
hr
p.
- When your fourth submission is deployed, the Crystal Sword will be available for purchase in the Rewards shop after the Golden Sword. As a bounty for your great work, you will also receive 2 Gems.
+ When your fourth submission is deployed, the Crystal Sword will be available for purchase in the Rewards shop after the Golden Sword. You will once again receive a bounty of 2 Gems.
tr
td
a.label.label-contributor-5(ng-click='toggleUserTier($event)') Champion (5-6)
div(style='display:none;')
p.
- When your fifth submission is deployed, the Crystal Shield will be available for purchase in the Reward shop after the Golden Shield. As a bounty for your great work, you will also receive 2 Gems.
+ When your fifth submission is deployed, the Crystal Shield will be available for purchase in the Reward shop after the Golden Shield. You will also receive 2 Gems.
hr
p.
-