[ME] Shiny lock MEs with custom or special sprites

This commit is contained in:
Moka 2024-11-07 23:31:06 +01:00
parent 2c186619b5
commit a67da46ea2
9 changed files with 20 additions and 16 deletions

View File

@ -890,7 +890,7 @@ export default class BattleScene extends SceneBase {
return pokemon; return pokemon;
} }
addEnemyPokemon(species: PokemonSpecies, level: integer, trainerSlot: TrainerSlot, boss: boolean = false, dataSource?: PokemonData, postProcess?: (enemyPokemon: EnemyPokemon) => void): EnemyPokemon { addEnemyPokemon(species: PokemonSpecies, level: integer, trainerSlot: TrainerSlot, boss: boolean = false, shinyLock: boolean = false, dataSource?: PokemonData, postProcess?: (enemyPokemon: EnemyPokemon) => void): EnemyPokemon {
if (Overrides.OPP_LEVEL_OVERRIDE > 0) { if (Overrides.OPP_LEVEL_OVERRIDE > 0) {
level = Overrides.OPP_LEVEL_OVERRIDE; level = Overrides.OPP_LEVEL_OVERRIDE;
} }
@ -900,7 +900,7 @@ export default class BattleScene extends SceneBase {
boss = this.getEncounterBossSegments(this.currentBattle.waveIndex, level, species) > 1; boss = this.getEncounterBossSegments(this.currentBattle.waveIndex, level, species) > 1;
} }
const pokemon = new EnemyPokemon(this, species, level, trainerSlot, boss, dataSource); const pokemon = new EnemyPokemon(this, species, level, trainerSlot, boss, shinyLock, dataSource);
if (Overrides.OPP_FUSION_OVERRIDE) { if (Overrides.OPP_FUSION_OVERRIDE) {
pokemon.generateFusionSpecies(); pokemon.generateFusionSpecies();
} }

View File

@ -216,6 +216,7 @@ export const AbsoluteAvariceEncounter: MysteryEncounter =
species: getPokemonSpecies(Species.GREEDENT), species: getPokemonSpecies(Species.GREEDENT),
isBoss: true, isBoss: true,
bossSegments: 3, bossSegments: 3,
shiny: false,
moveSet: [ Moves.THRASH, Moves.BODY_PRESS, Moves.STUFF_CHEEKS, Moves.CRUNCH ], moveSet: [ Moves.THRASH, Moves.BODY_PRESS, Moves.STUFF_CHEEKS, Moves.CRUNCH ],
modifierConfigs: bossModifierConfigs, modifierConfigs: bossModifierConfigs,
tags: [ BattlerTagType.MYSTERY_ENCOUNTER_POST_SUMMON ], tags: [ BattlerTagType.MYSTERY_ENCOUNTER_POST_SUMMON ],
@ -355,7 +356,7 @@ export const AbsoluteAvariceEncounter: MysteryEncounter =
// Let it have the food // Let it have the food
// Greedent joins the team, level equal to 2 below highest party member // Greedent joins the team, level equal to 2 below highest party member
const level = getHighestLevelPlayerPokemon(scene, false, true).level - 2; const level = getHighestLevelPlayerPokemon(scene, false, true).level - 2;
const greedent = new EnemyPokemon(scene, getPokemonSpecies(Species.GREEDENT), level, TrainerSlot.NONE, false); const greedent = new EnemyPokemon(scene, getPokemonSpecies(Species.GREEDENT), level, TrainerSlot.NONE, false, true);
greedent.moveset = [ new PokemonMove(Moves.THRASH), new PokemonMove(Moves.BODY_PRESS), new PokemonMove(Moves.STUFF_CHEEKS), new PokemonMove(Moves.SLACK_OFF) ]; greedent.moveset = [ new PokemonMove(Moves.THRASH), new PokemonMove(Moves.BODY_PRESS), new PokemonMove(Moves.STUFF_CHEEKS), new PokemonMove(Moves.SLACK_OFF) ];
greedent.passive = true; greedent.passive = true;

View File

@ -136,7 +136,7 @@ export const DancingLessonsEncounter: MysteryEncounter =
} }
const oricorioData = new PokemonData(enemyPokemon); const oricorioData = new PokemonData(enemyPokemon);
const oricorio = scene.addEnemyPokemon(species, level, TrainerSlot.NONE, false, oricorioData); const oricorio = scene.addEnemyPokemon(species, level, TrainerSlot.NONE, false, false, oricorioData);
// Adds a real Pokemon sprite to the field (required for the animation) // Adds a real Pokemon sprite to the field (required for the animation)
scene.getEnemyParty().forEach(enemyPokemon => { scene.getEnemyParty().forEach(enemyPokemon => {

View File

@ -194,10 +194,10 @@ async function summonPlayerPokemon(scene: BattleScene) {
playerAnimationPromise = summonPlayerPokemonAnimation(scene, playerPokemon); playerAnimationPromise = summonPlayerPokemonAnimation(scene, playerPokemon);
}); });
// Also loads Wobbuffet data // Also loads Wobbuffet data (cannot be shiny)
const enemySpecies = getPokemonSpecies(Species.WOBBUFFET); const enemySpecies = getPokemonSpecies(Species.WOBBUFFET);
scene.currentBattle.enemyParty = []; scene.currentBattle.enemyParty = [];
const wobbuffet = scene.addEnemyPokemon(enemySpecies, encounter.misc.playerPokemon.level, TrainerSlot.NONE, false); const wobbuffet = scene.addEnemyPokemon(enemySpecies, encounter.misc.playerPokemon.level, TrainerSlot.NONE, false, true);
wobbuffet.ivs = [ 0, 0, 0, 0, 0, 0 ]; wobbuffet.ivs = [ 0, 0, 0, 0, 0, 0 ];
wobbuffet.setNature(Nature.MILD); wobbuffet.setNature(Nature.MILD);
wobbuffet.setAlpha(0); wobbuffet.setAlpha(0);

View File

@ -61,11 +61,12 @@ export const TrashToTreasureEncounter: MysteryEncounter =
.withOnInit((scene: BattleScene) => { .withOnInit((scene: BattleScene) => {
const encounter = scene.currentBattle.mysteryEncounter!; const encounter = scene.currentBattle.mysteryEncounter!;
// Calculate boss mon // Calculate boss mon (shiny locked)
const bossSpecies = getPokemonSpecies(Species.GARBODOR); const bossSpecies = getPokemonSpecies(Species.GARBODOR);
const pokemonConfig: EnemyPokemonConfig = { const pokemonConfig: EnemyPokemonConfig = {
species: bossSpecies, species: bossSpecies,
isBoss: true, isBoss: true,
shiny: false,
formIndex: 1, // Gmax formIndex: 1, // Gmax
bossSegmentModifier: 1, // +1 Segment from normal bossSegmentModifier: 1, // +1 Segment from normal
moveSet: [ Moves.PAYBACK, Moves.GUNK_SHOT, Moves.STOMPING_TANTRUM, Moves.DRAIN_PUNCH ] moveSet: [ Moves.PAYBACK, Moves.GUNK_SHOT, Moves.STOMPING_TANTRUM, Moves.DRAIN_PUNCH ]

View File

@ -183,7 +183,7 @@ export async function initBattleWithEnemyConfig(scene: BattleScene, partyConfig:
dataSource = config.dataSource; dataSource = config.dataSource;
enemySpecies = config.species; enemySpecies = config.species;
isBoss = config.isBoss; isBoss = config.isBoss;
battle.enemyParty[e] = scene.addEnemyPokemon(enemySpecies, level, TrainerSlot.TRAINER, isBoss, dataSource); battle.enemyParty[e] = scene.addEnemyPokemon(enemySpecies, level, TrainerSlot.TRAINER, isBoss, false, dataSource);
} else { } else {
battle.enemyParty[e] = battle.trainer.genPartyMember(e); battle.enemyParty[e] = battle.trainer.genPartyMember(e);
} }
@ -201,7 +201,7 @@ export async function initBattleWithEnemyConfig(scene: BattleScene, partyConfig:
enemySpecies = scene.randomSpecies(battle.waveIndex, level, true); enemySpecies = scene.randomSpecies(battle.waveIndex, level, true);
} }
battle.enemyParty[e] = scene.addEnemyPokemon(enemySpecies, level, TrainerSlot.NONE, isBoss, dataSource); battle.enemyParty[e] = scene.addEnemyPokemon(enemySpecies, level, TrainerSlot.NONE, isBoss, false, dataSource);
} }
} }

View File

@ -1173,7 +1173,7 @@ export function getRandomPartyMemberFunc(speciesPool: Species[], trainerSlot: Tr
if (!ignoreEvolution) { if (!ignoreEvolution) {
species = getPokemonSpecies(species).getTrainerSpeciesForLevel(level, true, strength, scene.currentBattle.waveIndex); species = getPokemonSpecies(species).getTrainerSpeciesForLevel(level, true, strength, scene.currentBattle.waveIndex);
} }
return scene.addEnemyPokemon(getPokemonSpecies(species), level, trainerSlot, undefined, undefined, postProcess); return scene.addEnemyPokemon(getPokemonSpecies(species), level, trainerSlot, undefined, false, undefined, postProcess);
}; };
} }
@ -1181,7 +1181,7 @@ function getSpeciesFilterRandomPartyMemberFunc(speciesFilter: PokemonSpeciesFilt
const originalSpeciesFilter = speciesFilter; const originalSpeciesFilter = speciesFilter;
speciesFilter = (species: PokemonSpecies) => (allowLegendaries || (!species.legendary && !species.subLegendary && !species.mythical)) && !species.isTrainerForbidden() && originalSpeciesFilter(species); speciesFilter = (species: PokemonSpecies) => (allowLegendaries || (!species.legendary && !species.subLegendary && !species.mythical)) && !species.isTrainerForbidden() && originalSpeciesFilter(species);
return (scene: BattleScene, level: integer, strength: PartyMemberStrength) => { return (scene: BattleScene, level: integer, strength: PartyMemberStrength) => {
const ret = scene.addEnemyPokemon(getPokemonSpecies(scene.randomSpecies(scene.currentBattle.waveIndex, level, false, speciesFilter).getTrainerSpeciesForLevel(level, true, strength, scene.currentBattle.waveIndex)), level, trainerSlot, undefined, undefined, postProcess); const ret = scene.addEnemyPokemon(getPokemonSpecies(scene.randomSpecies(scene.currentBattle.waveIndex, level, false, speciesFilter).getTrainerSpeciesForLevel(level, true, strength, scene.currentBattle.waveIndex)), level, trainerSlot, undefined, false, undefined, postProcess);
return ret; return ret;
}; };
} }

View File

@ -1954,6 +1954,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
/** /**
* Function that tries to set a Pokemon shiny based on seed. * Function that tries to set a Pokemon shiny based on seed.
* For manual use only, usually to roll a Pokemon's shiny chance a second time. * For manual use only, usually to roll a Pokemon's shiny chance a second time.
* If it rolls shiny, also sets a random variant and give the Pokemon the associated luck.
* *
* The base shiny odds are {@linkcode BASE_SHINY_CHANCE} / `65536` * The base shiny odds are {@linkcode BASE_SHINY_CHANCE} / `65536`
* @param thresholdOverride number that is divided by `2^16` (`65536`) to get the shiny chance, overrides {@linkcode shinyThreshold} if set (bypassing shiny rate modifiers such as Shiny Charm) * @param thresholdOverride number that is divided by `2^16` (`65536`) to get the shiny chance, overrides {@linkcode shinyThreshold} if set (bypassing shiny rate modifiers such as Shiny Charm)
@ -4564,12 +4565,13 @@ export class EnemyPokemon extends Pokemon {
public aiType: AiType; public aiType: AiType;
public bossSegments: integer; public bossSegments: integer;
public bossSegmentIndex: integer; public bossSegmentIndex: integer;
/** To indicate of the instance was populated with a dataSource -> e.g. loaded & populated from session data */ /** To indicate if the instance was populated with a dataSource -> e.g. loaded & populated from session data */
public readonly isPopulatedFromDataSource: boolean; public readonly isPopulatedFromDataSource: boolean;
constructor(scene: BattleScene, species: PokemonSpecies, level: integer, trainerSlot: TrainerSlot, boss: boolean, dataSource?: PokemonData) { constructor(scene: BattleScene, species: PokemonSpecies, level: integer, trainerSlot: TrainerSlot, boss: boolean, shinyLock: boolean = false, dataSource?: PokemonData) {
super(scene, 236, 84, species, level, dataSource?.abilityIndex, dataSource?.formIndex, super(scene, 236, 84, species, level, dataSource?.abilityIndex, dataSource?.formIndex, dataSource?.gender,
dataSource?.gender, dataSource ? dataSource.shiny : false, dataSource ? dataSource.variant : undefined, undefined, dataSource ? dataSource.nature : undefined, dataSource); shinyLock ? false : (dataSource ? dataSource.shiny : false), shinyLock ? undefined : (dataSource ? dataSource.variant : undefined),
undefined, dataSource ? dataSource.nature : undefined, dataSource);
this.trainerSlot = trainerSlot; this.trainerSlot = trainerSlot;
this.isPopulatedFromDataSource = !!dataSource; // if a dataSource is provided, then it was populated from dataSource this.isPopulatedFromDataSource = !!dataSource; // if a dataSource is provided, then it was populated from dataSource

View File

@ -171,7 +171,7 @@ export default class PokemonData {
playerPokemon.nickname = this.nickname; playerPokemon.nickname = this.nickname;
} }
}) })
: scene.addEnemyPokemon(species, this.level, battleType === BattleType.TRAINER ? !double || !(partyMemberIndex % 2) ? TrainerSlot.TRAINER : TrainerSlot.TRAINER_PARTNER : TrainerSlot.NONE, this.boss, this); : scene.addEnemyPokemon(species, this.level, battleType === BattleType.TRAINER ? !double || !(partyMemberIndex % 2) ? TrainerSlot.TRAINER : TrainerSlot.TRAINER_PARTNER : TrainerSlot.NONE, this.boss, false, this);
if (this.summonData) { if (this.summonData) {
ret.primeSummonData(this.summonData); ret.primeSummonData(this.summonData);
} }