diff --git a/public/images/ui/legacy/shiny_1.png b/public/images/ui/legacy/shiny_1.png new file mode 100644 index 00000000000..9c7a583a7f9 Binary files /dev/null and b/public/images/ui/legacy/shiny_1.png differ diff --git a/public/images/ui/legacy/shiny_2.png b/public/images/ui/legacy/shiny_2.png new file mode 100644 index 00000000000..c00438ab0f6 Binary files /dev/null and b/public/images/ui/legacy/shiny_2.png differ diff --git a/public/images/ui/legacy/shiny_small_1.png b/public/images/ui/legacy/shiny_small_1.png new file mode 100644 index 00000000000..92f5c37c13a Binary files /dev/null and b/public/images/ui/legacy/shiny_small_1.png differ diff --git a/public/images/ui/legacy/shiny_small_2.png b/public/images/ui/legacy/shiny_small_2.png new file mode 100644 index 00000000000..f9dba355eeb Binary files /dev/null and b/public/images/ui/legacy/shiny_small_2.png differ diff --git a/public/images/ui/shiny_1.png b/public/images/ui/shiny_1.png new file mode 100644 index 00000000000..9c7a583a7f9 Binary files /dev/null and b/public/images/ui/shiny_1.png differ diff --git a/public/images/ui/shiny_2.png b/public/images/ui/shiny_2.png new file mode 100644 index 00000000000..c00438ab0f6 Binary files /dev/null and b/public/images/ui/shiny_2.png differ diff --git a/public/images/ui/shiny_small_1.png b/public/images/ui/shiny_small_1.png new file mode 100644 index 00000000000..92f5c37c13a Binary files /dev/null and b/public/images/ui/shiny_small_1.png differ diff --git a/public/images/ui/shiny_small_2.png b/public/images/ui/shiny_small_2.png new file mode 100644 index 00000000000..f9dba355eeb Binary files /dev/null and b/public/images/ui/shiny_small_2.png differ diff --git a/src/battle-scene.ts b/src/battle-scene.ts index 4ea2503ec55..fdcb9cc1374 100644 --- a/src/battle-scene.ts +++ b/src/battle-scene.ts @@ -13,11 +13,11 @@ import { Biome } from "./data/enums/biome"; import { Arena, ArenaBase } from './field/arena'; import { GameData, PlayerGender } from './system/game-data'; import StarterSelectUiHandler from './ui/starter-select-ui-handler'; -import { TextStyle, addTextObject } from './ui/text'; +import { TextStyle, addBBCodeTextObject, addTextObject } from './ui/text'; import { Moves } from "./data/enums/moves"; import { allMoves } from "./data/move"; import { initMoves } from './data/move'; -import { ModifierPoolType, getDefaultModifierTypeForTier, getEnemyModifierTypesForWave, getModifierPoolForType } from './modifier/modifier-type'; +import { ModifierPoolType, getDefaultModifierTypeForTier, getEnemyModifierTypesForWave, getLuckString, getLuckTextTint, getModifierPoolForType, getPartyLuckValue } from './modifier/modifier-type'; import AbilityBar from './ui/ability-bar'; import { BlockItemTheftAbAttr, DoubleBattleChanceAbAttr, IncrementMovePriorityAbAttr, applyAbAttrs, initAbilities } from './data/ability'; import { Abilities } from "./data/enums/abilities"; @@ -176,6 +176,8 @@ export default class BattleScene extends SceneBase { private waveCountText: Phaser.GameObjects.Text; private moneyText: Phaser.GameObjects.Text; private scoreText: Phaser.GameObjects.Text; + private luckLabelText: Phaser.GameObjects.Text; + private luckText: Phaser.GameObjects.Text; private modifierBar: ModifierBar; private enemyModifierBar: ModifierBar; private fieldOverlay: Phaser.GameObjects.Rectangle; @@ -401,6 +403,16 @@ export default class BattleScene extends SceneBase { this.scoreText.setOrigin(1, 0); this.fieldUI.add(this.scoreText); + this.luckText = addTextObject(this, (this.game.canvas.width / 6) - 2, 0, '', TextStyle.PARTY, { fontSize: '54px' }); + this.luckText.setOrigin(1, 0); + this.luckText.setVisible(false); + this.fieldUI.add(this.luckText); + + this.luckLabelText = addTextObject(this, (this.game.canvas.width / 6) - 2, 0, 'Luck:', TextStyle.PARTY, { fontSize: '54px' }); + this.luckLabelText.setOrigin(1, 0); + this.luckLabelText.setVisible(false); + this.fieldUI.add(this.luckLabelText); + this.updateUIPositions(); this.damageNumberHandler = new DamageNumberHandler(); @@ -806,6 +818,8 @@ export default class BattleScene extends SceneBase { this.updateScoreText(); this.scoreText.setVisible(false); + [ this.luckLabelText, this.luckText ].map(t => t.setVisible(false)); + this.newArena(STARTING_BIOME_OVERRIDE || Biome.TOWN); this.arenaBgTransition.setPosition(0, 0); @@ -1220,11 +1234,44 @@ export default class BattleScene extends SceneBase { this.scoreText.setVisible(this.gameMode.isDaily); } + updateAndShowLuckText(duration: integer): void { + const labels = [ this.luckLabelText, this.luckText ]; + labels.map(t => { + t.setAlpha(0); + t.setVisible(true); + }) + const luckValue = getPartyLuckValue(this.getParty()); + this.luckText.setText(getLuckString(luckValue)); + if (luckValue < 16) + this.luckText.setTint(getLuckTextTint(luckValue)); + else + this.luckText.setTint(0x83a55a, 0xee384a, 0x5271cd, 0x7b487b); + this.luckLabelText.setX((this.game.canvas.width / 6) - 2 - (this.luckText.displayWidth + 2)); + this.tweens.add({ + targets: labels, + duration: duration, + alpha: 1 + }); + } + + hideLuckText(duration: integer): void { + const labels = [ this.luckLabelText, this.luckText ]; + this.tweens.add({ + targets: labels, + duration: duration, + alpha: 0, + onComplete: () => { + labels.map(l => l.setVisible(false)); + } + }); + } + updateUIPositions(): void { const enemyModifierCount = this.enemyModifiers.filter(m => m.isIconVisible(this)).length; this.waveCountText.setY(-(this.game.canvas.height / 6) + (enemyModifierCount ? enemyModifierCount <= 12 ? 15 : 24 : 0)); this.moneyText.setY(this.waveCountText.y + 10); this.scoreText.setY(this.moneyText.y + 10); + [ this.luckLabelText, this.luckText ].map(l => l.setY((this.scoreText.visible ? this.scoreText : this.moneyText).y + 10)); const offsetY = (this.scoreText.visible ? this.scoreText : this.moneyText).y + 15; this.partyExpBar.setY(offsetY); this.candyBar.setY(offsetY + 15); diff --git a/src/field/pokemon.ts b/src/field/pokemon.ts index cb2c3bccc7b..af97a4e65db 100644 --- a/src/field/pokemon.ts +++ b/src/field/pokemon.ts @@ -4,7 +4,7 @@ import { Variant, VariantSet, variantColorCache } from '#app/data/variant'; import { variantData } from '#app/data/variant'; import BattleInfo, { PlayerBattleInfo, EnemyBattleInfo } from '../ui/battle-info'; import { Moves } from "../data/enums/moves"; -import Move, { HighCritAttr, HitsTagAttr, applyMoveAttrs, FixedDamageAttr, VariableAtkAttr, VariablePowerAttr, allMoves, MoveCategory, TypelessAttr, CritOnlyAttr, getMoveTargets, OneHitKOAttr, MultiHitAttr, StatusMoveTypeImmunityAttr, MoveTarget, VariableDefAttr, AttackMove, ModifiedDamageAttr, VariableMoveTypeMultiplierAttr, IgnoreOpponentStatChangesAttr, SacrificialAttr, VariableMoveTypeAttr, VariableMoveCategoryAttr, ExplosiveAttr } from "../data/move"; +import Move, { HighCritAttr, HitsTagAttr, applyMoveAttrs, FixedDamageAttr, VariableAtkAttr, VariablePowerAttr, allMoves, MoveCategory, TypelessAttr, CritOnlyAttr, getMoveTargets, OneHitKOAttr, MultiHitAttr, StatusMoveTypeImmunityAttr, MoveTarget, VariableDefAttr, AttackMove, ModifiedDamageAttr, VariableMoveTypeMultiplierAttr, IgnoreOpponentStatChangesAttr, SacrificialAttr, VariableMoveTypeAttr, VariableMoveCategoryAttr } from "../data/move"; import { default as PokemonSpecies, PokemonSpeciesForm, SpeciesFormKey, getFusedSpeciesName, getPokemonSpecies, getPokemonSpeciesForm, starterPassiveAbilities } from '../data/pokemon-species'; import * as Utils from '../utils'; import { Type, TypeDamageMultiplier, getTypeDamageMultiplier, getTypeRgb } from '../data/type'; diff --git a/src/loading-scene.ts b/src/loading-scene.ts index 38f82ff060e..2f37b900ab5 100644 --- a/src/loading-scene.ts +++ b/src/loading-scene.ts @@ -62,7 +62,11 @@ export class LoadingScene extends SceneBase { this.loadImage('achv_bar_3', 'ui'); this.loadImage('achv_bar_4', 'ui'); this.loadImage('shiny_star', 'ui', 'shiny.png'); + this.loadImage('shiny_star_1', 'ui', 'shiny_1.png'); + this.loadImage('shiny_star_2', 'ui', 'shiny_2.png'); this.loadImage('shiny_star_small', 'ui', 'shiny_small.png'); + this.loadImage('shiny_star_small_1', 'ui', 'shiny_small_1.png'); + this.loadImage('shiny_star_small_2', 'ui', 'shiny_small_2.png'); this.loadImage('ha_capsule', 'ui', 'ha_capsule.png'); this.loadImage('icon_spliced', 'ui'); this.loadImage('icon_tera', 'ui'); diff --git a/src/locales/fr/ability.ts b/src/locales/fr/ability.ts index c23ea295a26..a0c7f2d1b5d 100644 --- a/src/locales/fr/ability.ts +++ b/src/locales/fr/ability.ts @@ -1061,11 +1061,11 @@ export const ability: AbilityTranslationEntries = { name: "Sombre Ruade", description: "Quand le Pokémon met un ennemi K.O., il émet un hennissement terrifiant qui augmente son Attaque Spéciale.", }, - asOne: { + asOneGlastrier: { name: "Osmose Équine", description: "Les talents Tension de Sylveroy et Blanche Ruade de Blizzeval sont cumulés.", }, - asOne: { + asOneSpectrier: { name: "Osmose Équine", description: "Les talents Tension de Sylveroy et Sombre Ruade de Spectreval sont cumulés.", }, diff --git a/src/modifier/modifier-type.ts b/src/modifier/modifier-type.ts index 76ab3bd5f78..19826a07aff 100644 --- a/src/modifier/modifier-type.ts +++ b/src/modifier/modifier-type.ts @@ -20,6 +20,7 @@ import { FormChangeItem, SpeciesFormChangeItemTrigger, pokemonFormChanges } from import { ModifierTier } from './modifier-tier'; import { Nature, getNatureName, getNatureStatMultiplier } from '#app/data/nature'; import { Localizable } from '#app/plugins/i18n'; +import { getModifierTierTextTint } from '#app/ui/text'; const outputModifierData = false; const useMaxWeightForOutput = false; @@ -1428,11 +1429,11 @@ function getNewModifierTypeOption(party: Pokemon[], poolType: ModifierPoolType, if (!upgradeCount) upgradeCount = 0; if (player && tierValue) { - const partyShinyCount = party.filter(p => p.isShiny() && !p.isFainted()).length; - const upgradeOdds = Math.floor(32 / ((partyShinyCount + 2) / 2)); + const partyLuckValue = getPartyLuckValue(party); + const upgradeOdds = Math.floor(128 / ((partyLuckValue + 4) / 4)); let upgraded = false; do { - upgraded = !Utils.randSeedInt(upgradeOdds); + upgraded = Utils.randSeedInt(upgradeOdds) < 4; if (upgraded) upgradeCount++; } while (upgraded); @@ -1515,3 +1516,17 @@ export class ModifierTypeOption { this.cost = Math.round(cost); } } + +export function getPartyLuckValue(party: Pokemon[]): integer { + return Phaser.Math.Clamp(party.map(p => p.isFainted() || !p.isShiny() ? 0 : !p.isFusion() || !p.shiny || !p.fusionShiny ? p.variant + 1 : (p.variant + 1) + (p.fusionVariant + 1)) + .reduce((total: integer, value: integer) => total += value, 0), 0, 16); +} + +export function getLuckString(luckValue: integer): string { + return [ 'D', 'C', 'C+', 'B-', 'B', 'B+', 'A-', 'A', 'A+', 'A++', 'S', 'S+', 'S++', 'SS', 'SS+', 'SS++', 'SSS' ][luckValue]; +} + +export function getLuckTextTint(luckValue: integer): integer { + const modifierTier = luckValue ? luckValue > 2 ? luckValue > 5 ? luckValue > 9 ? luckValue > 12 ? ModifierTier.LUXURY : ModifierTier.MASTER : ModifierTier.ROGUE : ModifierTier.ULTRA : ModifierTier.GREAT : ModifierTier.COMMON; + return getModifierTierTextTint(modifierTier); +} \ No newline at end of file diff --git a/src/ui/battle-info.ts b/src/ui/battle-info.ts index c26214b5940..ae794a256fa 100644 --- a/src/ui/battle-info.ts +++ b/src/ui/battle-info.ts @@ -31,6 +31,7 @@ export default class BattleInfo extends Phaser.GameObjects.Container { private ownedIcon: Phaser.GameObjects.Sprite; private teraIcon: Phaser.GameObjects.Sprite; private shinyIcon: Phaser.GameObjects.Sprite; + private fusionShinyIcon: Phaser.GameObjects.Sprite; private splicedIcon: Phaser.GameObjects.Sprite; private statusIndicator: Phaser.GameObjects.Sprite; private levelContainer: Phaser.GameObjects.Container; @@ -101,6 +102,13 @@ export default class BattleInfo extends Phaser.GameObjects.Container { this.shinyIcon.setInteractive(new Phaser.Geom.Rectangle(0, 0, 12, 15), Phaser.Geom.Rectangle.Contains); this.add(this.shinyIcon); + this.fusionShinyIcon = this.scene.add.sprite(0, 0, 'shiny_star_2'); + this.fusionShinyIcon.setVisible(false); + this.fusionShinyIcon.setOrigin(0, 0); + this.fusionShinyIcon.setScale(0.5) + this.fusionShinyIcon.setPosition(this.shinyIcon.x, this.shinyIcon.y); + this.add(this.fusionShinyIcon); + this.splicedIcon = this.scene.add.sprite(0, 0, 'icon_spliced'); this.splicedIcon.setVisible(false); this.splicedIcon.setOrigin(0, 0); @@ -183,21 +191,35 @@ export default class BattleInfo extends Phaser.GameObjects.Container { }); this.teraIcon.on('pointerout', () => (this.scene as BattleScene).ui.hideTooltip()); + const isFusion = pokemon.isFusion(); + this.splicedIcon.setPositionRelative(this.nameText, nameTextWidth + this.genderText.displayWidth + 1 + (this.teraIcon.visible ? this.teraIcon.displayWidth + 1 : 0), 2.5); - this.splicedIcon.setVisible(!!pokemon.fusionSpecies); + this.splicedIcon.setVisible(isFusion); if (this.splicedIcon.visible) { this.splicedIcon.on('pointerover', () => (this.scene as BattleScene).ui.showTooltip(null, `${pokemon.species.getName(pokemon.formIndex)}/${pokemon.fusionSpecies.getName(pokemon.fusionFormIndex)}`)); this.splicedIcon.on('pointerout', () => (this.scene as BattleScene).ui.hideTooltip()); } + const doubleShiny = isFusion && pokemon.shiny && pokemon.fusionShiny; + const baseVariant = !doubleShiny ? pokemon.getVariant() : pokemon.variant; + this.shinyIcon.setPositionRelative(this.nameText, nameTextWidth + this.genderText.displayWidth + 1 + (this.teraIcon.visible ? this.teraIcon.displayWidth + 1 : 0) + (this.splicedIcon.visible ? this.splicedIcon.displayWidth + 1 : 0), 2.5); - this.shinyIcon.setVisible(!!pokemon.isShiny()); - this.shinyIcon.setTint(getVariantTint(pokemon.getVariant())); + this.shinyIcon.setTexture(`shiny_star${doubleShiny ? '_1' : ''}`); + this.shinyIcon.setVisible(pokemon.isShiny()); + this.shinyIcon.setTint(getVariantTint(baseVariant)); if (this.shinyIcon.visible) { - this.shinyIcon.on('pointerover', () => (this.scene as BattleScene).ui.showTooltip(null, `Shiny${pokemon.getVariant() ? ` (${pokemon.getVariant() === 2 ? 'Epic' : 'Rare'})` : ''}`)); + const shinyDescriptor = doubleShiny || baseVariant ? + `${baseVariant === 2 ? 'Epic' : baseVariant === 1 ? 'Rare' : 'Common'}${doubleShiny ? `/${pokemon.fusionVariant === 2 ? 'Epic' : pokemon.fusionVariant === 1 ? 'Rare' : 'Common'}` : ''}` + : ''; + this.shinyIcon.on('pointerover', () => (this.scene as BattleScene).ui.showTooltip(null, `Shiny${shinyDescriptor ? ` (${shinyDescriptor})` : ''}`)); this.shinyIcon.on('pointerout', () => (this.scene as BattleScene).ui.hideTooltip()); } + this.fusionShinyIcon.setPosition(this.shinyIcon.x, this.shinyIcon.y); + this.fusionShinyIcon.setVisible(doubleShiny); + if (isFusion) + this.fusionShinyIcon.setTint(getVariantTint(pokemon.fusionVariant)); + if (!this.player) { const dexEntry = pokemon.scene.gameData.dexData[pokemon.species.speciesId]; this.ownedIcon.setVisible(!!dexEntry.caughtAttr); diff --git a/src/ui/modifier-select-ui-handler.ts b/src/ui/modifier-select-ui-handler.ts index 1bd44bfd3c4..e5252e02a8f 100644 --- a/src/ui/modifier-select-ui-handler.ts +++ b/src/ui/modifier-select-ui-handler.ts @@ -138,6 +138,7 @@ export default class ModifierSelectUiHandler extends AwaitableUiHandler { const maxUpgradeCount = typeOptions.map(to => to.upgradeCount).reduce((max, current) => Math.max(current, max), 0); this.scene.showFieldOverlay(750); + this.scene.updateAndShowLuckText(750); let i = 0; @@ -363,6 +364,7 @@ export default class ModifierSelectUiHandler extends AwaitableUiHandler { this.eraseCursor(); this.scene.hideFieldOverlay(250); + this.scene.hideLuckText(750); const options = this.options.concat(this.shopOptionsRows.flat()); this.options.splice(0, this.options.length); diff --git a/src/ui/party-ui-handler.ts b/src/ui/party-ui-handler.ts index 919b9606700..30558b5bda0 100644 --- a/src/ui/party-ui-handler.ts +++ b/src/ui/party-ui-handler.ts @@ -900,12 +900,23 @@ class PartySlot extends Phaser.GameObjects.Container { } if (this.pokemon.isShiny()) { - const shinyStar = this.scene.add.image(0, 0, 'shiny_star_small'); + const doubleShiny = this.pokemon.isFusion() && this.pokemon.shiny && this.pokemon.fusionShiny; + + const shinyStar = this.scene.add.image(0, 0, `shiny_star_small${doubleShiny ? '_1' : ''}`); shinyStar.setOrigin(0, 0); shinyStar.setPositionRelative(slotName, -9, 3); - shinyStar.setTint(getVariantTint(this.pokemon.getVariant())); + shinyStar.setTint(getVariantTint(!doubleShiny ? this.pokemon.getVariant() : this.pokemon.variant)); slotInfoContainer.add(shinyStar); + + if (doubleShiny) { + const fusionShinyStar = this.scene.add.image(0, 0, `shiny_star_small_2`); + fusionShinyStar.setOrigin(0, 0); + fusionShinyStar.setPosition(shinyStar.x, shinyStar.y); + fusionShinyStar.setTint(getVariantTint(this.pokemon.fusionVariant)); + + slotInfoContainer.add(fusionShinyStar); + } } if (partyUiMode !== PartyUiMode.TM_MODIFIER) { diff --git a/src/ui/pokemon-info-container.ts b/src/ui/pokemon-info-container.ts index 2b2dcb07e34..4d8ecfe0b03 100644 --- a/src/ui/pokemon-info-container.ts +++ b/src/ui/pokemon-info-container.ts @@ -18,6 +18,7 @@ export default class PokemonInfoContainer extends Phaser.GameObjects.Container { private pokemonNatureLabelText: Phaser.GameObjects.Text; private pokemonNatureText: BBCodeText; private pokemonShinyIcon: Phaser.GameObjects.Image; + private pokemonFusionShinyIcon: Phaser.GameObjects.Image; private pokemonMovesContainer: Phaser.GameObjects.Container; private pokemonMovesContainers: Phaser.GameObjects.Container[]; private pokemonMoveBgs: Phaser.GameObjects.NineSlice[]; @@ -114,6 +115,11 @@ export default class PokemonInfoContainer extends Phaser.GameObjects.Container { this.pokemonShinyIcon.setInteractive(new Phaser.Geom.Rectangle(0, 0, 12, 15), Phaser.Geom.Rectangle.Contains); this.add(this.pokemonShinyIcon); + this.pokemonFusionShinyIcon = this.scene.add.image(this.pokemonShinyIcon.x, this.pokemonShinyIcon.y, 'shiny_star_2'); + this.pokemonFusionShinyIcon.setOrigin(0, 0); + this.pokemonFusionShinyIcon.setScale(0.75); + this.add(this.pokemonFusionShinyIcon); + this.setVisible(false); } @@ -135,12 +141,25 @@ export default class PokemonInfoContainer extends Phaser.GameObjects.Container { this.pokemonNatureText.setText(getNatureName(pokemon.getNature(), true, false, false, this.scene.uiTheme)); - this.pokemonShinyIcon.setTint(getVariantTint(pokemon.getVariant())); + const isFusion = pokemon.isFusion(); + const doubleShiny = isFusion && pokemon.shiny && pokemon.fusionShiny; + const baseVariant = !doubleShiny ? pokemon.getVariant() : pokemon.variant; + + this.pokemonShinyIcon.setTexture(`shiny_star${doubleShiny ? '_1' : ''}`); this.pokemonShinyIcon.setVisible(pokemon.isShiny()); + this.pokemonShinyIcon.setTint(getVariantTint(baseVariant)); if (this.pokemonShinyIcon.visible) { - this.pokemonShinyIcon.on('pointerover', () => (this.scene as BattleScene).ui.showTooltip(null, `Shiny${pokemon.getVariant() ? ` (${pokemon.getVariant() === 2 ? 'Epic' : 'Rare'})` : ''}`, true)); + const shinyDescriptor = doubleShiny || baseVariant ? + `${baseVariant === 2 ? 'Epic' : baseVariant === 1 ? 'Rare' : 'Common'}${doubleShiny ? `/${pokemon.fusionVariant === 2 ? 'Epic' : pokemon.fusionVariant === 1 ? 'Rare' : 'Common'}` : ''}` + : ''; + this.pokemonShinyIcon.on('pointerover', () => (this.scene as BattleScene).ui.showTooltip(null, `Shiny${shinyDescriptor ? ` (${shinyDescriptor})` : ''}`, true)); this.pokemonShinyIcon.on('pointerout', () => (this.scene as BattleScene).ui.hideTooltip()); } + + this.pokemonFusionShinyIcon.setPosition(this.pokemonShinyIcon.x, this.pokemonShinyIcon.y); + this.pokemonFusionShinyIcon.setVisible(doubleShiny); + if (isFusion) + this.pokemonFusionShinyIcon.setTint(getVariantTint(pokemon.fusionVariant)); const originalIvs: integer[] = this.scene.gameData.dexData[pokemon.species.speciesId].caughtAttr ? this.scene.gameData.dexData[pokemon.species.speciesId].ivs diff --git a/src/ui/summary-ui-handler.ts b/src/ui/summary-ui-handler.ts index 35a469317c1..e6f3d2233e5 100644 --- a/src/ui/summary-ui-handler.ts +++ b/src/ui/summary-ui-handler.ts @@ -43,6 +43,7 @@ export default class SummaryUiHandler extends UiHandler { private levelText: Phaser.GameObjects.Text; private genderText: Phaser.GameObjects.Text; private shinyIcon: Phaser.GameObjects.Image; + private fusionShinyIcon: Phaser.GameObjects.Image; private statusContainer: Phaser.GameObjects.Container; private status: Phaser.GameObjects.Image; private summaryPageContainer: Phaser.GameObjects.Container; @@ -125,6 +126,12 @@ export default class SummaryUiHandler extends UiHandler { this.shinyIcon.setInteractive(new Phaser.Geom.Rectangle(0, 0, 12, 15), Phaser.Geom.Rectangle.Contains); this.summaryContainer.add(this.shinyIcon); + this.fusionShinyIcon = this.scene.add.image(0, 0, 'shiny_star_2'); + this.fusionShinyIcon.setVisible(false); + this.fusionShinyIcon.setOrigin(0, 0); + this.fusionShinyIcon.setScale(0.75) + this.summaryContainer.add(this.fusionShinyIcon); + this.pokeball = this.scene.add.sprite(6, -19, 'pb'); this.pokeball.setOrigin(0, 1); this.summaryContainer.add(this.pokeball); @@ -137,8 +144,6 @@ export default class SummaryUiHandler extends UiHandler { this.genderText.setOrigin(0, 1); this.summaryContainer.add(this.genderText); - - this.statusContainer = this.scene.add.container(-106, -16); const statusBg = this.scene.add.image(0, 0, 'summary_status'); @@ -237,21 +242,35 @@ export default class SummaryUiHandler extends UiHandler { this.nameText.setText(this.pokemon.name); + const isFusion = this.pokemon.isFusion(); + this.splicedIcon.setPositionRelative(this.nameText, this.nameText.displayWidth + 2, 3); - this.splicedIcon.setVisible(!!this.pokemon.fusionSpecies); + this.splicedIcon.setVisible(isFusion); if (this.splicedIcon.visible) { this.splicedIcon.on('pointerover', () => (this.scene as BattleScene).ui.showTooltip(null, `${this.pokemon.species.getName(this.pokemon.formIndex)}/${this.pokemon.fusionSpecies.getName(this.pokemon.fusionFormIndex)}`, true)); this.splicedIcon.on('pointerout', () => (this.scene as BattleScene).ui.hideTooltip()); } + + const doubleShiny = isFusion && this.pokemon.shiny && this.pokemon.fusionShiny; + const baseVariant = !doubleShiny ? this.pokemon.getVariant() : this.pokemon.variant; this.shinyIcon.setPositionRelative(this.nameText, this.nameText.displayWidth + (this.splicedIcon.visible ? this.splicedIcon.displayWidth + 1 : 0) + 1, 3); - this.shinyIcon.setTint(getVariantTint(this.pokemon.getVariant())); + this.shinyIcon.setTexture(`shiny_star${doubleShiny ? '_1' : ''}`); this.shinyIcon.setVisible(this.pokemon.isShiny()); + this.shinyIcon.setTint(getVariantTint(baseVariant)); if (this.shinyIcon.visible) { - this.shinyIcon.on('pointerover', () => (this.scene as BattleScene).ui.showTooltip(null, `Shiny${this.pokemon.getVariant() ? ` (${this.pokemon.getVariant() === 2 ? 'Epic' : 'Rare'})` : ''}`, true)); + const shinyDescriptor = doubleShiny || baseVariant ? + `${baseVariant === 2 ? 'Epic' : baseVariant === 1 ? 'Rare' : 'Common'}${doubleShiny ? `/${this.pokemon.fusionVariant === 2 ? 'Epic' : this.pokemon.fusionVariant === 1 ? 'Rare' : 'Common'}` : ''}` + : ''; + this.shinyIcon.on('pointerover', () => (this.scene as BattleScene).ui.showTooltip(null, `Shiny${shinyDescriptor ? ` (${shinyDescriptor})` : ''}`, true)); this.shinyIcon.on('pointerout', () => (this.scene as BattleScene).ui.hideTooltip()); } + this.fusionShinyIcon.setPosition(this.shinyIcon.x, this.shinyIcon.y); + this.fusionShinyIcon.setVisible(doubleShiny); + if (isFusion) + this.fusionShinyIcon.setTint(getVariantTint(this.pokemon.fusionVariant)); + this.pokeball.setFrame(getPokeballAtlasKey(this.pokemon.pokeball)); this.levelText.setText(this.pokemon.level.toString()); this.genderText.setText(getGenderSymbol(this.pokemon.getGender(true)));