diff --git a/src/scripts/main.js b/src/scripts/main.js index d49a4106..c79c2b6e 100644 --- a/src/scripts/main.js +++ b/src/scripts/main.js @@ -1184,15 +1184,12 @@ import * as detailingFuncs from './modules/details/legacy'; "Furoma Rift": stagingFuncs.addFuromaRiftStage, "Gnawnian Express Station": stagingFuncs.addTrainStage, "Iceberg": stagingFuncs.addIcebergStage, - "Living Garden": stagingFuncs.addGardenStage, - "Muridae Market": stagingFuncs.addMuridaeMarketStage, "Queso Geyser": stagingFuncs.addQuesoGeyserStage, "Sand Dunes": stagingFuncs.addSandDunesStage, "Seasonal Garden": stagingFuncs.addSeasonalGardenStage, "Sunken City": stagingFuncs.addSunkenCityStage, "Table of Contents": stagingFuncs.addTableOfContentsStage, "Toxic Spill": stagingFuncs.addToxicSpillStage, - "Twisted Garden": stagingFuncs.addGardenStage, "Valour Rift": stagingFuncs.addValourRiftStage, "Whisker Woods Rift": stagingFuncs.addWhiskerWoodsRiftStage, "Zokor": stagingFuncs.addZokorStage, diff --git a/src/scripts/modules/stages/environments/livingGarden.ts b/src/scripts/modules/stages/environments/livingGarden.ts new file mode 100644 index 00000000..2f0a188c --- /dev/null +++ b/src/scripts/modules/stages/environments/livingGarden.ts @@ -0,0 +1,20 @@ +import {type User} from '@scripts/types/hg'; +import {type IntakeMessage} from '@scripts/types/mhct'; +import {type IStager} from '../stages.types'; + +export class LivingGardenStager implements IStager { + readonly environment: string = 'Living Garden'; + + /** + * Read the bucket / vial state to determine the stage for Living & Twisted garden. + */ + addStage(message: IntakeMessage, userPre: User, userPost: User, journal: unknown): void { + const quest = userPre.quests.QuestLivingGarden; + if (!quest) { + throw new Error('QuestLivingGarden is undefined'); + } + + const container_status = (quest.is_normal) ? quest.minigame.bucket_state : quest.minigame.vials_state; + message.stage = (container_status === "dumped") ? "Pouring" : "Not Pouring"; + } +} diff --git a/src/scripts/modules/stages/environments/muridaeMarket.ts b/src/scripts/modules/stages/environments/muridaeMarket.ts new file mode 100644 index 00000000..069f3894 --- /dev/null +++ b/src/scripts/modules/stages/environments/muridaeMarket.ts @@ -0,0 +1,18 @@ +import {type User} from '@scripts/types/hg'; +import {type IntakeMessage} from '@scripts/types/mhct'; +import {type IStager} from '../stages.types'; + +export class MuridaeMarketStager implements IStager { + readonly environment: string = 'Muridae Market'; + + /** + * Report the Artisan Charm status. + */ + addStage(message: IntakeMessage, userPre: User, userPost: User, journal: unknown): void { + const charm = userPre.trinket_name; + + message.stage = charm === "Artisan Charm" + ? "Artisan" + : "Not Artisan"; + } +} diff --git a/src/scripts/modules/stages/environments/twistedGarden.ts b/src/scripts/modules/stages/environments/twistedGarden.ts new file mode 100644 index 00000000..488e723a --- /dev/null +++ b/src/scripts/modules/stages/environments/twistedGarden.ts @@ -0,0 +1,20 @@ +import {type User} from '@scripts/types/hg'; +import {type IntakeMessage} from '@scripts/types/mhct'; +import {type IStager} from '../stages.types'; + +export class TwistedGardenStager implements IStager { + readonly environment: string = 'Twisted Garden'; + + /** + * Read the bucket / vial state to determine the stage for Living & Twisted garden. + */ + addStage(message: IntakeMessage, userPre: User, userPost: User, journal: unknown): void { + const quest = userPre.quests.QuestLivingGarden; + if (!quest) { + throw new Error('QuestLivingGarden is undefined'); + } + + const container_status = (quest.is_normal) ? quest.minigame.bucket_state : quest.minigame.vials_state; + message.stage = (container_status === "dumped") ? "Pouring" : "Not Pouring"; + } +} diff --git a/src/scripts/modules/stages/index.ts b/src/scripts/modules/stages/index.ts index eee2f4d4..4e980359 100644 --- a/src/scripts/modules/stages/index.ts +++ b/src/scripts/modules/stages/index.ts @@ -9,11 +9,14 @@ import {FungalCavernStager} from './environments/fungalCavern'; import {HarbourStager} from './environments/harbour'; import {IceFortressStager} from './environments/iceFortress'; import {LabyrinthStager} from './environments/labyrinth'; +import {LivingGardenStager} from './environments/livingGarden'; import {LostCityStager} from './environments/lostCity'; import {MoussuPicchuStager} from './environments/moussuPicchu'; import {MousoleumStager} from './environments/mousoleum'; +import {MuridaeMarketStager} from './environments/muridaeMarket'; import {SlushyShorelineStager} from './environments/slushyShoreline'; import {SuperBrieFactoryStager} from './environments/superBrieFactory'; +import {TwistedGardenStager} from './environments/twistedGarden'; const stageModules: IStager[] = [ new BalacksCoveStager(), @@ -26,11 +29,14 @@ const stageModules: IStager[] = [ new HarbourStager(), new IceFortressStager(), new LabyrinthStager(), + new LivingGardenStager(), new LostCityStager(), new MoussuPicchuStager(), new MousoleumStager(), + new MuridaeMarketStager(), new SlushyShorelineStager(), new SuperBrieFactoryStager(), + new TwistedGardenStager(), ]; export {stageModules}; diff --git a/src/scripts/modules/stages/legacy.js b/src/scripts/modules/stages/legacy.js index 2a138d37..ddde005f 100644 --- a/src/scripts/modules/stages/legacy.js +++ b/src/scripts/modules/stages/legacy.js @@ -114,19 +114,6 @@ export function addSeasonalGardenStage(message, user, user_post, hunt) { } } -/** - * Read the bucket / vial state to determine the stage for Living & Twisted garden. - * @param {Object } message The message to be sent. - * @param {Object } user The user state object, when the hunt was invoked (pre-hunt). - * @param {Object } user_post The user state object, after the hunt. - * @param {Object } hunt The journal entry corresponding to the active hunt. - */ -export function addGardenStage(message, user, user_post, hunt) { - const quest = user.quests.QuestLivingGarden; - const container_status = (quest.is_normal) ? quest.minigame.bucket_state : quest.minigame.vials_state; - message.stage = (container_status === "dumped") ? "Pouring" : "Not Pouring"; -} - /** * Determine if there is a stampede active * @param {Object } message The message to be sent. @@ -164,20 +151,6 @@ export function addIcebergStage(message, user, user_post, hunt) { } } -/** - * Report the Artisan Charm status. - * @param {Object } message The message to be sent. - * @param {Object } user The user state object, when the hunt was invoked (pre-hunt). - * @param {Object } user_post The user state object, after the hunt. - * @param {Object } hunt The journal entry corresponding to the active hunt. - */ -export function addMuridaeMarketStage(message, user, user_post, hunt) { - message.stage = "Not Artisan"; - if (user.trinket_name === "Artisan Charm") { - message.stage = "Artisan"; - } -} - /** * Report the zone and depth, if any. * @param {Object } message The message to be sent. diff --git a/src/scripts/types/hg.ts b/src/scripts/types/hg.ts index 01a03193..c7fdc7eb 100644 --- a/src/scripts/types/hg.ts +++ b/src/scripts/types/hg.ts @@ -51,7 +51,7 @@ export interface Quests { QuestIceberg?: quests.QuestIceberg; QuestIceFortress?: quests.QuestIceFortress; QuestLabyrinth?: quests.QuestLabyrinth - QuestLivingGarden?: unknown + QuestLivingGarden?: quests.QuestLivingGarden QuestLostCity?: quests.QuestLostCity QuestMousoleum?: quests.QuestMousoleum QuestMoussuPicchu?: quests.QuestMoussuPicchu diff --git a/src/scripts/types/quests/index.ts b/src/scripts/types/quests/index.ts index ea7dac4f..d7e01e0a 100644 --- a/src/scripts/types/quests/index.ts +++ b/src/scripts/types/quests/index.ts @@ -8,6 +8,7 @@ export * from '@scripts/types/quests/harbour'; export * from '@scripts/types/quests/iceberg'; export * from '@scripts/types/quests/iceFortress'; export * from '@scripts/types/quests/labyrinth'; +export * from '@scripts/types/quests/livingGarden'; export * from '@scripts/types/quests/lostCity'; export * from '@scripts/types/quests/mousoleum'; export * from '@scripts/types/quests/moussuPicchu'; diff --git a/src/scripts/types/quests/livingGarden.ts b/src/scripts/types/quests/livingGarden.ts new file mode 100644 index 00000000..d93fe066 --- /dev/null +++ b/src/scripts/types/quests/livingGarden.ts @@ -0,0 +1,17 @@ +export type QuestLivingGarden = LivingGardenState | TwistedGardenState + +interface LivingGardenState { + is_normal: true + minigame: { + bucket_state: PourStatus + } +} + +interface TwistedGardenState { + is_normal: false + minigame: { + vials_state: PourStatus + } +} + +type PourStatus = 'filling' | 'dumped'; diff --git a/tests/scripts/modules/stages/environments/livingGarden.spec.ts b/tests/scripts/modules/stages/environments/livingGarden.spec.ts new file mode 100644 index 00000000..c84d6c4e --- /dev/null +++ b/tests/scripts/modules/stages/environments/livingGarden.spec.ts @@ -0,0 +1,112 @@ +import {LivingGardenStager} from "@scripts/modules/stages/environments/livingGarden"; +import {TwistedGardenStager} from "@scripts/modules/stages/environments/twistedGarden"; +import {User} from "@scripts/types/hg"; +import {IntakeMessage} from "@scripts/types/mhct"; + +describe('Living/Twisted Garden stages', () => { + describe('Living', () => { + it('should be for the "Living Garden" environment', () => { + const stager = new LivingGardenStager(); + expect(stager.environment).toBe('Living Garden'); + }); + + it('should set stage to "Pouring" if bucket dumped', () => { + const stager = new LivingGardenStager(); + + const message = {} as IntakeMessage; + const preUser = {quests: {QuestLivingGarden: { + is_normal: true, + minigame: { + bucket_state: 'dumped', + }, + }}} as User; + const postUser = {} as User; + const journal = {}; + + stager.addStage(message, preUser, postUser, journal); + + expect(message.stage).toBe('Pouring'); + }); + + it('should set stage to "Not Pouring" if bucket not dumped', () => { + const stager = new LivingGardenStager(); + + const message = {} as IntakeMessage; + const preUser = {quests: {QuestLivingGarden: { + is_normal: true, + minigame: { + bucket_state: 'filling', + }, + }}} as User; + const postUser = {} as User; + const journal = {}; + + stager.addStage(message, preUser, postUser, journal); + }); + + it.each([undefined, null])('should throw if quest is %p', (quest) => { + const stager = new LivingGardenStager(); + + const message = {} as IntakeMessage; + const preUser = {quests: {QuestLivingGarden: quest}} as User; + const postUser = {} as User; + const journal = {}; + + expect(() => stager.addStage(message, preUser, postUser, journal)) + .toThrow('QuestLivingGarden is undefined'); + }); + }); + + describe('Twisted', () => { + it('should be for the "Twisted Garden" environment', () => { + const stager = new TwistedGardenStager(); + expect(stager.environment).toBe('Twisted Garden'); + }); + + it('should set stage to "Pouring" if bucket dumped', () => { + const stager = new TwistedGardenStager(); + + const message = {} as IntakeMessage; + const preUser = {quests: {QuestLivingGarden: { + is_normal: false, + minigame: { + vials_state: 'dumped', + }, + }}} as User; + const postUser = {} as User; + const journal = {}; + + stager.addStage(message, preUser, postUser, journal); + + expect(message.stage).toBe('Pouring'); + }); + + it('should set stage to "Not Pouring" if bucket not dumped', () => { + const stager = new TwistedGardenStager(); + + const message = {} as IntakeMessage; + const preUser = {quests: {QuestLivingGarden: { + is_normal: false, + minigame: { + vials_state: 'filling', + }, + }}} as User; + const postUser = {} as User; + const journal = {}; + + stager.addStage(message, preUser, postUser, journal); + }); + + it.each([undefined, null])('should throw if quest is %p', (quest) => { + const stager = new TwistedGardenStager(); + + const message = {} as IntakeMessage; + const preUser = {quests: {QuestLivingGarden: quest}} as User; + const postUser = {} as User; + const journal = {}; + + expect(() => stager.addStage(message, preUser, postUser, journal)) + .toThrow('QuestLivingGarden is undefined'); + }); + }); +}); diff --git a/tests/scripts/modules/stages/environments/muridaeMarket.spec.ts b/tests/scripts/modules/stages/environments/muridaeMarket.spec.ts new file mode 100644 index 00000000..20d3e088 --- /dev/null +++ b/tests/scripts/modules/stages/environments/muridaeMarket.spec.ts @@ -0,0 +1,34 @@ +import {MuridaeMarketStager} from "@scripts/modules/stages/environments/muridaeMarket"; +import {User} from "@scripts/types/hg"; +import {IntakeMessage} from "@scripts/types/mhct"; + +describe('Muridae Market stages', () => { + it('should be for the "Muridae Market" environment', () => { + const stager = new MuridaeMarketStager(); + expect(stager.environment).toBe('Muridae Market'); + }); + + it('should set stage to "Artisan" if user has artisan charm equipped', () => { + const stager = new MuridaeMarketStager(); + const message = {} as IntakeMessage; + const preUser = {trinket_name: 'Artisan Charm'} as User; + const postUser = {} as User; + const journal = {}; + + stager.addStage(message, preUser, postUser, journal); + + expect(message.stage).toBe('Artisan'); + }); + + it('should set stage to "Not Artisan" if user does not has artisan charm equipped', () => { + const stager = new MuridaeMarketStager(); + const message = {} as IntakeMessage; + const preUser = {trinket_name: 'Power Charm'} as User; + const postUser = {} as User; + const journal = {}; + + stager.addStage(message, preUser, postUser, journal); + + expect(message.stage).toBe('Not Artisan'); + }); +});