From 389b5b370a7502b90087910725a92bd3792434b6 Mon Sep 17 00:00:00 2001 From: Sabe Jones Date: Mon, 21 Sep 2015 17:12:23 -0400 Subject: [PATCH 01/16] feat(pets): Magic Hatching Potions WIP --- common/locales/en/content.json | 1 + common/script/content/index.coffee | 17 +++++++++++------ common/script/index.coffee | 2 +- test/common/count.js | 21 ++++++++++++++++++++- test/spec/services/statServicesSpec.js | 14 +++++++++----- website/views/options/inventory/drops.jade | 2 +- website/views/options/inventory/mounts.jade | 7 +++---- website/views/options/inventory/pets.jade | 6 +++--- 8 files changed, 49 insertions(+), 21 deletions(-) diff --git a/common/locales/en/content.json b/common/locales/en/content.json index 279c7b5562..4220c77ddc 100644 --- a/common/locales/en/content.json +++ b/common/locales/en/content.json @@ -114,6 +114,7 @@ "hatchingPotionCottonCandyPink": "Cotton Candy Pink", "hatchingPotionCottonCandyBlue": "Cotton Candy Blue", "hatchingPotionGolden": "Golden", + "hatchingPotionSpooky": "Spooky", "hatchingPotionNotes": "Pour this on an egg, and it will hatch as a <%= potText(locale) %> pet.", diff --git a/common/script/content/index.coffee b/common/script/content/index.coffee index b2ef3a9798..fb3eded07b 100644 --- a/common/script/content/index.coffee +++ b/common/script/content/index.coffee @@ -1165,25 +1165,30 @@ api.hatchingPotions = CottonCandyPink: value: 4, text: t('hatchingPotionCottonCandyPink') CottonCandyBlue: value: 4, text: t('hatchingPotionCottonCandyBlue') Golden: value: 5, text: t('hatchingPotionGolden') + Spooky: value: 3, text: t('hatchingPotionSpooky'), premium: true + _.each api.hatchingPotions, (pot,key) -> - _.defaults pot, {key, value: 2, notes: t('hatchingPotionNotes', {potText: pot.text})} + _.defaults pot, {key, value: 2, notes: t('hatchingPotionNotes', {potText: pot.text}), premium: false, canBuy: true} api.pets = _.transform api.dropEggs, (m, egg) -> _.defaults m, _.transform api.hatchingPotions, (m2, pot) -> - m2[egg.key + "-" + pot.key] = true + if not pot.premium + m2[egg.key + "-" + pot.key] = true api.questPets = _.transform api.questEggs, (m, egg) -> _.defaults m, _.transform api.hatchingPotions, (m2, pot) -> - m2[egg.key + "-" + pot.key] = true + if not pot.premium + m2[egg.key + "-" + pot.key] = true -## added for mountmaster -- yes, the transforms are correct, since the same strings are used for both pets and mounts api.mounts = _.transform api.dropEggs, (m, egg) -> _.defaults m, _.transform api.hatchingPotions, (m2, pot) -> - m2[egg.key + "-" + pot.key] = true + if not pot.premium + m2[egg.key + "-" + pot.key] = true api.questMounts = _.transform api.questEggs, (m, egg) -> _.defaults m, _.transform api.hatchingPotions, (m2, pot) -> - m2[egg.key + "-" + pot.key] = true + if not pot.premium + m2[egg.key + "-" + pot.key] = true api.food = # Base diff --git a/common/script/index.coffee b/common/script/index.coffee index d59b5a9828..3672e584e1 100644 --- a/common/script/index.coffee +++ b/common/script/index.coffee @@ -766,7 +766,7 @@ api.wrap = (user, main=true) -> if food.key is 'Saddle' evolve() else - if food.target is potion + if food.target is potion or content.hatchingPotions[potion].premium userPets[pet] += 5 message = i18n.t('messageLikesFood', {egg: petDisplayName, foodText: food.text(req.language)}, req.language) else diff --git a/test/common/count.js b/test/common/count.js index ddf45faae9..fc4fac6dca 100644 --- a/test/common/count.js +++ b/test/common/count.js @@ -6,7 +6,7 @@ var expect = chai.expect require('coffee-script'); var count = require('../../common/script/count'); -describe('count', function() { +describe.only('count', function() { describe('beastMasterProgress', function() { it('returns 0 if no pets', function() { var pets = {}; @@ -26,6 +26,16 @@ describe('count', function() { expect(beastMasterTotal).to.eql(1); }); + it('does not count pets hatched with premium potions', function() { + var pets = { + "Wolf-Spooky": 5, + "Dragon-Spooky": 5, + "FlyingPig-Base": 5 + } + var beastMasterTotal = count.beastMasterProgress(pets); + expect(beastMasterTotal).to.eql(1); + }); + it('does not count special pets', function() { var pets = { "Wolf-Base": 2, @@ -65,6 +75,15 @@ describe('count', function() { expect(mountMasterTotal).to.eql(2); }); + it('does not count premium mounts', function() { + var mounts = { + "Dragon-Red": true, + "FlyingPig-Spooky": true + } + var mountMasterTotal = count.mountMasterProgress(mounts); + expect(mountMasterTotal).to.eql(1); + }); + it('does not count quest mounts', function() { var mounts = { "Dragon-Red": true, "Gryphon-Base": true }; var mountMasterTotal = count.mountMasterProgress(mounts); diff --git a/test/spec/services/statServicesSpec.js b/test/spec/services/statServicesSpec.js index 8a1694b16a..d688be23fb 100644 --- a/test/spec/services/statServicesSpec.js +++ b/test/spec/services/statServicesSpec.js @@ -24,7 +24,8 @@ describe('Stats Service', function() { "Deer-Golden" : 5, "Deer-Red" : 5, "Egg-Desert" : 5, - "MantisShrimp-Base" : 5 + "MantisShrimp-Base" : 5, + "Wolf-Spooky": 5 } var beastMasterDisplay = statCalc.beastMasterProgress(user.items.pets); @@ -38,9 +39,10 @@ describe('Stats Service', function() { "BearCub-CottonCandyBlue" : -1, "Cactus-Zombie" : 5, "Deer-Golden" : 5, - "Deer-Red" : 5, + "Deer-Red" : -1, "Egg-Desert" : 5, - "MantisShrimp-Base" : 5 + "MantisShrimp-Base" : 5, + "Wolf-Spooky": -1 } var beastMasterDisplay = statCalc.beastMasterProgress(user.items.pets); @@ -221,7 +223,8 @@ describe('Stats Service', function() { "Wolf-Golden" : true, "Owl-CottonCandyBlue" : true, "Mammoth-Base" : true, - "Bunny-Skeleton" : true + "Bunny-Skeleton" : true, + "Tiger-Spooky": true } var mountMasterDisplay = statCalc.mountMasterProgress(user.items.mounts); @@ -237,7 +240,8 @@ describe('Stats Service', function() { "Wolf-Golden" : false, "Owl-CottonCandyBlue" : true, "Mammoth-Base" : true, - "Bunny-Skeleton" : true + "Bunny-Skeleton" : true, + "Tiger-Spooky": true } var mountMasterDisplay = statCalc.mountMasterProgress(user.items.mounts); diff --git a/website/views/options/inventory/drops.jade b/website/views/options/inventory/drops.jade index 86b10aedee..7812aece22 100644 --- a/website/views/options/inventory/drops.jade +++ b/website/views/options/inventory/drops.jade @@ -134,7 +134,7 @@ li.customize-menu menu.pets-menu(label=env.t('hatchingPotions')) p.muted!=env.t('dropsExplanation') - div(ng-repeat='pot in Content.hatchingPotions') + div(ng-repeat='pot in Content.hatchingPotions', ng-if='pot.canBuy') button.customize-option(class='Pet_HatchingPotion_{{::pot.key}}', popover='{{::pot.notes()}}', popover-append-to-body='true', popover-title!=env.t("potion", {potionType: "{{::pot.text()}}"}), diff --git a/website/views/options/inventory/mounts.jade b/website/views/options/inventory/mounts.jade index 2db2b8aa12..c5b3f3f273 100644 --- a/website/views/options/inventory/mounts.jade +++ b/website/views/options/inventory/mounts.jade @@ -1,4 +1,4 @@ -mixin mountList(source) +mixin mountList(source,showPremium) menu.pets(type='list') each egg in source -if(!egg.noMount) { @@ -6,9 +6,8 @@ mixin mountList(source) menu each potion in env.Content.hatchingPotions - mount = egg.key+"-"+potion.key - div(popover-trigger='mouseenter', popover=env.t('mountName', {potion: potion.text(env.language.code), mount: egg.mountText(env.language.code)}), popover-placement='bottom') + div(popover-trigger='mouseenter', popover=env.t('mountName', {potion: potion.text(env.language.code), mount: egg.mountText(env.language.code)}), popover-placement='bottom', ng-hide='#{potion.premium} && #{!showPremium}') button(class="pet-button Mount_Head_#{mount}", ng-show='user.items.mounts["#{mount}"]', ng-class='{active: user.items.currentMount == "#{mount}"}', ng-click='chooseMount("#{egg.key}", "#{potion.key}")') - //div(class='Mount_Head_{{mount}}') button(class="pet-button mount-not-owned", ng-hide='user.items.mounts["#{mount}"]') .PixelPaw -} @@ -24,7 +23,7 @@ mixin mountList(source) p=env.t('mattShall', {name: "{{user.profile.name}}"}) h4 {{:: env.t('stableMountMasterProgress', { number: mountMasterProgress }) }} .row: .col-md-12 - +mountList(env.Content.dropEggs) + +mountList(env.Content.dropEggs,true) .row: .col-md-12 h4=env.t('questMounts') +mountList(env.Content.questEggs) diff --git a/website/views/options/inventory/pets.jade b/website/views/options/inventory/pets.jade index 6fbe1f5fcd..86879215ba 100644 --- a/website/views/options/inventory/pets.jade +++ b/website/views/options/inventory/pets.jade @@ -1,11 +1,11 @@ -mixin petList(source) +mixin petList(source,showPremium) menu.pets(type='list') each egg in source li.customize-menu menu each potion in env.Content.hatchingPotions - pet = egg.key+"-"+potion.key - div(popover-trigger='mouseenter', popover=env.t('petName', {potion: potion.text(env.language.code), egg: egg.text(env.language.code)}), popover-placement='bottom') + div(popover-trigger='mouseenter', popover=env.t('petName', {potion: potion.text(env.language.code), egg: egg.text(env.language.code)}), popover-placement='bottom', ng-hide='#{potion.premium} && #{!showPremium}') button(class="pet-button Pet-#{pet}", ng-if='user.items.pets["#{pet}"]>0', ng-class='{active: user.items.currentPet == "#{pet}", selectableInventory: #{!egg.noMount} && selectedFood && !user.items.mounts["#{pet}"]}', ng-click='choosePet("#{egg.key}", "#{potion.key}")') .progress(ng-show='!user.items.mounts["#{pet}"]') .progress-bar.progress-bar-success(ng-style='{width: user.items.pets["#{pet}"]/.5 + "%"}') @@ -24,7 +24,7 @@ mixin petList(source) p=env.t('mattBochText1') h4 {{:: env.t('stableBeastMasterProgress', { number: beastMasterProgress }) }} .row: .col-md-12 - +petList(env.Content.dropEggs) + +petList(env.Content.dropEggs,true) .row: .col-md-12 h4=env.t('questPets') +petList(env.Content.questEggs) From acd3480b51c43de2e71a79df662bf6b2bcf1e2dd Mon Sep 17 00:00:00 2001 From: Sabe Jones Date: Mon, 21 Sep 2015 17:14:57 -0400 Subject: [PATCH 02/16] fix(test): Remove only --- test/common/count.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/common/count.js b/test/common/count.js index fc4fac6dca..b9040a71f1 100644 --- a/test/common/count.js +++ b/test/common/count.js @@ -6,7 +6,7 @@ var expect = chai.expect require('coffee-script'); var count = require('../../common/script/count'); -describe.only('count', function() { +describe('count', function() { describe('beastMasterProgress', function() { it('returns 0 if no pets', function() { var pets = {}; From cd9c3722549c6b143f5733ae36497f7c9fa448b2 Mon Sep 17 00:00:00 2001 From: Sabe Jones Date: Tue, 22 Sep 2015 12:45:59 -0400 Subject: [PATCH 03/16] feat(pets): Spooky sprites --- .../stable/mounts/Mount_Body_BearCub-Spooky.png | Bin 0 -> 3546 bytes .../stable/mounts/Mount_Body_Cactus-Spooky.png | Bin 0 -> 3339 bytes .../stable/mounts/Mount_Body_Dragon-Spooky.png | Bin 0 -> 3577 bytes .../mounts/Mount_Body_FlyingPig-Spooky.png | Bin 0 -> 3618 bytes .../stable/mounts/Mount_Body_Fox-Spooky.png | Bin 0 -> 3813 bytes .../stable/mounts/Mount_Body_LionCub-Spooky.png | Bin 0 -> 3517 bytes .../stable/mounts/Mount_Body_PandaCub-Spooky.png | Bin 0 -> 3319 bytes .../stable/mounts/Mount_Body_TigerCub-Spooky.png | Bin 0 -> 3600 bytes .../stable/mounts/Mount_Body_Wolf-Spooky.png | Bin 0 -> 3611 bytes .../stable/mounts/Mount_Head_BearCub-Spooky.png | Bin 0 -> 3245 bytes .../stable/mounts/Mount_Head_Cactus-Spooky.png | Bin 0 -> 3681 bytes .../stable/mounts/Mount_Head_Dragon-Spooky.png | Bin 0 -> 4461 bytes .../mounts/Mount_Head_FlyingPig-Spooky.png | Bin 0 -> 3532 bytes .../stable/mounts/Mount_Head_Fox-Spooky.png | Bin 0 -> 3328 bytes .../stable/mounts/Mount_Head_LionCub-Spooky.png | Bin 0 -> 3293 bytes .../stable/mounts/Mount_Head_PandaCub-Spooky.png | Bin 0 -> 3437 bytes .../stable/mounts/Mount_Head_TigerCub-Spooky.png | Bin 0 -> 3504 bytes .../stable/mounts/Mount_Head_Wolf-Spooky.png | Bin 0 -> 3944 bytes .../stable/pets/Pet-BearCub-Spooky.png | Bin 0 -> 3399 bytes .../stable/pets/Pet-Cactus-Spooky.png | Bin 0 -> 3324 bytes .../stable/pets/Pet-Dragon-Spooky.png | Bin 0 -> 3453 bytes .../stable/pets/Pet-FlyingPig-Spooky.png | Bin 0 -> 3546 bytes .../spritesmith/stable/pets/Pet-Fox-Spooky.png | Bin 0 -> 3399 bytes .../stable/pets/Pet-LionCub-Spooky.png | Bin 0 -> 3337 bytes .../stable/pets/Pet-PandaCub-Spooky.png | Bin 0 -> 3269 bytes .../stable/pets/Pet-TigerCub-Spooky.png | Bin 0 -> 3461 bytes .../spritesmith/stable/pets/Pet-Wolf-Spooky.png | Bin 0 -> 3454 bytes .../stable/potions/Pet_HatchingPotion_Spooky.png | Bin 0 -> 3196 bytes 28 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 common/img/sprites/spritesmith/stable/mounts/Mount_Body_BearCub-Spooky.png create mode 100644 common/img/sprites/spritesmith/stable/mounts/Mount_Body_Cactus-Spooky.png create mode 100644 common/img/sprites/spritesmith/stable/mounts/Mount_Body_Dragon-Spooky.png create mode 100644 common/img/sprites/spritesmith/stable/mounts/Mount_Body_FlyingPig-Spooky.png create mode 100644 common/img/sprites/spritesmith/stable/mounts/Mount_Body_Fox-Spooky.png create mode 100644 common/img/sprites/spritesmith/stable/mounts/Mount_Body_LionCub-Spooky.png create mode 100644 common/img/sprites/spritesmith/stable/mounts/Mount_Body_PandaCub-Spooky.png create mode 100644 common/img/sprites/spritesmith/stable/mounts/Mount_Body_TigerCub-Spooky.png create mode 100644 common/img/sprites/spritesmith/stable/mounts/Mount_Body_Wolf-Spooky.png create mode 100644 common/img/sprites/spritesmith/stable/mounts/Mount_Head_BearCub-Spooky.png create mode 100644 common/img/sprites/spritesmith/stable/mounts/Mount_Head_Cactus-Spooky.png create mode 100644 common/img/sprites/spritesmith/stable/mounts/Mount_Head_Dragon-Spooky.png create mode 100644 common/img/sprites/spritesmith/stable/mounts/Mount_Head_FlyingPig-Spooky.png create mode 100644 common/img/sprites/spritesmith/stable/mounts/Mount_Head_Fox-Spooky.png create mode 100644 common/img/sprites/spritesmith/stable/mounts/Mount_Head_LionCub-Spooky.png create mode 100644 common/img/sprites/spritesmith/stable/mounts/Mount_Head_PandaCub-Spooky.png create mode 100644 common/img/sprites/spritesmith/stable/mounts/Mount_Head_TigerCub-Spooky.png create mode 100644 common/img/sprites/spritesmith/stable/mounts/Mount_Head_Wolf-Spooky.png create mode 100644 common/img/sprites/spritesmith/stable/pets/Pet-BearCub-Spooky.png create mode 100644 common/img/sprites/spritesmith/stable/pets/Pet-Cactus-Spooky.png create mode 100644 common/img/sprites/spritesmith/stable/pets/Pet-Dragon-Spooky.png create mode 100644 common/img/sprites/spritesmith/stable/pets/Pet-FlyingPig-Spooky.png create mode 100644 common/img/sprites/spritesmith/stable/pets/Pet-Fox-Spooky.png create mode 100644 common/img/sprites/spritesmith/stable/pets/Pet-LionCub-Spooky.png create mode 100644 common/img/sprites/spritesmith/stable/pets/Pet-PandaCub-Spooky.png create mode 100644 common/img/sprites/spritesmith/stable/pets/Pet-TigerCub-Spooky.png create mode 100644 common/img/sprites/spritesmith/stable/pets/Pet-Wolf-Spooky.png create mode 100644 common/img/sprites/spritesmith/stable/potions/Pet_HatchingPotion_Spooky.png diff --git a/common/img/sprites/spritesmith/stable/mounts/Mount_Body_BearCub-Spooky.png b/common/img/sprites/spritesmith/stable/mounts/Mount_Body_BearCub-Spooky.png new file mode 100644 index 0000000000000000000000000000000000000000..2cb38aa406aee0a8029ddda6ad21d9da6860f85e GIT binary patch literal 3546 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 literal 0 HcmV?d00001 diff --git a/common/img/sprites/spritesmith/stable/mounts/Mount_Body_FlyingPig-Spooky.png b/common/img/sprites/spritesmith/stable/mounts/Mount_Body_FlyingPig-Spooky.png new file mode 100644 index 0000000000000000000000000000000000000000..04b47a6924a4a77484f0bf5f41edbf7aa568b6fe GIT binary patch literal 3618 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 XCm}+RE9dSb0RS*{J+&IJP3ZpsDVe>d literal 0 HcmV?d00001 diff --git a/common/img/sprites/spritesmith/stable/mounts/Mount_Body_Fox-Spooky.png b/common/img/sprites/spritesmith/stable/mounts/Mount_Body_Fox-Spooky.png new file mode 100644 index 0000000000000000000000000000000000000000..d4ac4674616ed130bc284412168d9267b7cfb171 GIT binary patch literal 3813 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 literal 0 HcmV?d00001 diff --git a/common/img/sprites/spritesmith/stable/mounts/Mount_Body_LionCub-Spooky.png b/common/img/sprites/spritesmith/stable/mounts/Mount_Body_LionCub-Spooky.png new file mode 100644 index 0000000000000000000000000000000000000000..9e785ef1619ee689dc9d0fe80e4f277ef631a1a6 GIT binary patch literal 3517 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 R#IyGS80%Z;)xcdI{~MuLeqI0o literal 0 HcmV?d00001 diff --git a/common/img/sprites/spritesmith/stable/mounts/Mount_Body_PandaCub-Spooky.png b/common/img/sprites/spritesmith/stable/mounts/Mount_Body_PandaCub-Spooky.png new file mode 100644 index 0000000000000000000000000000000000000000..424543f7381c42cd763d5a9cd7fd386b754ff83e GIT binary patch literal 3319 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 GG5kLu$*Ot) literal 0 HcmV?d00001 diff --git a/common/img/sprites/spritesmith/stable/mounts/Mount_Body_Wolf-Spooky.png b/common/img/sprites/spritesmith/stable/mounts/Mount_Body_Wolf-Spooky.png new file mode 100644 index 0000000000000000000000000000000000000000..d684f440558af25af4bc1a11da51d698fe31d79d GIT binary patch literal 3611 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 YKndT_@K>M#U%x&;U0Fw|0%8^Vf9R9GyZ`_I literal 0 HcmV?d00001 diff --git a/common/img/sprites/spritesmith/stable/mounts/Mount_Head_BearCub-Spooky.png b/common/img/sprites/spritesmith/stable/mounts/Mount_Head_BearCub-Spooky.png new file mode 100644 index 0000000000000000000000000000000000000000..063231b6acb9b75c47efed2ea03c9123eca5f9fd GIT binary patch literal 3245 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 M^h|YYz)q3>23L&!Jpcdz literal 0 HcmV?d00001 diff --git a/common/img/sprites/spritesmith/stable/mounts/Mount_Head_Cactus-Spooky.png b/common/img/sprites/spritesmith/stable/mounts/Mount_Head_Cactus-Spooky.png new file mode 100644 index 0000000000000000000000000000000000000000..4b2379ba1b261baa1b64772b61b5ed1697b56f52 GIT binary patch literal 3681 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 literal 0 HcmV?d00001 diff --git a/common/img/sprites/spritesmith/stable/mounts/Mount_Head_LionCub-Spooky.png b/common/img/sprites/spritesmith/stable/mounts/Mount_Head_LionCub-Spooky.png new file mode 100644 index 0000000000000000000000000000000000000000..0b10930f449273d19fbaa0b1144f9c9e6b47d8cb GIT binary patch literal 3293 zcmV<33?lQ1P)KLZ*U+IBfRsybQWXdwQbLP>6pAqfylh#{fb6;Z(vMMVS~$e@S=j*ftg6;Uhf59&ghTmgWD0l;*T zI709Y^p6lP1rIRMx#05C~cW=H_Aw*bJ-5DT&Z2n+x)QHX^p z00esgV8|mQcmRZ%02D^@S3L16t`O%c004NIvOKvYIYoh62rY33S640`D9%Y2D-rV&neh&#Q1i z007~1e$oCcFS8neI|hJl{-P!B1ZZ9hpmq0)X0i`JwE&>$+E?>%_LC6RbVIkUx0b+_+BaR3cnT7Zv!AJxW zizFb)h!jyGOOZ85F;a?DAXP{m@;!0_IfqH8(HlgRxt7s3}k3K`kFu>>-2Q$QMFfPW!La{h336o>X zu_CMttHv6zR;&ZNiS=X8v3CR#fknUxHUxJ0uoBa_M6WNWeqIg~6QE69c9o#eyhGvpiOA@W-aonk<7r1(?fC{oI5N*U!4 zfg=2N-7=cNnjjOr{yriy6mMFgG#l znCF=fnQv8CDz++o6_Lscl}eQ+l^ZHARH>?_s@|##Rr6KLRFA1%Q+=*RRWnoLsR`7U zt5vFIcfW3@?wFpwUVxrVZ>QdQz32KIeJ}k~{cZZE^+ya? z2D1z#2HOnI7(B%_ac?{wFUQ;QQA1tBKtrWrm0_3Rgps+?Jfqb{jYbcQX~taRB;#$y zZN{S}1|}gUOHJxc?wV3fxuz+mJ4`!F$IZ;mqRrNsHJd##*D~ju=bP7?-?v~|cv>vB zsJ6IeNwVZxrdjT`yl#bBIa#GxRa#xMMy;K#CDyyGyQdMSxlWT#tDe?p!?5wT$+oGt z8L;Kp2HUQ-ZMJ=3XJQv;x5ci*?vuTfeY$;({XGW_huIFR9a(?@3)XSs8O^N5RyOM=TTmp(3=8^+zpz2r)C z^>JO{deZfso3oq3?Wo(Y?l$ge?uXo;%ru`Vo>?<<(8I_>;8Eq#KMS9gFl*neeosSB zfoHYnBQIkwkyowPu(zdms`p{<7e4kra-ZWq<2*OsGTvEV%s0Td$hXT+!*8Bnh2KMe zBmZRodjHV?r+_5^X9J0WL4jKW`}lf%A-|44I@@LTvf1rHjG(ze6+w@Jt%Bvjts!X0 z?2xS?_ve_-kiKB_KiJlZ$9G`c^=E@oNG)mWWaNo-3TIW8)$Hg0Ub-~8?KhvJ>$ z3*&nim@mj(aCxE5!t{lw7O5^0EIO7zOo&c6l<+|iDySBWCGrz@C5{St!X3hAA}`T4 z(TLbXTq+(;@<=L8dXnssyft|w#WSTW<++3>sgS%(4NTpeI-VAqb|7ssJvzNHgOZVu zaYCvgO_R1~>SyL=cFU|~g|hy|Zi}}s9+d~lYqOB71z9Z$wnC=pR9Yz4DhIM>Wmjgu z&56o6maCpC&F##y%G;1PobR9i?GnNg;gYtchD%p19a!eQtZF&3JaKv33gZ<8D~47E ztUS1iwkmDaPpj=$m#%)jCVEY4fnLGNg2A-`YwHVD3gv};>)hAvT~AmqS>Lr``i7kw zJ{5_It`yrBmlc25DBO7E8;5VoznR>Ww5hAaxn$2~(q`%A-YuS64wkBy=9dm`4cXeX z4c}I@?e+FW+b@^RDBHV(wnMq2zdX3SWv9u`%{xC-q*U}&`cyXV(%rRT*Z6MH?i+i& z_B8C(+grT%{XWUQ+f@NoP1R=AW&26{v-dx)iK^-Nmiuj8txj!m?Z*Ss1N{dh4z}01 z)YTo*JycSU)+_5r4#yw9{+;i4Ee$peRgIj+;v;ZGdF1K$3E%e~4LaI(jC-u%2h$&R z9cLXcYC@Xwnns&bn)_Q~Te?roKGD|d-g^8;+aC{{G(1^(O7m37Y1-+6)01cN&y1aw zoqc{T`P^XJqPBbIW6s}d4{z_f5Om?vMgNQEJG?v2T=KYd^0M3I6IZxbny)%vZR&LD zJpPl@Psh8QyPB@KTx+@RdcC!KX7}kEo;S|j^u2lU7XQ}Oo;f|;z4Ll+_r>@1-xl3| zawq-H%e&ckC+@AhPrP6BKT#_XdT7&;F71j}Joy zkC~6lh7E@6o;W@^IpRNZ{ptLtL(gQ-CY~4mqW;US7Zxvm_|@yz&e53Bp_lTPlfP|z zrTyx_>lv@x#=^!PzR7qqF<$gm`|ZJZ+;<)Cqu&ot2z=0000WV@Og>004R=004l4008;_004mL004C`008P>0026e000+nl3&F} z0006ANkl1!Ng#NCHVDfh3Sb5*lS@TnAp6ozA+y`SIhcXOch?TAaI7))v>+NAf$9kU^6~ z5=KF+@0?}WPN_`VpZ-y656(zjj2gxFybZ%lSC5gr1oofxpejVn@J)GatD({5=a6`B!MK7KoUqI2_%6el0XtkAPFRq1d>2f bC-@!!YwEWmzrf literal 0 HcmV?d00001 diff --git a/common/img/sprites/spritesmith/stable/mounts/Mount_Head_PandaCub-Spooky.png b/common/img/sprites/spritesmith/stable/mounts/Mount_Head_PandaCub-Spooky.png new file mode 100644 index 0000000000000000000000000000000000000000..b6ed602a3090742bf381d319e59742875669c768 GIT binary patch literal 3437 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 literal 0 HcmV?d00001 diff --git a/common/img/sprites/spritesmith/stable/mounts/Mount_Head_TigerCub-Spooky.png b/common/img/sprites/spritesmith/stable/mounts/Mount_Head_TigerCub-Spooky.png new file mode 100644 index 0000000000000000000000000000000000000000..01f5461c7b306c111c101a32113e4c0acd23db3c GIT binary patch literal 3504 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 Us>OJ3?^XiPRyRFY#G~`~Uy| literal 0 HcmV?d00001 diff --git a/common/img/sprites/spritesmith/stable/mounts/Mount_Head_Wolf-Spooky.png b/common/img/sprites/spritesmith/stable/mounts/Mount_Head_Wolf-Spooky.png new file mode 100644 index 0000000000000000000000000000000000000000..a649bfd8b3736f97135019464ea26b6339c3d728 GIT binary patch literal 3944 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 literal 0 HcmV?d00001 diff --git a/common/img/sprites/spritesmith/stable/pets/Pet-Cactus-Spooky.png b/common/img/sprites/spritesmith/stable/pets/Pet-Cactus-Spooky.png new file mode 100644 index 0000000000000000000000000000000000000000..db480cdc1e40836061c7e2667a11cdea5c4148c1 GIT binary patch literal 3324 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 EFGJrq*#H0l literal 0 HcmV?d00001 diff --git a/common/img/sprites/spritesmith/stable/pets/Pet-Dragon-Spooky.png b/common/img/sprites/spritesmith/stable/pets/Pet-Dragon-Spooky.png new file mode 100644 index 0000000000000000000000000000000000000000..e746f2888bcba3ce699fa609f874fea9e1c1bbbd GIT binary patch literal 3453 zcmV-@4TAECP)KLZ*U+IBfRsybQWXdwQbLP>6pAqfylh#{fb6;Z(vMMVS~$e@S=j*ftg6;Uhf59&ghTmgWD0l;*T zI709Y^p6lP1rIRMx#05C~cW=H_Aw*bJ-5DT&Z2n+x)QHX^p z00esgV8|mQcmRZ%02D^@S3L16t`O%c004NIvOKvYIYoh62rY33S640`D9%Y2D-rV&neh&#Q1i z007~1e$oCcFS8neI|hJl{-P!B1ZZ9hpmq0)X0i`JwE&>$+E?>%_LC6RbVIkUx0b+_+BaR3cnT7Zv!AJxW zizFb)h!jyGOOZ85F;a?DAXP{m@;!0_IfqH8(HlgRxt7s3}k3K`kFu>>-2Q$QMFfPW!La{h336o>X zu_CMttHv6zR;&ZNiS=X8v3CR#fknUxHUxJ0uoBa_M6WNWeqIg~6QE69c9o#eyhGvpiOA@W-aonk<7r1(?fC{oI5N*U!4 zfg=2N-7=cNnjjOr{yriy6mMFgG#l znCF=fnQv8CDz++o6_Lscl}eQ+l^ZHARH>?_s@|##Rr6KLRFA1%Q+=*RRWnoLsR`7U zt5vFIcfW3@?wFpwUVxrVZ>QdQz32KIeJ}k~{cZZE^+ya? z2D1z#2HOnI7(B%_ac?{wFUQ;QQA1tBKtrWrm0_3Rgps+?Jfqb{jYbcQX~taRB;#$y zZN{S}1|}gUOHJxc?wV3fxuz+mJ4`!F$IZ;mqRrNsHJd##*D~ju=bP7?-?v~|cv>vB zsJ6IeNwVZxrdjT`yl#bBIa#GxRa#xMMy;K#CDyyGyQdMSxlWT#tDe?p!?5wT$+oGt z8L;Kp2HUQ-ZMJ=3XJQv;x5ci*?vuTfeY$;({XGW_huIFR9a(?@3)XSs8O^N5RyOM=TTmp(3=8^+zpz2r)C z^>JO{deZfso3oq3?Wo(Y?l$ge?uXo;%ru`Vo>?<<(8I_>;8Eq#KMS9gFl*neeosSB zfoHYnBQIkwkyowPu(zdms`p{<7e4kra-ZWq<2*OsGTvEV%s0Td$hXT+!*8Bnh2KMe zBmZRodjHV?r+_5^X9J0WL4jKW`}lf%A-|44I@@LTvf1rHjG(ze6+w@Jt%Bvjts!X0 z?2xS?_ve_-kiKB_KiJlZ$9G`c^=E@oNG)mWWaNo-3TIW8)$Hg0Ub-~8?KhvJ>$ z3*&nim@mj(aCxE5!t{lw7O5^0EIO7zOo&c6l<+|iDySBWCGrz@C5{St!X3hAA}`T4 z(TLbXTq+(;@<=L8dXnssyft|w#WSTW<++3>sgS%(4NTpeI-VAqb|7ssJvzNHgOZVu zaYCvgO_R1~>SyL=cFU|~g|hy|Zi}}s9+d~lYqOB71z9Z$wnC=pR9Yz4DhIM>Wmjgu z&56o6maCpC&F##y%G;1PobR9i?GnNg;gYtchD%p19a!eQtZF&3JaKv33gZ<8D~47E ztUS1iwkmDaPpj=$m#%)jCVEY4fnLGNg2A-`YwHVD3gv};>)hAvT~AmqS>Lr``i7kw zJ{5_It`yrBmlc25DBO7E8;5VoznR>Ww5hAaxn$2~(q`%A-YuS64wkBy=9dm`4cXeX z4c}I@?e+FW+b@^RDBHV(wnMq2zdX3SWv9u`%{xC-q*U}&`cyXV(%rRT*Z6MH?i+i& z_B8C(+grT%{XWUQ+f@NoP1R=AW&26{v-dx)iK^-Nmiuj8txj!m?Z*Ss1N{dh4z}01 z)YTo*JycSU)+_5r4#yw9{+;i4Ee$peRgIj+;v;ZGdF1K$3E%e~4LaI(jC-u%2h$&R z9cLXcYC@Xwnns&bn)_Q~Te?roKGD|d-g^8;+aC{{G(1^(O7m37Y1-+6)01cN&y1aw zoqc{T`P^XJqPBbIW6s}d4{z_f5Om?vMgNQEJG?v2T=KYd^0M3I6IZxbny)%vZR&LD zJpPl@Psh8QyPB@KTx+@RdcC!KX7}kEo;S|j^u2lU7XQ}Oo;f|;z4Ll+_r>@1-xl3| zawq-H%e&ckC+@AhPrP6BKT#_XdT7&;F71j}Joy zkC~6lh7E@6o;W@^IpRNZ{ptLtL(gQ-CY~4mqW;US7Zxvm_|@yz&e53Bp_lTPlfP|z zrTyx_>lv@x#=^!PzR7qqF<$gm`|ZJZ+;<)Cqu&ot2z=0000WV@Og>004R=004l4008;_004mL004C`008P>0026e000+nl3&F} z00080NklUuQZOy}Z0Ljvt=SKJU!9 z;lW@KB9kQo0w4krhy;j01R@X#5P=9pAQB(~5r{w}Km;NXfk=P|L?8l@01=2lBtQfr z5P?X52t*(Pk?0fs-@m|_QxWx}^Dn>q;c?eciRg^ZGgr9%Eux*5F|F}SZ7LCn=HR-s%(>d18%VYiO)Knrm2P5Gi|G%>vg|9wY zQse#dPsel0^~WC?A#_G(y7OGbuTD)RqVt02oKB~;?ccI2$EVQp5ms+ke}37KPvqKa zyuNwUu->8)(HWh`Q#iSjQuD2kM~=tJ&M4Jxl)kDpvCL`hu_lFUTY81h-)gbhMrZDw zM=SjP@gFsR>3-C)Bb&~1cwp=Qefy+#y;S?xJ7?wnQkY6a=Q-=nCWYN>s@-hJrNXz{ zIc>L<3ir#ls$IipUA$4!ey*GAq!Q72K{nf_&S+A`O&1>Ou=Z{7&^zT&$R58iT-%+y zB`Oh}(RuR7u5IeV@~0rNjQ&qVZOfkTUfCa8)n|_$s&S!Mq!Q7Yd*{&`=Dq8m9q(bi zcKJ_S>*=O|N<`-c(K%>pn>3dlc@l-GM08#dolR<+HsM~? zzE(f0#;+?C$7Ap9JWyl#vJ9Qk8J(x9xr}^gEuUt~mtUs!rl2!Aqw`EO_o}BGwVyw& zt8u~>B>CWhk&VkyHPeV^C5s2taB@!S4 f5r_nce&p`}{ZbUOvEr3K00000NkvXXu0mjfqv4EE literal 0 HcmV?d00001 diff --git a/common/img/sprites/spritesmith/stable/pets/Pet-FlyingPig-Spooky.png b/common/img/sprites/spritesmith/stable/pets/Pet-FlyingPig-Spooky.png new file mode 100644 index 0000000000000000000000000000000000000000..3a6e884d5f07518111de43eb505ddc722e29ffbb GIT binary patch literal 3546 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 UEDRW9zW@LL07*qoM6N<$f@ce+DgXcg literal 0 HcmV?d00001 diff --git a/common/img/sprites/spritesmith/stable/pets/Pet-Fox-Spooky.png b/common/img/sprites/spritesmith/stable/pets/Pet-Fox-Spooky.png new file mode 100644 index 0000000000000000000000000000000000000000..e6d196adabfaa47eee5113d4c530caf44ca75d82 GIT binary patch literal 3399 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 literal 0 HcmV?d00001 diff --git a/common/img/sprites/spritesmith/stable/pets/Pet-LionCub-Spooky.png b/common/img/sprites/spritesmith/stable/pets/Pet-LionCub-Spooky.png new file mode 100644 index 0000000000000000000000000000000000000000..104277605dfb05b0c0226a0630038661e6985a8c GIT binary patch literal 3337 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 Tc*LJ000000NkvXXu0mjfGO9Gd literal 0 HcmV?d00001 diff --git a/common/img/sprites/spritesmith/stable/pets/Pet-PandaCub-Spooky.png b/common/img/sprites/spritesmith/stable/pets/Pet-PandaCub-Spooky.png new file mode 100644 index 0000000000000000000000000000000000000000..876de60ee095f134d907acded5db4188dc18c411 GIT binary patch literal 3269 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 literal 0 HcmV?d00001 diff --git a/common/img/sprites/spritesmith/stable/pets/Pet-TigerCub-Spooky.png b/common/img/sprites/spritesmith/stable/pets/Pet-TigerCub-Spooky.png new file mode 100644 index 0000000000000000000000000000000000000000..c01662e804dc581447338a5a0fbf2ad7e8e75a0a GIT binary patch literal 3461 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 literal 0 HcmV?d00001 diff --git a/common/img/sprites/spritesmith/stable/pets/Pet-Wolf-Spooky.png b/common/img/sprites/spritesmith/stable/pets/Pet-Wolf-Spooky.png new file mode 100644 index 0000000000000000000000000000000000000000..7144c77c3e6c3df95003517163b97d7da4f35862 GIT binary patch literal 3454 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 literal 0 HcmV?d00001 diff --git a/common/img/sprites/spritesmith/stable/potions/Pet_HatchingPotion_Spooky.png b/common/img/sprites/spritesmith/stable/potions/Pet_HatchingPotion_Spooky.png new file mode 100644 index 0000000000000000000000000000000000000000..62d2bfc325e9fe41523341d59aa73f2e1e62d44d GIT binary patch literal 3196 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 ia-sx`j!q9{02lx=W9IIA Date: Tue, 22 Sep 2015 14:23:52 -0400 Subject: [PATCH 04/16] feat(pets): Spooky pets/mounts --- common/locales/en/pets.json | 1 + common/script/content/index.coffee | 9 +++++++-- website/src/models/user.js | 11 ++++++----- website/views/options/inventory/drops.jade | 14 +++++++++++++- website/views/options/inventory/mounts.jade | 2 +- website/views/options/inventory/pets.jade | 2 +- website/views/options/inventory/seasonal-shop.jade | 11 ++++++++++- 7 files changed, 39 insertions(+), 11 deletions(-) diff --git a/common/locales/en/pets.json b/common/locales/en/pets.json index b71cc08173..b6421abdc9 100644 --- a/common/locales/en/pets.json +++ b/common/locales/en/pets.json @@ -24,6 +24,7 @@ "eggSingular": "egg", "noEggs": "You don't have any eggs.", "hatchingPotions": "Hatching Potions", + "magicHatchingPotions": "Magic Hatching Potions", "hatchingPotion": "hatching potion", "noHatchingPotions": "You don't have any hatching potions.", "inventoryText": "Click an egg to see usable potions highlighted in green and then click one of the highlighted potions to hatch your pet. If no potions are highlighted, click that egg again to deselect it, and instead click a potion first to have the usable eggs highlighted. You can also sell unwanted drops to Alexander the Merchant.", diff --git a/common/script/content/index.coffee b/common/script/content/index.coffee index fb3eded07b..fc0c621545 100644 --- a/common/script/content/index.coffee +++ b/common/script/content/index.coffee @@ -1165,16 +1165,21 @@ api.hatchingPotions = CottonCandyPink: value: 4, text: t('hatchingPotionCottonCandyPink') CottonCandyBlue: value: 4, text: t('hatchingPotionCottonCandyBlue') Golden: value: 5, text: t('hatchingPotionGolden') - Spooky: value: 3, text: t('hatchingPotionSpooky'), premium: true + Spooky: value: 3, text: t('hatchingPotionSpooky'), premium: true, limited: true _.each api.hatchingPotions, (pot,key) -> - _.defaults pot, {key, value: 2, notes: t('hatchingPotionNotes', {potText: pot.text}), premium: false, canBuy: true} + _.defaults pot, {key, value: 2, notes: t('hatchingPotionNotes', {potText: pot.text}), premium: false, limited: false, canBuy: true} api.pets = _.transform api.dropEggs, (m, egg) -> _.defaults m, _.transform api.hatchingPotions, (m2, pot) -> if not pot.premium m2[egg.key + "-" + pot.key] = true +api.premiumPets = _.transform api.dropEggs, (m, egg) -> + _.defaults m, _.transform api.hatchingPotions, (m2, pot) -> + if pot.premium + m2[egg.key + "-" + pot.key] = true + api.questPets = _.transform api.questEggs, (m, egg) -> _.defaults m, _.transform api.hatchingPotions, (m2, pot) -> if not pot.premium diff --git a/website/src/models/user.js b/website/src/models/user.js index cf124db584..c883caacc1 100644 --- a/website/src/models/user.js +++ b/website/src/models/user.js @@ -232,10 +232,10 @@ var UserSchema = new Schema({ _.defaults( // First transform to a 1D eggs/potions mapping _.transform(shared.content.pets, function(m,v,k){ m[k] = Number; }), - // Then add quest pets + // Then add additional pets (quest, backer, contributor, premium) _.transform(shared.content.questPets, function(m,v,k){ m[k] = Number; }), - // Then add additional pets (backer, contributor) - _.transform(shared.content.specialPets, function(m,v,k){ m[k] = Number; }) + _.transform(shared.content.specialPets, function(m,v,k){ m[k] = Number; }), + _.transform(shared.content.premiumPets, function(m,v,k){ m[k] = Number; }) ), currentPet: String, // Cactus-Desert @@ -265,9 +265,10 @@ var UserSchema = new Schema({ mounts: _.defaults( // First transform to a 1D eggs/potions mapping _.transform(shared.content.pets, function(m,v,k){ m[k] = Boolean; }), - // Then add quest pets + // Then add quest and premium pets _.transform(shared.content.questPets, function(m,v,k){ m[k] = Boolean; }), - // Then add additional pets (backer, contributor) + _.transform(shared.content.premiumPets, function(m,v,k){ m[k] = Boolean; }), + // Then add additional mounts (backer, contributor) _.transform(shared.content.specialMounts, function(m,v,k){ m[k] = Boolean; }) ), currentMount: String, diff --git a/website/views/options/inventory/drops.jade b/website/views/options/inventory/drops.jade index 7812aece22..de0b102248 100644 --- a/website/views/options/inventory/drops.jade +++ b/website/views/options/inventory/drops.jade @@ -134,7 +134,19 @@ li.customize-menu menu.pets-menu(label=env.t('hatchingPotions')) p.muted!=env.t('dropsExplanation') - div(ng-repeat='pot in Content.hatchingPotions', ng-if='pot.canBuy') + div(ng-repeat='pot in Content.hatchingPotions', ng-if='!pot.premium') + button.customize-option(class='Pet_HatchingPotion_{{::pot.key}}', + popover='{{::pot.notes()}}', popover-append-to-body='true', + popover-title!=env.t("potion", {potionType: "{{::pot.text()}}"}), + popover-trigger='mouseenter', popover-placement='top', + ng-click='purchase("hatchingPotions", pot)') + p + | {{::pot.value}}  + span.Pet_Currency_Gem1x.inline-gems + + li.customize-menu + menu.pets-menu(label=env.t('magicHatchingPotions')) + div(ng-repeat='pot in Content.hatchingPotions', ng-if='pot.premium') button.customize-option(class='Pet_HatchingPotion_{{::pot.key}}', popover='{{::pot.notes()}}', popover-append-to-body='true', popover-title!=env.t("potion", {potionType: "{{::pot.text()}}"}), diff --git a/website/views/options/inventory/mounts.jade b/website/views/options/inventory/mounts.jade index c5b3f3f273..f1317e1a39 100644 --- a/website/views/options/inventory/mounts.jade +++ b/website/views/options/inventory/mounts.jade @@ -8,7 +8,7 @@ mixin mountList(source,showPremium) - mount = egg.key+"-"+potion.key div(popover-trigger='mouseenter', popover=env.t('mountName', {potion: potion.text(env.language.code), mount: egg.mountText(env.language.code)}), popover-placement='bottom', ng-hide='#{potion.premium} && #{!showPremium}') button(class="pet-button Mount_Head_#{mount}", ng-show='user.items.mounts["#{mount}"]', ng-class='{active: user.items.currentMount == "#{mount}"}', ng-click='chooseMount("#{egg.key}", "#{potion.key}")') - button(class="pet-button mount-not-owned", ng-hide='user.items.mounts["#{mount}"]') + button(class="pet-button mount-not-owned", ng-if='!user.items.mounts["#{mount}"] && (#{potion.canBuy} || user.items.hatchingPotions["#{potion.key}"] || user.items.pets["#{mount}"])') .PixelPaw -} diff --git a/website/views/options/inventory/pets.jade b/website/views/options/inventory/pets.jade index 86879215ba..3ee59389b2 100644 --- a/website/views/options/inventory/pets.jade +++ b/website/views/options/inventory/pets.jade @@ -9,7 +9,7 @@ mixin petList(source,showPremium) button(class="pet-button Pet-#{pet}", ng-if='user.items.pets["#{pet}"]>0', ng-class='{active: user.items.currentPet == "#{pet}", selectableInventory: #{!egg.noMount} && selectedFood && !user.items.mounts["#{pet}"]}', ng-click='choosePet("#{egg.key}", "#{potion.key}")') .progress(ng-show='!user.items.mounts["#{pet}"]') .progress-bar.progress-bar-success(ng-style='{width: user.items.pets["#{pet}"]/.5 + "%"}') - button(class="pet-button pet-not-owned", ng-if='!user.items.pets["#{pet}"]') + button(class="pet-button pet-not-owned", ng-if='!user.items.pets["#{pet}"] && (#{potion.canBuy} || user.items.hatchingPotions["#{potion.key}"])') .PixelPaw button(class="pet-evolved pet-button Pet-#{pet}", ng-if='user.items.pets["#{pet}"]<0') diff --git a/website/views/options/inventory/seasonal-shop.jade b/website/views/options/inventory/seasonal-shop.jade index ecfc4b72c7..fb63545e17 100644 --- a/website/views/options/inventory/seasonal-shop.jade +++ b/website/views/options/inventory/seasonal-shop.jade @@ -33,7 +33,7 @@ span.Pet_Currency_Gem1x.inline-gems menu.pets-menu(label=env.t('seasonalItems')) div - button.customize-option(class='shop_spookDust', + button.customize-option(class='inventory_special_spookDust', popover='{{::Content.spells.special.spookDust.notes()}}', popover-title='{{::Content.spells.special.spookDust.text()}}', popover-trigger='mouseenter', popover-placement='right', @@ -41,6 +41,15 @@ ng-click='purchase("special", Content.spells.special.spookDust)') p {{::Content.spells.special.spookDust.value}} span(class='shop_gold') + div + button.customize-option(class='Pet_HatchingPotion_Spooky', + popover='{{::Content.hatchingPotions.Spooky.notes()}}', + popover-title!=env.t("potion", {potionType: "{{::Content.hatchingPotions.Spooky.text()}}"}), + popover-trigger='mouseenter', popover-placement='right', + popover-append-to-body='true', + ng-click='purchase("hatchingPotions", Content.hatchingPotions.Spooky)') + p {{::Content.hatchingPotions.Spooky.value}}  + span.Pet_Currency_Gem1x.inline-gems // div button.customize-option(popover='{{::Content.spells.special.nye.notes()}}', popover-title='{{::Content.spells.special.nye.text()}}', popover-trigger='mouseenter', popover-placement='right', popover-append-to-body='true', ng-click='castStart(Content.spells.special.nye)', class='inventory_special_nye') From 8c67d22a91abb8efde12bb91291039295cf6e845 Mon Sep 17 00:00:00 2001 From: Sabe Jones Date: Tue, 22 Sep 2015 17:03:41 -0400 Subject: [PATCH 05/16] feat(pets): Full purchase behavior --- common/locales/en/messages.json | 2 + common/script/index.coffee | 10 +- test/common/user.ops.hatch.js | 139 +++++++++++++++++++++ website/views/options/inventory/drops.jade | 4 +- 4 files changed, 149 insertions(+), 6 deletions(-) create mode 100644 test/common/user.ops.hatch.js diff --git a/common/locales/en/messages.json b/common/locales/en/messages.json index bf23a6363c..70c65c7b62 100644 --- a/common/locales/en/messages.json +++ b/common/locales/en/messages.json @@ -5,6 +5,7 @@ "messageTagNotFound": "Tag not found.", "messagePetNotFound": ":pet not found in user.items.pets", "messageFoodNotFound": ":food not found in user.items.food", + "messageNotAvailable": "This item is not currently available for purchase.", "messageCannotFeedPet": "Can't feed this pet.", "messageAlreadyMount": "You already have that mount. Try feeding another pet.", "messageEvolve": "You have tamed <%= egg %>, let's go for a ride!", @@ -14,6 +15,7 @@ "messageEquipped": " <%= itemText %> equipped.", "messageUnEquipped": "<%= itemText %> un-equipped.", "messageMissingEggPotion": "You're missing either that egg or that potion", + "messageInvalidEggPotionCombo": "Invalid egg+potion combination. Try hatching a different egg!", "messageAlreadyPet": "You already have that pet. Try hatching a different combination!", "messageHatched": "Your egg hatched! Visit your stable to equip your pet.", "messageNotEnoughGold": "Not Enough Gold", diff --git a/common/script/index.coffee b/common/script/index.coffee index 3672e584e1..d25ad683a2 100644 --- a/common/script/index.coffee +++ b/common/script/index.coffee @@ -822,7 +822,8 @@ api.wrap = (user, main=true) -> item = content[type][key] price = item.value / 4 return cb?({code:404,message:":key not found for Content.#{type}"},req) unless item - return cb?({code:401, message: i18n.t('notEnoughGems', req.language)}) if (user.balance < price) or !user.balance + return cb?({code:403, message: i18n.t('messageNotAvailable', req.language)}) if type is 'hatchingPotions' and not item.canBuy + return cb?({code:403, message: i18n.t('notEnoughGems', req.language)}) if (user.balance < price) or !user.balance user.balance -= price if type is 'gear' then user.items.gear.owned[key] = true else @@ -1070,10 +1071,11 @@ api.wrap = (user, main=true) -> hatch: (req, cb) -> {egg, hatchingPotion} = req.params - return cb?({code:404,message:"Please specify query.egg & query.hatchingPotion"}) unless egg and hatchingPotion - return cb?({code:401,message:i18n.t('messageMissingEggPotion', req.language)}) unless user.items.eggs[egg] > 0 and user.items.hatchingPotions[hatchingPotion] > 0 + return cb?({code:400,message:"Please specify query.egg & query.hatchingPotion"}) unless egg and hatchingPotion + return cb?({code:403,message:i18n.t('messageMissingEggPotion', req.language)}) unless user.items.eggs[egg] > 0 and user.items.hatchingPotions[hatchingPotion] > 0 + return cb?({code:403,message:i18n.t('messageInvalidEggPotionCombo', req.language)}) if content.hatchingPotions[hatchingPotion].premium and not content.dropEggs[egg] pet = "#{egg}-#{hatchingPotion}" - return cb?({code:401, message:i18n.t('messageAlreadyPet', req.language)}) if user.items.pets[pet] and user.items.pets[pet] > 0 + return cb?({code:403, message:i18n.t('messageAlreadyPet', req.language)}) if user.items.pets[pet] and user.items.pets[pet] > 0 user.items.pets[pet] = 5 user.items.eggs[egg]-- user.items.hatchingPotions[hatchingPotion]-- diff --git a/test/common/user.ops.hatch.js b/test/common/user.ops.hatch.js new file mode 100644 index 0000000000..2ec1d627d3 --- /dev/null +++ b/test/common/user.ops.hatch.js @@ -0,0 +1,139 @@ +var sinon = require('sinon'); +var chai = require('chai'); +chai.use(require('sinon-chai')) +var expect = chai.expect + +require('coffee-script'); +var shared = require('../../common/script/index.coffee'); +var content = require('../../common/script/content/index.coffee'); + +describe('user.ops.hatch', function() { + var user; + + beforeEach(function() { + user = { + items: { + eggs: {}, + hatchingPotions: {}, + pets: {} + } + }; + + shared.wrap(user); + }); + + context('Pet Hatching', function() { + + context('failure conditions', function() { + + it('does not allow hatching without specifying egg and potion', function(done) { + user.ops.hatch({params:{}},function(response) { + expect(response.message).to.eql('Please specify query.egg & query.hatchingPotion'); + expect(user.items.pets).to.be.empty; + done(); + }); + }); + + it('does not allow hatching if user lacks specified egg', function(done) { + user.items.eggs = {'Wolf':1}; + user.items.hatchingPotions = {'Base':1}; + user.ops.hatch({params:{egg:'Dragon',hatchingPotion:'Base'}}, function(response) { + expect(response.message).to.eql(shared.i18n.t('messageMissingEggPotion')); + expect(user.items.pets).to.be.empty; + expect(user.items.eggs).to.eql({'Wolf':1}); + expect(user.items.hatchingPotions).to.eql({'Base':1}); + done(); + }); + }); + + it('does not allow hatching if user lacks specified hatching potion', function(done) { + user.items.eggs = {'Wolf':1}; + user.items.hatchingPotions = {'Base':1}; + user.ops.hatch({params:{egg:'Wolf',hatchingPotion:'Golden'}}, function(response) { + expect(response.message).to.eql(shared.i18n.t('messageMissingEggPotion')); + expect(user.items.pets).to.be.empty; + expect(user.items.eggs).to.eql({'Wolf':1}); + expect(user.items.hatchingPotions).to.eql({'Base':1}); + done(); + }); + }); + + it('does not allow hatching if user already owns target pet', function(done) { + user.items.eggs = {'Wolf':1}; + user.items.hatchingPotions = {'Base':1}; + user.items.pets = {'Wolf-Base':10}; + user.ops.hatch({params:{egg:'Wolf',hatchingPotion:'Base'}}, function(response) { + expect(response.message).to.eql(shared.i18n.t('messageAlreadyPet')); + expect(user.items.pets).to.eql({'Wolf-Base':10}); + expect(user.items.eggs).to.eql({'Wolf':1}); + expect(user.items.hatchingPotions).to.eql({'Base':1}); + done(); + }); + }); + + it('does not allow hatching quest pet egg using premium potion', function(done) { + user.items.eggs = {'Cheetah':1}; + user.items.hatchingPotions = {'Spooky':1}; + user.ops.hatch({params:{egg:'Cheetah',hatchingPotion:'Spooky'}}, function(response) { + expect(response.message).to.eql(shared.i18n.t('messageInvalidEggPotionCombo')); + expect(user.items.pets).to.be.empty; + expect(user.items.eggs).to.eql({'Cheetah':1}); + expect(user.items.hatchingPotions).to.eql({'Spooky':1}); + done(); + }); + }); + }); + + context('successful hatching', function() { + + it('hatches a basic pet', function(done) { + user.items.eggs = {'Wolf':1}; + user.items.hatchingPotions = {'Base':1}; + user.ops.hatch({params:{egg:'Wolf',hatchingPotion:'Base'}}, function(response) { + expect(response.message).to.eql(shared.i18n.t('messageHatched')); + expect(user.items.pets).to.eql({'Wolf-Base':5}); + expect(user.items.eggs).to.eql({'Wolf':0}); + expect(user.items.hatchingPotions).to.eql({'Base':0}); + done(); + }); + }); + + it('hatches a quest pet', function(done) { + user.items.eggs = {'Cheetah':1}; + user.items.hatchingPotions = {'Base':1}; + user.ops.hatch({params:{egg:'Cheetah',hatchingPotion:'Base'}}, function(response) { + expect(response.message).to.eql(shared.i18n.t('messageHatched')); + expect(user.items.pets).to.eql({'Cheetah-Base':5}); + expect(user.items.eggs).to.eql({'Cheetah':0}); + expect(user.items.hatchingPotions).to.eql({'Base':0}); + done(); + }); + }); + + it('hatches a premium pet', function(done) { + user.items.eggs = {'Wolf':1}; + user.items.hatchingPotions = {'Spooky':1}; + user.ops.hatch({params:{egg:'Wolf',hatchingPotion:'Spooky'}}, function(response) { + expect(response.message).to.eql(shared.i18n.t('messageHatched')); + expect(user.items.pets).to.eql({'Wolf-Spooky':5}); + expect(user.items.eggs).to.eql({'Wolf':0}); + expect(user.items.hatchingPotions).to.eql({'Spooky':0}); + done(); + }); + }); + + it('hatches a pet previously raised to a mount', function(done) { + user.items.eggs = {'Wolf':1}; + user.items.hatchingPotions = {'Base':1}; + user.items.pets = {'Wolf-Base':-1}; + user.ops.hatch({params:{egg:'Wolf',hatchingPotion:'Base'}}, function(response) { + expect(response.message).to.eql(shared.i18n.t('messageHatched')); + expect(user.items.pets).to.eql({'Wolf-Base':5}); + expect(user.items.eggs).to.eql({'Wolf':0}); + expect(user.items.hatchingPotions).to.eql({'Base':0}); + done(); + }); + }); + }); + }); +}); diff --git a/website/views/options/inventory/drops.jade b/website/views/options/inventory/drops.jade index de0b102248..4a98a9a57c 100644 --- a/website/views/options/inventory/drops.jade +++ b/website/views/options/inventory/drops.jade @@ -18,7 +18,7 @@ .badge.badge-info.stack-count {{points}} li.customize-menu - menu.hatchingPotion-menu(label=(env.t('hatchingPotions') + ' ({{potCount}})')) + menu.pets-menu(label=(env.t('hatchingPotions') + ' ({{potCount}})')) p.muted(ng-show='potCount < 1')=env.t('noHatchingPotions') div(ng-repeat='(pot,points) in ownedItems(user.items.hatchingPotions)') button.customize-option(class='Pet_HatchingPotion_{{::pot}}', @@ -146,7 +146,7 @@ li.customize-menu menu.pets-menu(label=env.t('magicHatchingPotions')) - div(ng-repeat='pot in Content.hatchingPotions', ng-if='pot.premium') + div(ng-repeat='pot in Content.hatchingPotions', ng-if='pot.premium && pot.canBuy') button.customize-option(class='Pet_HatchingPotion_{{::pot.key}}', popover='{{::pot.notes()}}', popover-append-to-body='true', popover-title!=env.t("potion", {potionType: "{{::pot.text()}}"}), From 1aa5757847dc25146bd39455861ede5ae0d3f1d3 Mon Sep 17 00:00:00 2001 From: Sabe Jones Date: Wed, 23 Sep 2015 16:40:45 -0400 Subject: [PATCH 06/16] fix(magic-potions): Hatching tweaks * Additional notes on popover noting magic potions can't be used on quest pet eggs * Less techy error message when attempting to hatch quest pet egg with magic potion * Don't highlight quest pet eggs as targets for magic hatching potion --- common/locales/en/content.json | 1 + common/locales/en/messages.json | 2 +- common/script/content/index.coffee | 2 +- website/views/options/inventory/drops.jade | 8 ++++---- 4 files changed, 7 insertions(+), 6 deletions(-) diff --git a/common/locales/en/content.json b/common/locales/en/content.json index 4220c77ddc..586fea1849 100644 --- a/common/locales/en/content.json +++ b/common/locales/en/content.json @@ -117,6 +117,7 @@ "hatchingPotionSpooky": "Spooky", "hatchingPotionNotes": "Pour this on an egg, and it will hatch as a <%= potText(locale) %> pet.", + "premiumPotionAddlNotes": "Not usable on quest pet eggs.", "foodMeat": "Meat", "foodMilk": "Milk", diff --git a/common/locales/en/messages.json b/common/locales/en/messages.json index 70c65c7b62..4b7b394656 100644 --- a/common/locales/en/messages.json +++ b/common/locales/en/messages.json @@ -15,7 +15,7 @@ "messageEquipped": " <%= itemText %> equipped.", "messageUnEquipped": "<%= itemText %> un-equipped.", "messageMissingEggPotion": "You're missing either that egg or that potion", - "messageInvalidEggPotionCombo": "Invalid egg+potion combination. Try hatching a different egg!", + "messageInvalidEggPotionCombo": "You can't hatch that egg with this potion. Try a different egg!", "messageAlreadyPet": "You already have that pet. Try hatching a different combination!", "messageHatched": "Your egg hatched! Visit your stable to equip your pet.", "messageNotEnoughGold": "Not Enough Gold", diff --git a/common/script/content/index.coffee b/common/script/content/index.coffee index 1f88f38671..2fa0a0d73f 100644 --- a/common/script/content/index.coffee +++ b/common/script/content/index.coffee @@ -1168,7 +1168,7 @@ api.hatchingPotions = CottonCandyPink: value: 4, text: t('hatchingPotionCottonCandyPink') CottonCandyBlue: value: 4, text: t('hatchingPotionCottonCandyBlue') Golden: value: 5, text: t('hatchingPotionGolden') - Spooky: value: 3, text: t('hatchingPotionSpooky'), premium: true, limited: true + Spooky: value: 3, text: t('hatchingPotionSpooky'), addlNotes: t('premiumPotionAddlNotes'), premium: true, limited: true _.each api.hatchingPotions, (pot,key) -> _.defaults pot, {key, value: 2, notes: t('hatchingPotionNotes', {potText: pot.text}), premium: false, limited: false, canBuy: true} diff --git a/website/views/options/inventory/drops.jade b/website/views/options/inventory/drops.jade index 4a98a9a57c..b64523cdfd 100644 --- a/website/views/options/inventory/drops.jade +++ b/website/views/options/inventory/drops.jade @@ -10,7 +10,7 @@ p.muted(ng-show='eggCount < 1')=env.t('noEggs') div(ng-repeat='(egg,points) in ownedItems(user.items.eggs)') button.customize-option(class='Pet_Egg_{{::egg}}', - ng-class='{selectableInventory: selectedPotion && !(user.items.pets[egg+"-"+selectedPotion.key]>0)}', + ng-class='{selectableInventory: selectedPotion && !(user.items.pets[egg+"-"+selectedPotion.key]>0) && (Content.dropEggs[egg] || !selectedPotion.premium)}', popover='{{::Content.eggs[egg].notes()}}', popover-append-to-body='true', popover-title!=env.t("egg", {eggType: "{{::Content.eggs[egg].text()}}"}), popover-trigger='mouseenter', popover-placement='right', @@ -22,8 +22,8 @@ p.muted(ng-show='potCount < 1')=env.t('noHatchingPotions') div(ng-repeat='(pot,points) in ownedItems(user.items.hatchingPotions)') button.customize-option(class='Pet_HatchingPotion_{{::pot}}', - ng-class='{selectableInventory: selectedEgg && !(user.items.pets[selectedEgg.key+"-"+pot]>0)}', - popover='{{::Content.hatchingPotions[pot].notes()}}', + ng-class='{selectableInventory: selectedEgg && !(user.items.pets[selectedEgg.key+"-"+pot]>0) && (Content.dropEggs[selectedEgg.key] || !Content.hatchingPotions[pot].premium)}', + popover='{{::Content.hatchingPotions[pot].notes()}} {{::Content.hatchingPotions[pot].addlNotes()}}', popover-title!=env.t("potion", {potionType: "{{::Content.hatchingPotions[pot].text()}}"}), popover-trigger='mouseenter', popover-placement='right', popover-append-to-body='true', @@ -148,7 +148,7 @@ menu.pets-menu(label=env.t('magicHatchingPotions')) div(ng-repeat='pot in Content.hatchingPotions', ng-if='pot.premium && pot.canBuy') button.customize-option(class='Pet_HatchingPotion_{{::pot.key}}', - popover='{{::pot.notes()}}', popover-append-to-body='true', + popover='{{::pot.notes()}} {{::pot.addlNotes()}}', popover-append-to-body='true', popover-title!=env.t("potion", {potionType: "{{::pot.text()}}"}), popover-trigger='mouseenter', popover-placement='top', ng-click='purchase("hatchingPotions", pot)') From 04416c4d73e29d81eb6b8f9ac7a6a5d5ba644f67 Mon Sep 17 00:00:00 2001 From: Sabe Jones Date: Thu, 24 Sep 2015 17:33:58 -0400 Subject: [PATCH 07/16] feat(pets): Improve egg canBuy logic --- common/locales/en/content.json | 62 +++++++++++----------- common/locales/en/messages.json | 2 +- common/script/content/index.coffee | 44 +++++++-------- website/views/options/inventory/drops.jade | 22 +------- 4 files changed, 55 insertions(+), 75 deletions(-) diff --git a/common/locales/en/content.json b/common/locales/en/content.json index 586fea1849..e22eb2643b 100644 --- a/common/locales/en/content.json +++ b/common/locales/en/content.json @@ -8,101 +8,101 @@ "armoireNotesEmpty": "The Armoire will have new Equipment in the first week of every month. Until then, keep clicking for Experience and Food!", "dropEggWolfText": "Wolf", - "dropEggWolfAdjective": "loyal", + "dropEggWolfAdjective": "a loyal", "dropEggTigerCubText": "Tiger Cub", "dropEggTigerCubMountText": "Tiger", - "dropEggTigerCubAdjective": "fierce", + "dropEggTigerCubAdjective": "a fierce", "dropEggPandaCubText": "Panda Cub", "dropEggPandaCubMountText": "Panda", - "dropEggPandaCubAdjective": "gentle", + "dropEggPandaCubAdjective": "a gentle", "dropEggLionCubText": "Lion Cub", "dropEggLionCubMountText": "Lion", - "dropEggLionCubAdjective": "regal", + "dropEggLionCubAdjective": "a regal", "dropEggFoxText": "Fox", - "dropEggFoxAdjective": "wily", + "dropEggFoxAdjective": "a wily", "dropEggFlyingPigText": "Flying Pig", - "dropEggFlyingPigAdjective": "whimsical", + "dropEggFlyingPigAdjective": "a whimsical", "dropEggDragonText": "Dragon", - "dropEggDragonAdjective": "mighty", + "dropEggDragonAdjective": "a mighty", "dropEggCactusText": "Cactus", - "dropEggCactusAdjective": "prickly", + "dropEggCactusAdjective": "a prickly", "dropEggBearCubText": "Bear Cub", "dropEggBearCubMountText": "Bear", - "dropEggBearCubAdjective": "cuddly", + "dropEggBearCubAdjective": "a cuddly", "questEggGryphonText": "Gryphon", - "questEggGryphonAdjective": "proud", + "questEggGryphonAdjective": "a proud", "questEggHedgehogText": "Hedgehog", - "questEggHedgehogAdjective": "spiky", + "questEggHedgehogAdjective": "a spiky", "questEggDeerText": "Deer", - "questEggDeerAdjective": "elegant", + "questEggDeerAdjective": "an elegant", "questEggEggText": "Egg", "questEggEggMountText": "Egg Basket", - "questEggEggAdjective": "colorful", + "questEggEggAdjective": "a colorful", "questEggRatText": "Rat", - "questEggRatAdjective": "dirty", + "questEggRatAdjective": "a dirty", "questEggOctopusText": "Octopus", - "questEggOctopusAdjective": "slippery", + "questEggOctopusAdjective": "a slippery", "questEggSeahorseText": "Seahorse", - "questEggSeahorseAdjective": "prize", + "questEggSeahorseAdjective": "a prize", "questEggParrotText": "Parrot", - "questEggParrotAdjective": "vibrant", + "questEggParrotAdjective": "a vibrant", "questEggRoosterText": "Rooster", - "questEggRoosterAdjective": "strutting", + "questEggRoosterAdjective": "a strutting", "questEggSpiderText": "Spider", - "questEggSpiderAdjective": "creepy", + "questEggSpiderAdjective": "a creepy", "questEggOwlText": "Owl", - "questEggOwlAdjective": "wise", + "questEggOwlAdjective": "a wise", "questEggPenguinText": "Penguin", - "questEggPenguinAdjective": "perspicacious", + "questEggPenguinAdjective": "a perspicacious", "questEggTRexText": "Tyrannosaur", - "questEggTRexAdjective": "tiny-armed", + "questEggTRexAdjective": "a tiny-armed", "questEggRockText": "Rock", - "questEggRockAdjective": "lively", + "questEggRockAdjective": "a lively", "questEggBunnyText": "Bunny", - "questEggBunnyAdjective": "snuggly", + "questEggBunnyAdjective": "a snuggly", "questEggSlimeText": "Marshmallow Slime", - "questEggSlimeAdjective": "sweet", + "questEggSlimeAdjective": "a sweet", "questEggSheepText": "Sheep", - "questEggSheepAdjective": "woolly", + "questEggSheepAdjective": "a woolly", "questEggCuttlefishText": "Cuttlefish", - "questEggCuttlefishAdjective": "cuddly", + "questEggCuttlefishAdjective": "a cuddly", "questEggWhaleText": "Whale", - "questEggWhaleAdjective": "splashy", + "questEggWhaleAdjective": "a splashy", "questEggCheetahText": "Cheetah", - "questEggCheetahAdjective": "honest", + "questEggCheetahAdjective": "an honest", "questEggHorseText": "Horse", - "questEggHorseAdjective": "galloping", + "questEggHorseAdjective": "a galloping", - "eggNotes": "Find a hatching potion to pour on this egg, and it will hatch into a <%= eggAdjective(locale) %> <%= eggText(locale) %>.", + "eggNotes": "Find a hatching potion to pour on this egg, and it will hatch into <%= eggAdjective(locale) %> <%= eggText(locale) %>.", "hatchingPotionBase": "Base", "hatchingPotionWhite": "White", diff --git a/common/locales/en/messages.json b/common/locales/en/messages.json index 4b7b394656..6a7bfb6e16 100644 --- a/common/locales/en/messages.json +++ b/common/locales/en/messages.json @@ -15,7 +15,7 @@ "messageEquipped": " <%= itemText %> equipped.", "messageUnEquipped": "<%= itemText %> un-equipped.", "messageMissingEggPotion": "You're missing either that egg or that potion", - "messageInvalidEggPotionCombo": "You can't hatch that egg with this potion. Try a different egg!", + "messageInvalidEggPotionCombo": "You can't hatch Quest Pet Eggs with Magic Hatching Potions! Try a different egg.", "messageAlreadyPet": "You already have that pet. Try hatching a different combination!", "messageHatched": "Your egg hatched! Visit your stable to equip your pet.", "messageNotEnoughGold": "Not Enough Gold", diff --git a/common/script/content/index.coffee b/common/script/content/index.coffee index 2fa0a0d73f..b363e883f2 100644 --- a/common/script/content/index.coffee +++ b/common/script/content/index.coffee @@ -1088,7 +1088,7 @@ api.dropEggs = _.each api.dropEggs, (egg,key) -> _.defaults egg, - canBuy:true + canBuy: (()->true) value: 3 key: key notes: t('eggNotes', {eggText: egg.text, eggAdjective: egg.adjective}) @@ -1096,27 +1096,27 @@ _.each api.dropEggs, (egg,key) -> api.questEggs = # value & other defaults set below - Gryphon: text: t('questEggGryphonText'), adjective: t('questEggGryphonAdjective'), canBuy: false - Hedgehog: text: t('questEggHedgehogText'), adjective: t('questEggHedgehogAdjective'), canBuy: false - Deer: text: t('questEggDeerText'), adjective: t('questEggDeerAdjective'), canBuy: false - Egg: text: t('questEggEggText'), adjective: t('questEggEggAdjective'), canBuy: false, mountText: t('questEggEggMountText') - Rat: text: t('questEggRatText'), adjective: t('questEggRatAdjective'), canBuy: false - Octopus: text: t('questEggOctopusText'), adjective: t('questEggOctopusAdjective'), canBuy: false - Seahorse: text: t('questEggSeahorseText'), adjective: t('questEggSeahorseAdjective'), canBuy: false - Parrot: text: t('questEggParrotText'), adjective: t('questEggParrotAdjective'), canBuy: false - Rooster: text: t('questEggRoosterText'), adjective: t('questEggRoosterAdjective'), canBuy: false - Spider: text: t('questEggSpiderText'), adjective: t('questEggSpiderAdjective'), canBuy: false - Owl: text: t('questEggOwlText'), adjective: t('questEggOwlAdjective'), canBuy: false - Penguin: text: t('questEggPenguinText'), adjective: t('questEggPenguinAdjective'), canBuy: false - TRex: text: t('questEggTRexText'), adjective: t('questEggTRexAdjective'), canBuy: false - Rock: text: t('questEggRockText'), adjective: t('questEggRockAdjective'), canBuy: false - Bunny: text: t('questEggBunnyText'), adjective: t('questEggBunnyAdjective'), canBuy: false - Slime: text: t('questEggSlimeText'), adjective: t('questEggSlimeAdjective'), canBuy: false - Sheep: text: t('questEggSheepText'), adjective: t('questEggSheepAdjective'), canBuy: false - Cuttlefish: text: t('questEggCuttlefishText'), adjective: t('questEggCuttlefishAdjective'), canBuy: false - Whale: text: t('questEggWhaleText'), adjective: t('questEggWhaleAdjective'), canBuy: false - Cheetah: text: t('questEggCheetahText'), adjective: t('questEggCheetahAdjective'), canBuy: false - Horse: text: t('questEggHorseText'), adjective: t('questEggHorseAdjective'), canBuy: false + Gryphon: text: t('questEggGryphonText'), adjective: t('questEggGryphonAdjective'), canBuy: ((q)-> q.gryphon? > 0) + Hedgehog: text: t('questEggHedgehogText'), adjective: t('questEggHedgehogAdjective'), canBuy: ((q)-> q.hedgehog? > 0) + Deer: text: t('questEggDeerText'), adjective: t('questEggDeerAdjective'), canBuy: ((q)-> q.ghost_stag? > 0) + Egg: text: t('questEggEggText'), adjective: t('questEggEggAdjective'), canBuy: (()->false), mountText: t('questEggEggMountText') + Rat: text: t('questEggRatText'), adjective: t('questEggRatAdjective'), canBuy: ((q)-> q.rat? > 0) + Octopus: text: t('questEggOctopusText'), adjective: t('questEggOctopusAdjective'), canBuy: ((q)-> q.octopus? > 0) + Seahorse: text: t('questEggSeahorseText'), adjective: t('questEggSeahorseAdjective'), canBuy: ((q)-> q.dilatory_derby? > 0) + Parrot: text: t('questEggParrotText'), adjective: t('questEggParrotAdjective'), canBuy: ((q)-> q.harpy? > 0) + Rooster: text: t('questEggRoosterText'), adjective: t('questEggRoosterAdjective'), canBuy: ((q)-> q.rooster? > 0) + Spider: text: t('questEggSpiderText'), adjective: t('questEggSpiderAdjective'), canBuy: ((q)-> q.spider? > 0) + Owl: text: t('questEggOwlText'), adjective: t('questEggOwlAdjective'), canBuy: ((q)-> q.owl? > 0) + Penguin: text: t('questEggPenguinText'), adjective: t('questEggPenguinAdjective'), canBuy: ((q)-> q.penguin? > 0) + TRex: text: t('questEggTRexText'), adjective: t('questEggTRexAdjective'), canBuy: ((q)-> (q.trex? > 0 or q.trex_undead? > 0)) + Rock: text: t('questEggRockText'), adjective: t('questEggRockAdjective'), canBuy: ((q)-> q.rock? > 0) + Bunny: text: t('questEggBunnyText'), adjective: t('questEggBunnyAdjective'), canBuy: ((q)-> q.bunny? > 0) + Slime: text: t('questEggSlimeText'), adjective: t('questEggSlimeAdjective'), canBuy: ((q)-> q.slime? > 0) + Sheep: text: t('questEggSheepText'), adjective: t('questEggSheepAdjective'), canBuy: ((q)-> q.sheep? > 0) + Cuttlefish: text: t('questEggCuttlefishText'), adjective: t('questEggCuttlefishAdjective'), canBuy: ((q)-> q.kraken? > 0) + Whale: text: t('questEggWhaleText'), adjective: t('questEggWhaleAdjective'), canBuy: ((q)-> q.whale? > 0) + Cheetah: text: t('questEggCheetahText'), adjective: t('questEggCheetahAdjective'), canBuy: ((q)-> q.cheetah? > 0) + Horse: text: t('questEggHorseText'), adjective: t('questEggHorseAdjective'), canBuy: ((q)-> q.horse? > 0) _.each api.questEggs, (egg,key) -> _.defaults egg, diff --git a/website/views/options/inventory/drops.jade b/website/views/options/inventory/drops.jade index b64523cdfd..e4f6384303 100644 --- a/website/views/options/inventory/drops.jade +++ b/website/views/options/inventory/drops.jade @@ -102,7 +102,7 @@ menu.pets-menu(label=env.t('eggs')) p.muted!=env.t('dropsExplanation') - div(ng-repeat='egg in Content.eggs', ng-if='egg.canBuy') + div(ng-repeat='egg in Content.eggs', ng-if='egg.canBuy(user.achievements.quests)') button.customize-option(class='Pet_Egg_{{::egg.key}}', popover='{{::egg.notes()}}', popover-append-to-body='true', popover-title!=env.t("egg", {eggType: "{{::egg.text()}}"}), @@ -110,26 +110,6 @@ ng-click='purchase("eggs", egg)') p {{::egg.value}}  span.Pet_Currency_Gem1x.inline-gems - //- buyable quest eggs. TODO: Get this from a collection so we don't have to maintain this ridiculous comma-delimited list - //- The hard part will be the trex stuff, since it is allowed to exist with two quests - each egg,quest in {gryphon:'Gryphon',hedgehog:'Hedgehog',ghost_stag:'Deer',rat:'Rat',octopus:'Octopus',dilatory_derby:'Seahorse',harpy:'Parrot',rooster:'Rooster',spider:'Spider',owl:'Owl',penguin:'Penguin',rock:'Rock',bunny:'Bunny',slime:'Slime',sheep:'Sheep',kraken:'Cuttlefish',whale:'Whale',cheetah:'Cheetah',horse:'Horse'} - div(ng-show='user.achievements.quests.#{quest} > 0') - button.customize-option(class='Pet_Egg_#{egg}', - popover='{{::Content.eggs.#{egg}.notes()}}', popover-append-to-body='true', - popover-title!=env.t("egg", {eggType: "{{::Content.eggs.#{egg}.text()}}"}), - popover-trigger='mouseenter', popover-placement='top', - ng-click='purchase("eggs", Content.eggs.#{egg})') - p {{::Content.eggs.#{egg}.value}}  - span.Pet_Currency_Gem1x.inline-gems - - div(ng-show='(user.achievements.quests.trex + user.achievements.quests.trex_undead) > 0') - button.customize-option(class='Pet_Egg_TRex', - popover='{{::Content.eggs.TRex.notes()}}', popover-append-to-body='true', - popover-title!=env.t("egg", {eggType: "{{Content.eggs.TRex.text()}}"}), - popover-trigger='mouseenter', popover-placement='top', - ng-click='purchase("eggs", Content.eggs.TRex)') - p {{::Content.eggs.TRex.value}}  - span.Pet_Currency_Gem1x.inline-gems li.customize-menu menu.pets-menu(label=env.t('hatchingPotions')) From 38bdbf020b306fed99ae7823893fffdfe79e5674 Mon Sep 17 00:00:00 2001 From: Sabe Jones Date: Fri, 25 Sep 2015 15:01:08 -0400 Subject: [PATCH 08/16] feat(content): Generalize canBuy --- common/script/content/index.coffee | 170 ++++++++++---------- common/script/index.coffee | 2 +- website/views/options/inventory/drops.jade | 6 +- website/views/options/inventory/quests.jade | 2 +- 4 files changed, 90 insertions(+), 90 deletions(-) diff --git a/common/script/content/index.coffee b/common/script/content/index.coffee index b363e883f2..79b0309a17 100644 --- a/common/script/content/index.coffee +++ b/common/script/content/index.coffee @@ -131,10 +131,10 @@ gear = summerMage: event: events.summer, specialClass: 'wizard', twoHanded:true, text: t('weaponSpecialSummerMageText'), notes: t('weaponSpecialSummerMageNotes', {int: 15, per: 7}), value: 160, int:15, per:7 summerHealer: event: events.summer, specialClass: 'healer', text: t('weaponSpecialSummerHealerText'), notes: t('weaponSpecialSummerHealerNotes', {int: 9}), value: 90, int: 9 # Fall Festival - fallRogue: event: events.fall, specialClass: 'rogue', text: t('weaponSpecialFallRogueText'), notes: t('weaponSpecialFallRogueNotes', {str: 8}), value: 80, str: 8 - fallWarrior: event: events.fall, specialClass: 'warrior', text: t('weaponSpecialFallWarriorText'), notes: t('weaponSpecialFallWarriorNotes', {str: 15}), value: 90, str: 15 - fallMage: event: events.fall, specialClass: 'wizard', twoHanded:true, text: t('weaponSpecialFallMageText'), notes: t('weaponSpecialFallMageNotes', {int: 15, per: 7}), value: 160, int:15, per:7 - fallHealer: event: events.fall, specialClass: 'healer', text: t('weaponSpecialFallHealerText'), notes: t('weaponSpecialFallHealerNotes', {int: 9}), value: 90, int: 9 + fallRogue: event: events.fall, specialClass: 'rogue', text: t('weaponSpecialFallRogueText'), notes: t('weaponSpecialFallRogueNotes', {str: 8}), value: 80, str: 8, canBuy: (()->true) + fallWarrior: event: events.fall, specialClass: 'warrior', text: t('weaponSpecialFallWarriorText'), notes: t('weaponSpecialFallWarriorNotes', {str: 15}), value: 90, str: 15, canBuy: (()->true) + fallMage: event: events.fall, specialClass: 'wizard', twoHanded:true, text: t('weaponSpecialFallMageText'), notes: t('weaponSpecialFallMageNotes', {int: 15, per: 7}), value: 160, int:15, per:7, canBuy: (()->true) + fallHealer: event: events.fall, specialClass: 'healer', text: t('weaponSpecialFallHealerText'), notes: t('weaponSpecialFallHealerNotes', {int: 9}), value: 90, int: 9, canBuy: (()->true) # Winter 2015 winter2015Rogue: event: events.winter2015, specialClass: 'rogue', text: t('weaponSpecialWinter2015RogueText'), notes: t('weaponSpecialWinter2015RogueNotes', {str: 8}), value: 80, str: 8 winter2015Warrior: event: events.winter2015, specialClass: 'warrior', text: t('weaponSpecialWinter2015WarriorText'), notes: t('weaponSpecialWinter2015WarriorNotes', {str: 15}), value: 90, str: 15 @@ -218,10 +218,10 @@ gear = summerMage: event: events.summer, specialClass: 'wizard', text: t('armorSpecialSummerMageText'), notes: t('armorSpecialSummerMageNotes', {int: 9}), value: 90, int: 9 summerHealer: event: events.summer, specialClass: 'healer', text: t('armorSpecialSummerHealerText'), notes: t('armorSpecialSummerHealerNotes', {con: 15}), value: 90, con: 15 # Fall Festival - fallRogue: event: events.fall, specialClass: 'rogue', text: t('armorSpecialFallRogueText'), notes: t('armorSpecialFallRogueNotes', {per: 15}), value: 90, per: 15 - fallWarrior: event: events.fall, specialClass: 'warrior', text: t('armorSpecialFallWarriorText'), notes: t('armorSpecialFallWarriorNotes', {con: 9}), value: 90, con: 9 - fallMage: event: events.fall, specialClass: 'wizard', text: t('armorSpecialFallMageText'), notes: t('armorSpecialFallMageNotes', {int: 9}), value: 90, int: 9 - fallHealer: event: events.fall, specialClass: 'healer', text: t('armorSpecialFallHealerText'), notes: t('armorSpecialFallHealerNotes', {con: 15}), value: 90, con: 15 + fallRogue: event: events.fall, specialClass: 'rogue', text: t('armorSpecialFallRogueText'), notes: t('armorSpecialFallRogueNotes', {per: 15}), value: 90, per: 15, canBuy: (()->true) + fallWarrior: event: events.fall, specialClass: 'warrior', text: t('armorSpecialFallWarriorText'), notes: t('armorSpecialFallWarriorNotes', {con: 9}), value: 90, con: 9, canBuy: (()->true) + fallMage: event: events.fall, specialClass: 'wizard', text: t('armorSpecialFallMageText'), notes: t('armorSpecialFallMageNotes', {int: 9}), value: 90, int: 9, canBuy: (()->true) + fallHealer: event: events.fall, specialClass: 'healer', text: t('armorSpecialFallHealerText'), notes: t('armorSpecialFallHealerNotes', {con: 15}), value: 90, con: 15, canBuy: (()->true) # Winter 2015 winter2015Rogue: event: events.winter2015, specialClass: 'rogue', text: t('armorSpecialWinter2015RogueText'), notes: t('armorSpecialWinter2015RogueNotes', {per: 15}), value: 90, per: 15 winter2015Warrior: event: events.winter2015, specialClass: 'warrior', text: t('armorSpecialWinter2015WarriorText'), notes: t('armorSpecialWinter2015WarriorNotes', {con: 9}), value: 90, con: 9 @@ -320,10 +320,10 @@ gear = summerMage: event: events.summer, specialClass: 'wizard', text: t('headSpecialSummerMageText'), notes: t('headSpecialSummerMageNotes', {per: 7}),value: 60,per: 7 summerHealer: event: events.summer, specialClass: 'healer', text: t('headSpecialSummerHealerText'), notes: t('headSpecialSummerHealerNotes', {int: 7}), value: 60, int: 7 # Fall Festival - fallRogue: event: events.fall, specialClass: 'rogue', text: t('headSpecialFallRogueText'), notes: t('headSpecialFallRogueNotes', {per: 9}),value: 60,per: 9 - fallWarrior: event: events.fall, specialClass: 'warrior', text: t('headSpecialFallWarriorText'), notes: t('headSpecialFallWarriorNotes', {str: 9}),value: 60,str: 9 - fallMage: event: events.fall, specialClass: 'wizard', text: t('headSpecialFallMageText'), notes: t('headSpecialFallMageNotes', {per: 7}),value: 60,per: 7 - fallHealer: event: events.fall, specialClass: 'healer', text: t('headSpecialFallHealerText'), notes: t('headSpecialFallHealerNotes', {int: 7}), value: 60, int: 7 + fallRogue: event: events.fall, specialClass: 'rogue', text: t('headSpecialFallRogueText'), notes: t('headSpecialFallRogueNotes', {per: 9}),value: 60,per: 9, canBuy: (()->true) + fallWarrior: event: events.fall, specialClass: 'warrior', text: t('headSpecialFallWarriorText'), notes: t('headSpecialFallWarriorNotes', {str: 9}),value: 60,str: 9, canBuy: (()->true) + fallMage: event: events.fall, specialClass: 'wizard', text: t('headSpecialFallMageText'), notes: t('headSpecialFallMageNotes', {per: 7}),value: 60,per: 7, canBuy: (()->true) + fallHealer: event: events.fall, specialClass: 'healer', text: t('headSpecialFallHealerText'), notes: t('headSpecialFallHealerNotes', {int: 7}), value: 60, int: 7, canBuy: (()->true) # Winter 2015 winter2015Rogue: event: events.winter2015, specialClass: 'rogue', text: t('headSpecialWinter2015RogueText'), notes: t('headSpecialWinter2015RogueNotes', {per: 9}),value: 60,per: 9 winter2015Warrior: event: events.winter2015, specialClass: 'warrior', text: t('headSpecialWinter2015WarriorText'), notes: t('headSpecialWinter2015WarriorNotes', {str: 9}),value: 60,str: 9 @@ -422,9 +422,9 @@ gear = summerWarrior: event: events.summer, specialClass: 'warrior', text: t('shieldSpecialSummerWarriorText'), notes: t('shieldSpecialSummerWarriorNotes', {con: 7}), value: 70, con: 7 summerHealer: event: events.summer, specialClass: 'healer', text: t('shieldSpecialSummerHealerText'), notes: t('shieldSpecialSummerHealerNotes', {con: 9}), value: 70, con: 9 # Fall Festival - fallRogue: event: events.fall, specialClass: 'rogue', text: t('shieldSpecialFallRogueText'), notes: t('shieldSpecialFallRogueNotes', {str: 8}), value: 80, str: 8 - fallWarrior: event: events.fall, specialClass: 'warrior', text: t('shieldSpecialFallWarriorText'), notes: t('shieldSpecialFallWarriorNotes', {con: 7}), value: 70, con: 7 - fallHealer: event: events.fall, specialClass: 'healer', text: t('shieldSpecialFallHealerText'), notes: t('shieldSpecialFallHealerNotes', {con: 9}), value: 70, con: 9 + fallRogue: event: events.fall, specialClass: 'rogue', text: t('shieldSpecialFallRogueText'), notes: t('shieldSpecialFallRogueNotes', {str: 8}), value: 80, str: 8, canBuy: (()->true) + fallWarrior: event: events.fall, specialClass: 'warrior', text: t('shieldSpecialFallWarriorText'), notes: t('shieldSpecialFallWarriorNotes', {con: 7}), value: 70, con: 7, canBuy: (()->true) + fallHealer: event: events.fall, specialClass: 'healer', text: t('shieldSpecialFallHealerText'), notes: t('shieldSpecialFallHealerNotes', {con: 9}), value: 70, con: 9, canBuy: (()->true) # Winter 2015 winter2015Rogue: event: events.winter2015, specialClass: 'rogue', text: t('shieldSpecialWinter2015RogueText'), notes: t('shieldSpecialWinter2015RogueNotes', {str: 8}), value: 80, str: 8 winter2015Warrior: event: events.winter2015, specialClass: 'warrior', text: t('shieldSpecialWinter2015WarriorText'), notes: t('shieldSpecialWinter2015WarriorNotes', {con: 7}), value: 70, con: 7 @@ -490,14 +490,14 @@ gear = spring2015Mage: event: events.spring2015, specialClass: 'wizard', text: t('headAccessorySpecialSpring2015MageText'), notes: t('headAccessorySpecialSpring2015MageNotes'), value: 20 spring2015Healer: event: events.spring2015, specialClass: 'healer', text: t('headAccessorySpecialSpring2015HealerText'), notes: t('headAccessorySpecialSpring2015HealerNotes'), value: 20 # Animal ears - bearEars: gearSet: 'animal', text: t('headAccessoryBearEarsText'), notes: t('headAccessoryBearEarsNotes'), value: 20, canOwn: ((u)-> u.items.gear.owned.headAccessory_special_bearEars?) - cactusEars: gearSet: 'animal', text: t('headAccessoryCactusEarsText'), notes: t('headAccessoryCactusEarsNotes'), value: 20, canOwn: ((u)-> u.items.gear.owned.headAccessory_special_cactusEars?) - foxEars: gearSet: 'animal', text: t('headAccessoryFoxEarsText'), notes: t('headAccessoryFoxEarsNotes'), value: 20, canOwn: ((u)-> u.items.gear.owned.headAccessory_special_foxEars?) - lionEars: gearSet: 'animal', text: t('headAccessoryLionEarsText'), notes: t('headAccessoryLionEarsNotes'), value: 20, canOwn: ((u)-> u.items.gear.owned.headAccessory_special_lionEars?) - pandaEars: gearSet: 'animal', text: t('headAccessoryPandaEarsText'), notes: t('headAccessoryPandaEarsNotes'), value: 20, canOwn: ((u)-> u.items.gear.owned.headAccessory_special_pandaEars?) - pigEars: gearSet: 'animal', text: t('headAccessoryPigEarsText'), notes: t('headAccessoryPigEarsNotes'), value: 20, canOwn: ((u)-> u.items.gear.owned.headAccessory_special_pigEars?) - tigerEars: gearSet: 'animal', text: t('headAccessoryTigerEarsText'), notes: t('headAccessoryTigerEarsNotes'), value: 20, canOwn: ((u)-> u.items.gear.owned.headAccessory_special_tigerEars?) - wolfEars: gearSet: 'animal', text: t('headAccessoryWolfEarsText'), notes: t('headAccessoryWolfEarsNotes'), value: 20, canOwn: ((u)-> u.items.gear.owned.headAccessory_special_wolfEars?) + bearEars: gearSet: 'animal', text: t('headAccessoryBearEarsText'), notes: t('headAccessoryBearEarsNotes'), value: 20, canOwn: ((u)-> u.items.gear.owned.headAccessory_special_bearEars?), canBuy: (()->true) + cactusEars: gearSet: 'animal', text: t('headAccessoryCactusEarsText'), notes: t('headAccessoryCactusEarsNotes'), value: 20, canOwn: ((u)-> u.items.gear.owned.headAccessory_special_cactusEars?), canBuy: (()->true) + foxEars: gearSet: 'animal', text: t('headAccessoryFoxEarsText'), notes: t('headAccessoryFoxEarsNotes'), value: 20, canOwn: ((u)-> u.items.gear.owned.headAccessory_special_foxEars?), canBuy: (()->true) + lionEars: gearSet: 'animal', text: t('headAccessoryLionEarsText'), notes: t('headAccessoryLionEarsNotes'), value: 20, canOwn: ((u)-> u.items.gear.owned.headAccessory_special_lionEars?), canBuy: (()->true) + pandaEars: gearSet: 'animal', text: t('headAccessoryPandaEarsText'), notes: t('headAccessoryPandaEarsNotes'), value: 20, canOwn: ((u)-> u.items.gear.owned.headAccessory_special_pandaEars?), canBuy: (()->true) + pigEars: gearSet: 'animal', text: t('headAccessoryPigEarsText'), notes: t('headAccessoryPigEarsNotes'), value: 20, canOwn: ((u)-> u.items.gear.owned.headAccessory_special_pigEars?), canBuy: (()->true) + tigerEars: gearSet: 'animal', text: t('headAccessoryTigerEarsText'), notes: t('headAccessoryTigerEarsNotes'), value: 20, canOwn: ((u)-> u.items.gear.owned.headAccessory_special_tigerEars?), canBuy: (()->true) + wolfEars: gearSet: 'animal', text: t('headAccessoryWolfEarsText'), notes: t('headAccessoryWolfEarsNotes'), value: 20, canOwn: ((u)-> u.items.gear.owned.headAccessory_special_wolfEars?), canBuy: (()->true) mystery: 201403: text: t('headAccessoryMystery201403Text'), notes: t('headAccessoryMystery201403Notes'), mystery:'201403', value: 0 201404: text: t('headAccessoryMystery201404Text'), notes: t('headAccessoryMystery201404Notes'), mystery:'201404', value: 0 @@ -536,7 +536,7 @@ _.each gearTypes, (type) -> # add "type" to each item, so we can reference that as "weapon" or "armor" in the html _.each gear[type][klass], (item, i) -> key = "#{type}_#{klass}_#{i}" - _.defaults item, {type, key, klass, index: i, str:0, int:0, per:0, con:0} + _.defaults item, {type, key, klass, index: i, str:0, int:0, per:0, con:0, canBuy:(()->false)} if item.event #? indicates null/undefined. true means they own currently, false means they once owned - and false is what we're @@ -1096,31 +1096,31 @@ _.each api.dropEggs, (egg,key) -> api.questEggs = # value & other defaults set below - Gryphon: text: t('questEggGryphonText'), adjective: t('questEggGryphonAdjective'), canBuy: ((q)-> q.gryphon? > 0) - Hedgehog: text: t('questEggHedgehogText'), adjective: t('questEggHedgehogAdjective'), canBuy: ((q)-> q.hedgehog? > 0) - Deer: text: t('questEggDeerText'), adjective: t('questEggDeerAdjective'), canBuy: ((q)-> q.ghost_stag? > 0) - Egg: text: t('questEggEggText'), adjective: t('questEggEggAdjective'), canBuy: (()->false), mountText: t('questEggEggMountText') - Rat: text: t('questEggRatText'), adjective: t('questEggRatAdjective'), canBuy: ((q)-> q.rat? > 0) - Octopus: text: t('questEggOctopusText'), adjective: t('questEggOctopusAdjective'), canBuy: ((q)-> q.octopus? > 0) - Seahorse: text: t('questEggSeahorseText'), adjective: t('questEggSeahorseAdjective'), canBuy: ((q)-> q.dilatory_derby? > 0) - Parrot: text: t('questEggParrotText'), adjective: t('questEggParrotAdjective'), canBuy: ((q)-> q.harpy? > 0) - Rooster: text: t('questEggRoosterText'), adjective: t('questEggRoosterAdjective'), canBuy: ((q)-> q.rooster? > 0) - Spider: text: t('questEggSpiderText'), adjective: t('questEggSpiderAdjective'), canBuy: ((q)-> q.spider? > 0) - Owl: text: t('questEggOwlText'), adjective: t('questEggOwlAdjective'), canBuy: ((q)-> q.owl? > 0) - Penguin: text: t('questEggPenguinText'), adjective: t('questEggPenguinAdjective'), canBuy: ((q)-> q.penguin? > 0) - TRex: text: t('questEggTRexText'), adjective: t('questEggTRexAdjective'), canBuy: ((q)-> (q.trex? > 0 or q.trex_undead? > 0)) - Rock: text: t('questEggRockText'), adjective: t('questEggRockAdjective'), canBuy: ((q)-> q.rock? > 0) - Bunny: text: t('questEggBunnyText'), adjective: t('questEggBunnyAdjective'), canBuy: ((q)-> q.bunny? > 0) - Slime: text: t('questEggSlimeText'), adjective: t('questEggSlimeAdjective'), canBuy: ((q)-> q.slime? > 0) - Sheep: text: t('questEggSheepText'), adjective: t('questEggSheepAdjective'), canBuy: ((q)-> q.sheep? > 0) - Cuttlefish: text: t('questEggCuttlefishText'), adjective: t('questEggCuttlefishAdjective'), canBuy: ((q)-> q.kraken? > 0) - Whale: text: t('questEggWhaleText'), adjective: t('questEggWhaleAdjective'), canBuy: ((q)-> q.whale? > 0) - Cheetah: text: t('questEggCheetahText'), adjective: t('questEggCheetahAdjective'), canBuy: ((q)-> q.cheetah? > 0) - Horse: text: t('questEggHorseText'), adjective: t('questEggHorseAdjective'), canBuy: ((q)-> q.horse? > 0) + Gryphon: text: t('questEggGryphonText'), adjective: t('questEggGryphonAdjective'), canBuy: ((u)-> u.achievements.quests.gryphon? > 0) + Hedgehog: text: t('questEggHedgehogText'), adjective: t('questEggHedgehogAdjective'), canBuy: ((u)-> u.achievements.quests.hedgehog? > 0) + Deer: text: t('questEggDeerText'), adjective: t('questEggDeerAdjective'), canBuy: ((u)-> u.achievements.quests.ghost_stag? > 0) + Egg: text: t('questEggEggText'), adjective: t('questEggEggAdjective'), mountText: t('questEggEggMountText') + Rat: text: t('questEggRatText'), adjective: t('questEggRatAdjective'), canBuy: ((u)-> u.achievements.quests.rat? > 0) + Octopus: text: t('questEggOctopusText'), adjective: t('questEggOctopusAdjective'), canBuy: ((u)-> u.achievements.quests.octopus? > 0) + Seahorse: text: t('questEggSeahorseText'), adjective: t('questEggSeahorseAdjective'), canBuy: ((u)-> u.achievements.quests.dilatory_derby? > 0) + Parrot: text: t('questEggParrotText'), adjective: t('questEggParrotAdjective'), canBuy: ((u)-> u.achievements.quests.harpy? > 0) + Rooster: text: t('questEggRoosterText'), adjective: t('questEggRoosterAdjective'), canBuy: ((u)-> u.achievements.quests.rooster? > 0) + Spider: text: t('questEggSpiderText'), adjective: t('questEggSpiderAdjective'), canBuy: ((u)-> u.achievements.quests.spider? > 0) + Owl: text: t('questEggOwlText'), adjective: t('questEggOwlAdjective'), canBuy: ((u)-> u.achievements.quests.owl? > 0) + Penguin: text: t('questEggPenguinText'), adjective: t('questEggPenguinAdjective'), canBuy: ((u)-> u.achievements.quests.penguin? > 0) + TRex: text: t('questEggTRexText'), adjective: t('questEggTRexAdjective'), canBuy: ((u)-> (u.achievements.quests.trex? > 0 or u.achievements.quests.trex_undead? > 0)) + Rock: text: t('questEggRockText'), adjective: t('questEggRockAdjective'), canBuy: ((u)-> u.achievements.quests.rock? > 0) + Bunny: text: t('questEggBunnyText'), adjective: t('questEggBunnyAdjective'), canBuy: ((u)-> u.achievements.quests.bunny? > 0) + Slime: text: t('questEggSlimeText'), adjective: t('questEggSlimeAdjective'), canBuy: ((u)-> u.achievements.quests.slime? > 0) + Sheep: text: t('questEggSheepText'), adjective: t('questEggSheepAdjective'), canBuy: ((u)-> u.achievements.quests.sheep? > 0) + Cuttlefish: text: t('questEggCuttlefishText'), adjective: t('questEggCuttlefishAdjective'), canBuy: ((u)-> u.achievements.quests.kraken? > 0) + Whale: text: t('questEggWhaleText'), adjective: t('questEggWhaleAdjective'), canBuy: ((u)-> u.achievements.quests.whale? > 0) + Cheetah: text: t('questEggCheetahText'), adjective: t('questEggCheetahAdjective'), canBuy: ((u)-> u.achievements.quests.cheetah? > 0) + Horse: text: t('questEggHorseText'), adjective: t('questEggHorseAdjective'), canBuy: ((u)-> u.achievements.quests.horse? > 0) _.each api.questEggs, (egg,key) -> _.defaults egg, - canBuy:false + canBuy: (()->false) value: 3 key: key notes: t('eggNotes', {eggText: egg.text, eggAdjective: egg.adjective}) @@ -1171,7 +1171,7 @@ api.hatchingPotions = Spooky: value: 3, text: t('hatchingPotionSpooky'), addlNotes: t('premiumPotionAddlNotes'), premium: true, limited: true _.each api.hatchingPotions, (pot,key) -> - _.defaults pot, {key, value: 2, notes: t('hatchingPotionNotes', {potText: pot.text}), premium: false, limited: false, canBuy: true} + _.defaults pot, {key, value: 2, notes: t('hatchingPotionNotes', {potText: pot.text}), premium: false, limited: false, canBuy: (()->true)} api.pets = _.transform api.dropEggs, (m, egg) -> _.defaults m, _.transform api.hatchingPotions, (m2, pot) -> @@ -1200,45 +1200,45 @@ api.questMounts = _.transform api.questEggs, (m, egg) -> api.food = # Base - Meat: canBuy:false, canDrop:false, text: t('foodMeat'), target: 'Base', article: '' - Milk: canBuy:false, canDrop:false, text: t('foodMilk'), target: 'White', article: '' - Potatoe: canBuy:false, canDrop:false, text: t('foodPotatoe'), target: 'Desert', article: 'a ' - Strawberry: canBuy:false, canDrop:false, text: t('foodStrawberry'), target: 'Red', article: 'a ' - Chocolate: canBuy:false, canDrop:false, text: t('foodChocolate'), target: 'Shade', article: '' - Fish: canBuy:false, canDrop:false, text: t('foodFish'), target: 'Skeleton', article: 'a ' - RottenMeat: canBuy:false, canDrop:false, text: t('foodRottenMeat'), target: 'Zombie', article: '' - CottonCandyPink: canBuy:false, canDrop:false, text: t('foodCottonCandyPink'), target: 'CottonCandyPink', article: '' - CottonCandyBlue: canBuy:false, canDrop:false, text: t('foodCottonCandyBlue'), target: 'CottonCandyBlue', article: '' - Honey: canBuy:false, canDrop:false, text: t('foodHoney'), target: 'Golden', article: '' + Meat: text: t('foodMeat'), target: 'Base', article: '' + Milk: text: t('foodMilk'), target: 'White', article: '' + Potatoe: text: t('foodPotatoe'), target: 'Desert', article: 'a ' + Strawberry: text: t('foodStrawberry'), target: 'Red', article: 'a ' + Chocolate: text: t('foodChocolate'), target: 'Shade', article: '' + Fish: text: t('foodFish'), target: 'Skeleton', article: 'a ' + RottenMeat: text: t('foodRottenMeat'), target: 'Zombie', article: '' + CottonCandyPink: text: t('foodCottonCandyPink'), target: 'CottonCandyPink', article: '' + CottonCandyBlue: text: t('foodCottonCandyBlue'), target: 'CottonCandyBlue', article: '' + Honey: text: t('foodHoney'), target: 'Golden', article: '' - Saddle: canBuy:true, canDrop:false, text: t('foodSaddleText'), value: 5, notes: t('foodSaddleNotes') + Saddle: canBuy:(()->true), text: t('foodSaddleText'), value: 5, notes: t('foodSaddleNotes') # Cake - Cake_Skeleton: canBuy:false, canDrop:false, text: t('foodCakeSkeleton'), target: 'Skeleton', article: '' - Cake_Base: canBuy:false, canDrop:false, text: t('foodCakeBase'), target: 'Base', article: '' - Cake_CottonCandyBlue: canBuy:false, canDrop:false, text: t('foodCakeCottonCandyBlue'), target: 'CottonCandyBlue', article: '' - Cake_CottonCandyPink: canBuy:false, canDrop:false, text: t('foodCakeCottonCandyPink'), target: 'CottonCandyPink', article: '' - Cake_Shade: canBuy:false, canDrop:false, text: t('foodCakeShade'), target: 'Shade', article: '' - Cake_White: canBuy:false, canDrop:false, text: t('foodCakeWhite'), target: 'White', article: '' - Cake_Golden: canBuy:false, canDrop:false, text: t('foodCakeGolden'), target: 'Golden', article: '' - Cake_Zombie: canBuy:false, canDrop:false, text: t('foodCakeZombie'), target: 'Zombie', article: '' - Cake_Desert: canBuy:false, canDrop:false, text: t('foodCakeDesert'), target: 'Desert', article: '' - Cake_Red: canBuy:false, canDrop:false, text: t('foodCakeRed'), target: 'Red', article: '' + Cake_Skeleton: text: t('foodCakeSkeleton'), target: 'Skeleton', article: '' + Cake_Base: text: t('foodCakeBase'), target: 'Base', article: '' + Cake_CottonCandyBlue: text: t('foodCakeCottonCandyBlue'), target: 'CottonCandyBlue', article: '' + Cake_CottonCandyPink: text: t('foodCakeCottonCandyPink'), target: 'CottonCandyPink', article: '' + Cake_Shade: text: t('foodCakeShade'), target: 'Shade', article: '' + Cake_White: text: t('foodCakeWhite'), target: 'White', article: '' + Cake_Golden: text: t('foodCakeGolden'), target: 'Golden', article: '' + Cake_Zombie: text: t('foodCakeZombie'), target: 'Zombie', article: '' + Cake_Desert: text: t('foodCakeDesert'), target: 'Desert', article: '' + Cake_Red: text: t('foodCakeRed'), target: 'Red', article: '' # Fall - Candy_Skeleton: canBuy:true, canDrop:true, text: t('foodCandySkeleton'), target: 'Skeleton', article: '' - Candy_Base: canBuy:true, canDrop:true, text: t('foodCandyBase'), target: 'Base', article: '' - Candy_CottonCandyBlue: canBuy:true, canDrop:true, text: t('foodCandyCottonCandyBlue'), target: 'CottonCandyBlue', article: '' - Candy_CottonCandyPink: canBuy:true, canDrop:true, text: t('foodCandyCottonCandyPink'), target: 'CottonCandyPink', article: '' - Candy_Shade: canBuy:true, canDrop:true, text: t('foodCandyShade'), target: 'Shade', article: '' - Candy_White: canBuy:true, canDrop:true, text: t('foodCandyWhite'), target: 'White', article: '' - Candy_Golden: canBuy:true, canDrop:true, text: t('foodCandyGolden'), target: 'Golden', article: '' - Candy_Zombie: canBuy:true, canDrop:true, text: t('foodCandyZombie'), target: 'Zombie', article: '' - Candy_Desert: canBuy:true, canDrop:true, text: t('foodCandyDesert'), target: 'Desert', article: '' - Candy_Red: canBuy:true, canDrop:true, text: t('foodCandyRed'), target: 'Red', article: '' + Candy_Skeleton: canBuy:(()->true), canDrop:true, text: t('foodCandySkeleton'), target: 'Skeleton', article: '' + Candy_Base: canBuy:(()->true), canDrop:true, text: t('foodCandyBase'), target: 'Base', article: '' + Candy_CottonCandyBlue: canBuy:(()->true), canDrop:true, text: t('foodCandyCottonCandyBlue'), target: 'CottonCandyBlue', article: '' + Candy_CottonCandyPink: canBuy:(()->true), canDrop:true, text: t('foodCandyCottonCandyPink'), target: 'CottonCandyPink', article: '' + Candy_Shade: canBuy:(()->true), canDrop:true, text: t('foodCandyShade'), target: 'Shade', article: '' + Candy_White: canBuy:(()->true), canDrop:true, text: t('foodCandyWhite'), target: 'White', article: '' + Candy_Golden: canBuy:(()->true), canDrop:true, text: t('foodCandyGolden'), target: 'Golden', article: '' + Candy_Zombie: canBuy:(()->true), canDrop:true, text: t('foodCandyZombie'), target: 'Zombie', article: '' + Candy_Desert: canBuy:(()->true), canDrop:true, text: t('foodCandyDesert'), target: 'Desert', article: '' + Candy_Red: canBuy:(()->true), canDrop:true, text: t('foodCandyRed'), target: 'Red', article: '' _.each api.food, (food,key) -> - _.defaults food, {value: 1, key, notes: t('foodNotes')} + _.defaults food, {value: 1, key, notes: t('foodNotes'), canBuy:(()->false), canDrop:false} api.userCanOwnQuestCategories = [ 'unlockable' @@ -1253,7 +1253,7 @@ api.quests = notes: t("questDilatoryNotes") completion: t("questDilatoryCompletion") value: 0 - canBuy: false + canBuy: (()->false) category: 'world' boss: name: t("questDilatoryBoss") @@ -1296,7 +1296,7 @@ api.quests = completion: t("questStressbeastCompletion") completionChat: t("questStressbeastCompletionChat") value: 0 - canBuy: false + canBuy: (()->false) category: 'world' boss: name: t("questStressbeastBoss") @@ -1336,7 +1336,7 @@ api.quests = exp: 0 evilsanta: - canBuy:false + canBuy: (()->false) text: t('questEvilSantaText') # title of the quest (eg, Deep into Vice's Layer) notes: t('questEvilSantaNotes') completion: t('questEvilSantaCompletion') @@ -1354,7 +1354,7 @@ api.quests = exp: 100 # Exp bonus from defeating the boss evilsanta2: - canBuy:false + canBuy: (()->false) text: t('questEvilSanta2Text') notes: t('questEvilSanta2Notes') completion: t('questEvilSanta2Completion') @@ -1492,7 +1492,7 @@ api.quests = notes: t('questEggHuntNotes') completion: t('questEggHuntCompletion') value: 1 - canBuy: false + canBuy: (()->false) category: 'pet' collect: plainEgg: text: t('questEggHuntCollectPlainEgg'), count: 100 @@ -2125,7 +2125,7 @@ api.quests = unlock: t('questHorseUnlockText') _.each api.quests, (v,key) -> - _.defaults v, {key,canBuy:true} + _.defaults v, {key,canBuy:(()->true)} b = v.boss if b _.defaults b, {str:1,def:1} diff --git a/common/script/index.coffee b/common/script/index.coffee index d25ad683a2..7145bf083e 100644 --- a/common/script/index.coffee +++ b/common/script/index.coffee @@ -822,7 +822,7 @@ api.wrap = (user, main=true) -> item = content[type][key] price = item.value / 4 return cb?({code:404,message:":key not found for Content.#{type}"},req) unless item - return cb?({code:403, message: i18n.t('messageNotAvailable', req.language)}) if type is 'hatchingPotions' and not item.canBuy + return cb?({code:403, message: i18n.t('messageNotAvailable', req.language)}) if not item.canBuy(user) return cb?({code:403, message: i18n.t('notEnoughGems', req.language)}) if (user.balance < price) or !user.balance user.balance -= price if type is 'gear' then user.items.gear.owned[key] = true diff --git a/website/views/options/inventory/drops.jade b/website/views/options/inventory/drops.jade index e4f6384303..bef1acff77 100644 --- a/website/views/options/inventory/drops.jade +++ b/website/views/options/inventory/drops.jade @@ -102,7 +102,7 @@ menu.pets-menu(label=env.t('eggs')) p.muted!=env.t('dropsExplanation') - div(ng-repeat='egg in Content.eggs', ng-if='egg.canBuy(user.achievements.quests)') + div(ng-repeat='egg in Content.eggs', ng-if='egg.canBuy(user)') button.customize-option(class='Pet_Egg_{{::egg.key}}', popover='{{::egg.notes()}}', popover-append-to-body='true', popover-title!=env.t("egg", {eggType: "{{::egg.text()}}"}), @@ -126,7 +126,7 @@ li.customize-menu menu.pets-menu(label=env.t('magicHatchingPotions')) - div(ng-repeat='pot in Content.hatchingPotions', ng-if='pot.premium && pot.canBuy') + div(ng-repeat='pot in Content.hatchingPotions', ng-if='pot.premium && pot.canBuy(user)') button.customize-option(class='Pet_HatchingPotion_{{::pot.key}}', popover='{{::pot.notes()}} {{::pot.addlNotes()}}', popover-append-to-body='true', popover-title!=env.t("potion", {potionType: "{{::pot.text()}}"}), @@ -139,7 +139,7 @@ li.customize-menu menu.pets-menu(label=env.t('food')) p.muted!=env.t('dropsExplanation') - div(ng-repeat='food in Content.food', ng-if='food.canBuy') + div(ng-repeat='food in Content.food', ng-if='food.canBuy(user)') button.customize-option(class='Pet_Food_{{::food.key}}', popover='{{::food.notes()}}', popover-title='{{::food.text()}}', popover-trigger='mouseenter', popover-placement='top', diff --git a/website/views/options/inventory/quests.jade b/website/views/options/inventory/quests.jade index 1b6a05793f..1e200f57e3 100644 --- a/website/views/options/inventory/quests.jade +++ b/website/views/options/inventory/quests.jade @@ -19,7 +19,7 @@ include ../../shared/mixins h3.equipment-title=env.t('questsForSale') div(ng-repeat='type in Content.userCanOwnQuestCategories') menu.pets-menu(label='{{env.t(type + "Quests")}}') - div(ng-repeat='quest in Content.questsByLevel', ng-if='quest.canBuy && quest.category === type') + div(ng-repeat='quest in Content.questsByLevel', ng-if='quest.canBuy(user) && quest.category === type') button.customize-option(ng-class='lockQuest(quest) ? "inventory_quest_scroll_locked inventory_quest_scroll_{{::quest.key}}_locked locked" : "inventory_quest_scroll inventory_quest_scroll_{{::quest.key}}"', data-popover-html="{{::lockQuest(quest,true) ? env.t('scrollsPre') : questPopover(quest) | markdown}}", popover-title='{{::quest.text()}}', popover-append-to-body="true", From 926bedcfea37222746c27c5bd026c3fbff3e285c Mon Sep 17 00:00:00 2001 From: Sabe Jones Date: Fri, 25 Sep 2015 15:16:17 -0400 Subject: [PATCH 09/16] fix(test): Change quest's canBuy to fn call --- test/common/algos.mocha.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/common/algos.mocha.coffee b/test/common/algos.mocha.coffee index 914b3e2820..5f98890666 100644 --- a/test/common/algos.mocha.coffee +++ b/test/common/algos.mocha.coffee @@ -544,7 +544,7 @@ describe 'User', -> expect(quest.notes()).to.be.an('string') expect(quest.completion()).to.be.an('string') if quest.completion expect(quest.previous).to.be.an('string') if quest.previous - expect(quest.value).to.be.greaterThan 0 if quest.canBuy + expect(quest.value).to.be.greaterThan 0 if quest.canBuy() expect(quest.drop.gp).to.not.be.lessThan 0 expect(quest.drop.exp).to.not.be.lessThan 0 expect(quest.category).to.match(/pet|unlockable|gold|world/) From 8dcfe3078f9d426c5dcfc38a2883555c25de385e Mon Sep 17 00:00:00 2001 From: Sabe Jones Date: Fri, 25 Sep 2015 16:31:07 -0400 Subject: [PATCH 10/16] fix(inventory): Missing pixel paws --- website/views/options/inventory/mounts.jade | 2 +- website/views/options/inventory/pets.jade | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/website/views/options/inventory/mounts.jade b/website/views/options/inventory/mounts.jade index f1317e1a39..1d3191780f 100644 --- a/website/views/options/inventory/mounts.jade +++ b/website/views/options/inventory/mounts.jade @@ -8,7 +8,7 @@ mixin mountList(source,showPremium) - mount = egg.key+"-"+potion.key div(popover-trigger='mouseenter', popover=env.t('mountName', {potion: potion.text(env.language.code), mount: egg.mountText(env.language.code)}), popover-placement='bottom', ng-hide='#{potion.premium} && #{!showPremium}') button(class="pet-button Mount_Head_#{mount}", ng-show='user.items.mounts["#{mount}"]', ng-class='{active: user.items.currentMount == "#{mount}"}', ng-click='chooseMount("#{egg.key}", "#{potion.key}")') - button(class="pet-button mount-not-owned", ng-if='!user.items.mounts["#{mount}"] && (#{potion.canBuy} || user.items.hatchingPotions["#{potion.key}"] || user.items.pets["#{mount}"])') + button(class="pet-button mount-not-owned", ng-if='!user.items.mounts["#{mount}"] && (#{potion.canBuy()} || user.items.hatchingPotions["#{potion.key}"] || user.items.pets["#{mount}"])') .PixelPaw -} diff --git a/website/views/options/inventory/pets.jade b/website/views/options/inventory/pets.jade index 3ee59389b2..21ba457cdb 100644 --- a/website/views/options/inventory/pets.jade +++ b/website/views/options/inventory/pets.jade @@ -9,7 +9,7 @@ mixin petList(source,showPremium) button(class="pet-button Pet-#{pet}", ng-if='user.items.pets["#{pet}"]>0', ng-class='{active: user.items.currentPet == "#{pet}", selectableInventory: #{!egg.noMount} && selectedFood && !user.items.mounts["#{pet}"]}', ng-click='choosePet("#{egg.key}", "#{potion.key}")') .progress(ng-show='!user.items.mounts["#{pet}"]') .progress-bar.progress-bar-success(ng-style='{width: user.items.pets["#{pet}"]/.5 + "%"}') - button(class="pet-button pet-not-owned", ng-if='!user.items.pets["#{pet}"] && (#{potion.canBuy} || user.items.hatchingPotions["#{potion.key}"])') + button(class="pet-button pet-not-owned", ng-if='!user.items.pets["#{pet}"] && (#{potion.canBuy()} || user.items.hatchingPotions["#{potion.key}"])') .PixelPaw button(class="pet-evolved pet-button Pet-#{pet}", ng-if='user.items.pets["#{pet}"]<0') From feff6fadfab48e15d8afe6f15967fafc6b1057dd Mon Sep 17 00:00:00 2001 From: Sabe Jones Date: Mon, 28 Sep 2015 14:58:46 -0400 Subject: [PATCH 11/16] feat(magic-potions): Final tweaks --- common/locales/en/limited.json | 3 ++- common/locales/en/pets.json | 4 ++-- common/script/content/index.coffee | 2 +- website/views/options/inventory/drops.jade | 3 ++- 4 files changed, 7 insertions(+), 5 deletions(-) diff --git a/common/locales/en/limited.json b/common/locales/en/limited.json index ac2318be30..711355ae22 100644 --- a/common/locales/en/limited.json +++ b/common/locales/en/limited.json @@ -59,5 +59,6 @@ "monsterOfScienceSet": "Monster of Science (Warrior)", "witchyWizardSet": "Witchy Wizard (Mage)", "mummyMedicSet": "Mummy Medic (Healer)", - "vampireSmiterSet": "Vampire Smiter (Rogue)" + "vampireSmiterSet": "Vampire Smiter (Rogue)", + "fallEventAvailability": "Available until October 31" } diff --git a/common/locales/en/pets.json b/common/locales/en/pets.json index b6421abdc9..fab7bc6ff1 100644 --- a/common/locales/en/pets.json +++ b/common/locales/en/pets.json @@ -24,14 +24,14 @@ "eggSingular": "egg", "noEggs": "You don't have any eggs.", "hatchingPotions": "Hatching Potions", - "magicHatchingPotions": "Magic Hatching Potions", + "magicHatchingPotions": "Magic Hatching Potions", "hatchingPotion": "hatching potion", "noHatchingPotions": "You don't have any hatching potions.", "inventoryText": "Click an egg to see usable potions highlighted in green and then click one of the highlighted potions to hatch your pet. If no potions are highlighted, click that egg again to deselect it, and instead click a potion first to have the usable eggs highlighted. You can also sell unwanted drops to Alexander the Merchant.", "foodText": "food", "food": "Food and Saddles", "noFood": "You don't have any food or saddles.", - "dropsExplanation": "Get these items faster with gems if you don't want to wait for them to drop when completing a task. Learn more about the drop system.", + "dropsExplanation": "Get these items faster with Gems if you don't want to wait for them to drop when completing a task. Learn more about the drop system.", "beastMasterProgress": "Beast Master Progress", "stableBeastMasterProgress": "Beast Master Progress: <%= number %> Pets Found", "beastAchievement": "You have earned the \"Beast Master\" Achievement for collecting all the pets!", diff --git a/common/script/content/index.coffee b/common/script/content/index.coffee index 79b0309a17..6d53393b08 100644 --- a/common/script/content/index.coffee +++ b/common/script/content/index.coffee @@ -1168,7 +1168,7 @@ api.hatchingPotions = CottonCandyPink: value: 4, text: t('hatchingPotionCottonCandyPink') CottonCandyBlue: value: 4, text: t('hatchingPotionCottonCandyBlue') Golden: value: 5, text: t('hatchingPotionGolden') - Spooky: value: 3, text: t('hatchingPotionSpooky'), addlNotes: t('premiumPotionAddlNotes'), premium: true, limited: true + Spooky: value: 2, text: t('hatchingPotionSpooky'), addlNotes: t('premiumPotionAddlNotes'), premium: true, limited: true _.each api.hatchingPotions, (pot,key) -> _.defaults pot, {key, value: 2, notes: t('hatchingPotionNotes', {potText: pot.text}), premium: false, limited: false, canBuy: (()->true)} diff --git a/website/views/options/inventory/drops.jade b/website/views/options/inventory/drops.jade index bef1acff77..b0d385c346 100644 --- a/website/views/options/inventory/drops.jade +++ b/website/views/options/inventory/drops.jade @@ -125,7 +125,8 @@ span.Pet_Currency_Gem1x.inline-gems li.customize-menu - menu.pets-menu(label=env.t('magicHatchingPotions')) + menu.pets-menu!=env.t('magicHatchingPotions') + " - " + env.t('fallEventAvailability') + p.muted=env.t('premiumPotionAddlNotes') div(ng-repeat='pot in Content.hatchingPotions', ng-if='pot.premium && pot.canBuy(user)') button.customize-option(class='Pet_HatchingPotion_{{::pot.key}}', popover='{{::pot.notes()}} {{::pot.addlNotes()}}', popover-append-to-body='true', From ffe0cff7cd19ec37b493b84b32fb3540a3814d03 Mon Sep 17 00:00:00 2001 From: Sabe Jones Date: Mon, 28 Sep 2015 16:27:49 -0400 Subject: [PATCH 12/16] fix(drops): Pick drop eggs from dropEggs --- common/script/index.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/script/index.coffee b/common/script/index.coffee index 7145bf083e..22be5f504c 100644 --- a/common/script/index.coffee +++ b/common/script/index.coffee @@ -1531,7 +1531,7 @@ api.wrap = (user, main=true) -> # Eggs: 30% chance else if rarity > .3 - drop = user.fns.randomVal _.where(content.eggs,{canBuy:true}) + drop = user.fns.randomVal content.dropEggs user.items.eggs[drop.key] ?= 0 user.items.eggs[drop.key]++ drop.type = 'Egg' From 9afaa92c2ea1eb99be858e04fa71e687f6a01b98 Mon Sep 17 00:00:00 2001 From: Sabe Jones Date: Wed, 30 Sep 2015 15:31:09 -0400 Subject: [PATCH 13/16] feat(magic-potions): Clarify drop behavior --- common/locales/en/pets.json | 1 + website/views/options/inventory/drops.jade | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/common/locales/en/pets.json b/common/locales/en/pets.json index fab7bc6ff1..528c36ed9e 100644 --- a/common/locales/en/pets.json +++ b/common/locales/en/pets.json @@ -32,6 +32,7 @@ "food": "Food and Saddles", "noFood": "You don't have any food or saddles.", "dropsExplanation": "Get these items faster with Gems if you don't want to wait for them to drop when completing a task. Learn more about the drop system.", + "premiumPotionNoDropExplanation": "Magic Hatching Potions cannot be used on eggs received from Quests. The only way to get Magic Hatching Potions is by buying them below, not from random drops.", "beastMasterProgress": "Beast Master Progress", "stableBeastMasterProgress": "Beast Master Progress: <%= number %> Pets Found", "beastAchievement": "You have earned the \"Beast Master\" Achievement for collecting all the pets!", diff --git a/website/views/options/inventory/drops.jade b/website/views/options/inventory/drops.jade index b0d385c346..f4eaef8487 100644 --- a/website/views/options/inventory/drops.jade +++ b/website/views/options/inventory/drops.jade @@ -126,7 +126,7 @@ li.customize-menu menu.pets-menu!=env.t('magicHatchingPotions') + " - " + env.t('fallEventAvailability') - p.muted=env.t('premiumPotionAddlNotes') + p.muted=env.t('premiumPotionNoDropExplanation') div(ng-repeat='pot in Content.hatchingPotions', ng-if='pot.premium && pot.canBuy(user)') button.customize-option(class='Pet_HatchingPotion_{{::pot.key}}', popover='{{::pot.notes()}} {{::pot.addlNotes()}}', popover-append-to-body='true', From c8afac95803ce5134ce03ce227df9b719d667378 Mon Sep 17 00:00:00 2001 From: Blade Barringer Date: Thu, 1 Oct 2015 13:21:15 -0500 Subject: [PATCH 14/16] Put magic pets on their own row --- common/locales/en/pets.json | 2 ++ common/script/content/index.coffee | 12 +++++++-- website/views/options/inventory/mounts.jade | 17 +++++++++++-- website/views/options/inventory/pets.jade | 27 ++++++++++++++++----- 4 files changed, 48 insertions(+), 10 deletions(-) diff --git a/common/locales/en/pets.json b/common/locales/en/pets.json index 528c36ed9e..3d3cc45748 100644 --- a/common/locales/en/pets.json +++ b/common/locales/en/pets.json @@ -1,11 +1,13 @@ { "pets": "Pets", "petsFound": "Pets Found", + "magicPets": "Magic Potion Pets", "rarePets": "Rare Pets", "questPets": "Quest Pets", "mounts": "Mounts", "mountsTamed": "Mounts Tamed", "questMounts": "Quest Mounts", + "magicMounts": "Magic Potion Mounts", "rareMounts": "Rare Mounts", "etherealLion": "Ethereal Lion", "veteranWolf": "Veteran Wolf", diff --git a/common/script/content/index.coffee b/common/script/content/index.coffee index 6d53393b08..b70fff0add 100644 --- a/common/script/content/index.coffee +++ b/common/script/content/index.coffee @@ -1157,7 +1157,7 @@ api.timeTravelStable = 'Mammoth-Base': t('mammoth') 'MantisShrimp-Base': t('mantisShrimp') -api.hatchingPotions = +api.dropHatchingPotions = Base: value: 2, text: t('hatchingPotionBase') White: value: 2, text: t('hatchingPotionWhite') Desert: value: 2, text: t('hatchingPotionDesert') @@ -1168,11 +1168,19 @@ api.hatchingPotions = CottonCandyPink: value: 4, text: t('hatchingPotionCottonCandyPink') CottonCandyBlue: value: 4, text: t('hatchingPotionCottonCandyBlue') Golden: value: 5, text: t('hatchingPotionGolden') + +api.premiumHatchingPotions = Spooky: value: 2, text: t('hatchingPotionSpooky'), addlNotes: t('premiumPotionAddlNotes'), premium: true, limited: true -_.each api.hatchingPotions, (pot,key) -> +_.each api.dropHatchingPotions, (pot,key) -> _.defaults pot, {key, value: 2, notes: t('hatchingPotionNotes', {potText: pot.text}), premium: false, limited: false, canBuy: (()->true)} +_.each api.premiumHatchingPotions, (pot,key) -> + _.defaults pot, {key, value: 2, notes: t('hatchingPotionNotes', {potText: pot.text}), premium: true, limited: false, canBuy: (()->true)} + +api.hatchingPotions = _.merge(api.dropHatchingPotions, api.premiumPotionAddlNotes) + + api.pets = _.transform api.dropEggs, (m, egg) -> _.defaults m, _.transform api.hatchingPotions, (m2, pot) -> if not pot.premium diff --git a/website/views/options/inventory/mounts.jade b/website/views/options/inventory/mounts.jade index 1d3191780f..bd4db1beac 100644 --- a/website/views/options/inventory/mounts.jade +++ b/website/views/options/inventory/mounts.jade @@ -1,4 +1,4 @@ -mixin mountList(source,showPremium) +mixin mountList(source) menu.pets(type='list') each egg in source -if(!egg.noMount) { @@ -6,7 +6,7 @@ mixin mountList(source,showPremium) menu each potion in env.Content.hatchingPotions - mount = egg.key+"-"+potion.key - div(popover-trigger='mouseenter', popover=env.t('mountName', {potion: potion.text(env.language.code), mount: egg.mountText(env.language.code)}), popover-placement='bottom', ng-hide='#{potion.premium} && #{!showPremium}') + div(popover-trigger='mouseenter', popover=env.t('mountName', {potion: potion.text(env.language.code), mount: egg.mountText(env.language.code)}), popover-placement='bottom') button(class="pet-button Mount_Head_#{mount}", ng-show='user.items.mounts["#{mount}"]', ng-class='{active: user.items.currentMount == "#{mount}"}', ng-click='chooseMount("#{egg.key}", "#{potion.key}")') button(class="pet-button mount-not-owned", ng-if='!user.items.mounts["#{mount}"] && (#{potion.canBuy()} || user.items.hatchingPotions["#{potion.key}"] || user.items.pets["#{mount}"])') .PixelPaw @@ -24,6 +24,19 @@ mixin mountList(source,showPremium) h4 {{:: env.t('stableMountMasterProgress', { number: mountMasterProgress }) }} .row: .col-md-12 +mountList(env.Content.dropEggs,true) + + .row: .col-md-12 + h4=env.t('magicMounts') + menu.pets(type='list') + each potion in env.Content.premiumHatchingPotions + li.customize-menu + menu + each egg in env.Content.dropEggs + - mount = egg.key+"-"+potion.key + div(popover-trigger='mouseenter', popover=env.t('mountName', {potion: potion.text(env.language.code), mount: egg.mountText(env.language.code)}), popover-placement='bottom') + button(class="pet-button Mount_Head_#{mount}", ng-show='user.items.mounts["#{mount}"]', ng-class='{active: user.items.currentMount == "#{mount}"}', ng-click='chooseMount("#{egg.key}", "#{potion.key}")') + button(class="pet-button mount-not-owned", ng-if='!user.items.mounts["#{mount}"] && (#{potion.canBuy()} || user.items.hatchingPotions["#{potion.key}"] || user.items.pets["#{mount}"])') + .PixelPaw .row: .col-md-12 h4=env.t('questMounts') +mountList(env.Content.questEggs) diff --git a/website/views/options/inventory/pets.jade b/website/views/options/inventory/pets.jade index 21ba457cdb..898ad529e9 100644 --- a/website/views/options/inventory/pets.jade +++ b/website/views/options/inventory/pets.jade @@ -1,11 +1,11 @@ -mixin petList(source,showPremium) +mixin petList(eggSource, potionSource) menu.pets(type='list') - each egg in source + each egg in eggSource li.customize-menu menu - each potion in env.Content.hatchingPotions + each potion in potionSource - pet = egg.key+"-"+potion.key - div(popover-trigger='mouseenter', popover=env.t('petName', {potion: potion.text(env.language.code), egg: egg.text(env.language.code)}), popover-placement='bottom', ng-hide='#{potion.premium} && #{!showPremium}') + div(popover-trigger='mouseenter', popover=env.t('petName', {potion: potion.text(env.language.code), egg: egg.text(env.language.code)}), popover-placement='bottom') button(class="pet-button Pet-#{pet}", ng-if='user.items.pets["#{pet}"]>0', ng-class='{active: user.items.currentPet == "#{pet}", selectableInventory: #{!egg.noMount} && selectedFood && !user.items.mounts["#{pet}"]}', ng-click='choosePet("#{egg.key}", "#{potion.key}")') .progress(ng-show='!user.items.mounts["#{pet}"]') .progress-bar.progress-bar-success(ng-style='{width: user.items.pets["#{pet}"]/.5 + "%"}') @@ -24,10 +24,25 @@ mixin petList(source,showPremium) p=env.t('mattBochText1') h4 {{:: env.t('stableBeastMasterProgress', { number: beastMasterProgress }) }} .row: .col-md-12 - +petList(env.Content.dropEggs,true) + +petList(env.Content.dropEggs,env.Content.dropHatchingPotions) + .row: .col-md-12 + h4=env.t('magicPets') + menu.pets(type='list') + each potion in env.Content.premiumHatchingPotions + li.customize-menu + menu + each egg in env.Content.dropEggs + - pet = egg.key+"-"+potion.key + div(popover-trigger='mouseenter', popover=env.t('petName', {potion: potion.text(env.language.code), egg: egg.text(env.language.code)}), popover-placement='bottom') + button(class="pet-button Pet-#{pet}", ng-if='user.items.pets["#{pet}"]>0', ng-class='{active: user.items.currentPet == "#{pet}", selectableInventory: #{!egg.noMount} && selectedFood && !user.items.mounts["#{pet}"]}', ng-click='choosePet("#{egg.key}", "#{potion.key}")') + .progress(ng-show='!user.items.mounts["#{pet}"]') + .progress-bar.progress-bar-success(ng-style='{width: user.items.pets["#{pet}"]/.5 + "%"}') + button(class="pet-button pet-not-owned", ng-if='!user.items.pets["#{pet}"] && (#{potion.canBuy()} || user.items.hatchingPotions["#{potion.key}"])') + .PixelPaw + button(class="pet-evolved pet-button Pet-#{pet}", ng-if='user.items.pets["#{pet}"]<0') .row: .col-md-12 h4=env.t('questPets') - +petList(env.Content.questEggs) + +petList(env.Content.questEggs,env.Content.dropHatchingPotions) .row: .col-md-12 h4=env.t('rarePets') From 0f8c3e03c24b11e59b728049135748ee61cc06d4 Mon Sep 17 00:00:00 2001 From: Blade Barringer Date: Thu, 1 Oct 2015 13:25:00 -0500 Subject: [PATCH 15/16] Correct mount mixin --- website/views/options/inventory/mounts.jade | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/website/views/options/inventory/mounts.jade b/website/views/options/inventory/mounts.jade index bd4db1beac..bbb9e9889d 100644 --- a/website/views/options/inventory/mounts.jade +++ b/website/views/options/inventory/mounts.jade @@ -1,10 +1,10 @@ -mixin mountList(source) +mixin mountList(eggSource, potionSource) menu.pets(type='list') - each egg in source + each egg in eggSource -if(!egg.noMount) { li.customize-menu menu - each potion in env.Content.hatchingPotions + each potion in potionSource - mount = egg.key+"-"+potion.key div(popover-trigger='mouseenter', popover=env.t('mountName', {potion: potion.text(env.language.code), mount: egg.mountText(env.language.code)}), popover-placement='bottom') button(class="pet-button Mount_Head_#{mount}", ng-show='user.items.mounts["#{mount}"]', ng-class='{active: user.items.currentMount == "#{mount}"}', ng-click='chooseMount("#{egg.key}", "#{potion.key}")') @@ -23,7 +23,7 @@ mixin mountList(source) p=env.t('mattShall', {name: "{{user.profile.name}}"}) h4 {{:: env.t('stableMountMasterProgress', { number: mountMasterProgress }) }} .row: .col-md-12 - +mountList(env.Content.dropEggs,true) + +mountList(env.Content.dropEggs,env.Content.dropHatchingPotions) .row: .col-md-12 h4=env.t('magicMounts') @@ -39,7 +39,7 @@ mixin mountList(source) .PixelPaw .row: .col-md-12 h4=env.t('questMounts') - +mountList(env.Content.questEggs) + +mountList(env.Content.questEggs,env.Content.dropHatchingPotions) .row: .col-md-12 h4=env.t('rareMounts') menu From 3d38777ec89e2ae1f5ce6be4a3058070af7208a8 Mon Sep 17 00:00:00 2001 From: Sabe Jones Date: Thu, 1 Oct 2015 14:54:52 -0400 Subject: [PATCH 16/16] fix(content): Correctly generate api.hatchingPotions --- common/script/content/index.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/script/content/index.coffee b/common/script/content/index.coffee index b70fff0add..196b25602d 100644 --- a/common/script/content/index.coffee +++ b/common/script/content/index.coffee @@ -1178,7 +1178,7 @@ _.each api.dropHatchingPotions, (pot,key) -> _.each api.premiumHatchingPotions, (pot,key) -> _.defaults pot, {key, value: 2, notes: t('hatchingPotionNotes', {potText: pot.text}), premium: true, limited: false, canBuy: (()->true)} -api.hatchingPotions = _.merge(api.dropHatchingPotions, api.premiumPotionAddlNotes) +api.hatchingPotions = _.merge(api.dropHatchingPotions, api.premiumHatchingPotions) api.pets = _.transform api.dropEggs, (m, egg) ->