Merge branch 'develop' into sabe/attributes

This commit is contained in:
Sabe Jones 2013-12-30 10:25:08 -06:00
commit d3a6191a5e
52 changed files with 1177 additions and 641 deletions

View file

@ -3,3 +3,5 @@ views/*
build
build/*
Gruntfile.js
.idea*
.git*

View file

@ -57,7 +57,7 @@ module.exports = function(grunt) {
nodemon: {
dev: {
ignoredFiles: ['public/*', 'Gruntfile.js', 'views/*', 'build/*']
ignoredFiles: ['public/*', 'Gruntfile.js', 'views/*', 'build/*', '.idea*', '.git*']
}
},

417
locales-old/en/app.json Normal file
View file

@ -0,0 +1,417 @@
{
"languageName": "English",
"stringNotFound": "String not found.",
"_commentfrontpage":"HABITRPG FRONT PAGE",
"synopsis" : "A habit building program which treats your life like a Role Playing Game. Level up as you succeed, lose HP as you fail, earn money to buy weapons and armor.",
"playButton" : "Play",
"_commenttut": "TUTORIAL/TOUR",
"endTourButton": "End Tour",
"nextButton" : "Next",
"prevButton" : "Prev",
"tour1Title" : "Welcome to HabitRPG",
"tour1Text" : "Welcome to HabitRPG, a habit-tracker which treats your goals like a Role Playing Game.",
"tour2Title" : "Habits",
"tour2Text" : "Habits are good or bad goals that you constantly track.",
"tour3Title" : "Dailies",
"tour3Text" : "Dailies are goals that you want to complete once a day.",
"tour4Title" : "Todos",
"tour4Text" : "Todos are one-off goals which need to be completed eventually. ",
"tour5Title" : "Rewards",
"tour5Text" : "As you complete goals, you earn gold to buy rewards. Buy them liberally - rewards are integral in forming good habits. ",
"tour6Title" : "Hover over comments",
"tour6Text" : "Different task-types have special properties. Hover over each task's comment for more information. When you're ready to get started, delete the existing tasks and add your own.",
"_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!",
"_commentdefaulttags" : "DEFAULT TAGS",
"morning" : "morning",
"afternoon" : "afternoon",
"evening" : "evening",
"_commenthead": "HEADER",
"health": "Health",
"experience": "Experience",
"history": "History",
"anonymous": "Anonymous",
"level": "Level",
"tasks": "Tasks",
"loginAndReg" : "Login / Register",
"loginFacebookAlt" : "Login / Register with Facebook",
"login" : "Login",
"register" : "Register",
"options": "Options",
"logout": "Logout",
"_commentnotifcations" : "NOTIFICATIONS",
"partyNotification" : "New Party Messages",
"_commenttaskview": "TASK VIEW",
"habits": "Habits",
"Habits": "Habits",
"newHabit": "New Habit",
"edit": "Edit",
"text": "Text",
"extraNotes": "Extra Notes",
"directions/Actions": "Directions/Actions",
"advancedOptions": "Advanced Options",
"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": "Easy",
"medium": "Medium",
"hard": "Hard",
"delete": "Delete",
"progress": "Progress",
"score": "Score",
"dailies": "Dailies",
"Dailies": "Dailies",
"newDaily": "New Daily",
"repeat": "Repeat",
"Su": "Su",
"M": "M",
"T": "T",
"We": "W",
"Th": "Th",
"F": "F",
"S": "S",
"todos": "To-Dos",
"Todos": "To-Dos",
"newTodo": "New To-Do",
"dueDate": "Due Date",
"remaining": "Remaining",
"complete": "Complete",
"rewards": "Rewards",
"Rewards": "Rewards",
"gold": "Gold",
"silver": "Silver",
"newReward": "New Reward",
"price": "Price",
"tags" : "Tags",
"editTags" : "Edit Tags",
"newTag" : "New Tag",
"clearFilters" : "Clear Filters",
"_commentdrops" : "DROP SYSTEM",
"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 item has dropped",
"_commentoptionsview": "OPTIONS VIEW",
"profile": "Profile",
"avatar": "Avatar",
"head": "Head",
"showHelm": "Show Helm",
"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",
"items" : "Items",
"weapon" : "Weapon",
"armor" : "armor",
"helm" : "Helm",
"shield" : "shield",
"stats" : "Stats",
"strength" : "Strength",
"defense" : "Defense",
"totalStrength" : "Total Strength",
"totalDefense" : "Total Defense",
"party": "Party",
"createAParty":"Create A Party",
"noPartyText": "You are not in a party. You can either create one and invite friends, or if you want to join an existing party, have them enter:",
"partyName": "Party Name",
"create":"Create",
"userId":"User Id",
"invite":"Invite",
"leave": "Leave",
"invitedTo" : "You're Invited To",
"chat": "Chat",
"inventory": "Inventory",
"eggs": "Eggs",
"noEggs": "You don't have any eggs yet.",
"hatchingPotions": "Hatching Potions",
"noHatchingPotions": "You don't have any hatching potions yet.",
"hatchYourEgg" : "Hatch Your Egg",
"whichHatchingPotion1" : "Which hatching potion will you pour on your",
"whichHatchingPotion2" : "egg?",
"pour" : "pour",
"rarePets" : "Rare Pets",
"market": "Market",
"stable": "Stable",
"petsFound":"Pets Found",
"rarePets": "Rare Pets",
"tavern": "Tavern",
"restButton":"Rest In The Inn",
"checkoutButton": "Check Out Of Inn",
"tavernTalkTitle":"Tavern Talk & LFG",
"tavernRestingInfo" : "Whilst resting your dailies are saved and aren't effected by day turn-over. Whether you check out tomorrow or in a weeks time you'll continue in the same state as when you checked in.",
"resources" : "Resources",
"LFGPosts" : "LGF Posts",
"tutorials" : "Tutorials",
"achievements":"Achievements",
"achievementUnlocked" : "Achievement Unlocked!",
"npcText" : "Backed the Kickstarter project at the maximum level!",
"contribName" : "Contributor",
"contribText" : "Has contributed to HabitRPG (code, design, pixel art, legal advice, docs, etc). Want this badge? Fix a bug",
"kickstartName1" : "Kickstarter Backer - ",
"kickstartName2" : "Tier",
"kickstartText" : "Backed the Kickstarter Project",
"streakName" : " Streak Achievement(s)",
"streakText1" : "Has performed ",
"stureakText2" : " 21-day streaks on Dailies",
"origUserName" : "Original User",
"origUserText" : "Goes way back to the Habit's days of yore (bless them for soldiering through bugs!)",
"ultimGearName" : "Ultimate Gear",
"ultimGearText" : "Has attained the maximum weapon and armor set",
"ultimGearUnlocked" : "You have earned the 'Ultimate Gear' Achievement for upgrading to the maximum gear set!",
"beastMastName" : "Beast Master",
"beastMastText" : "Has found all 90 pets (insanely difficult, give this user props!)",
"beastMastUnlocked" : "You have earned the 'Beast Master' Achievement for collecting all the pets!",
"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",
"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",
"deleteText2":" DELETE ",
"deleteText3":"into the text-box",
"API":"API",
"APIText":"Copy these for use in third party applications.",
"APIToken":"Api Token",
"_commentitems": "ITEMS",
"_commentitemsweps": "WEAPONS",
"sword0name" : "Training Sword",
"sword1Name" : "Sword",
"sword1Text" : "Increases experience gain by 3%.",
"sword2Name" : "Axe",
"sword2Text" : "Increases experience gain by 6%.",
"sword3Name" : "Morningstar",
"sword3Text" : "Increases experience gain by 9%.",
"sword4Name" : "Blue Sword",
"sword4Text" : "Increases experience gain by 12%.",
"sword5Name" : "Red Sword",
"sword5Text" : "Increases experience gain by 15%.",
"sword6Name" : "Golden Sword",
"sword6Text" : "Increases experience gain by 18%.",
"_commentitemsarmor": "ARMOR",
"armor0Name" : "Cloth Armor",
"armor1Name" : "Leather Armor" ,
"armor1Text": "Decreases HP Loss by 4%",
"armor2Name" : "Chain Mail",
"armor2Text": "Decreases HP Loss by 6%",
"armor3Name" : "Plate Mail",
"armor3Text": "Decreases HP Loss by 7%",
"armor4Name" : "Red Armor",
"armor4Text": "Decreases HP Loss by 8%",
"armor5Name" : "Golden Armor",
"armor5Text": "Decreases HP Loss by 10%",
"_commentitemshead" : "HEADGEAR",
"head0Name" : "No Helm",
"head1Name" : "Leather Helm" ,
"head1Text": "Decreases HP loss by 2%",
"head2Name" : "Chain Coif",
"head2Text": "Decreases HP loss by 3%",
"head3Name" : "Plate Helm",
"head3Text": "Decreases HP loss by 4%",
"head4Name" : "Red Helm",
"head4Text": "Decreases HP loss by 5%",
"head5Name" : "Golden Helm",
"head5Text": "Decreases HP loss by 6%",
"_commentitemsshield" : "SHIELDS",
"sheild0Name" : "No Shield",
"sheild1Name" : "Wooden Shield",
"sheild1Text": "Decreases HP loss by 3%",
"sheild2Name" : "Buckler",
"sheild2Text": "Decreases HP loss by 4%",
"sheild3Name" : "Reinforced Shield",
"sheild3Text": "Decreases HP loss by 5%",
"sheild4Name" : "Red Shield",
"sheild4Text": "Decreases HP loss by 7%",
"sheild5Name" : "Golden Shield",
"sheild5Text": "Decreases HP loss by 8%",
"_commentitemsother" : "OTHER ITEMS",
"healthPotionName" : "Health Potion",
"healthPotionNotes" : "Recover 15 HP Instantly",
"rerollName" : "Fortify Potion",
"rerollNotes" : "Resets your task values back to yellow. Useful when everything's red and it's hard to stay alive.",
"rerollModelHeader" : "Reset Your Tasks",
"rerollModelText1" : "Highly discouraged because red tasks provide good incentive to improve",
"rerollModelText2" : "read more",
"rerollModelText3" : "However, this becomes necessary after long bouts of bad habits.",
"_commentitemspeteggs": "PET EGGS",
"wolfEgg": "Wolf Cub",
"tigerEgg": "Tiger Cub",
"pandaEgg": "Panda Cub",
"lionEgg": "Lion Cub",
"foxEgg": "Fox",
"pigEgg": "Flying Pig",
"dragonEgg": "Dragon",
"cactusEgg": "Cactus",
"bearEgg": "Bear Cub",
"_commentitemshatchingpotions": "HATCHING POTIONS",
"basePotName": "Base",
"basePotText" : "Hatches your pet into its base form.",
"whitePotName": "White",
"whitePotText" : "Hatches your pet into its white form.",
"desertPotName": "Desert",
"desertPotText" : "Hatches your pet into its desert form.",
"redPotName": "Red",
"redPotText" : "Hatches your pet into its red form.",
"shadePotName": "Shadepot",
"shadePotText" : "Hatches your pet into its shade form.",
"skeletonPotName": "Skeleton",
"skeletonPotText" : "Hatches your pet into its skeleton form.",
"zombiePotName": "Zombie",
"zombiePotText" : "Hatches your pet into its zombie form.",
"cottonPinkPotName": "Cotton Candy Pink",
"cottonPinkPotText" : "Hatches your pet into its cotton candy pink form.",
"cottonBluePotName": "Cotton Candy Blue",
"cottonBluePotText" : "Hatches your pet into its cotton candy blue form.",
"goldenPotName": "Golden",
"goldenPotText" : "Hatches your pet into its golden form.",
"_commentnpcsandchars": "NPCS & CHARACTERS",
"_commentNPCS" : "NPCS",
"NPCBaileyText1" : "the Town Crier here! Announcing new stuff!",
"NPCAugustinText1" : "Welcome to the Market! I'm the merchant;",
"NPCAugustinText2" : "Dying to get that particular pet you're after, but don't want to wait for it to drop? Buy it here!",
"NPCJohanssonText1" : "Welcome to the Tavern! I'm",
"NPCJohanssonText2": "the bar keep. If you want to rest a while (going on vacation? sudden illness?), I'll set you up at the inn - dailies won't hurt you while you're resting. Stay a while & meet the locals.",
"NPCMelchiorText1" : "",
"NPCBowenText1" : "",
"NPCBochText1" : "",
"_commentdeathstuff" : "DEATH",
"deathTitle" : "You Died!",
"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",
"outOfGems" : "Out Of Gems",
"buyMoreGems" : "Buy More Gems",
"notEnoughGems" : "Not enough Gems",
"petsOutOfGems" : "Oops, out of Gems, which are used to buy special items! Habit is an open source project, and can use all the help it can get - buy more Gems to receive this pet, and consider it a donation to the contributors",
"gemsWhatFor" : "Used for buying special items (reroll, eggs, hatching potions, etc). You'll need to unlock those features before being able to use Gems.",
"_commentfooter": "FOOTER",
"footerCompany" : "Company",
"companyAbout" : "About",
"companyBlog" : "Blog",
"companyTeam" : "Team",
"companyExtensions" : "Extensions",
"companyFAQ" : "FAQ",
"footerLegal" : "Legal",
"legalPrivacy" : "Privacy",
"legalTerms" : "Terms",
"footerCommunity" : "Community",
"communityBugs" : "Submit Bugs",
"communityFeatures" : "Request Features",
"communityExtensions" : "Add-ons / Extensions",
"communityForum" : "Community Forum",
"footerSocial" : "Social",
"_commentmisc": "MISC & GLOBAL",
"removeAds": "Remove Ads",
"whyAds": "Why Ads?",
"whyAdsContent1": "Habit is an open source project, and can use all the help it can get - consider this a donation to the contributors. You also get 20 Gems from the purchase, which you can use to buy special items.",
"whyAdsContent2": "'Hey, I backed the Kickstarter!' - follow",
"whyAdsContent3": "these instructions",
"_commentbuttons": "BUTTONS",
"submit":"Submit",
"close":"Close",
"saveAndClose": "Save & Close",
"cancel":"Cancel",
"ok" : "Ok",
"add" : "Add",
"undo" : "Undo",
"continue" : "Continue",
"accept" : "Accept",
"reject" : "Reject",
"or" : "Or",
"_commenttimestamps":"TIME STAMPS",
"justNow":"Just now",
"aMinuteAgo":"A minute ago",
"minutesAgo":"minutes ago",
"anHourAgo": "An hour ago",
"hoursAgo": "hours ago",
"yesterday":"Yesterday",
"daysAgo":"days ago"
}

View file

@ -1,417 +1,6 @@
{
"languageName": "English",
"stringNotFound": "String not found.",
"_commentfrontpage":"HABITRPG FRONT PAGE",
"synopsis" : "A habit building program which treats your life like a Role Playing Game. Level up as you succeed, lose HP as you fail, earn money to buy weapons and armor.",
"playButton" : "Play",
"_commenttut": "TUTORIAL/TOUR",
"endTourButton": "End Tour",
"nextButton" : "Next",
"prevButton" : "Prev",
"tour1Title" : "Welcome to HabitRPG",
"tour1Text" : "Welcome to HabitRPG, a habit-tracker which treats your goals like a Role Playing Game.",
"tour2Title" : "Habits",
"tour2Text" : "Habits are good or bad goals that you constantly track.",
"tour3Title" : "Dailies",
"tour3Text" : "Dailies are goals that you want to complete once a day.",
"tour4Title" : "Todos",
"tour4Text" : "Todos are one-off goals which need to be completed eventually. ",
"tour5Title" : "Rewards",
"tour5Text" : "As you complete goals, you earn gold to buy rewards. Buy them liberally - rewards are integral in forming good habits. ",
"tour6Title" : "Hover over comments",
"tour6Text" : "Different task-types have special properties. Hover over each task's comment for more information. When you're ready to get started, delete the existing tasks and add your own.",
"_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!",
"_commentdefaulttags" : "DEFAULT TAGS",
"morning" : "morning",
"afternoon" : "afternoon",
"evening" : "evening",
"_commenthead": "HEADER",
"health": "Health",
"experience": "Experience",
"history": "History",
"anonymous": "Anonymous",
"level": "Level",
"tasks": "Tasks",
"loginAndReg" : "Login / Register",
"loginFacebookAlt" : "Login / Register with Facebook",
"login" : "Login",
"register" : "Register",
"options": "Options",
"logout": "Logout",
"_commentnotifcations" : "NOTIFICATIONS",
"partyNotification" : "New Party Messages",
"_commenttaskview": "TASK VIEW",
"habits": "Habits",
"Habits": "Habits",
"newHabit": "New Habit",
"edit": "Edit",
"text": "Text",
"extraNotes": "Extra Notes",
"directions/Actions": "Directions/Actions",
"advancedOptions": "Advanced Options",
"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": "Easy",
"medium": "Medium",
"hard": "Hard",
"delete": "Delete",
"progress": "Progress",
"score": "Score",
"dailies": "Dailies",
"Dailies": "Dailies",
"newDaily": "New Daily",
"repeat": "Repeat",
"Su": "Su",
"M": "M",
"T": "T",
"We": "W",
"Th": "Th",
"F": "F",
"S": "S",
"todos": "To-Dos",
"Todos": "To-Dos",
"newTodo": "New To-Do",
"dueDate": "Due Date",
"remaining": "Remaining",
"complete": "Complete",
"rewards": "Rewards",
"Rewards": "Rewards",
"gold": "Gold",
"silver": "Silver",
"newReward": "New Reward",
"price": "Price",
"tags" : "Tags",
"editTags" : "Edit Tags",
"newTag" : "New Tag",
"clearFilters" : "Clear Filters",
"_commentdrops" : "DROP SYSTEM",
"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 item has dropped",
"_commentoptionsview": "OPTIONS VIEW",
"profile": "Profile",
"avatar": "Avatar",
"head": "Head",
"showHelm": "Show Helm",
"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",
"items" : "Items",
"weapon" : "Weapon",
"armor" : "armor",
"helm" : "Helm",
"shield" : "shield",
"stats" : "Stats",
"strength" : "Strength",
"defense" : "Defense",
"totalStrength" : "Total Strength",
"totalDefense" : "Total Defense",
"party": "Party",
"createAParty":"Create A Party",
"noPartyText": "You are not in a party. You can either create one and invite friends, or if you want to join an existing party, have them enter:",
"partyName": "Party Name",
"create":"Create",
"userId":"User Id",
"invite":"Invite",
"leave": "Leave",
"invitedTo" : "You're Invited To",
"chat": "Chat",
"inventory": "Inventory",
"eggs": "Eggs",
"noEggs": "You don't have any eggs yet.",
"hatchingPotions": "Hatching Potions",
"noHatchingPotions": "You don't have any hatching potions yet.",
"hatchYourEgg" : "Hatch Your Egg",
"whichHatchingPotion1" : "Which hatching potion will you pour on your",
"whichHatchingPotion2" : "egg?",
"pour" : "pour",
"rarePets" : "Rare Pets",
"market": "Market",
"stable": "Stable",
"petsFound":"Pets Found",
"rarePets": "Rare Pets",
"tavern": "Tavern",
"restButton":"Rest In The Inn",
"checkoutButton": "Check Out Of Inn",
"tavernTalkTitle":"Tavern Talk & LFG",
"tavernRestingInfo" : "Whilst resting your dailies are saved and aren't effected by day turn-over. Whether you check out tomorrow or in a weeks time you'll continue in the same state as when you checked in.",
"resources" : "Resources",
"LFGPosts" : "LGF Posts",
"tutorials" : "Tutorials",
"achievements":"Achievements",
"achievementUnlocked" : "Achievement Unlocked!",
"npcText" : "Backed the Kickstarter project at the maximum level!",
"contribName" : "Contributor",
"contribText" : "Has contributed to HabitRPG (code, design, pixel art, legal advice, docs, etc). Want this badge? Fix a bug",
"kickstartName1" : "Kickstarter Backer - ",
"kickstartName2" : "Tier",
"kickstartText" : "Backed the Kickstarter Project",
"streakName" : " Streak Achievement(s)",
"streakText1" : "Has performed ",
"stureakText2" : " 21-day streaks on Dailies",
"origUserName" : "Original User",
"origUserText" : "Goes way back to the Habit's days of yore (bless them for soldiering through bugs!)",
"ultimGearName" : "Ultimate Gear",
"ultimGearText" : "Has attained the maximum weapon and armor set",
"ultimGearUnlocked" : "You have earned the 'Ultimate Gear' Achievement for upgrading to the maximum gear set!",
"beastMastName" : "Beast Master",
"beastMastText" : "Has found all 90 pets (insanely difficult, give this user props!)",
"beastMastUnlocked" : "You have earned the 'Beast Master' Achievement for collecting all the pets!",
"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",
"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",
"deleteText2":" DELETE ",
"deleteText3":"into the text-box",
"API":"API",
"APIText":"Copy these for use in third party applications.",
"APIToken":"Api Token",
"_commentitems": "ITEMS",
"_commentitemsweps": "WEAPONS",
"sword0name" : "Training Sword",
"sword1Name" : "Sword",
"sword1Text" : "Increases experience gain by 3%.",
"sword2Name" : "Axe",
"sword2Text" : "Increases experience gain by 6%.",
"sword3Name" : "Morningstar",
"sword3Text" : "Increases experience gain by 9%.",
"sword4Name" : "Blue Sword",
"sword4Text" : "Increases experience gain by 12%.",
"sword5Name" : "Red Sword",
"sword5Text" : "Increases experience gain by 15%.",
"sword6Name" : "Golden Sword",
"sword6Text" : "Increases experience gain by 18%.",
"_commentitemsarmor": "ARMOR",
"armor0Name" : "Cloth Armor",
"armor1Name" : "Leather Armor" ,
"armor1Text": "Decreases HP Loss by 4%",
"armor2Name" : "Chain Mail",
"armor2Text": "Decreases HP Loss by 6%",
"armor3Name" : "Plate Mail",
"armor3Text": "Decreases HP Loss by 7%",
"armor4Name" : "Red Armor",
"armor4Text": "Decreases HP Loss by 8%",
"armor5Name" : "Golden Armor",
"armor5Text": "Decreases HP Loss by 10%",
"_commentitemshead" : "HEADGEAR",
"head0Name" : "No Helm",
"head1Name" : "Leather Helm" ,
"head1Text": "Decreases HP loss by 2%",
"head2Name" : "Chain Coif",
"head2Text": "Decreases HP loss by 3%",
"head3Name" : "Plate Helm",
"head3Text": "Decreases HP loss by 4%",
"head4Name" : "Red Helm",
"head4Text": "Decreases HP loss by 5%",
"head5Name" : "Golden Helm",
"head5Text": "Decreases HP loss by 6%",
"_commentitemsshield" : "SHIELDS",
"sheild0Name" : "No Shield",
"sheild1Name" : "Wooden Shield",
"sheild1Text": "Decreases HP loss by 3%",
"sheild2Name" : "Buckler",
"sheild2Text": "Decreases HP loss by 4%",
"sheild3Name" : "Reinforced Shield",
"sheild3Text": "Decreases HP loss by 5%",
"sheild4Name" : "Red Shield",
"sheild4Text": "Decreases HP loss by 7%",
"sheild5Name" : "Golden Shield",
"sheild5Text": "Decreases HP loss by 8%",
"_commentitemsother" : "OTHER ITEMS",
"healthPotionName" : "Health Potion",
"healthPotionNotes" : "Recover 15 HP Instantly",
"rerollName" : "Fortify Potion",
"rerollNotes" : "Resets your task values back to yellow. Useful when everything's red and it's hard to stay alive.",
"rerollModelHeader" : "Reset Your Tasks",
"rerollModelText1" : "Highly discouraged because red tasks provide good incentive to improve",
"rerollModelText2" : "read more",
"rerollModelText3" : "However, this becomes necessary after long bouts of bad habits.",
"_commentitemspeteggs": "PET EGGS",
"wolfEgg": "Wolf Cub",
"tigerEgg": "Tiger Cub",
"pandaEgg": "Panda Cub",
"lionEgg": "Lion Cub",
"foxEgg": "Fox",
"pigEgg": "Flying Pig",
"dragonEgg": "Dragon",
"cactusEgg": "Cactus",
"bearEgg": "Bear Cub",
"_commentitemshatchingpotions": "HATCHING POTIONS",
"basePotName": "Base",
"basePotText" : "Hatches your pet into its base form.",
"whitePotName": "White",
"whitePotText" : "Hatches your pet into its white form.",
"desertPotName": "Desert",
"desertPotText" : "Hatches your pet into its desert form.",
"redPotName": "Red",
"redPotText" : "Hatches your pet into its red form.",
"shadePotName": "Shadepot",
"shadePotText" : "Hatches your pet into its shade form.",
"skeletonPotName": "Skeleton",
"skeletonPotText" : "Hatches your pet into its skeleton form.",
"zombiePotName": "Zombie",
"zombiePotText" : "Hatches your pet into its zombie form.",
"cottonPinkPotName": "Cotton Candy Pink",
"cottonPinkPotText" : "Hatches your pet into its cotton candy pink form.",
"cottonBluePotName": "Cotton Candy Blue",
"cottonBluePotText" : "Hatches your pet into its cotton candy blue form.",
"goldenPotName": "Golden",
"goldenPotText" : "Hatches your pet into its golden form.",
"_commentnpcsandchars": "NPCS & CHARACTERS",
"_commentNPCS" : "NPCS",
"NPCBaileyText1" : "the Town Crier here! Announcing new stuff!",
"NPCAugustinText1" : "Welcome to the Market! I'm the merchant;",
"NPCAugustinText2" : "Dying to get that particular pet you're after, but don't want to wait for it to drop? Buy it here!",
"NPCJohanssonText1" : "Welcome to the Tavern! I'm",
"NPCJohanssonText2": "the bar keep. If you want to rest a while (going on vacation? sudden illness?), I'll set you up at the inn - dailies won't hurt you while you're resting. Stay a while & meet the locals.",
"NPCMelchiorText1" : "",
"NPCBowenText1" : "",
"NPCBochText1" : "",
"_commentdeathstuff" : "DEATH",
"deathTitle" : "You Died!",
"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",
"outOfGems" : "Out Of Gems",
"buyMoreGems" : "Buy More Gems",
"notEnoughGems" : "Not enough Gems",
"petsOutOfGems" : "Oops, out of Gems, which are used to buy special items! Habit is an open source project, and can use all the help it can get - buy more Gems to receive this pet, and consider it a donation to the contributors",
"gemsWhatFor" : "Used for buying special items (reroll, eggs, hatching potions, etc). You'll need to unlock those features before being able to use Gems.",
"_commentfooter": "FOOTER",
"footerCompany" : "Company",
"companyAbout" : "About",
"companyBlog" : "Blog",
"companyTeam" : "Team",
"companyExtensions" : "Extensions",
"companyFAQ" : "FAQ",
"footerLegal" : "Legal",
"legalPrivacy" : "Privacy",
"legalTerms" : "Terms",
"footerCommunity" : "Community",
"communityBugs" : "Submit Bugs",
"communityFeatures" : "Request Features",
"communityExtensions" : "Add-ons / Extensions",
"communityForum" : "Community Forum",
"footerSocial" : "Social",
"_commentmisc": "MISC & GLOBAL",
"removeAds": "Remove Ads",
"whyAds": "Why Ads?",
"whyAdsContent1": "Habit is an open source project, and can use all the help it can get - consider this a donation to the contributors. You also get 20 Gems from the purchase, which you can use to buy special items.",
"whyAdsContent2": "'Hey, I backed the Kickstarter!' - follow",
"whyAdsContent3": "these instructions",
"_commentbuttons": "BUTTONS",
"submit":"Submit",
"close":"Close",
"saveAndClose": "Save & Close",
"cancel":"Cancel",
"ok" : "Ok",
"add" : "Add",
"undo" : "Undo",
"continue" : "Continue",
"accept" : "Accept",
"reject" : "Reject",
"or" : "Or",
"_commenttimestamps":"TIME STAMPS",
"justNow":"Just now",
"aMinuteAgo":"A minute ago",
"minutesAgo":"minutes ago",
"anHourAgo": "An hour ago",
"hoursAgo": "hours ago",
"yesterday":"Yesterday",
"daysAgo":"days ago"
"files": [
"main.json",
"secondary.json"
]
}

417
locales/en/main.json Normal file
View file

@ -0,0 +1,417 @@
{
"languageName": "English",
"stringNotFound": "String not found.",
"_commentfrontpage":"HABITRPG FRONT PAGE",
"synopsis" : "A habit building program which treats your life like a Role Playing Game. Level up as you succeed, lose HP as you fail, earn money to buy weapons and armor.",
"playButton" : "Play",
"_commenttut": "TUTORIAL/TOUR",
"endTourButton": "End Tour",
"nextButton" : "Next",
"prevButton" : "Prev",
"tour1Title" : "Welcome to HabitRPG",
"tour1Text" : "Welcome to HabitRPG, a habit-tracker which treats your goals like a Role Playing Game.",
"tour2Title" : "Habits",
"tour2Text" : "Habits are good or bad goals that you constantly track.",
"tour3Title" : "Dailies",
"tour3Text" : "Dailies are goals that you want to complete once a day.",
"tour4Title" : "Todos",
"tour4Text" : "Todos are one-off goals which need to be completed eventually. ",
"tour5Title" : "Rewards",
"tour5Text" : "As you complete goals, you earn gold to buy rewards. Buy them liberally - rewards are integral in forming good habits. ",
"tour6Title" : "Hover over comments",
"tour6Text" : "Different task-types have special properties. Hover over each task's comment for more information. When you're ready to get started, delete the existing tasks and add your own.",
"_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!",
"_commentdefaulttags" : "DEFAULT TAGS",
"morning" : "morning",
"afternoon" : "afternoon",
"evening" : "evening",
"_commenthead": "HEADER",
"health": "Health",
"experience": "Experience",
"history": "History",
"anonymous": "Anonymous",
"level": "Level",
"tasks": "Tasks",
"loginAndReg" : "Login / Register",
"loginFacebookAlt" : "Login / Register with Facebook",
"login" : "Login",
"register" : "Register",
"options": "Options",
"logout": "Logout",
"_commentnotifcations" : "NOTIFICATIONS",
"partyNotification" : "New Party Messages",
"_commenttaskview": "TASK VIEW",
"habits": "Habits",
"Habits": "Habits",
"newHabit": "New Habit",
"edit": "Edit",
"text": "Text",
"extraNotes": "Extra Notes",
"directions/Actions": "Directions/Actions",
"advancedOptions": "Advanced Options",
"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": "Easy",
"medium": "Medium",
"hard": "Hard",
"delete": "Delete",
"progress": "Progress",
"score": "Score",
"dailies": "Dailies",
"Dailies": "Dailies",
"newDaily": "New Daily",
"repeat": "Repeat",
"Su": "Su",
"M": "M",
"T": "T",
"We": "W",
"Th": "Th",
"F": "F",
"S": "S",
"todos": "To-Dos",
"Todos": "To-Dos",
"newTodo": "New To-Do",
"dueDate": "Due Date",
"remaining": "Remaining",
"complete": "Complete",
"rewards": "Rewards",
"Rewards": "Rewards",
"gold": "Gold",
"silver": "Silver",
"newReward": "New Reward",
"price": "Price",
"tags" : "Tags",
"editTags" : "Edit Tags",
"newTag" : "New Tag",
"clearFilters" : "Clear Filters",
"_commentdrops" : "DROP SYSTEM",
"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 item has dropped",
"_commentoptionsview": "OPTIONS VIEW",
"profile": "Profile",
"avatar": "Avatar",
"head": "Head",
"showHelm": "Show Helm",
"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",
"items" : "Items",
"weapon" : "Weapon",
"armor" : "armor",
"helm" : "Helm",
"shield" : "shield",
"stats" : "Stats",
"strength" : "Strength",
"defense" : "Defense",
"totalStrength" : "Total Strength",
"totalDefense" : "Total Defense",
"party": "Party",
"createAParty":"Create A Party",
"noPartyText": "You are not in a party. You can either create one and invite friends, or if you want to join an existing party, have them enter:",
"partyName": "Party Name",
"create":"Create",
"userId":"User Id",
"invite":"Invite",
"leave": "Leave",
"invitedTo" : "You're Invited To",
"chat": "Chat",
"inventory": "Inventory",
"eggs": "Eggs",
"noEggs": "You don't have any eggs yet.",
"hatchingPotions": "Hatching Potions",
"noHatchingPotions": "You don't have any hatching potions yet.",
"hatchYourEgg" : "Hatch Your Egg",
"whichHatchingPotion1" : "Which hatching potion will you pour on your",
"whichHatchingPotion2" : "egg?",
"pour" : "pour",
"rarePets" : "Rare Pets",
"market": "Market",
"stable": "Stable",
"petsFound":"Pets Found",
"rarePets": "Rare Pets",
"tavern": "Tavern",
"restButton":"Rest In The Inn",
"checkoutButton": "Check Out Of Inn",
"tavernTalkTitle":"Tavern Talk & LFG",
"tavernRestingInfo" : "Whilst resting your dailies are saved and aren't effected by day turn-over. Whether you check out tomorrow or in a weeks time you'll continue in the same state as when you checked in.",
"resources" : "Resources",
"LFGPosts" : "LGF Posts",
"tutorials" : "Tutorials",
"achievements":"Achievements",
"achievementUnlocked" : "Achievement Unlocked!",
"npcText" : "Backed the Kickstarter project at the maximum level!",
"contribName" : "Contributor",
"contribText" : "Has contributed to HabitRPG (code, design, pixel art, legal advice, docs, etc). Want this badge? Fix a bug",
"kickstartName1" : "Kickstarter Backer - ",
"kickstartName2" : "Tier",
"kickstartText" : "Backed the Kickstarter Project",
"streakName" : " Streak Achievement(s)",
"streakText1" : "Has performed ",
"stureakText2" : " 21-day streaks on Dailies",
"origUserName" : "Original User",
"origUserText" : "Goes way back to the Habit's days of yore (bless them for soldiering through bugs!)",
"ultimGearName" : "Ultimate Gear",
"ultimGearText" : "Has attained the maximum weapon and armor set",
"ultimGearUnlocked" : "You have earned the 'Ultimate Gear' Achievement for upgrading to the maximum gear set!",
"beastMastName" : "Beast Master",
"beastMastText" : "Has found all 90 pets (insanely difficult, give this user props!)",
"beastMastUnlocked" : "You have earned the 'Beast Master' Achievement for collecting all the pets!",
"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",
"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",
"deleteText2":" DELETE ",
"deleteText3":"into the text-box",
"API":"API",
"APIText":"Copy these for use in third party applications.",
"APIToken":"Api Token",
"_commentitems": "ITEMS",
"_commentitemsweps": "WEAPONS",
"sword0name" : "Training Sword",
"sword1Name" : "Sword",
"sword1Text" : "Increases experience gain by 3%.",
"sword2Name" : "Axe",
"sword2Text" : "Increases experience gain by 6%.",
"sword3Name" : "Morningstar",
"sword3Text" : "Increases experience gain by 9%.",
"sword4Name" : "Blue Sword",
"sword4Text" : "Increases experience gain by 12%.",
"sword5Name" : "Red Sword",
"sword5Text" : "Increases experience gain by 15%.",
"sword6Name" : "Golden Sword",
"sword6Text" : "Increases experience gain by 18%.",
"_commentitemsarmor": "ARMOR",
"armor0Name" : "Cloth Armor",
"armor1Name" : "Leather Armor" ,
"armor1Text": "Decreases HP Loss by 4%",
"armor2Name" : "Chain Mail",
"armor2Text": "Decreases HP Loss by 6%",
"armor3Name" : "Plate Mail",
"armor3Text": "Decreases HP Loss by 7%",
"armor4Name" : "Red Armor",
"armor4Text": "Decreases HP Loss by 8%",
"armor5Name" : "Golden Armor",
"armor5Text": "Decreases HP Loss by 10%",
"_commentitemshead" : "HEADGEAR",
"head0Name" : "No Helm",
"head1Name" : "Leather Helm" ,
"head1Text": "Decreases HP loss by 2%",
"head2Name" : "Chain Coif",
"head2Text": "Decreases HP loss by 3%",
"head3Name" : "Plate Helm",
"head3Text": "Decreases HP loss by 4%",
"head4Name" : "Red Helm",
"head4Text": "Decreases HP loss by 5%",
"head5Name" : "Golden Helm",
"head5Text": "Decreases HP loss by 6%",
"_commentitemsshield" : "SHIELDS",
"sheild0Name" : "No Shield",
"sheild1Name" : "Wooden Shield",
"sheild1Text": "Decreases HP loss by 3%",
"sheild2Name" : "Buckler",
"sheild2Text": "Decreases HP loss by 4%",
"sheild3Name" : "Reinforced Shield",
"sheild3Text": "Decreases HP loss by 5%",
"sheild4Name" : "Red Shield",
"sheild4Text": "Decreases HP loss by 7%",
"sheild5Name" : "Golden Shield",
"sheild5Text": "Decreases HP loss by 8%",
"_commentitemsother" : "OTHER ITEMS",
"healthPotionName" : "Health Potion",
"healthPotionNotes" : "Recover 15 HP Instantly",
"rerollName" : "Fortify Potion",
"rerollNotes" : "Resets your task values back to yellow. Useful when everything's red and it's hard to stay alive.",
"rerollModelHeader" : "Reset Your Tasks",
"rerollModelText1" : "Highly discouraged because red tasks provide good incentive to improve",
"rerollModelText2" : "read more",
"rerollModelText3" : "However, this becomes necessary after long bouts of bad habits.",
"_commentitemspeteggs": "PET EGGS",
"wolfEgg": "Wolf Cub",
"tigerEgg": "Tiger Cub",
"pandaEgg": "Panda Cub",
"lionEgg": "Lion Cub",
"foxEgg": "Fox",
"pigEgg": "Flying Pig",
"dragonEgg": "Dragon",
"cactusEgg": "Cactus",
"bearEgg": "Bear Cub",
"_commentitemshatchingpotions": "HATCHING POTIONS",
"basePotName": "Base",
"basePotText" : "Hatches your pet into its base form.",
"whitePotName": "White",
"whitePotText" : "Hatches your pet into its white form.",
"desertPotName": "Desert",
"desertPotText" : "Hatches your pet into its desert form.",
"redPotName": "Red",
"redPotText" : "Hatches your pet into its red form.",
"shadePotName": "Shadepot",
"shadePotText" : "Hatches your pet into its shade form.",
"skeletonPotName": "Skeleton",
"skeletonPotText" : "Hatches your pet into its skeleton form.",
"zombiePotName": "Zombie",
"zombiePotText" : "Hatches your pet into its zombie form.",
"cottonPinkPotName": "Cotton Candy Pink",
"cottonPinkPotText" : "Hatches your pet into its cotton candy pink form.",
"cottonBluePotName": "Cotton Candy Blue",
"cottonBluePotText" : "Hatches your pet into its cotton candy blue form.",
"goldenPotName": "Golden",
"goldenPotText" : "Hatches your pet into its golden form.",
"_commentnpcsandchars": "NPCS & CHARACTERS",
"_commentNPCS" : "NPCS",
"NPCBaileyText1" : "the Town Crier here! Announcing new stuff!",
"NPCAugustinText1" : "Welcome to the Market! I'm the merchant;",
"NPCAugustinText2" : "Dying to get that particular pet you're after, but don't want to wait for it to drop? Buy it here!",
"NPCJohanssonText1" : "Welcome to the Tavern! I'm",
"NPCJohanssonText2": "the bar keep. If you want to rest a while (going on vacation? sudden illness?), I'll set you up at the inn - dailies won't hurt you while you're resting. Stay a while & meet the locals.",
"NPCMelchiorText1" : "",
"NPCBowenText1" : "",
"NPCBochText1" : "",
"_commentdeathstuff" : "DEATH",
"deathTitle" : "You Died!",
"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",
"outOfGems" : "Out Of Gems",
"buyMoreGems" : "Buy More Gems",
"notEnoughGems" : "Not enough Gems",
"petsOutOfGems" : "Oops, out of Gems, which are used to buy special items! Habit is an open source project, and can use all the help it can get - buy more Gems to receive this pet, and consider it a donation to the contributors",
"gemsWhatFor" : "Used for buying special items (reroll, eggs, hatching potions, etc). You'll need to unlock those features before being able to use Gems.",
"_commentfooter": "FOOTER",
"footerCompany" : "Company",
"companyAbout" : "About",
"companyBlog" : "Blog",
"companyTeam" : "Team",
"companyExtensions" : "Extensions",
"companyFAQ" : "FAQ",
"footerLegal" : "Legal",
"legalPrivacy" : "Privacy",
"legalTerms" : "Terms",
"footerCommunity" : "Community",
"communityBugs" : "Submit Bugs",
"communityFeatures" : "Request Features",
"communityExtensions" : "Add-ons / Extensions",
"communityForum" : "Community Forum",
"footerSocial" : "Social",
"_commentmisc": "MISC & GLOBAL",
"removeAds": "Remove Ads",
"whyAds": "Why Ads?",
"whyAdsContent1": "Habit is an open source project, and can use all the help it can get - consider this a donation to the contributors. You also get 20 Gems from the purchase, which you can use to buy special items.",
"whyAdsContent2": "'Hey, I backed the Kickstarter!' - follow",
"whyAdsContent3": "these instructions",
"_commentbuttons": "BUTTONS",
"submit":"Submit",
"close":"Close",
"saveAndClose": "Save & Close",
"cancel":"Cancel",
"ok" : "Ok",
"add" : "Add",
"undo" : "Undo",
"continue" : "Continue",
"accept" : "Accept",
"reject" : "Reject",
"or" : "Or",
"_commenttimestamps":"TIME STAMPS",
"justNow":"Just now",
"aMinuteAgo":"A minute ago",
"minutesAgo":"minutes ago",
"anHourAgo": "An hour ago",
"hoursAgo": "hours ago",
"yesterday":"Yesterday",
"daysAgo":"days ago"
}

View file

@ -0,0 +1,3 @@
{
"secondaryString": "an example"
}

View file

@ -28,6 +28,8 @@ xpColor = #DCC0FB
xpText = #635673
deathColor = #4E4E4E
deathText = #ABABAB
mpColor = #c7d3e9
mpText = #003aa1
borderDarken = 20%
// alert styles
@ -57,6 +59,11 @@ borderDarken = 20%
border-color: deathColor
color: deathText
.alert-mp
background-color: mpColor
border-color: darken(mpColor,borderDarken)
color: mpText
// alert icons
.icon-gold

View file

@ -15,12 +15,12 @@ future re: pets and whatnot, this is just temporary.
width: 10em
max-width: 10em
margin: 0 // need this b/c of bootstrap, remove or reset later
padding: 0 // push down the sprite
position: relative
cursor: pointer
background: #f5f5f5
transition: padding 0.13s ease-out, border 0.25s ease-out, background 0.25s ease-out
transition: border 0.25s ease-out, background 0.25s ease-out//, padding 0.13s ease-out
outline: 1px solid rgba(0,0,0,0.1)
// padding: 0 // push down the sprite
// the hero's info frame
.herobox:after
@ -74,12 +74,12 @@ future re: pets and whatnot, this is just temporary.
background: desaturate(lighten($better, 30%), 10%)
&:after
opacity: 1
.herobox.hasPet
/* .herobox.hasPet
&:hover, &:focus
padding-top: 3.25em
.herobox:not(.hasPet)
&:hover, &:focus
padding-top: 2.5em
padding-top: 2.5em */
// positioning the sprites, etc

View file

@ -70,6 +70,8 @@
li
border:0
padding-top:0px
padding-bottom:0px
// Name tags
.label-contributor-1, .label-contributor-2

View file

@ -119,6 +119,11 @@ for $stage in $stages
line-height: 1.4
word-wrap: break-word
span.emoji
width:1.5em
height:1.5em
background-size:1.5em
// task due date (for to-dos)
.task-date
font-size: 70%

View file

@ -31,6 +31,13 @@ habitrpg.controller('NotificationCtrl',
}
});
$rootScope.$watch('user.stats.mp', function(after,before) {
if (after == before) return;
if (User.user.stats.lvl == 0) return;
var mana = after - before;
Notification.mp(mana);
});
$rootScope.$watch('user._tmp.drop', function(after, before){
// won't work when getting the same item twice?
if (after == before || !after) return;
@ -41,7 +48,7 @@ habitrpg.controller('NotificationCtrl',
User.user.items[type][after.key] = 0;
}
User.user.items[type][after.key]++;
$rootScope.modals.drop = true;
Notification.text(User.user._tmp.drop.dialog);
});
$rootScope.$watch('user.achievements.streak', function(after, before){

View file

@ -3,6 +3,7 @@
habitrpg.controller("UserCtrl", ['$rootScope', '$scope', '$location', 'User', '$http', '$state', 'Guide',
function($rootScope, $scope, $location, User, $http, $state, Guide) {
$scope.profile = User.user;
$scope.profile.petCount = $rootScope.Shared.countPets(null, $scope.profile.items.pets);
$scope.hideUserAvatar = function() {
$(".userAvatar").hide();
};

View file

@ -9,3 +9,9 @@ angular.module('habitrpg')
return Math.floor((gp - Math.floor(gp))*100);
}
})
.filter('completedFilter', function(){
return function(tasks,_showCompleted) {
if (!tasks[0] || tasks[0].type != 'todo') return tasks;
return _.where(tasks, {completed:!!_showCompleted});
}
})

View file

@ -16,6 +16,7 @@ angular.module('groupServices', ['ngResource']).
join: {method: "POST", url: API_URL + '/api/v2/groups/:gid/join'},
leave: {method: "POST", url: API_URL + '/api/v2/groups/:gid/leave'},
invite: {method: "POST", url: API_URL + '/api/v2/groups/:gid/invite'},
removeMember: {method: "POST", url: API_URL + '/api/v2/groups/:gid/removeMember'},
questAccept: {method: "POST", url: API_URL + '/api/v2/groups/:gid/questAccept'},
questReject: {method: "POST", url: API_URL + '/api/v2/groups/:gid/questReject'},
questAbort: {method: "POST", url: API_URL + '/api/v2/groups/:gid/questAbort'}

View file

@ -65,6 +65,9 @@ angular.module("notificationServices", [])
},
error: function(error){
growl("<i class='icon-exclamation-sign'></i> " + error, "error");
},
mp: function(val) {
growl("<i class='icon-fire'></i> " + sign(val) + " " + round(val) + " MP", 'mp');
}
};
}

View file

@ -1,28 +0,0 @@
/* Load nconf and define default configuration values if config.json or ENV vars are not found*/
var conf = require("nconf");
var path = require("path");
conf.argv()
.env()
//.file('defaults', path.join(path.resolve(__dirname, '../config.json.example')))
.file('user', path.join(path.resolve(__dirname, '../config.json')));
/*
var agent;
if (process.env.NODE_ENV === 'development') {
// Follow these instructions for profiling / debugging leaks
// * https://developers.google.com/chrome-developer-tools/docs/heap-profiling
// * https://developers.google.com/chrome-developer-tools/docs/memory-analysis-101
agent = require('webkit-devtools-agent');
console.log("To debug memory leaks:" +
"\n\t(1) Run `kill -SIGUSR2 " + process.pid + "`" +
"\n\t(2) open http://c4milo.github.com/node-webkit-agent/21.0.1180.57/inspector.html?host=localhost:1337&page=0");
}
*/
if (conf.get('NODE_ENV') === "development") {
Error.stackTraceLimit = Infinity;
}

View file

@ -106,20 +106,22 @@ api.create = function(req, res){
if (+req.body.prize > 0) {
waterfall.push(function(cb){
var groupBalance = ((group.balance && group.leader==user._id) ? group.balance : 0);
if (req.body.prize > (user.balance*4 + groupBalance*4))
return cb("Challenge.prize > (your gems + group balance). Purchase more gems or lower prize amount.s")
var prizeCost = req.body.prize/4; // I really should have stored user.balance as gems rather than dollars... stupid...
if (prizeCost > user.balance + groupBalance)
return cb("You can't afford this prize. Purchase more gems or lower the prize amount.")
var net = req.body.prize/4; // I really should have stored user.balance as gems rather than dollars... stupid...
// user is group leader, and group has balance. Subtract from that first, then take the rest from user
if (groupBalance > 0) {
group.balance -= net;
if (group.balance < 0) {
net = Math.abs(group.balance);
group.balance = 0;
}
}
user.balance -= net;
if (groupBalance >= prizeCost) {
// Group pays for all of prize
group.balance -= prizeCost;
} else if (groupBalance > 0) {
// User pays remainder of prize cost after group
var remainder = prizeCost - group.balance;
group.balance = 0;
user.balance -= remainder;
} else {
// User pays for all of prize
user.balance -= prizeCost;
}
cb(null)
});
}

View file

@ -248,6 +248,11 @@ api.join = function(req, res) {
if (group.type == 'party' && group._id == (user.invitations && user.invitations.party && user.invitations.party.id)) {
user.invitations.party = undefined;
user.save();
// invite new user to pending quest
if (group.quest.key && !group.quest.active) {
group.quest.members[user._id] = undefined;
group.markModified('quest.members');
}
}
else if (group.type == 'guild' && user.invitations && user.invitations.guilds) {
var i = _.findIndex(user.invitations.guilds, {id:group._id});
@ -278,11 +283,25 @@ api.join = function(req, res) {
api.leave = function(req, res, next) {
var user = res.locals.user,
group = res.locals.group;
Group.update({_id:group._id},{$pull:{members:user._id}}, function(err, saved){
if (err) return res.json(500,{err:err});
async.parallel([
// Remove active quest from user if they're leaving the party
function(cb){
if (group.type != 'party') return cb(null,{},1);
user.party.quest = Group.cleanQuestProgress();
user.save(cb);
},
function(cb){
var update = {$pull:{members:user._id}};
if (group.type == 'party' && group.quest.key){
update['$unset'] = {};
update['$unset']['quest.members.' + user._id] = 1;
}
Group.update({_id:group._id},update,cb);
}
],function(err){
if (err) return next(err);
return res.send(204);
});
})
}
api.invite = function(req, res, next) {
@ -351,7 +370,7 @@ api.removeMember = function(req, res, next){
}
if(_.contains(group.members, uuid)){
Group.update({_id:group._id},{$pull:{members:uuid}}, function(err, saved){
Group.update({_id:group._id},{$pull:{members:uuid},$inc:{memberCount:-1}}, function(err, saved){
if (err) return res.json(500,{err:err});
// Sending an empty 204 because Group.update doesn't return the group
@ -417,16 +436,13 @@ questStart = function(req, res) {
// TODO will this handle appropriately when people leave/join party between quest invite?
_.each(group.members, function(m){
var updates = {$set:{},$inc:{'_v':1}};
if (m == user._id)
if (m == group.quest.leader)
updates['$inc']['items.quests.'+key] = -1;
if (group.quest.members[m] == true) {
updates['$set']['party.quest.key'] = key;
updates['$set']['party.quest.progress'] = {up:0,down:0,collect:collected};
updates['$unset'] = {'party.quest.completed':1};
updates['$set']['party.quest'] = Group.cleanQuestProgress({key:key,progress:{collect:collected}});
questMembers[m] = true;
} else {
updates['$unset'] = {'party.quest.key':1};
updates['$set']['party.quest.progress'] = {};
updates['$set']['party.quest'] = Group.cleanQuestProgress();
}
parallel.push(function(cb2){
User.update({_id:m},updates,cb2);
@ -464,9 +480,10 @@ api.questAccept = function(req, res) {
// Invite everyone. true means "accepted", false="rejected", undefined="pending". Once we click "start quest"
// or everyone has either accepted/rejected, then we store quest key in user object.
_.each(group.members, function(m){
if (m == user._id)
if (m == user._id) {
group.quest.members[m] = true;
else
group.quest.leader = user._id;
} else
group.quest.members[m] = undefined;
});
@ -493,14 +510,23 @@ api.questAbort = function(req, res, next){
var group = res.locals.group;
async.parallel([
function(cb){
User.update({_id:{$in: _.keys(group.quest.members)}},{
$unset: {'party.quest.key':1},
$set: {'party.quest.progress.collect':{}},
$inc: {_v:1}
},cb);
User.update(
{_id:{$in: _.keys(group.quest.members)}},
{
$set: {'party.quest':Group.cleanQuestProgress()},
$inc: {_v:1}
},
{multi:true},
cb);
},
// Refund party leader quest scroll
function(cb){
var update = {$inc:{}};
update['$inc']['items.quests.' + group.quest.key] = 1;
User.update({_id:group.quest.leader}, update, cb);
},
function(cb) {
group.quest = {};
group.quest = {key:null,progress:{},leader:null};
group.markModified('quest');
group.save(cb);
}

View file

@ -71,7 +71,7 @@ api.score = function(req, res, next) {
id: id,
type: req.body && req.body.type,
text: req.body && req.body.text,
notes: (req.body.notes && req.body.notes) || "This task was created by a third-party service. Feel free to edit, it won't harm the connection to that service. Additionally, multiple services may piggy-back off this task."
notes: (req.body && req.body.notes) || "This task was created by a third-party service. Feel free to edit, it won't harm the connection to that service. Additionally, multiple services may piggy-back off this task."
};
task = user.ops.addTask({body:task});
if (task.type === 'daily' || task.type === 'todo')
@ -81,8 +81,11 @@ api.score = function(req, res, next) {
user.save(function(err,saved){
if (err) return res.json(500, {err: err});
// TODO this should be return {_v,task,stats,_tmp}, instead of merging everything togther at top-level response
// However, this is the most commonly used API route, and changing it will mess with all 3rd party consumers. Bad idea :(
res.json(200, _.extend({
delta: delta,
_tmp: user._tmp
}, saved.toJSON().stats));
});
@ -141,6 +144,7 @@ api.getUser = function(req, res, next) {
var user = res.locals.user.toJSON();
user.stats.toNextLevel = shared.tnl(user.stats.lvl);
user.stats.maxHealth = 50;
user.stats.maxMP = res.locals.user._statsComputed.maxMP;
delete user.apiToken;
if (user.auth) {
delete user.auth.hashed_password;
@ -367,7 +371,7 @@ api.cast = function(req, res) {
if (group) {
series.push(function(cb2){
var message = '`<'+user.profile.name+'> casts '+spell.text + (type=='user' ? ' on @'+found.profile.name : ' for the party')+'.`';
var message = '`'+user.profile.name+' casts '+spell.text + (type=='user' ? ' on @'+found.profile.name : ' for the party')+'.`';
group.sendChat(message);
group.save(cb2);
})
@ -389,7 +393,7 @@ api.cast = function(req, res) {
_.each(shared.wrap({}).ops, function(op,k){
if (!api[k]) {
api[k] = function(req, res, next) {
res.locals.user.ops[k](req,function(err){
res.locals.user.ops[k](req,function(err, response){
// If we want to send something other than 500, pass err as {code: 200, message: "Not enough GP"}
if (err) {
if (!err.code) return res.json(500,{err:err});
@ -398,7 +402,7 @@ _.each(shared.wrap({}).ops, function(op,k){
}
res.locals.user.save(function(err){
if (err) return res.json(500,{err:err});
res.send(200);
res.json(200,response);
})
})
}

View file

@ -94,7 +94,11 @@ var getManifestFiles = function(page){
var translations = {};
var loadTranslations = function(locale){
translations[locale] = require(path.join(__dirname, "/../locales/", locale, 'app.json'));
var files = require(path.join(__dirname, "/../locales/", locale, 'app.json')).files;
translations[locale] = {};
_.each(files, function(file){
_.merge(translations[locale], require(path.join(__dirname, "/../locales/", locale, file)));
});
}
// First fetch english so we can merge with missing strings in other languages

View file

@ -36,6 +36,7 @@ var GroupSchema = new Schema({
quest: {
key: String,
active: {type:Boolean, 'default':false},
leader: {type:String, ref:'User'},
progress:{
hp: Number,
collect: {type:Schema.Types.Mixed, 'default':{}} // {feather: 5, ingot: 3}
@ -107,6 +108,23 @@ GroupSchema.methods.sendChat = function(message, user){
group.chat.splice(200);
}
var cleanQuestProgress = function(merge){
var clean = {
key: null,
progress: {
up: 0,
down: 0,
collect: {}
},
completed: null
};
merge = merge || {progress:{}};
_.merge(clean, _.omit(merge,'progress'));
_.merge(clean.progress, merge.progress);
return clean;
}
GroupSchema.statics.cleanQuestProgress = cleanQuestProgress;
// Participants: Grant rewards & achievements, finish quest
GroupSchema.methods.finishQuest = function(quest, cb) {
var group = this;
@ -119,9 +137,7 @@ GroupSchema.methods.finishQuest = function(quest, cb) {
updates['$inc']['stats.gp'] = +quest.drop.gp;
updates['$inc']['stats.exp'] = +quest.drop.exp;
updates['$inc']['_v'] = 1;
updates['$unset'] = {'party.quest.key':undefined};
updates['$set']['party.quest.collect'] = {};
updates['$set']['party.quest.completed'] = questK;
updates['$set']['party.quest'] = cleanQuestProgress({completed:questK});
switch (quest.drop.type) {
case 'gear':
@ -140,10 +156,10 @@ GroupSchema.methods.finishQuest = function(quest, cb) {
updates['$set']['items.mounts.'+dropK] = true;
break;
}
// FIXME this is TERRIBLE practice. Looks like there are circular dependencies in the models, such that `var User` at
// this point is undefined. So we get around that by loading from mongoose only once we get to this point
var members = _.keys(group.quest.members);
group.quest = {};group.markModified('quest');
// FIXME this is TERRIBLE practice. Looks like there are circular dependencies in the models, such that `var User` at
// this point is undefined. So we get around that by loading from mongoose only once we get to this point
mongoose.models.User.update({_id:{$in:members}}, updates, {multi:true}, cb);
}
@ -194,7 +210,7 @@ GroupSchema.statics.bossQuest = function(user, progress, cb) {
var down = progress.down * quest.boss.str; // multiply by boss strength
group.quest.progress.hp -= progress.up;
group.sendChat("`<" + user.profile.name + "> attacks <" + quest.boss.name + "> for " + (progress.up.toFixed(1)) + " damage, <" + quest.boss.name + "> attacks party for " + (down.toFixed(1)) + " damage.`");
group.sendChat("`<" + user.profile.name + "> attacks <" + quest.boss.name + "> for " + (progress.up.toFixed(1)) + " damage, <" + quest.boss.name + "> attacks party for " + Math.abs(down).toFixed(1) + " damage.`");
// Everyone takes damage
var series = [

View file

@ -12,8 +12,7 @@ var server;
var TWO_WEEKS = 1000 * 60 * 60 * 24 * 14;
// ------------ Setup configurations ------------
require('./config');
utils.setupConfig();
// ------------ MongoDB Configuration ------------
mongoose = require('mongoose');
@ -109,27 +108,14 @@ app.use('/api/v2', require('./routes/apiv2').middleware);
app.use('/api/v1', require('./routes/apiv1').middleware);
app.use('/export', require('./routes/dataexport').middleware);
app.use(function(err, req, res, next) {
// when we hit an error, send it to admin as an email. If no ADMIN_EMAIL is present, just send it to yourself (SMTP_USER)
var stack = "["+req.session.userId+"] " + (err.stack ? err.stack : err.message ? err.message : err);
utils.sendEmail({
from: "HabitRPG <" + nconf.get('SMTP_USER') + ">",
to: nconf.get('ADMIN_EMAIL') || nconf.get('SMTP_USER'),
subject: "HabitRPG Error",
text: stack
});
console.error(stack);
var shortMessage = (err.message.length < 200) ? err.message :
err.message.substring(0,100) + err.message.substring(err.message.length-100,err.message.length);
res.json(500,{err:shortMessage}); //res.end(err.message);
});
app.use(utils.errorHandler);
server = http.createServer(app).listen(app.get("port"), function() {
return console.log("Express server listening on port " + app.get("port"));
});
app.use(domainMiddleware({
server: server,
server: server
//killTimeout: 30000,
}))
}));
module.exports = server;

View file

@ -1,6 +1,7 @@
var nodemailer = require('nodemailer');
var nconf = require('nconf');
var crypto = require('crypto');
var path = require("path");
module.exports.sendEmail = function(mailData) {
var smtpTransport = nodemailer.createTransport("SMTP",{
@ -11,11 +12,8 @@ module.exports.sendEmail = function(mailData) {
}
});
smtpTransport.sendMail(mailData, function(error, response){
if(error){
console.log(error);
}else{
console.log("Message sent: " + response.message);
}
if(error) console.log(error);
else console.log("Message sent: " + response.message);
smtpTransport.close(); // shut down the connection pool, no more messages
});
}
@ -32,3 +30,51 @@ module.exports.makeSalt = function() {
var len = 10;
return crypto.randomBytes(Math.ceil(len / 2)).toString('hex').substring(0, len);
}
/**
* Load nconf and define default configuration values if config.json or ENV vars are not found
*/
module.exports.setupConfig = function(){
nconf.argv()
.env()
//.file('defaults', path.join(path.resolve(__dirname, '../config.json.example')))
.file('user', path.join(path.resolve(__dirname, '../config.json')));
// var agent;
// if (process.env.NODE_ENV === 'development') {
// // Follow these instructions for profiling / debugging leaks
// // * https://developers.google.com/chrome-developer-tools/docs/heap-profiling
// // * https://developers.google.com/chrome-developer-tools/docs/memory-analysis-101
// agent = require('webkit-devtools-agent');
// console.log("To debug memory leaks:" +
// "\n\t(1) Run `kill -SIGUSR2 " + process.pid + "`" +
// "\n\t(2) open http://c4milo.github.com/node-webkit-agent/21.0.1180.57/inspector.html?host=localhost:1337&page=0");
// }
if (nconf.get('NODE_ENV') === "development") {
Error.stackTraceLimit = Infinity;
}
};
module.exports.errorHandler = function(err, req, res, next) {
// when we hit an error, send it to admin as an email. If no ADMIN_EMAIL is present, just send it to yourself (SMTP_USER)
var stack = (err.stack ? err.stack : err.message ? err.message : err) +
"\n ----------------------------\n" +
"\n\noriginalUrl: " + req.originalUrl +
"\n\nauth: " + req.headers['x-api-user'] + ' | ' + req.headers['x-api-key'] +
"\n\nheaders: " + JSON.stringify(req.headers) +
"\n\nbody: " + JSON.stringify(req.body);
module.exports.sendEmail({
from: "HabitRPG <" + nconf.get('SMTP_USER') + ">",
to: nconf.get('ADMIN_EMAIL') || nconf.get('SMTP_USER'),
subject: "HabitRPG Error",
text: stack
});
console.error(stack);
var shortMessage = (err.message.length < 200) ? err.message :
err.message.substring(0,100) + err.message.substring(err.message.length-100,err.message.length);
res.json(500,{err:shortMessage}); //res.end(err.message);
}

View file

@ -138,13 +138,14 @@ script(id='partials/options.profile.stats.html', type='text/ng-template')
.border-right(ng-class='user.flags.classSelected && !user.preferences.disableClasses ? "span4" : "span6"')
include ../shared/profiles/stats
.span4.border-right.allocate-stats(ng-if='user.flags.classSelected && !user.preferences.disableClasses')
h4
| {{user.stats.class}}&nbsp;
h3 Character Build
h4 Class:&nbsp;
span {{ {warrior:'Warrior',wizard:'Mage',healer:'Healer',rogue:'Rogue'}[user.stats.class] }}&nbsp;
a.btn.btn-danger.btn-mini(ng-click='changeClass(null)')
| Change Class, Refund Attribute Points&nbsp;
small 3 <span class="Pet_Currency_Gem1x inline-gems"/>
h6 Points: {{user.stats.points}}
h5 Unallocated Attribute Points: {{user.stats.points}}
fieldset.auto-allocate
label.checkbox
input(type='checkbox', ng-model='user.preferences.automaticAllocation', ng-change='set({"preferences.automaticAllocation": user.preferences.automaticAllocation?true: false})')

View file

@ -21,7 +21,7 @@ a.pull-right.gem-wallet(popover-trigger='mouseenter', popover-title='Guild Bank'
hr
.npc_ian.pull-left
p Once all members have either accepted or rejected, the quest begins. Only those that clicked "accept" will be able to participate in the quest and recieve the drops. If members are pending too long (inactive?), you can start without them by clicking "Begin".
button.btn.btn-small.btn-warning(ng-click='party.$questAccept({"force":true})') Begin
button.btn.btn-small.btn-warning(ng-if='!group.quest.leader || group.quest.leader==user._id', ng-click='party.$questAccept({"force":true})') Begin
//-TODO Cancel button
//-TODO Both force-start & cancel should only be available to quest-initiator
@ -71,7 +71,7 @@ a.pull-right.gem-wallet(popover-trigger='mouseenter', popover-title='Guild Bank'
p Only participants can collect items and share in the quest loot. If you die during a quest, you get booted from the quest. If everyone dies once, the quest fails.
button.btn.btn-mini.btn-danger(ng-click='questAbort()') Abort
button.btn.btn-mini.btn-danger(ng-if='!group.quest.leader || group.quest.leader==user._id', ng-click='questAbort()') Abort
// ------ Information -------
.modal.inline-modal

View file

@ -42,7 +42,7 @@
a(target='_blank', href='https://github.com/HabitRPG/habitrpg/issues') Report a Problem
tr
td
a(target='_blank', href='https://trello.com/board/habitrpg/50e5d3684fe3a7266b0036d6') Request a Feature
a(target='_blank', href='https://trello.com/c/8gzGlle8') Request a Feature
tr
td
a(target='_blank', href='http://community.habitrpg.com/forum') Community Forum

View file

@ -34,7 +34,7 @@ footer.footer(ng-controller='FooterCtrl')
li
a(target='_blank', href='https://github.com/HabitRPG/habitrpg/issues') Submit Bug
li
a(target='_blank', href='https://trello.com/board/habitrpg/50e5d3684fe3a7266b0036d6') Request Feature
a(target='_blank', href='https://trello.com/c/8gzGlle8') Request Feature
li
a(target='_blank', href='https://github.com/lefnire/habitrpg/wiki/API') API
li

View file

@ -1,6 +1,6 @@
.modal(ng-if='!user.flags.classSelected && user.stats.lvl >= 10', data-backdrop=true, ng-controller='UserCtrl')
.modal-header
h3 Class System Unlocked!
h3 Choose Your Class!
.modal-body.select-class
p Select your class. Click each class for more information. See <a href="http://habitrpg.wikia.com/wiki/Class_System" target="_blank">Wikia</a> for thorough details.
.row-fluid
@ -10,7 +10,7 @@
.character-sprites
span(class='skin_{{user.preferences.skin}}')
span(class='{{user.preferences.size}}_armor_warrior_5')
span(class='head_base_0')
span(class='head_0')
span(class='hair_base_{{user.preferences.hair.base}}_{{user.preferences.hair.color}}')
span(class='hair_bangs_{{user.preferences.hair.bangs}}_{{user.preferences.hair.color}}')
span(class='hair_beard_{{user.preferences.hair.beard}}_{{user.preferences.hair.color}}')
@ -19,12 +19,12 @@
span(class='shield_warrior_5')
span(class='weapon_warrior_6')
.span3(ng-click='selectedClass = "wizard"')
h5 Wizard
h5 Mage
figure.herobox(ng-class='{"selected-class": selectedClass=="wizard"}')
.character-sprites
span(class='skin_{{user.preferences.skin}}')
span(class='{{user.preferences.size}}_armor_wizard_5')
span(class='head_base_0')
span(class='head_0')
span(class='hair_base_{{user.preferences.hair.base}}_{{user.preferences.hair.color}}')
span(class='hair_bangs_{{user.preferences.hair.bangs}}_{{user.preferences.hair.color}}')
span(class='hair_beard_{{user.preferences.hair.beard}}_{{user.preferences.hair.color}}')
@ -38,7 +38,7 @@
.character-sprites
span(class='skin_{{user.preferences.skin}}')
span(class='{{user.preferences.size}}_armor_rogue_5')
span(class='head_base_0')
span(class='head_0')
span(class='hair_base_{{user.preferences.hair.base}}_{{user.preferences.hair.color}}')
span(class='hair_bangs_{{user.preferences.hair.bangs}}_{{user.preferences.hair.color}}')
span(class='hair_beard_{{user.preferences.hair.beard}}_{{user.preferences.hair.color}}')
@ -52,7 +52,7 @@
.character-sprites
span(class='skin_{{user.preferences.skin}}')
span(class='{{user.preferences.size}}_armor_healer_5')
span(class='head_base_0')
span(class='head_0')
span(class='hair_base_{{user.preferences.hair.base}}_{{user.preferences.hair.color}}')
span(class='hair_bangs_{{user.preferences.hair.bangs}}_{{user.preferences.hair.color}}')
span(class='hair_beard_{{user.preferences.hair.beard}}_{{user.preferences.hair.color}}')
@ -62,7 +62,7 @@
span(class='weapon_healer_6')
br
.well(ng-show='selectedClass=="warrior"') Warriors deal damage to tasks (reducing redness), have moderate defense, and improved critical hits.
.well(ng-show='selectedClass=="wizard"') Wizards deal damage to tasks (reducing redness), can debuff tasks, and they gain experience rapidly.
.well(ng-show='selectedClass=="wizard"') Mages deal damage to tasks (reducing redness), can debuff tasks, and they gain experience rapidly.
.well(ng-show='selectedClass=="rogue"') Rogues finds more drops and gold. They can also "go stealth" to avoid damage at the end of a day.
.well(ng-show='selectedClass=="healer"') Healers have high defense against damage, and can heal themselves and other players in the party, as well as buff players.

View file

@ -14,6 +14,7 @@ div(ng-controller='MemberModalCtrl')
li(ng-show='profile.auth.timestamps.created') - Member since {{timestamp(profile.auth.timestamps.created)}} -
li(ng-show='profile.auth.timestamps.loggedin') - Last logged in {{timestamp(profile.auth.timestamps.loggedin)}} -
h3 Stats
.label.label-info {{profile.stats.class}}
p.alert.alert-info Coming back soon!
//-include ../profiles/stats
.span6

View file

@ -96,3 +96,8 @@
td x{{v}}
hr
div(ng-if='profile.achievements.snowball')
.achievement.achievement-snowball
h5 Annoying Friends
small Got snowballed {{profile.achievements.snowball}} times by party members.
hr

View file

@ -3,7 +3,7 @@ table.table.table-striped
tr(ng-repeat='(k,v) in user.items.gear.equipped', ng-init='piece=Content.gear.flat[v]', ng-show='piece')
td
strong {{piece.text}}:&nbsp;
span(ng-repeat='stat in ["str","con","per","int"]', ng-show='piece[stat]') {{piece[stat]}}{{stat}}&nbsp;
span(ng-repeat='stat in ["str","con","per","int"]', ng-show='piece[stat]') {{piece[stat]}} {{stat.toUpperCase()}}&nbsp;
h4 Stats
table.table.table-striped
@ -31,19 +31,25 @@ table.table.table-striped
strong {{v}}: {{profile._statsComputed[k]}}
td
ul
li Allocated: {{profile.stats[k] || 0}}
li
| Gear: {{Content.gear.flat[profile.items.gear.equipped.weapon][k] + Content.gear.flat[profile.items.gear.equipped.armor][k] + Content.gear.flat[profile.items.gear.equipped.head][k] + Content.gear.flat[profile.items.gear.equipped.shield][k] || 0}}&nbsp;
i.icon-question-sign(popover-title='Class Gear', popover-trigger='mouseenter', popover-placement='right', popover="Wearing your class's gear gives that stat a 1.5% bonus, in addition to this number.")
li Level: {{(profile.stats.lvl - 1) / 2}}
li Buffs: {{profile.stats.buffs[k] || 0}}
li Level: {{(profile.stats.lvl - 1) / 2}}&nbsp;
i.icon-question-sign(popover-title='Level Bonus', popover-trigger='mouseenter', popover-placement='right', popover="Each attribute gets a bonus equal to half your Level.")
li Equipment: {{Content.gear.flat[profile.items.gear.equipped.weapon][k] + Content.gear.flat[profile.items.gear.equipped.armor][k] + Content.gear.flat[profile.items.gear.equipped.head][k] + Content.gear.flat[profile.items.gear.equipped.shield][k] || 0}}&nbsp;
i.icon-question-sign(popover-title='Equipment', popover-trigger='mouseenter', popover-placement='right', popover="Attribute bonuses provided by your equipped battle gear. See the Equipment tab under Inventory to select your battle gear.")
li Class Equip Bonus: {{profile._statsComputed[k] - profile.stats.buffs[k] - ((profile.stats.lvl - 1) / 2) - Content.gear.flat[profile.items.gear.equipped.weapon][k] - Content.gear.flat[profile.items.gear.equipped.armor][k] - Content.gear.flat[profile.items.gear.equipped.head][k] - Content.gear.flat[profile.items.gear.equipped.shield][k]}}&nbsp;
i.icon-question-sign(popover-title='Class Equipment Bonus', popover-trigger='mouseenter', popover-placement='right', popover="Your class uses its own equipment more effectively than gear from other classes. Equipped gear from your current class gets a 50% boost to the attribute bonus it grants.")
li Allocated: {{profile.stats[k] || 0}}&nbsp;
i.icon-question-sign(popover-title='Allocated Points', popover-trigger='mouseenter', popover-placement='right', popover="Attribute points you've earned and assigned. Assign points using the Character Build column.")
li Buffs: {{profile.stats.buffs[k] || 0}}&nbsp;
i.icon-question-sign(popover-title='Buffs', popover-trigger='mouseenter', popover-placement='right', popover="Attribute bonuses provided by abilities you or your party members have used. The abilities you can use are found in the Rewards column on your Tasks page.")
tr(ng-if='profile.stats.buffs.stealth')
td
strong Stealth: {{profile.stats.buffs.stealth}}
strong Stealth: {{profile.stats.buffs.stealth}}&nbsp;
i.icon-question-sign(popover-title='Stealth', popover-trigger='mouseenter', popover-placement='right', popover="When a new day begins, you will avoid damage from this many missed Dailies.")
td
tr(ng-if='profile.stats.buffs.streaks')
td
strong Frozen Streaks: true
strong Streaks Frozen&nbsp;
i.icon-question-sign(popover-title='Streaks Frozen', popover-trigger='mouseenter', popover-placement='right', popover="Streaks on missed Dailies will not reset at the end of the day.")
td
h4 Pets
@ -52,3 +58,8 @@ table.table.table-striped
td
strong Pets Found
| : {{profile.petCount}}
// Dunno why this doesn't work //
// tr
td
strong Mounts Tamed
| : {{profile.mountCount}} //

View file

@ -1,4 +1,4 @@
li(bindonce='list', ng-repeat='task in obj[list.type+"s"]', class='task {{Shared.taskClasses(task, user.filters, user.preferences.dayStart, user.lastCron, list.showCompleted, main)}}', ng-click='spell && castEnd(task, "task", $event)', ng-class='{"cast-target":spell}')
li(bindonce='list', ng-repeat='task in obj[list.type+"s"] | completedFilter: list.showCompleted', class='task {{Shared.taskClasses(task, user.filters, user.preferences.dayStart, user.lastCron, list.showCompleted, main)}}', ng-click='spell && castEnd(task, "task", $event)', ng-class='{"cast-target":spell}')
// right-hand side control buttons
.task-meta-controls
@ -61,116 +61,118 @@ li(bindonce='list', ng-repeat='task in obj[list.type+"s"]', class='task {{Shared
label(for='box-{{obj._id}}_{{task.id}}')
// main content
p.task-text
| {{task.text}}
markdown(ng-model='task.text',target='_blank')
//-| {{task.text}}
// edit/options dialog
.task-options(ng-show='task._editing')
div(ng-if='task._editing')
.task-options
// Broken Challenge
.well(ng-if='task.challenge.broken')
div(ng-if='task.challenge.broken=="TASK_DELETED"')
p Broken Challenge Link: this task was part of a challenge, but has been removed from it. What would you like to do?
p
a(ng-click='unlink(task, "keep")') Keep It
| &nbsp;|&nbsp;
a(ng-click="removeTask(obj[list.type+'s'], $index)") Remove It
div(ng-if='task.challenge.broken=="CHALLENGE_DELETED"')
p Broken Challenge Link: this task was part of a challenge, but the challenge (or group) has been deleted. What to do with the orphan tasks?
p
a(ng-click='unlink(task, "keep-all")') Keep Them
| &nbsp;|&nbsp;
a(ng-click='unlink(task, "remove-all")') Remove Them
div(ng-if='task.challenge.broken=="CHALLENGE_CLOSED"')
p.
This challenge has been completed, and the winner was <span class='badge'>{{task.challenge.winner}}</span>! What to do with the orphan tasks?
p
a(ng-click='unlink(task, "keep-all")') Keep Them
| &nbsp;|&nbsp;
a(ng-click='unlink(task, "remove-all")') Remove Them
//div(ng-if='task.challenge.broken=="UNSUBSCRIBED"')
p Broken Challenge Link: this task was part of a challenge, but you have unsubscribed from the challenge. What to do with the orphan tasks?
p
a(ng-click="unlink(task, 'keep-all')") Keep Them
| &nbsp;|&nbsp;
a(ng-click="unlink(task, 'remove-all')") Remove Them
// Broken Challenge
.well(ng-if='task.challenge.broken')
div(ng-if='task.challenge.broken=="TASK_DELETED"')
p Broken Challenge Link: this task was part of a challenge, but has been removed from it. What would you like to do?
p
a(ng-click='unlink(task, "keep")') Keep It
| &nbsp;|&nbsp;
a(ng-click="removeTask(obj[list.type+'s'], $index)") Remove It
div(ng-if='task.challenge.broken=="CHALLENGE_DELETED"')
p Broken Challenge Link: this task was part of a challenge, but the challenge (or group) has been deleted. What to do with the orphan tasks?
p
a(ng-click='unlink(task, "keep-all")') Keep Them
| &nbsp;|&nbsp;
a(ng-click='unlink(task, "remove-all")') Remove Them
div(ng-if='task.challenge.broken=="CHALLENGE_CLOSED"')
p.
This challenge has been completed, and the winner was <span class='badge'>{{task.challenge.winner}}</span>! What to do with the orphan tasks?
p
a(ng-click='unlink(task, "keep-all")') Keep Them
| &nbsp;|&nbsp;
a(ng-click='unlink(task, "remove-all")') Remove Them
//div(ng-if='task.challenge.broken=="UNSUBSCRIBED"')
p Broken Challenge Link: this task was part of a challenge, but you have unsubscribed from the challenge. What to do with the orphan tasks?
p
a(ng-click="unlink(task, 'keep-all')") Keep Them
| &nbsp;|&nbsp;
a(ng-click="unlink(task, 'remove-all')") Remove Them
form(ng-submit='saveTask(task)')
// text & notes
fieldset.option-group
label.option-title Text
input.option-content(type='text', ng-model='task.text', required, ng-disabled='task.challenge.id')
form(ng-submit='saveTask(task)')
// text & notes
fieldset.option-group
label.option-title Text
input.option-content(type='text', ng-model='task.text', required, ng-disabled='task.challenge.id')
label.option-title Extra Notes
textarea.option-content(rows='3', ng-model='task.notes', ng-disabled='task.challenge.id')
label.option-title Extra Notes
textarea.option-content(rows='3', ng-model='task.notes', ng-disabled='task.challenge.id')
// if Habit, plus/minus command options
fieldset.option-group(ng-if='task.type=="habit" && !task.challenge.id')
legend.option-title Direction/Actions
span.task-checker.action-plusminus.select-toggle
input.visuallyhidden.focusable(id='{{obj._id}}_{{task.id}}-option-plus', type='checkbox', ng-model='task.up')
label(for='{{obj._id}}_{{task.id}}-option-plus')
span.task-checker.action-plusminus.select-toggle
input.visuallyhidden.focusable(id='{{obj._id}}_{{task.id}}-option-minus', type='checkbox', ng-model='task.down')
label(for='{{obj._id}}_{{task.id}}-option-minus')
// if Habit, plus/minus command options
fieldset.option-group(ng-if='task.type=="habit" && !task.challenge.id')
legend.option-title Direction/Actions
span.task-checker.action-plusminus.select-toggle
input.visuallyhidden.focusable(id='{{obj._id}}_{{task.id}}-option-plus', type='checkbox', ng-model='task.up')
label(for='{{obj._id}}_{{task.id}}-option-plus')
span.task-checker.action-plusminus.select-toggle
input.visuallyhidden.focusable(id='{{obj._id}}_{{task.id}}-option-minus', type='checkbox', ng-model='task.down')
label(for='{{obj._id}}_{{task.id}}-option-minus')
// if Daily, calendar
fieldset(bo-if='task.type=="daily"', class="option-group")
legend.option-title Repeat
.task-controls.tile-group.repeat-days(bindonce)
// note, does not use data-toggle="buttons-checkbox" - it would interfere with our own click binding
button.task-action-btn.tile(ng-class='{active: task.repeat.su}', type='button', ng-click='task.challenge.id || (task.repeat.su = !task.repeat.su)', bo-text='moment.weekdaysMin(0)')
button.task-action-btn.tile(ng-class='{active: task.repeat.m}', type='button', ng-click='task.challenge.id || (task.repeat.m = !task.repeat.m)', bo-text='moment.weekdaysMin(1)')
button.task-action-btn.tile(ng-class='{active: task.repeat.t}', type='button', ng-click='task.challenge.id || (task.repeat.t = !task.repeat.t)', bo-text='moment.weekdaysMin(2)')
button.task-action-btn.tile(ng-class='{active: task.repeat.w}', type='button', ng-click='task.challenge.id || (task.repeat.w = !task.repeat.w)', bo-text='moment.weekdaysMin(3)')
button.task-action-btn.tile(ng-class='{active: task.repeat.th}', type='button', ng-click='task.challenge.id || (task.repeat.th = !task.repeat.th)', bo-text='moment.weekdaysMin(4)')
button.task-action-btn.tile(ng-class='{active: task.repeat.f}', type='button', ng-click='task.challenge.id || (task.repeat.f= !task.repeat.f)', bo-text='moment.weekdaysMin(5)')
button.task-action-btn.tile(ng-class='{active: task.repeat.s}', type='button', ng-click='task.challenge.id || (task.repeat.s = !task.repeat.s)', bo-text='moment.weekdaysMin(6)')
// if Daily, calendar
fieldset(bo-if='task.type=="daily"', class="option-group")
legend.option-title Repeat
.task-controls.tile-group.repeat-days(bindonce)
// note, does not use data-toggle="buttons-checkbox" - it would interfere with our own click binding
button.task-action-btn.tile(ng-class='{active: task.repeat.su}', type='button', ng-click='task.challenge.id || (task.repeat.su = !task.repeat.su)', bo-text='moment.weekdaysMin(0)')
button.task-action-btn.tile(ng-class='{active: task.repeat.m}', type='button', ng-click='task.challenge.id || (task.repeat.m = !task.repeat.m)', bo-text='moment.weekdaysMin(1)')
button.task-action-btn.tile(ng-class='{active: task.repeat.t}', type='button', ng-click='task.challenge.id || (task.repeat.t = !task.repeat.t)', bo-text='moment.weekdaysMin(2)')
button.task-action-btn.tile(ng-class='{active: task.repeat.w}', type='button', ng-click='task.challenge.id || (task.repeat.w = !task.repeat.w)', bo-text='moment.weekdaysMin(3)')
button.task-action-btn.tile(ng-class='{active: task.repeat.th}', type='button', ng-click='task.challenge.id || (task.repeat.th = !task.repeat.th)', bo-text='moment.weekdaysMin(4)')
button.task-action-btn.tile(ng-class='{active: task.repeat.f}', type='button', ng-click='task.challenge.id || (task.repeat.f= !task.repeat.f)', bo-text='moment.weekdaysMin(5)')
button.task-action-btn.tile(ng-class='{active: task.repeat.s}', type='button', ng-click='task.challenge.id || (task.repeat.s = !task.repeat.s)', bo-text='moment.weekdaysMin(6)')
// if Reward, pricing
fieldset.option-group.option-short(ng-if='task.type=="reward" && !task.challenge.id')
legend.option-title Price
input.option-content(type='number', size='16', min='0', step="any", ng-model='task.value')
.money.input-suffix
span.shop_gold
// if Reward, pricing
fieldset.option-group.option-short(ng-if='task.type=="reward" && !task.challenge.id')
legend.option-title Price
input.option-content(type='number', size='16', min='0', step="any", ng-model='task.value')
.money.input-suffix
span.shop_gold
// if Todos, the due date
fieldset.option-group(ng-if='task.type=="todo" && !task.challenge.id')
legend.option-title Due Date
input.option-content.datepicker(type='text', data-date-format='mm/dd/yyyy', ng-model='task.date')
// if Todos, the due date
fieldset.option-group(ng-if='task.type=="todo" && !task.challenge.id')
legend.option-title Due Date
input.option-content.datepicker(type='text', data-date-format='mm/dd/yyyy', ng-model='task.date')
fieldset.option-group(ng-if='!$state.includes("options.social.challenges")')
legend.option-title Tags
label.checkbox(ng-repeat='tag in user.tags')
input(type='checkbox', ng-model='task.tags[tag.id]')
| {{tag.name}}
fieldset.option-group(ng-if='!$state.includes("options.social.challenges")')
legend.option-title Tags
label.checkbox(ng-repeat='tag in user.tags')
input(type='checkbox', ng-model='task.tags[tag.id]')
| {{tag.name}}
// Advanced Options
span(bo-if='task.type!="reward"')
p.option-title.mega(ng-click='task._advanced = !task._advanced') Advanced Options
fieldset.option-group.advanced-option(ng-class="{visuallyhidden: !task._advanced}")
legend.option-title
a.priority-multiplier-help(href='https://trello.com/card/priority-multiplier/50e5d3684fe3a7266b0036d6/17', target='_blank', popover-title='How difficult is this task?', popover-trigger='mouseenter', popover="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.")
i.icon-question-sign
| Difficulty
.task-controls.tile-group.priority-multiplier
button.task-action-btn.tile(type='button', ng-class='{active: task.priority==1 || !task.priority}', ng-click='task.challenge.id || (task.priority=1)') Easy
button.task-action-btn.tile(type='button', ng-class='{active: task.priority==1.5}', ng-click='task.challenge.id || (task.priority=1.5)') Medium
button.task-action-btn.tile(type='button', ng-class='{active: task.priority==2}', ng-click='task.challenge.id || (task.priority=2)') Hard
//span(ng-if='task.type=="daily" && !task.challenge.id')
br
span(ng-if='task.type=="daily"')
legend.option-title Restore Streak
input.option-content(type='number', ng-model='task.streak')
// Advanced Options
span(bo-if='task.type!="reward"')
p.option-title.mega(ng-click='task._advanced = !task._advanced') Advanced Options
fieldset.option-group.advanced-option(ng-class="{visuallyhidden: !task._advanced}")
legend.option-title
a.priority-multiplier-help(href='https://trello.com/card/priority-multiplier/50e5d3684fe3a7266b0036d6/17', target='_blank', popover-title='How difficult is this task?', popover-trigger='mouseenter', popover="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.")
i.icon-question-sign
| Difficulty
.task-controls.tile-group.priority-multiplier
button.task-action-btn.tile(type='button', ng-class='{active: task.priority==1 || !task.priority}', ng-click='task.challenge.id || (task.priority=1)') Easy
button.task-action-btn.tile(type='button', ng-class='{active: task.priority==1.5}', ng-click='task.challenge.id || (task.priority=1.5)') Medium
button.task-action-btn.tile(type='button', ng-class='{active: task.priority==2}', ng-click='task.challenge.id || (task.priority=2)') Hard
//span(ng-if='task.type=="daily" && !task.challenge.id')
br
span(ng-if='task.type=="daily"')
legend.option-title Restore Streak
input.option-content(type='number', ng-model='task.streak')
legend.option-title Attributes
.task-controls.tile-group
button.task-action-btn.tile(type='button', ng-class='{active: task.attribute=="str"}', ng-click='task.attribute="str"') Physical
button.task-action-btn.tile(type='button', ng-class='{active: task.attribute=="int"}', ng-click='task.attribute="int"') Mental
button.task-action-btn.tile(type='button', ng-class='{active: task.attribute=="con"}', ng-click='task.attribute="con"') Social
button.task-action-btn.tile(type='button', ng-class='{active: task.attribute=="per"}', ng-click='task.attribute="per"')
| Other&nbsp;
i.icon-question-sign(popover='Eg, professional pursuits, hobbies, financial, etc.', popover-trigger='mouseenter', popover-placement='top')
legend.option-title Attributes
.task-controls.tile-group
button.task-action-btn.tile(type='button', ng-class='{active: task.attribute=="str"}', ng-click='task.attribute="str"') Physical
button.task-action-btn.tile(type='button', ng-class='{active: task.attribute=="int"}', ng-click='task.attribute="int"') Mental
button.task-action-btn.tile(type='button', ng-class='{active: task.attribute=="con"}', ng-click='task.attribute="con"') Social
button.task-action-btn.tile(type='button', ng-class='{active: task.attribute=="per"}', ng-click='task.attribute="per"')
| Other&nbsp;
i.icon-question-sign(popover='Eg, professional pursuits, hobbies, financial, etc.', popover-trigger='mouseenter', popover-placement='top')
button.task-action-btn.tile.spacious(type='submit') Save & Close
button.task-action-btn.tile.spacious(type='submit') Save & Close
div(class='{{obj._id}}{{task.id}}-chart', ng-show='charts[obj._id+task.id]')