-
-
Notifications
You must be signed in to change notification settings - Fork 1.8k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[Feature] Seasonal splash messages logic + scaffolding (#4318)
* add: seasonsl splash messages logic + scaffolding * refactor: settin up and displaying splash messages. They are now stored with their i18next keys and only get translated as soon as they are displayed. This also allows for better display of the `battlesWon` parameter which now supports better number formatting and the count is an interpolation * fix: updateTitleStats not checking the namespace of battlesWon * add tests for splash_messages * test: always use UTC time * fix: time-pattern to MM-DD * fix splash_messages test * add: const to control usage of seasonal splash messages * fix tests (splashj) * Update src/locales/ja/splash-messages.json Co-authored-by: Chapybara-jp <charlie.beer@hotmail.com> * Update src/locales/es/splash-messages.json Add missing `number` format for battlesWon message --------- Co-authored-by: Chapybara-jp <charlie.beer@hotmail.com>
- Loading branch information
1 parent
7490699
commit 48430c8
Showing
15 changed files
with
234 additions
and
57 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,5 @@ | ||
export const PLAYER_PARTY_MAX_SIZE = 6; | ||
/** The maximum size of the player's party */ | ||
export const PLAYER_PARTY_MAX_SIZE: number = 6; | ||
|
||
/** Whether to use seasonal splash messages in general */ | ||
export const USE_SEASONAL_SPLASH_MESSAGES: boolean = false; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,46 +1,136 @@ | ||
import i18next from "i18next"; | ||
import { USE_SEASONAL_SPLASH_MESSAGES } from "#app/constants"; | ||
|
||
export function getBattleCountSplashMessage(): string { | ||
return `{COUNT} ${i18next.t("splashMessages:battlesWon")}`; | ||
//#region Interfaces/Types | ||
|
||
type Month = "01" | "02" | "03" | "04" | "05" | "06" | "07" | "08" | "09" | "10" | "11" | "12"; | ||
type Day = | ||
| Month | ||
| "13" | ||
| "14" | ||
| "15" | ||
| "16" | ||
| "17" | ||
| "18" | ||
| "19" | ||
| "20" | ||
| "21" | ||
| "22" | ||
| "23" | ||
| "24" | ||
| "25" | ||
| "26" | ||
| "27" | ||
| "28" | ||
| "29" | ||
| "30" | ||
| "31"; | ||
|
||
/** | ||
* Represents a season with its {@linkcode name}, | ||
* {@linkcode start} day+month, {@linkcode end} day+month | ||
* and {@linkcode messages}. | ||
*/ | ||
interface Season { | ||
/** The name of the season (internal use only) */ | ||
name: string; | ||
/** The start day and month of the season. Format `MM-DD` */ | ||
start: `${Month}-${Day}`; | ||
/** The end day and month of the season. Format `MM-DD` */ | ||
end: `${Month}-${Day}`; | ||
/** Collection of the messages to display (without the `i18next.t()` call!) */ | ||
messages: string[]; | ||
} | ||
|
||
//#region Constants | ||
|
||
/** The weight multiplier for the battles-won splash message */ | ||
const BATTLES_WON_WEIGHT_MULTIPLIER = 10; | ||
/** The weight multiplier for the seasonal splash messages */ | ||
const SEASONAL_WEIGHT_MULTIPLIER = 10; | ||
|
||
//#region Common Messages | ||
|
||
const commonSplashMessages = [ | ||
...Array(BATTLES_WON_WEIGHT_MULTIPLIER).fill("battlesWon"), | ||
"joinTheDiscord", | ||
"infiniteLevels", | ||
"everythingStacks", | ||
"optionalSaveScumming", | ||
"biomes", | ||
"openSource", | ||
"playWithSpeed", | ||
"liveBugTesting", | ||
"heavyInfluence", | ||
"pokemonRiskAndPokemonRain", | ||
"nowWithMoreSalt", | ||
"infiniteFusionAtHome", | ||
"brokenEggMoves", | ||
"magnificent", | ||
"mubstitute", | ||
"thatsCrazy", | ||
"oranceJuice", | ||
"questionableBalancing", | ||
"coolShaders", | ||
"aiFree", | ||
"suddenDifficultySpikes", | ||
"basedOnAnUnfinishedFlashGame", | ||
"moreAddictiveThanIntended", | ||
"mostlyConsistentSeeds", | ||
"achievementPointsDontDoAnything", | ||
"youDoNotStartAtLevel", | ||
"dontTalkAboutTheManaphyEggIncident", | ||
"alsoTryPokengine", | ||
"alsoTryEmeraldRogue", | ||
"alsoTryRadicalRed", | ||
"eeveeExpo", | ||
"ynoproject", | ||
"breedersInSpace", | ||
]; | ||
|
||
//#region Seasonal Messages | ||
|
||
const seasonalSplashMessages: Season[] = [ | ||
{ | ||
name: "Halloween", | ||
start: "09-15", | ||
end: "10-31", | ||
messages: ["halloween.pumpkaboosAbout", "halloween.mayContainSpiders", "halloween.spookyScaryDuskulls"], | ||
}, | ||
{ | ||
name: "XMAS", | ||
start: "12-01", | ||
end: "12-26", | ||
messages: ["xmas.happyHolidays", "xmas.delibirdSeason"], | ||
}, | ||
{ | ||
name: "New Year's", | ||
start: "01-01", | ||
end: "01-31", | ||
messages: ["newYears.happyNewYear"], | ||
}, | ||
]; | ||
|
||
//#endregion | ||
|
||
export function getSplashMessages(): string[] { | ||
const splashMessages = Array(10).fill(getBattleCountSplashMessage()); | ||
splashMessages.push( | ||
i18next.t("splashMessages:joinTheDiscord"), | ||
i18next.t("splashMessages:infiniteLevels"), | ||
i18next.t("splashMessages:everythingStacks"), | ||
i18next.t("splashMessages:optionalSaveScumming"), | ||
i18next.t("splashMessages:biomes"), | ||
i18next.t("splashMessages:openSource"), | ||
i18next.t("splashMessages:playWithSpeed"), | ||
i18next.t("splashMessages:liveBugTesting"), | ||
i18next.t("splashMessages:heavyInfluence"), | ||
i18next.t("splashMessages:pokemonRiskAndPokemonRain"), | ||
i18next.t("splashMessages:nowWithMoreSalt"), | ||
i18next.t("splashMessages:infiniteFusionAtHome"), | ||
i18next.t("splashMessages:brokenEggMoves"), | ||
i18next.t("splashMessages:magnificent"), | ||
i18next.t("splashMessages:mubstitute"), | ||
i18next.t("splashMessages:thatsCrazy"), | ||
i18next.t("splashMessages:oranceJuice"), | ||
i18next.t("splashMessages:questionableBalancing"), | ||
i18next.t("splashMessages:coolShaders"), | ||
i18next.t("splashMessages:aiFree"), | ||
i18next.t("splashMessages:suddenDifficultySpikes"), | ||
i18next.t("splashMessages:basedOnAnUnfinishedFlashGame"), | ||
i18next.t("splashMessages:moreAddictiveThanIntended"), | ||
i18next.t("splashMessages:mostlyConsistentSeeds"), | ||
i18next.t("splashMessages:achievementPointsDontDoAnything"), | ||
i18next.t("splashMessages:youDoNotStartAtLevel"), | ||
i18next.t("splashMessages:dontTalkAboutTheManaphyEggIncident"), | ||
i18next.t("splashMessages:alsoTryPokengine"), | ||
i18next.t("splashMessages:alsoTryEmeraldRogue"), | ||
i18next.t("splashMessages:alsoTryRadicalRed"), | ||
i18next.t("splashMessages:eeveeExpo"), | ||
i18next.t("splashMessages:ynoproject"), | ||
i18next.t("splashMessages:breedersInSpace"), | ||
); | ||
|
||
return splashMessages; | ||
const splashMessages: string[] = [...commonSplashMessages]; | ||
console.log("use seasonal splash messages", USE_SEASONAL_SPLASH_MESSAGES); | ||
if (USE_SEASONAL_SPLASH_MESSAGES) { | ||
// add seasonal splash messages if the season is active | ||
for (const { name, start, end, messages } of seasonalSplashMessages) { | ||
const now = new Date(); | ||
const startDate = new Date(`${start}-${now.getFullYear()}`); | ||
const endDate = new Date(`${end}-${now.getFullYear()}`); | ||
|
||
if (now >= startDate && now <= endDate) { | ||
console.log(`Adding ${messages.length} ${name} splash messages (weight: x${SEASONAL_WEIGHT_MULTIPLIER})`); | ||
messages.forEach((message) => { | ||
const weightedMessage = Array(SEASONAL_WEIGHT_MULTIPLIER).fill(message); | ||
splashMessages.push(...weightedMessage); | ||
}); | ||
} | ||
} | ||
} | ||
|
||
return splashMessages.map((message) => `splashMessages:${message}`); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
import { getSplashMessages } from "#app/data/splash-messages"; | ||
import { describe, expect, it, vi, afterEach, beforeEach } from "vitest"; | ||
import * as Constants from "#app/constants"; | ||
|
||
describe("Data - Splash Messages", () => { | ||
it("should contain at least 15 splash messages", () => { | ||
expect(getSplashMessages().length).toBeGreaterThanOrEqual(15); | ||
}); | ||
|
||
// make sure to adjust this test if the weight it changed! | ||
it("should add contain 10 `battlesWon` splash messages", () => { | ||
const battlesWonMessages = getSplashMessages().filter((message) => message === "splashMessages:battlesWon"); | ||
expect(battlesWonMessages).toHaveLength(10); | ||
}); | ||
|
||
describe("Seasonal", () => { | ||
beforeEach(() => { | ||
vi.spyOn(Constants, "USE_SEASONAL_SPLASH_MESSAGES", "get").mockReturnValue(true); | ||
}); | ||
|
||
afterEach(() => { | ||
vi.useRealTimers(); // reset system time | ||
}); | ||
|
||
it("should contain halloween messages from Sep 15 to Oct 31", () => { | ||
testSeason(new Date("2024-09-15"), new Date("2024-10-31"), "halloween"); | ||
}); | ||
|
||
it("should contain xmas messages from Dec 1 to Dec 26", () => { | ||
testSeason(new Date("2024-12-01"), new Date("2024-12-26"), "xmas"); | ||
}); | ||
|
||
it("should contain new years messages frm Jan 1 to Jan 31", () => { | ||
testSeason(new Date("2024-01-01"), new Date("2024-01-31"), "newYears"); | ||
}); | ||
}); | ||
}); | ||
|
||
/** | ||
* Helpoer method to test seasonal messages | ||
* @param startDate The seasons start date | ||
* @param endDate The seasons end date | ||
* @param prefix the splash message prefix (e.g. `newYears` or `xmas`) | ||
*/ | ||
function testSeason(startDate: Date, endDate: Date, prefix: string) { | ||
const filterFn = (message: string) => message.startsWith(`splashMessages:${prefix}.`); | ||
|
||
const beforeDate = new Date(startDate); | ||
beforeDate.setDate(startDate.getDate() - 1); | ||
|
||
const afterDate = new Date(endDate); | ||
afterDate.setDate(endDate.getDate() + 1); | ||
|
||
const dates: Date[] = [beforeDate, startDate, endDate, afterDate]; | ||
const [before, start, end, after] = dates.map((date) => { | ||
vi.setSystemTime(date); | ||
console.log("System time set to", date); | ||
const count = getSplashMessages().filter(filterFn).length; | ||
return count; | ||
}); | ||
|
||
expect(before).toBe(0); | ||
expect(start).toBeGreaterThanOrEqual(10); // make sure to adjust if weight is changed! | ||
expect(end).toBeGreaterThanOrEqual(10); // make sure to adjust if weight is changed! | ||
expect(after).toBe(0); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters