From 9c9b67aa9d8161dec27bf37d1a4969875681759e Mon Sep 17 00:00:00 2001 From: Keith Holliday Date: Fri, 2 Mar 2018 14:30:11 -0700 Subject: [PATCH] Keys kennel fixes (#9848) * Show keys to pets immediately * Ensured keys to pets dissapear after use * Added resdirect to stable after purchase * Added mount check and updated keys to mounts and to both * Added api calls * Added check for beastmaster progress * Added mount check for release mounts. Added pets and mount check to release both * Added actions * Added catch to common tests * Added beast count and reload * Removed extra console log --- test/common/ops/releaseBoth.js | 55 ++++++++++++++----- test/common/ops/releaseMounts.js | 29 ++++++++-- test/common/ops/releasePets.js | 37 ++++++++++--- .../components/inventory/stable/index.vue | 7 +-- website/client/components/shops/buyModal.vue | 3 + .../client/components/shops/market/index.vue | 2 +- .../components/shops/market/keysToKennel.vue | 37 +++++++++---- website/client/store/actions/common.js | 4 +- website/client/store/actions/shops.js | 19 +++++++ website/common/locales/en/pets.json | 5 +- website/common/script/count.js | 11 ++++ website/common/script/ops/releaseBoth.js | 5 ++ website/common/script/ops/releaseMounts.js | 5 ++ website/common/script/ops/releasePets.js | 5 ++ 14 files changed, 174 insertions(+), 50 deletions(-) diff --git a/test/common/ops/releaseBoth.js b/test/common/ops/releaseBoth.js index 72411e419b..b5eae68863 100644 --- a/test/common/ops/releaseBoth.js +++ b/test/common/ops/releaseBoth.js @@ -41,6 +41,22 @@ describe('shared.ops.releaseBoth', () => { } }); + it('returns an error when user does not have all pets', (done) => { + const petKeys = Object.keys(user.items.pets); + delete user.items.pets[petKeys[0]]; + + const mountKeys = Object.keys(user.items.mounts); + delete user.items.mounts[mountKeys[0]]; + + try { + releaseBoth(user); + } catch (err) { + expect(err).to.be.an.instanceof(NotAuthorized); + expect(err.message).to.equal(i18n.t('notEnoughPetsMounts')); + done(); + } + }); + it('grants triad bingo with gems', () => { let message = releaseBoth(user)[1]; @@ -79,26 +95,33 @@ describe('shared.ops.releaseBoth', () => { it('does not increment beastMasterCount if any pet is level 0 (released)', () => { let beastMasterCountBeforeRelease = user.achievements.beastMasterCount; user.items.pets[animal] = 0; - - releaseBoth(user); - - expect(user.achievements.beastMasterCount).to.equal(beastMasterCountBeforeRelease); + try { + releaseBoth(user); + } catch (e) { + expect(user.achievements.beastMasterCount).to.equal(beastMasterCountBeforeRelease); + } }); it('does not increment beastMasterCount if any pet is missing (null)', () => { let beastMasterCountBeforeRelease = user.achievements.beastMasterCount; user.items.pets[animal] = null; - releaseBoth(user); - expect(user.achievements.beastMasterCount).to.equal(beastMasterCountBeforeRelease); + try { + releaseBoth(user); + } catch (e) { + expect(user.achievements.beastMasterCount).to.equal(beastMasterCountBeforeRelease); + } }); it('does not increment beastMasterCount if any pet is missing (undefined)', () => { let beastMasterCountBeforeRelease = user.achievements.beastMasterCount; delete user.items.pets[animal]; - releaseBoth(user); - expect(user.achievements.beastMasterCount).to.equal(beastMasterCountBeforeRelease); + try { + releaseBoth(user); + } catch (e) { + expect(user.achievements.beastMasterCount).to.equal(beastMasterCountBeforeRelease); + } }); it('releases mounts', () => { @@ -112,18 +135,22 @@ describe('shared.ops.releaseBoth', () => { let mountMasterCountBeforeRelease = user.achievements.mountMasterCount; user.items.mounts[animal] = null; - releaseBoth(user); - - expect(user.achievements.mountMasterCount).to.equal(mountMasterCountBeforeRelease); + try { + releaseBoth(user); + } catch (e) { + expect(user.achievements.mountMasterCount).to.equal(mountMasterCountBeforeRelease); + } }); it('does not increase mountMasterCount achievement if mount is missing (undefined)', () => { let mountMasterCountBeforeRelease = user.achievements.mountMasterCount; delete user.items.mounts[animal]; - releaseBoth(user); - - expect(user.achievements.mountMasterCount).to.equal(mountMasterCountBeforeRelease); + try { + releaseBoth(user); + } catch (e) { + expect(user.achievements.mountMasterCount).to.equal(mountMasterCountBeforeRelease); + } }); it('removes drop currentPet', () => { diff --git a/test/common/ops/releaseMounts.js b/test/common/ops/releaseMounts.js index dc8fbae7b4..816d5f035d 100644 --- a/test/common/ops/releaseMounts.js +++ b/test/common/ops/releaseMounts.js @@ -35,6 +35,19 @@ describe('shared.ops.releaseMounts', () => { } }); + it('returns an error when user does not have all pets', (done) => { + const mountsKeys = Object.keys(user.items.mounts); + delete user.items.mounts[mountsKeys[0]]; + + try { + releaseMounts(user); + } catch (err) { + expect(err).to.be.an.instanceof(NotAuthorized); + expect(err.message).to.equal(i18n.t('notEnoughMounts')); + done(); + } + }); + it('releases mounts', () => { let message = releaseMounts(user)[1]; @@ -71,18 +84,22 @@ describe('shared.ops.releaseMounts', () => { let mountMasterCountBeforeRelease = user.achievements.mountMasterCount; user.items.mounts[animal] = null; - releaseMounts(user); - - expect(user.achievements.mountMasterCount).to.equal(mountMasterCountBeforeRelease); + try { + releaseMounts(user); + } catch (e) { + expect(user.achievements.mountMasterCount).to.equal(mountMasterCountBeforeRelease); + } }); it('does not increase mountMasterCount achievement if mount is missing (undefined)', () => { let mountMasterCountBeforeRelease = user.achievements.mountMasterCount; delete user.items.mounts[animal]; - releaseMounts(user); - - expect(user.achievements.mountMasterCount).to.equal(mountMasterCountBeforeRelease); + try { + releaseMounts(user); + } catch (e) { + expect(user.achievements.mountMasterCount).to.equal(mountMasterCountBeforeRelease); + } }); it('subtracts gems from balance', () => { diff --git a/test/common/ops/releasePets.js b/test/common/ops/releasePets.js index 62ab66c540..97089607d3 100644 --- a/test/common/ops/releasePets.js +++ b/test/common/ops/releasePets.js @@ -35,6 +35,19 @@ describe('shared.ops.releasePets', () => { } }); + it('returns an error when user does not have all pets', (done) => { + const petKeys = Object.keys(user.items.pets); + delete user.items.pets[petKeys[0]]; + + try { + releasePets(user); + } catch (err) { + expect(err).to.be.an.instanceof(NotAuthorized); + expect(err.message).to.equal(i18n.t('notEnoughPets')); + done(); + } + }); + it('releases pets', () => { let message = releasePets(user)[1]; @@ -75,27 +88,35 @@ describe('shared.ops.releasePets', () => { }); it('does not increment beastMasterCount if any pet is level 0 (released)', () => { - let beastMasterCountBeforeRelease = user.achievements.beastMasterCount; - + const beastMasterCountBeforeRelease = user.achievements.beastMasterCount; user.items.pets[animal] = 0; - releasePets(user); - expect(user.achievements.beastMasterCount).to.equal(beastMasterCountBeforeRelease); + try { + releasePets(user); + } catch (e) { + expect(user.achievements.beastMasterCount).to.equal(beastMasterCountBeforeRelease); + } }); it('does not increment beastMasterCount if any pet is missing (null)', () => { let beastMasterCountBeforeRelease = user.achievements.beastMasterCount; user.items.pets[animal] = null; - releasePets(user); - expect(user.achievements.beastMasterCount).to.equal(beastMasterCountBeforeRelease); + try { + releasePets(user); + } catch (e) { + expect(user.achievements.beastMasterCount).to.equal(beastMasterCountBeforeRelease); + } }); it('does not increment beastMasterCount if any pet is missing (undefined)', () => { let beastMasterCountBeforeRelease = user.achievements.beastMasterCount; delete user.items.pets[animal]; - releasePets(user); - expect(user.achievements.beastMasterCount).to.equal(beastMasterCountBeforeRelease); + try { + releasePets(user); + } catch (e) { + expect(user.achievements.beastMasterCount).to.equal(beastMasterCountBeforeRelease); + } }); }); diff --git a/website/client/components/inventory/stable/index.vue b/website/client/components/inventory/stable/index.vue index e0b2816008..15f689a413 100644 --- a/website/client/components/inventory/stable/index.vue +++ b/website/client/components/inventory/stable/index.vue @@ -963,25 +963,21 @@ this.$root.$emit('bv::show::modal', 'hatching-modal'); } }, - async feedAction (petKey, foodKey) { - let result = await this.$store.dispatch('common:feed', {pet: petKey, food: foodKey}); + const result = await this.$store.dispatch('common:feed', {pet: petKey, food: foodKey}); if (result.message) { this.text(result.message); } }, - closeHatchPetDialog () { this.$root.$emit('bv::hide::modal', 'hatching-modal'); }, - resetHatchablePet ($event) { if (!$event) { this.hatchablePet = null; } }, - onFoodClicked ($event, food) { if (this.currentDraggingFood === null || this.currentDraggingFood !== food) { this.currentDraggingFood = food; @@ -995,7 +991,6 @@ this.foodClickMode = false; } }, - mouseMoved ($event) { if (this.foodClickMode) { this.$refs.clickFoodInfo.style.left = `${$event.x - 70}px`; diff --git a/website/client/components/shops/buyModal.vue b/website/client/components/shops/buyModal.vue index bc2a9978c4..b4cc1b6ea1 100644 --- a/website/client/components/shops/buyModal.vue +++ b/website/client/components/shops/buyModal.vue @@ -51,6 +51,9 @@ span(:class="{'notEnough': notEnoughCurrency}") span.svg-icon.inline.icon-32(aria-hidden="true", v-html="icons[getPriceClass()]") span.cost(:class="getPriceClass()") {{ item.value }} + div(v-else) + span.svg-icon.inline.icon-32(aria-hidden="true", v-html="icons[getPriceClass()]") + span.cost(:class="getPriceClass()") {{ item.value }} .gems-left(v-if='item.key === "gem"') strong(v-if='gemsLeft > 0') {{ gemsLeft }} {{ $t('gemsRemaining') }} diff --git a/website/client/components/shops/market/index.vue b/website/client/components/shops/market/index.vue index db3da6abda..f2345effe8 100644 --- a/website/client/components/shops/market/index.vue +++ b/website/client/components/shops/market/index.vue @@ -163,7 +163,7 @@ ) span.svg-icon.inline.icon-12.color(v-html="icons.pin") - //keys-to-kennel(v-if='category.identifier === "special"') + keys-to-kennel(v-if='category.identifier === "special"') div.fill-height diff --git a/website/client/components/shops/market/keysToKennel.vue b/website/client/components/shops/market/keysToKennel.vue index 3d7f57cf99..ad1a9a1b1f 100644 --- a/website/client/components/shops/market/keysToKennel.vue +++ b/website/client/components/shops/market/keysToKennel.vue @@ -6,7 +6,7 @@ :emptyItem="false", popoverPosition="'top'", @click="releasePets()", - v-if='this.user.achievements.beastMaster' + v-if='userHasAllPets' ) shopItem( :key="keysToMounts.key", @@ -14,7 +14,7 @@ :emptyItem="false", popoverPosition="'top'", @click="releaseMounts()", - v-if='this.user.achievements.mountMaster' + v-if='userHasAllMounts' ) shopItem( :key="keysToBoth.key", @@ -22,7 +22,7 @@ :emptyItem="false", popoverPosition="'top'", @click="releaseBoth()", - v-if='this.user.achievements.mountMaster' + v-if='userHasAllPets && userHasAllMounts' ) @@ -61,9 +61,7 @@ import { mapState } from 'client/libs/store'; import ShopItem from '../shopItem'; -import releasePets from 'common/script/ops/releasePets'; -import releaseMounts from 'common/script/ops/releaseMounts'; -import releaseBoth from 'common/script/ops/releaseBoth'; +import count from 'common/script/count'; import notifications from 'client/mixins/notifications'; @@ -88,11 +86,14 @@ export default { buy: () => { if (!confirm(this.$t('releasePetsConfirm'))) return; try { - releasePets(this.user); + this.$store.dispatch('shops:releasePets', {user: this.user}); + this.text(this.$t('releasePetsSuccess')); + // this.$router.push({name: 'stable'}); + // Reload because achievement is set in user.save instead of common + window.location.reload(true); } catch (err) { alert(err.message); } - this.text(this.$t('releasePetsSuccess')); }, }, keysToMounts: { @@ -108,11 +109,14 @@ export default { buy: () => { if (!confirm(this.$t('releaseMountsConfirm'))) return; try { - releaseMounts(this.user); + this.$store.dispatch('shops:releaseMounts', {user: this.user}); + this.text(this.$t('releaseMountsSuccess')); + // this.$router.push({name: 'stable'}); + // Reload because achievement is set in user.save instead of common + window.location.reload(true); } catch (err) { alert(err.message); } - this.text(this.$t('releaseMountsSuccess')); }, }, keysToBoth: { @@ -128,17 +132,26 @@ export default { buy: () => { if (!confirm(this.$t('releaseBothConfirm'))) return; try { - releaseBoth(this.user); + this.$store.dispatch('shops:releaseBoth', {user: this.user}); + this.text(this.$t('releaseBothSuccess')); + // this.$router.push({name: 'stable'}); + // Reload because achievement is set in user.save instead of common + window.location.reload(true); } catch (err) { alert(err.message); } - this.text(this.$t('releaseBothSuccess')); }, }, }; }, computed: { ...mapState({user: 'user.data'}), + userHasAllPets () { + return count.beastCount(this.user.items.pets) === 90; + }, + userHasAllMounts () { + return count.mountMasterProgress(this.user.items.mounts) === 90; + }, }, methods: { releasePets () { diff --git a/website/client/store/actions/common.js b/website/client/store/actions/common.js index e3e2ac8428..ab504c07a8 100644 --- a/website/client/store/actions/common.js +++ b/website/client/store/actions/common.js @@ -26,8 +26,8 @@ export function hatch (store, params) { export async function feed (store, params) { const user = store.state.user.data; feedOp(user, {params}); - let response = await axios - .post(`/api/v3/user/feed/${params.pet}/${params.food}`); + const response = await axios + .post(`/api/v3/user/feed/${params.pet}/${params.food}`); return response.data; } diff --git a/website/client/store/actions/shops.js b/website/client/store/actions/shops.js index 46480de461..ca109b735d 100644 --- a/website/client/store/actions/shops.js +++ b/website/client/store/actions/shops.js @@ -6,6 +6,10 @@ import hourglassPurchaseOp from 'common/script/ops/buy/hourglassPurchase'; import sellOp from 'common/script/ops/sell'; import unlockOp from 'common/script/ops/unlock'; import rerollOp from 'common/script/ops/reroll'; +import releasePetsOp from 'common/script/ops/releasePets'; +import releaseMountsOp from 'common/script/ops/releaseMounts'; +import releaseBothOp from 'common/script/ops/releaseBoth'; + import { getDropClass } from 'client/libs/notifications'; // @TODO: Purchase means gems and buy means gold. That wording is misused below, but we should also change @@ -176,3 +180,18 @@ export function sellItems (store, params) { sellOp(user, {params, query: {amount: params.amount}}); axios.post(`/api/v3/user/sell/${params.type}/${params.key}?amount=${params.amount}`); } + +export function releasePets (store, params) { + releasePetsOp(params.user); + axios.post('/api/v3/user/release-pets'); +} + +export function releaseMounts (store, params) { + releaseMountsOp(params.user); + axios.post('/api/v3/user/release-mounts'); +} + +export function releaseBoth (store, params) { + releaseBothOp(params.user); + axios.post('/api/v3/user/release-both'); +} diff --git a/website/common/locales/en/pets.json b/website/common/locales/en/pets.json index bd0653c9ae..2298efc77f 100644 --- a/website/common/locales/en/pets.json +++ b/website/common/locales/en/pets.json @@ -138,5 +138,8 @@ "dragThisPotion": "Drag this <%= potionName %> to an Egg and hatch a new pet!", "clickOnEggToHatch": "Click on an Egg to use your <%= potionName %> hatching potion and hatch a new pet!", "hatchDialogText": "Pour your <%= potionName %> hatching potion on your <%= eggName %> egg, and it will hatch into a <%= petName %>.", - "clickOnPotionToHatch": "Click on a hatching potion to use it on your <%= eggName %> and hatch a new pet!" + "clickOnPotionToHatch": "Click on a hatching potion to use it on your <%= eggName %> and hatch a new pet!", + "notEnoughPets": "You have not collected enough pets", + "notEnoughMounts": "You have not collected enough mounts", + "notEnoughPetsMounts": "You have not collected enough pets and mounts" } diff --git a/website/common/script/count.js b/website/common/script/count.js index 530c3d22e9..0a840e029d 100644 --- a/website/common/script/count.js +++ b/website/common/script/count.js @@ -17,6 +17,16 @@ function beastMasterProgress (pets = {}) { return count; } +function beastCount (pets = {}) { + let count = 0; + + each(DROP_ANIMALS, (animal) => { + if (pets[animal] > 0) count++; + }); + + return count; +} + function dropPetsCurrentlyOwned (pets = {}) { let count = 0; @@ -67,6 +77,7 @@ function questsOfCategory (userQuests = {}, category) { module.exports = { beastMasterProgress, + beastCount, dropPetsCurrentlyOwned, mountMasterProgress, remainingGearInSet, diff --git a/website/common/script/ops/releaseBoth.js b/website/common/script/ops/releaseBoth.js index 39b27e8926..7548a45d9c 100644 --- a/website/common/script/ops/releaseBoth.js +++ b/website/common/script/ops/releaseBoth.js @@ -1,4 +1,5 @@ import content from '../content/index'; +import {beastMasterProgress, mountMasterProgress} from '../count'; import i18n from '../i18n'; import { NotAuthorized, @@ -13,6 +14,10 @@ module.exports = function releaseBoth (user, req = {}, analytics) { throw new NotAuthorized(i18n.t('notEnoughGems', req.language)); } + if (beastMasterProgress(user.items.pets) !== 90 || mountMasterProgress(user.items.mounts) !== 90) { + throw new NotAuthorized(i18n.t('notEnoughPetsMounts', req.language)); + } + let giveTriadBingo = true; let giveBeastMasterAchievement = true; let giveMountMasterAchievement = true; diff --git a/website/common/script/ops/releaseMounts.js b/website/common/script/ops/releaseMounts.js index 0f7159502e..4462d11f44 100644 --- a/website/common/script/ops/releaseMounts.js +++ b/website/common/script/ops/releaseMounts.js @@ -1,4 +1,5 @@ import content from '../content/index'; +import {mountMasterProgress} from '../count'; import i18n from '../i18n'; import { NotAuthorized, @@ -9,6 +10,10 @@ module.exports = function releaseMounts (user, req = {}, analytics) { throw new NotAuthorized(i18n.t('notEnoughGems', req.language)); } + if (mountMasterProgress(user.items.mounts) !== 90) { + throw new NotAuthorized(i18n.t('notEnoughMounts', req.language)); + } + user.balance -= 1; let giveMountMasterAchievement = true; diff --git a/website/common/script/ops/releasePets.js b/website/common/script/ops/releasePets.js index 6a356b8629..0124474a37 100644 --- a/website/common/script/ops/releasePets.js +++ b/website/common/script/ops/releasePets.js @@ -1,4 +1,5 @@ import content from '../content/index'; +import {beastMasterProgress} from '../count'; import i18n from '../i18n'; import { NotAuthorized, @@ -9,6 +10,10 @@ module.exports = function releasePets (user, req = {}, analytics) { throw new NotAuthorized(i18n.t('notEnoughGems', req.language)); } + if (beastMasterProgress(user.items.pets) !== 90) { + throw new NotAuthorized(i18n.t('notEnoughPets', req.language)); + } + user.balance -= 1; let giveBeastMasterAchievement = true;