diff --git a/public/images/ui/dawn_icon.png b/public/images/ui/dawn_icon.png deleted file mode 100644 index e04e6024aa0..00000000000 Binary files a/public/images/ui/dawn_icon.png and /dev/null differ diff --git a/public/images/ui/dawn_icon_bg.png b/public/images/ui/dawn_icon_bg.png new file mode 100644 index 00000000000..2983c2744a3 Binary files /dev/null and b/public/images/ui/dawn_icon_bg.png differ diff --git a/public/images/ui/dawn_icon_fg.png b/public/images/ui/dawn_icon_fg.png new file mode 100644 index 00000000000..e6c195bd371 Binary files /dev/null and b/public/images/ui/dawn_icon_fg.png differ diff --git a/public/images/ui/dawn_icon_mg.png b/public/images/ui/dawn_icon_mg.png new file mode 100644 index 00000000000..ff32b4418aa Binary files /dev/null and b/public/images/ui/dawn_icon_mg.png differ diff --git a/public/images/ui/day_icon.png b/public/images/ui/day_icon.png deleted file mode 100644 index fe41acffd9c..00000000000 Binary files a/public/images/ui/day_icon.png and /dev/null differ diff --git a/public/images/ui/day_icon_bg.png b/public/images/ui/day_icon_bg.png new file mode 100644 index 00000000000..9028e0309f7 Binary files /dev/null and b/public/images/ui/day_icon_bg.png differ diff --git a/public/images/ui/day_icon_fg.png b/public/images/ui/day_icon_fg.png new file mode 100644 index 00000000000..523f7b1be7e Binary files /dev/null and b/public/images/ui/day_icon_fg.png differ diff --git a/public/images/ui/day_icon_mg.png b/public/images/ui/day_icon_mg.png new file mode 100644 index 00000000000..7a236fa48d3 Binary files /dev/null and b/public/images/ui/day_icon_mg.png differ diff --git a/public/images/ui/dusk_icon.png b/public/images/ui/dusk_icon.png deleted file mode 100644 index e848fa31345..00000000000 Binary files a/public/images/ui/dusk_icon.png and /dev/null differ diff --git a/public/images/ui/dusk_icon_bg.png b/public/images/ui/dusk_icon_bg.png new file mode 100644 index 00000000000..57d22ec2b21 Binary files /dev/null and b/public/images/ui/dusk_icon_bg.png differ diff --git a/public/images/ui/dusk_icon_fg.png b/public/images/ui/dusk_icon_fg.png new file mode 100644 index 00000000000..e0ca1bce79b Binary files /dev/null and b/public/images/ui/dusk_icon_fg.png differ diff --git a/public/images/ui/dusk_icon_mg.png b/public/images/ui/dusk_icon_mg.png new file mode 100644 index 00000000000..4e6a880b37f Binary files /dev/null and b/public/images/ui/dusk_icon_mg.png differ diff --git a/public/images/ui/legacy/dawn_icon.png b/public/images/ui/legacy/dawn_icon.png deleted file mode 100644 index eb24a799ab9..00000000000 Binary files a/public/images/ui/legacy/dawn_icon.png and /dev/null differ diff --git a/public/images/ui/legacy/dawn_icon_bg.png b/public/images/ui/legacy/dawn_icon_bg.png new file mode 100644 index 00000000000..87c4d75cd94 Binary files /dev/null and b/public/images/ui/legacy/dawn_icon_bg.png differ diff --git a/public/images/ui/legacy/dawn_icon_fg.png b/public/images/ui/legacy/dawn_icon_fg.png new file mode 100644 index 00000000000..db985f953d3 Binary files /dev/null and b/public/images/ui/legacy/dawn_icon_fg.png differ diff --git a/public/images/ui/legacy/dawn_icon_mg.png b/public/images/ui/legacy/dawn_icon_mg.png new file mode 100644 index 00000000000..442cb1b674c Binary files /dev/null and b/public/images/ui/legacy/dawn_icon_mg.png differ diff --git a/public/images/ui/legacy/day_icon.png b/public/images/ui/legacy/day_icon.png deleted file mode 100644 index 310ba50dcf3..00000000000 Binary files a/public/images/ui/legacy/day_icon.png and /dev/null differ diff --git a/public/images/ui/legacy/day_icon_bg.png b/public/images/ui/legacy/day_icon_bg.png new file mode 100644 index 00000000000..3db0dab4589 Binary files /dev/null and b/public/images/ui/legacy/day_icon_bg.png differ diff --git a/public/images/ui/legacy/day_icon_fg.png b/public/images/ui/legacy/day_icon_fg.png new file mode 100644 index 00000000000..657c82e5dbd Binary files /dev/null and b/public/images/ui/legacy/day_icon_fg.png differ diff --git a/public/images/ui/legacy/day_icon_mg.png b/public/images/ui/legacy/day_icon_mg.png new file mode 100644 index 00000000000..90fce4a761c Binary files /dev/null and b/public/images/ui/legacy/day_icon_mg.png differ diff --git a/public/images/ui/legacy/dusk_icon.png b/public/images/ui/legacy/dusk_icon.png deleted file mode 100644 index f383ebf5246..00000000000 Binary files a/public/images/ui/legacy/dusk_icon.png and /dev/null differ diff --git a/public/images/ui/legacy/dusk_icon_bg.png b/public/images/ui/legacy/dusk_icon_bg.png new file mode 100644 index 00000000000..7610a2e67f8 Binary files /dev/null and b/public/images/ui/legacy/dusk_icon_bg.png differ diff --git a/public/images/ui/legacy/dusk_icon_fg.png b/public/images/ui/legacy/dusk_icon_fg.png new file mode 100644 index 00000000000..d4bbb98fdd1 Binary files /dev/null and b/public/images/ui/legacy/dusk_icon_fg.png differ diff --git a/public/images/ui/legacy/dusk_icon_mg.png b/public/images/ui/legacy/dusk_icon_mg.png new file mode 100644 index 00000000000..dc603f8ca79 Binary files /dev/null and b/public/images/ui/legacy/dusk_icon_mg.png differ diff --git a/public/images/ui/legacy/night_icon.png b/public/images/ui/legacy/night_icon.png deleted file mode 100644 index 1796081c05b..00000000000 Binary files a/public/images/ui/legacy/night_icon.png and /dev/null differ diff --git a/public/images/ui/legacy/night_icon_bg.png b/public/images/ui/legacy/night_icon_bg.png new file mode 100644 index 00000000000..c32ee1ebd2a Binary files /dev/null and b/public/images/ui/legacy/night_icon_bg.png differ diff --git a/public/images/ui/legacy/night_icon_fg.png b/public/images/ui/legacy/night_icon_fg.png new file mode 100644 index 00000000000..737cca3305e Binary files /dev/null and b/public/images/ui/legacy/night_icon_fg.png differ diff --git a/public/images/ui/legacy/night_icon_mg.png b/public/images/ui/legacy/night_icon_mg.png new file mode 100644 index 00000000000..f5fdff51cc8 Binary files /dev/null and b/public/images/ui/legacy/night_icon_mg.png differ diff --git a/public/images/ui/night_icon.png b/public/images/ui/night_icon.png deleted file mode 100644 index 1782303f73d..00000000000 Binary files a/public/images/ui/night_icon.png and /dev/null differ diff --git a/public/images/ui/night_icon_bg.png b/public/images/ui/night_icon_bg.png new file mode 100644 index 00000000000..1ce4007d54c Binary files /dev/null and b/public/images/ui/night_icon_bg.png differ diff --git a/public/images/ui/night_icon_fg.png b/public/images/ui/night_icon_fg.png new file mode 100644 index 00000000000..78741584312 Binary files /dev/null and b/public/images/ui/night_icon_fg.png differ diff --git a/public/images/ui/night_icon_mg.png b/public/images/ui/night_icon_mg.png new file mode 100644 index 00000000000..5583c8f799d Binary files /dev/null and b/public/images/ui/night_icon_mg.png differ diff --git a/src/battle-scene-events.ts b/src/battle-scene-events.ts index 74fac97d2b7..aaeb590f8ba 100644 --- a/src/battle-scene-events.ts +++ b/src/battle-scene-events.ts @@ -20,6 +20,11 @@ export enum BattleSceneEventType { */ BERRY_USED = "onBerryUsed", + /** + * Triggers at the start of each new encounter + * @see {@linkcode EncounterPhaseEvent} + */ + ENCOUNTER_PHASE = "onEncounterPhase", /** * Triggers on the first turn of a new battle * @see {@linkcode TurnInitEvent} @@ -85,6 +90,15 @@ export class BerryUsedEvent extends Event { } } +/** + * Container class for {@linkcode BattleSceneEventType.ENCOUNTER_PHASE} events + * @extends Event +*/ +export class EncounterPhaseEvent extends Event { + constructor() { + super(BattleSceneEventType.ENCOUNTER_PHASE); + } +} /** * Container class for {@linkcode BattleSceneEventType.TURN_INIT} events * @extends Event diff --git a/src/battle-scene.ts b/src/battle-scene.ts index 53b58cb8a41..38882cf3e68 100644 --- a/src/battle-scene.ts +++ b/src/battle-scene.ts @@ -60,6 +60,7 @@ import {UiInputs} from "./ui-inputs"; import { MoneyFormat } from "./enums/money-format"; import { NewArenaEvent } from "./battle-scene-events"; import ArenaFlyout from "./ui/arena-flyout"; +import { EaseType } from "./ui/enums/ease-type"; export const bypassLogin = import.meta.env.VITE_BYPASS_LOGIN === "1"; @@ -100,6 +101,8 @@ export default class BattleScene extends SceneBase { public reroll: boolean = false; public showMovesetFlyout: boolean = true; public showArenaFlyout: boolean = true; + public showTimeOfDayWidget: boolean = true; + public timeOfDayAnimation: EaseType = EaseType.NONE; public showLevelUpStats: boolean = true; public enableTutorials: boolean = import.meta.env.VITE_BYPASS_TUTORIAL === "1"; public enableMoveInfo: boolean = true; diff --git a/src/loading-scene.ts b/src/loading-scene.ts index 34b2f9d6be7..522962d5829 100644 --- a/src/loading-scene.ts +++ b/src/loading-scene.ts @@ -96,10 +96,18 @@ export class LoadingScene extends SceneBase { this.loadImage("type_tera", "ui"); this.loadAtlas("type_bgs", "ui"); - this.loadImage("dawn_icon", "ui"); - this.loadImage("day_icon", "ui"); - this.loadImage("dusk_icon", "ui"); - this.loadImage("night_icon", "ui"); + this.loadImage("dawn_icon_fg", "ui"); + this.loadImage("dawn_icon_mg", "ui"); + this.loadImage("dawn_icon_bg", "ui"); + this.loadImage("day_icon_fg", "ui"); + this.loadImage("day_icon_mg", "ui"); + this.loadImage("day_icon_bg", "ui"); + this.loadImage("dusk_icon_fg", "ui"); + this.loadImage("dusk_icon_mg", "ui"); + this.loadImage("dusk_icon_bg", "ui"); + this.loadImage("night_icon_fg", "ui"); + this.loadImage("night_icon_mg", "ui"); + this.loadImage("night_icon_bg", "ui"); this.loadImage("pb_tray_overlay_player", "ui"); this.loadImage("pb_tray_overlay_enemy", "ui"); diff --git a/src/phases.ts b/src/phases.ts index 406d47cff22..e9becbe485d 100644 --- a/src/phases.ts +++ b/src/phases.ts @@ -62,7 +62,7 @@ import { Abilities } from "./data/enums/abilities"; import * as Overrides from "./overrides"; import { TextStyle, addTextObject } from "./ui/text"; import { Type } from "./data/type"; -import { BerryUsedEvent, MoveUsedEvent, TurnEndEvent, TurnInitEvent } from "./battle-scene-events"; +import { BerryUsedEvent, EncounterPhaseEvent, MoveUsedEvent, TurnEndEvent, TurnInitEvent } from "./battle-scene-events"; export class LoginPhase extends Phase { @@ -741,6 +741,8 @@ export class EncounterPhase extends BattlePhase { this.scene.initSession(); + this.scene.eventTarget.dispatchEvent(new EncounterPhaseEvent()); + // Failsafe if players somehow skip floor 200 in classic mode if (this.scene.gameMode.isClassic && this.scene.currentBattle.waveIndex > 200) { this.scene.unshiftPhase(new GameOverPhase(this.scene)); diff --git a/src/system/settings/settings.ts b/src/system/settings/settings.ts index 81971a08d69..b2175275eef 100644 --- a/src/system/settings/settings.ts +++ b/src/system/settings/settings.ts @@ -7,6 +7,7 @@ import { PlayerGender } from "#app/data/enums/player-gender"; import { CandyUpgradeNotificationChangedEvent } from "#app/battle-scene-events.js"; import { MoneyFormat } from "../../enums/money-format"; import SettingsUiHandler from "#app/ui/settings/settings-ui-handler"; +import { EaseType } from "#app/ui/enums/ease-type.js"; const MUTE = "Mute"; const VOLUME_OPTIONS = new Array(11).fill(null).map((_, i) => i ? (i * 10).toString() : MUTE); @@ -54,6 +55,8 @@ export const SettingKeys = { Move_Animations: "MOVE_ANIMATIONS", Show_Moveset_Flyout: "SHOW_MOVESET_FLYOUT", Show_Arena_Flyout: "SHOW_ARENA_FLYOUT", + Show_Time_Of_Day_Widget: "SHOW_TIME_OF_DAY_WIDGET", + Time_Of_Day_Animation: "TIME_OF_DAY_ANIMATION", Show_Stats_on_Level_Up: "SHOW_LEVEL_UP_STATS", EXP_Gains_Speed: "EXP_GAINS_SPEED", EXP_Party_Display: "EXP_PARTY_DISPLAY", @@ -205,6 +208,21 @@ export const Setting: Array = [ default: 1, type: SettingType.ACCESSIBILITY }, + { + key: SettingKeys.Show_Time_Of_Day_Widget, + label: "Show Time of Day Widget", + options: OFF_ON, + default: 1, + type: SettingType.ACCESSIBILITY, + requireReload: true, + }, + { + key: SettingKeys.Time_Of_Day_Animation, + label: "Time of Day Animation", + options: ["Bounce", "Back"], + default: 0, + type: SettingType.ACCESSIBILITY + }, { key: SettingKeys.Show_Stats_on_Level_Up, label: "Show Stats on Level Up", @@ -365,6 +383,12 @@ export function setSetting(scene: BattleScene, setting: string, value: integer): case SettingKeys.Show_Arena_Flyout: scene.showArenaFlyout = Setting[index].options[value] === "On"; break; + case SettingKeys.Show_Time_Of_Day_Widget: + scene.showTimeOfDayWidget = Setting[index].options[value] === "On"; + break; + case SettingKeys.Time_Of_Day_Animation: + scene.timeOfDayAnimation = Setting[index].options[value] === "Bounce" ? EaseType.BOUNCE : EaseType.BACK; + break; case SettingKeys.Show_Stats_on_Level_Up: scene.showLevelUpStats = Setting[index].options[value] === "On"; break; diff --git a/src/ui/arena-flyout.ts b/src/ui/arena-flyout.ts index 77996625fed..e854de2006b 100644 --- a/src/ui/arena-flyout.ts +++ b/src/ui/arena-flyout.ts @@ -1,4 +1,3 @@ -import * as Utils from "../utils"; import { addTextObject, TextStyle } from "./text"; import BattleScene from "#app/battle-scene.js"; import { ArenaTagSide } from "#app/data/arena-tag.js"; @@ -8,7 +7,8 @@ import { addWindow, WindowVariant } from "./ui-theme"; import { ArenaEvent, ArenaEventType, TagAddedEvent, TagRemovedEvent, TerrainChangedEvent, WeatherChangedEvent } from "#app/field/arena-events.js"; import { BattleSceneEventType, TurnEndEvent } from "#app/battle-scene-events.js"; import { ArenaTagType } from "#app/data/enums/arena-tag-type.js"; -import { TimeOfDay } from "#app/data/enums/time-of-day.js"; +import TimeOfDayWidget from "./time-of-day-widget"; +import * as Utils from "../utils"; /** Enum used to differentiate {@linkcode Arena} effects */ enum ArenaEffectType { @@ -60,8 +60,7 @@ export default class ArenaFlyout extends Phaser.GameObjects.Container { /** The {@linkcode Phaser.GameObjects.Text} that goes inside of the header */ private flyoutTextHeader: Phaser.GameObjects.Text; - /** The {@linkcode Phaser.GameObjects.Sprite} that represents the current time of day */ - private timeOfDayIcon: Phaser.GameObjects.Sprite; + private timeOfDayWidget: TimeOfDayWidget; /** The {@linkcode Phaser.GameObjects.Text} header used to indicate the player's effects */ private flyoutTextHeaderPlayer: Phaser.GameObjects.Text; @@ -82,7 +81,6 @@ export default class ArenaFlyout extends Phaser.GameObjects.Container { // Stores callbacks in a variable so they can be unsubscribed from when destroyed private readonly onNewArenaEvent = (event: Event) => this.onNewArena(event); - private readonly onTurnInitEvent = (event: Event) => this.onTurnInit(event); private readonly onTurnEndEvent = (event: Event) => this.onTurnEnd(event); private readonly onFieldEffectChangedEvent = (event: Event) => this.onFieldEffectChanged(event); @@ -117,10 +115,8 @@ export default class ArenaFlyout extends Phaser.GameObjects.Container { this.flyoutContainer.add(this.flyoutTextHeader); - this.timeOfDayIcon = this.scene.add.sprite((this.flyoutWidth / 2) + (this.flyoutWindowHeader.displayWidth / 2), 0, "dawn_icon").setOrigin(); - this.timeOfDayIcon.setVisible(false); - - this.flyoutContainer.add(this.timeOfDayIcon); + this.timeOfDayWidget = new TimeOfDayWidget(this.scene, (this.flyoutWidth / 2) + (this.flyoutWindowHeader.displayWidth / 2)); + this.flyoutContainer.add(this.timeOfDayWidget); this.flyoutTextHeaderPlayer = addTextObject(this.scene, 6, 5, "Player", TextStyle.SUMMARY_BLUE); this.flyoutTextHeaderPlayer.setFontSize(54); @@ -172,18 +168,9 @@ export default class ArenaFlyout extends Phaser.GameObjects.Container { // Subscribes to required events available on game start this.battleScene.eventTarget.addEventListener(BattleSceneEventType.NEW_ARENA, this.onNewArenaEvent); - this.battleScene.eventTarget.addEventListener(BattleSceneEventType.TURN_INIT, this.onTurnInitEvent); this.battleScene.eventTarget.addEventListener(BattleSceneEventType.TURN_END, this.onTurnEndEvent); } - private setTimeOfDayIcon() { - this.timeOfDayIcon.setTexture(TimeOfDay[this.battleScene.arena.getTimeOfDay()].toLowerCase() + "_icon"); - } - - private onTurnInit(event: Event) { - this.setTimeOfDayIcon(); - } - private onNewArena(event: Event) { this.fieldEffectInfo.length = 0; @@ -192,8 +179,6 @@ export default class ArenaFlyout extends Phaser.GameObjects.Container { this.battleScene.arena.eventTarget.addEventListener(ArenaEventType.TERRAIN_CHANGED, this.onFieldEffectChangedEvent); this.battleScene.arena.eventTarget.addEventListener(ArenaEventType.TAG_ADDED, this.onFieldEffectChangedEvent); this.battleScene.arena.eventTarget.addEventListener(ArenaEventType.TAG_REMOVED, this.onFieldEffectChangedEvent); - - this.setTimeOfDayIcon(); } /** @@ -360,17 +345,18 @@ export default class ArenaFlyout extends Phaser.GameObjects.Container { * Animates the flyout to either show or hide it by applying a fade and translation * @param visible Should the flyout be shown? */ - toggleFlyout(visible: boolean): void { + public toggleFlyout(visible: boolean): void { this.scene.tweens.add({ targets: this.flyoutParent, x: visible ? this.anchorX : this.anchorX - this.translationX, duration: Utils.fixedInt(125), ease: "Sine.easeInOut", alpha: visible ? 1 : 0, + onComplete: () => this.timeOfDayWidget.parentVisible = visible, }); } - destroy(fromScene?: boolean): void { + public destroy(fromScene?: boolean): void { this.battleScene.eventTarget.removeEventListener(BattleSceneEventType.NEW_ARENA, this.onNewArenaEvent); this.battleScene.eventTarget.removeEventListener(BattleSceneEventType.TURN_END, this.onTurnEndEvent); diff --git a/src/ui/enums/ease-type.ts b/src/ui/enums/ease-type.ts new file mode 100644 index 00000000000..fbe06fd536d --- /dev/null +++ b/src/ui/enums/ease-type.ts @@ -0,0 +1,15 @@ +export enum EaseType { + NONE, + LINEAR = "Linear", + QUADRATIC = "Quad", + CUBIC = "Cubic", + QUARTIC = "Quart", + QUINTIC = "Quint", + SINUSOIDAL = "Sine", + EXPONENTIAL = "Expo", + CIRCULAR = "Circ", + ELASTIC = "Elastic", + BACK = "Back", + BOUNCE = "Bounce", + STEPPED = "Stepped", +} diff --git a/src/ui/time-of-day-widget.ts b/src/ui/time-of-day-widget.ts new file mode 100644 index 00000000000..fd5a8b0b15e --- /dev/null +++ b/src/ui/time-of-day-widget.ts @@ -0,0 +1,172 @@ +import * as Utils from "../utils"; +import BattleScene from "#app/battle-scene.js"; +import { TimeOfDay } from "#app/data/enums/time-of-day.js"; +import { BattleSceneEventType } from "#app/battle-scene-events.js"; +import { EaseType } from "./enums/ease-type"; + +/** A small self contained UI element that displays the time of day as an icon */ +export default class TimeOfDayWidget extends Phaser.GameObjects.Container { + /** An alias for the scene typecast to a {@linkcode BattleScene} */ + private battleScene: BattleScene; + + /** The {@linkcode Phaser.GameObjects.Sprite} that represents the foreground of the current time of day */ + private readonly timeOfDayIconFgs: Phaser.GameObjects.Sprite[] = new Array(2); + /** The {@linkcode Phaser.GameObjects.Sprite} that represents the middle-ground of the current time of day */ + private readonly timeOfDayIconMgs: Phaser.GameObjects.Sprite[] = new Array(2); + /** The {@linkcode Phaser.GameObjects.Sprite} that represents the background of the current time of day */ + private readonly timeOfDayIconBgs: Phaser.GameObjects.Sprite[] = new Array(2); + + /** An array containing all timeOfDayIcon objects for easier iteration */ + private timeOfDayIcons: Phaser.GameObjects.Sprite[]; + + /** A map containing all timeOfDayIcon arrays with a matching string key for easier iteration */ + private timeOfDayIconPairs: Map = new Map([ + ["bg", this.timeOfDayIconBgs], + ["mg", this.timeOfDayIconMgs], + ["fg", this.timeOfDayIconFgs],]); + + /** The current time of day */ + private currentTime: TimeOfDay = TimeOfDay.ALL; + /** The previous time of day */ + private previousTime: TimeOfDay = TimeOfDay.ALL; + + // Subscribes to required events available on game start + private readonly onEncounterPhaseEvent = (event: Event) => this.onEncounterPhase(event); + + private _parentVisible: boolean; + /** Is the parent object visible? */ + public get parentVisible(): boolean { + return this._parentVisible; + } + /** On set, resumes any paused tweens if true */ + public set parentVisible(visible: boolean) { + if (visible && !this._parentVisible) { // Only resume the tweens if parent is newly visible + this.timeOfDayIcons?.forEach( + icon => this.scene.tweens.getTweensOf(icon).forEach( + tween => tween.resume())); + } + + this._parentVisible = visible; + } + + constructor(scene: Phaser.Scene, x: number = 0, y: number = 0) { + super(scene, x, y); + this.battleScene = this.scene as BattleScene; + + this.setVisible(this.battleScene.showTimeOfDayWidget); + if (!this.battleScene.showTimeOfDayWidget) { + return; + } + + // Initialize all sprites + this.timeOfDayIconPairs.forEach( + (icons, key) => { + for (let i = 0; i < icons.length; i++) { + icons[i] = this.scene.add.sprite(0, 0, "dawn_icon_" + key).setOrigin(); + } + }); + // Store a flat array of all icons for later + this.timeOfDayIcons = [this.timeOfDayIconBgs, this.timeOfDayIconMgs, this.timeOfDayIconFgs].flat(); + this.add(this.timeOfDayIcons); + + this.battleScene.eventTarget.addEventListener(BattleSceneEventType.ENCOUNTER_PHASE, this.onEncounterPhaseEvent); + } + + /** + * Creates a tween animation based on the 'Back' ease algorithm + * @returns an array of all tweens in the animation + */ + private getBackTween(): Phaser.Types.Tweens.TweenBuilderConfig[] { + const rotate = { + targets: [this.timeOfDayIconMgs[0], this.timeOfDayIconMgs[1]], + angle: "+=90", + duration: Utils.fixedInt(1500), + ease: "Back.easeOut", + paused: !this.parentVisible, + }; + const fade = { + targets: [this.timeOfDayIconBgs[1], this.timeOfDayIconMgs[1], this.timeOfDayIconFgs[1]], + alpha: 0, + duration: Utils.fixedInt(500), + ease: "Linear", + paused: !this.parentVisible, + }; + + return [rotate, fade]; + } + + /** + * Creates a tween animation based on the 'Bounce' ease algorithm + * @returns an array of all tweens in the animation + */ + private getBounceTween(): Phaser.Types.Tweens.TweenBuilderConfig[] { + const bounce = { + targets: [this.timeOfDayIconMgs[0], this.timeOfDayIconMgs[1]], + angle: "+=90", + duration: Utils.fixedInt(2000), + ease: "Bounce.easeOut", + paused: !this.parentVisible, + }; + const fade = { + targets: [this.timeOfDayIconBgs[1], this.timeOfDayIconMgs[1], this.timeOfDayIconFgs[1]], + alpha: 0, + duration: Utils.fixedInt(800), + ease: "Linear", + paused: !this.parentVisible, + }; + + return [bounce, fade]; + } + + /** Resets all icons to the proper depth, texture, and alpha so they are ready to tween */ + private resetIcons() { + this.moveBelow(this.timeOfDayIconBgs[0], this.timeOfDayIconBgs[1]); + this.moveBelow(this.timeOfDayIconMgs[0], this.timeOfDayIconBgs[1]); + this.moveBelow(this.timeOfDayIconFgs[0], this.timeOfDayIconFgs[1]); + + this.timeOfDayIconPairs.forEach( + (icons, key) => { + icons[0].setTexture(TimeOfDay[this.currentTime].toLowerCase() + "_icon_" + key); + icons[1].setTexture(TimeOfDay[this.previousTime].toLowerCase() + "_icon_" + key); + }); + this.timeOfDayIconMgs[0].setRotation(-90 * (3.14/180)); + + this.timeOfDayIcons.forEach(icon => icon.setAlpha(1)); + } + + /** Adds the proper tween for all icons */ + private tweenTimeOfDayIcon() { + this.scene.tweens.killTweensOf(this.timeOfDayIcons); + + this.resetIcons(); + + // Tween based on the player setting + (this.battleScene.timeOfDayAnimation === EaseType.BACK ? this.getBackTween() : this.getBounceTween()) + .forEach(tween => this.scene.tweens.add(tween)); + + // Swaps all elements of the icon arrays by shifting the first element onto the end of the array + // This ensures index[0] is always the new time of day icon and index[1] is always the current one + this.timeOfDayIconPairs.forEach( + icons => icons.push(icons.shift())); + } + + /** + * Grabs the current time of day from the arena and calls {@linkcode tweenTimeOfDayIcon} + * @param event {@linkcode Event} being sent + */ + private onEncounterPhase(event: Event) { + const newTime = this.battleScene.arena.getTimeOfDay(); + + if (this.currentTime === newTime) { + return; + } + + this.currentTime = newTime; + this.previousTime = this.currentTime - 1; + if (this.previousTime < TimeOfDay.DAWN) { + this.previousTime = TimeOfDay.NIGHT; + } + + this.tweenTimeOfDayIcon(); + } +}