diff --git a/src/battle-scene.ts b/src/battle-scene.ts index ba0720baab2..743fe467d1c 100644 --- a/src/battle-scene.ts +++ b/src/battle-scene.ts @@ -112,6 +112,7 @@ export default class BattleScene extends SceneBase { public damageNumbersMode: integer = 0; public reroll: boolean = false; public showMovesetFlyout: boolean = true; + public showTeams: boolean = true; public showArenaFlyout: boolean = true; public showTimeOfDayWidget: boolean = true; public timeOfDayAnimation: EaseType = EaseType.NONE; diff --git a/src/field/pokemon.ts b/src/field/pokemon.ts index b76717d7d44..cfae5072237 100644 --- a/src/field/pokemon.ts +++ b/src/field/pokemon.ts @@ -108,6 +108,8 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { private shinySparkle: Phaser.GameObjects.Sprite; + public usedInBattle: boolean = false; + constructor(scene: BattleScene, x: number, y: number, species: PokemonSpecies, level: integer, abilityIndex?: integer, formIndex?: integer, gender?: Gender, shiny?: boolean, variant?: Variant, ivs?: integer[], nature?: Nature, dataSource?: Pokemon | PokemonData) { super(scene, x, y); diff --git a/src/phases.ts b/src/phases.ts index df7314e6285..fc8ed5ec591 100644 --- a/src/phases.ts +++ b/src/phases.ts @@ -1873,6 +1873,9 @@ export class TurnInitPhase extends FieldPhase { if (pokemon?.isActive()) { if (pokemon.isPlayer()) { this.scene.currentBattle.addParticipant(pokemon as PlayerPokemon); + } else { + pokemon.usedInBattle = true; + pokemon.getBattleInfo().iconsActive = true } pokemon.resetTurnData(); @@ -1881,6 +1884,32 @@ export class TurnInitPhase extends FieldPhase { } }); + var Pt = this.scene.getEnemyParty() + var Pt2 = Pt.slice() + if (Pt2.length > 1) { + Pt2[1] = Pt[0] + Pt2[0] = Pt[1] + } + Pt.forEach((pokemon, i) => { + if (pokemon.hasTrainer() || true) { + console.log(i) + if (pokemon.getFieldIndex() == 1 && pokemon.isOnField()) { + // Switch this to cycle between + // - hiding the top mon's team bar + // - showing the bottom mon's team bar with its active slots reversed + if (false) { + pokemon.getBattleInfo().displayParty(Pt) + Pt[0].getBattleInfo().switchIconVisibility(false); // Make the top mon's team bar go away + Pt[0].getBattleInfo().iconsActive = false; // Prevent the top mon from re-opening its bar + } else { + pokemon.getBattleInfo().displayParty(Pt2) + } + } else { + pokemon.getBattleInfo().displayParty(Pt) + } + } + }) + this.scene.pushPhase(new TurnStartPhase(this.scene)); this.end(); diff --git a/src/system/settings/settings.ts b/src/system/settings/settings.ts index b09de095259..bf3a5359fff 100644 --- a/src/system/settings/settings.ts +++ b/src/system/settings/settings.ts @@ -98,6 +98,7 @@ export const SettingKeys = { SE_Volume: "SE_VOLUME", Music_Preference: "MUSIC_PREFERENCE", Show_BGM_Bar: "SHOW_BGM_BAR", + Show_Pokemon_Teams: "SHOW_POKEMON_TEAMS" }; /** @@ -645,6 +646,10 @@ export function setSetting(scene: BattleScene, setting: string, value: integer): case SettingKeys.Show_Moveset_Flyout: scene.showMovesetFlyout = Setting[index].options[value].value === "On"; break; + case SettingKeys.Show_Pokemon_Teams: + // Currently not used + scene.showTeams = Setting[index].options[value].value === "On"; + break; case SettingKeys.Show_Arena_Flyout: scene.showArenaFlyout = Setting[index].options[value].value === "On"; break; diff --git a/src/ui/battle-info.ts b/src/ui/battle-info.ts index 3b889228e27..652718342bb 100644 --- a/src/ui/battle-info.ts +++ b/src/ui/battle-info.ts @@ -70,6 +70,15 @@ export default class BattleInfo extends Phaser.GameObjects.Container { public flyoutMenu?: BattleFlyout; + private teamIcons: Phaser.GameObjects.Sprite[]; + private teamIconOver: Phaser.GameObjects.Sprite[]; + private teamIconsShow: boolean[]; + public iconsActive: boolean = false; + private teamCount: integer = 0; + private showingTeam: boolean = false; + private pressedShow: boolean = false; + private override: boolean = false; + constructor(scene: Phaser.Scene, x: number, y: number, player: boolean) { super(scene, x, y); this.baseY = y; @@ -114,6 +123,27 @@ export default class BattleInfo extends Phaser.GameObjects.Container { this.ownedIcon.setPositionRelative(this.nameText, 0, 11.75); this.add(this.ownedIcon); + this.teamIcons = new Array(6); + this.teamIconOver = new Array(6); + this.teamIconsShow = new Array(6).fill(false); + + for (var ballindex = 0; ballindex < 6; ballindex++) { + this.teamIcons[ballindex] = this.scene.add.sprite(0, 0, "pb_tray_ball", "empty") + this.teamIcons[ballindex].setName("pb_teamball_" + ballindex); + this.teamIcons[ballindex].setVisible(true); + this.teamIcons[ballindex].setAlpha(0); + this.teamIcons[ballindex].setOrigin(0, 0); + this.teamIcons[ballindex].setPositionRelative(this.nameText, 6 * ballindex, 11.75); + this.add(this.teamIcons[ballindex]); + this.teamIconOver[ballindex] = this.scene.add.sprite(0, 0, "pb_tray_ball", "empty") + this.teamIconOver[ballindex].setName("pb_teamball_" + ballindex); + this.teamIconOver[ballindex].setVisible(true); + this.teamIconOver[ballindex].setAlpha(0); + this.teamIconOver[ballindex].setOrigin(0, 0); + this.teamIconOver[ballindex].setPositionRelative(this.nameText, 6 * ballindex, 11.75); + this.add(this.teamIconOver[ballindex]); + } + this.championRibbon = this.scene.add.sprite(0, 0, "champion_ribbon"); this.championRibbon.setName("icon_champion_ribbon"); this.championRibbon.setVisible(false); @@ -484,6 +514,116 @@ export default class BattleInfo extends Phaser.GameObjects.Container { } } + displayParty(overwriteparty?: Pokemon[], useparty?: EnemyPokemon[]): void { + // Floor 8: 2 pokemon + // Floor 25: 3 + // Floor 55: 4 + // Floor 95: 5 + // Floor 145: 6 + // Floor 195: 6 + var party = (this.scene as BattleScene).getEnemyParty() + if (useparty != undefined) { + console.debug("Using specified enemy party"); + //party = useparty; + } else if (overwriteparty != undefined) { + console.debug("Using specified party"); + } + var P; + if (useparty != undefined) { + //console.debug("Using specified enemy party"); + P = useparty; + } else if (overwriteparty != undefined) { + //console.debug("Using specified party"); + P = overwriteparty + } else { + P = party + } + var staticparty = (this.scene as BattleScene).getEnemyParty() + var states = new Array(6) + for (var i = 0; i < 6; i++) { + states[i] = "empty"; + } + var total_visible = 0 + for (var i = 0; i < P.length; i++) { + states[i] = "ball" + if (!party[i].hp) { + states[i] = "faint" + } else if (party[i].status) { + states[i] = "ball" + } + if (P[i].isOnField()) { + //console.log(P[i].name + " is in battle; set it as seen") + P[i].usedInBattle = true + } + if (P[i].usedInBattle) total_visible++; + //console.log(P[i].name, P[i].getIconAtlasKey(true)) + } + console.log("Updating ball icons for party (" + P.length + ")") + if (staticparty.length > 0) { + for (var i = 0; i < staticparty.length; i++) { + //console.log(i, staticparty[i].name) + } + } + var Spacing = P.length == 6 ? 6 : 8 + this.teamCount = P.length + for (var ballindex = 0; ballindex < 6; ballindex++) { + //console.log(ballindex + ": setting icon " + states[ballindex]) + if (states[ballindex] == "ball" && P[ballindex].usedInBattle) { + this.teamIcons[ballindex].setTexture(P[ballindex].getIconAtlasKey(true)) + this.teamIcons[ballindex].setFrame(P[ballindex].getIconId(true)) + this.teamIcons[ballindex].setPositionRelative(this.nameText, Spacing * ballindex - 3, 11.75 - 4); + this.teamIcons[ballindex].setDisplaySize(18 * 0.8, 15 * 0.8) + this.teamIconOver[ballindex].setTexture(P[ballindex].getIconAtlasKey(true)) + this.teamIconOver[ballindex].setFrame(P[ballindex].getIconId(true)) + this.teamIconOver[ballindex].setPositionRelative(this.nameText, Spacing * ballindex - 3, 11.75 - 4); + this.teamIconOver[ballindex].setDisplaySize(18 * 0.8, 15 * 0.8) + this.teamIconOver[ballindex].setVisible(true) + this.teamIconsShow[ballindex] = true + if (P[ballindex].status && P[ballindex].hp) { + switch (P[ballindex].status.effect) { + case StatusEffect.NONE: + // Uncallable; replaced by "ball" + break; + case StatusEffect.POISON: + this.teamIconOver[ballindex].setTintFill(0xe40dfc) + break; + case StatusEffect.TOXIC: + this.teamIconOver[ballindex].setTintFill(0xfa2590) + break; + case StatusEffect.PARALYSIS: + this.teamIconOver[ballindex].setTintFill(0xf7ec1e) + break; + case StatusEffect.SLEEP: + this.teamIconOver[ballindex].setTintFill(0x54bfaa) + break; + case StatusEffect.FREEZE: + this.teamIconOver[ballindex].setTintFill(0xcbf0f2) + break; + case StatusEffect.BURN: + this.teamIconOver[ballindex].setTintFill(0xf51905) + break; + case StatusEffect.FAINT: + // Uncallable; replaced by "faint" + break; + } + } else { + this.teamIconOver[ballindex].clearTint() + this.teamIconOver[ballindex].setVisible(false) + this.teamIconsShow[ballindex] = false + } + } else { + this.teamIcons[ballindex].setTexture("pb_tray_ball") + this.teamIcons[ballindex].setFrame(states[ballindex]) + this.teamIcons[ballindex].setPositionRelative(this.nameText, Spacing * ballindex, 11.75); + this.teamIcons[ballindex].setDisplaySize(7, 7) + this.teamIcons[ballindex].setVisible(states[ballindex] != 'empty') + this.teamIconOver[ballindex].clearTint() + this.teamIconOver[ballindex].setVisible(false) + this.teamIconsShow[ballindex] = false + } + } + } + setOffset(offset: boolean): void { if (this.offset === offset) { return; @@ -532,11 +672,15 @@ export default class BattleInfo extends Phaser.GameObjects.Container { if (this.lastStatus !== StatusEffect.NONE) { this.statusIndicator.setFrame(StatusEffect[this.lastStatus].toLowerCase()); + } else if (this.player) { + this.statusIndicator.setVisible(!!this.lastStatus); + } else { + this.statusIndicator.setVisible(!!this.lastStatus); + this.switchIconVisibility(this.showingTeam, true) } - this.statusIndicator.setVisible(!!this.lastStatus); if (!this.player && this.ownedIcon.visible) { - this.ownedIcon.setAlpha(this.statusIndicator.visible ? 0 : 1); + this.switchIconVisibility(this.showingTeam, true) } } @@ -746,6 +890,59 @@ export default class BattleInfo extends Phaser.GameObjects.Container { } } + /** + * Overrides the state of the team display. + * + * The state can't be switched by the player until the override is removed, but you can call this again to change the override state. + */ + addTeamDisplayOverride(visible: boolean): void { + this.override = true; + this.switchIconVisibility(visible); + } + /** + * Removes any override on the team display. + * + * The team display will then show/hide as required. + */ + removeTeamDisplayOverride(): void { + this.override = false; + this.switchIconVisibility(this.pressedShow); + } + + /** Show or hide team display. */ + switchIconVisibility(visible: boolean = this.showingTeam, override?: boolean): void { + if (!this.iconsActive) visible = false + if (this.showingTeam == visible && !override) return; // Don't spam requests + this.showingTeam = visible + this.scene.tweens.add({ + targets: this.teamIcons, + duration: Utils.fixedInt(125), + ease: "Sine.easeInOut", + alpha: visible ? 1 : 0 + }); + this.scene.tweens.add({ + targets: this.teamIconOver, + duration: Utils.fixedInt(125), + ease: "Sine.easeInOut", + alphaTopLeft: visible ? 0.4 : 0, + alphaTopRight: visible ? 0.4 : 0, + alphaBottomLeft: visible ? 0.7 : 0, + alphaBottomRight: visible ? 0.7 : 0, + }); + this.scene.tweens.add({ + targets: [ this.championRibbon, this.ownedIcon ], + duration: Utils.fixedInt(125), + ease: "Sine.easeInOut", + alpha: visible && this.iconsActive ? 0 : this.statusIndicator.visible ? 0 : 1 + }); + this.scene.tweens.add({ + targets: this.statusIndicator, + duration: Utils.fixedInt(125), + ease: "Sine.easeInOut", + alpha: visible && this.iconsActive ? 0 : (!!this.lastStatus ? 1 : 0) + }); + } + /** * Show or hide the type effectiveness multiplier window * Passing undefined will hide the window