Compare commits
12 Commits
5de0185c0a
...
8a0b5c52d3
Author | SHA1 | Date | |
---|---|---|---|
|
8a0b5c52d3 | ||
|
ee4d130ebb | ||
|
942c119814 | ||
|
a97933fe4c | ||
|
bcfeaf0639 | ||
|
36f3cc6b47 | ||
|
c2375a0f5d | ||
|
f672ecc8ed | ||
|
29d9ac7038 | ||
|
7d55c165df | ||
|
e29c08ba1f | ||
|
32d222c9cd |
13175
public/images/items.json
Before Width: | Height: | Size: 125 KiB After Width: | Height: | Size: 50 KiB |
BIN
public/images/items/blank_memory.png
Normal file
After Width: | Height: | Size: 405 B |
BIN
public/images/items/blank_plate.png
Normal file
After Width: | Height: | Size: 308 B |
Before Width: | Height: | Size: 396 B After Width: | Height: | Size: 396 B |
Before Width: | Height: | Size: 411 B After Width: | Height: | Size: 411 B |
BIN
public/images/items/draco_plate.png
Normal file
After Width: | Height: | Size: 308 B |
Before Width: | Height: | Size: 378 B After Width: | Height: | Size: 378 B |
BIN
public/images/items/dread_plate.png
Normal file
After Width: | Height: | Size: 308 B |
BIN
public/images/items/earth_plate.png
Normal file
After Width: | Height: | Size: 308 B |
Before Width: | Height: | Size: 397 B After Width: | Height: | Size: 397 B |
Before Width: | Height: | Size: 386 B After Width: | Height: | Size: 386 B |
Before Width: | Height: | Size: 391 B After Width: | Height: | Size: 391 B |
Before Width: | Height: | Size: 390 B After Width: | Height: | Size: 390 B |
BIN
public/images/items/fist_plate.png
Normal file
After Width: | Height: | Size: 308 B |
BIN
public/images/items/flame_plate.png
Normal file
After Width: | Height: | Size: 308 B |
Before Width: | Height: | Size: 381 B After Width: | Height: | Size: 381 B |
Before Width: | Height: | Size: 393 B After Width: | Height: | Size: 393 B |
Before Width: | Height: | Size: 385 B After Width: | Height: | Size: 385 B |
Before Width: | Height: | Size: 383 B After Width: | Height: | Size: 383 B |
Before Width: | Height: | Size: 375 B After Width: | Height: | Size: 375 B |
BIN
public/images/items/icicle_plate.png
Normal file
After Width: | Height: | Size: 308 B |
BIN
public/images/items/insect_plate.png
Normal file
After Width: | Height: | Size: 308 B |
BIN
public/images/items/iron_plate.png
Normal file
After Width: | Height: | Size: 308 B |
BIN
public/images/items/legend_plate.png
Normal file
After Width: | Height: | Size: 343 B |
BIN
public/images/items/meadow_plate.png
Normal file
After Width: | Height: | Size: 308 B |
Before Width: | Height: | Size: 334 B |
BIN
public/images/items/mind_plate.png
Normal file
After Width: | Height: | Size: 308 B |
BIN
public/images/items/pixie_plate.png
Normal file
After Width: | Height: | Size: 367 B |
Before Width: | Height: | Size: 385 B After Width: | Height: | Size: 385 B |
Before Width: | Height: | Size: 390 B After Width: | Height: | Size: 390 B |
Before Width: | Height: | Size: 383 B After Width: | Height: | Size: 383 B |
BIN
public/images/items/sky_plate.png
Normal file
After Width: | Height: | Size: 308 B |
BIN
public/images/items/splash_plate.png
Normal file
After Width: | Height: | Size: 308 B |
BIN
public/images/items/spooky_plate.png
Normal file
After Width: | Height: | Size: 308 B |
Before Width: | Height: | Size: 387 B After Width: | Height: | Size: 387 B |
BIN
public/images/items/stone_plate.png
Normal file
After Width: | Height: | Size: 308 B |
BIN
public/images/items/toxic_plate.png
Normal file
After Width: | Height: | Size: 308 B |
Before Width: | Height: | Size: 381 B After Width: | Height: | Size: 381 B |
BIN
public/images/items/zap_plate.png
Normal file
After Width: | Height: | Size: 308 B |
@ -4043,8 +4043,7 @@ export function initAbilities() {
|
|||||||
.attr(UncopiableAbilityAbAttr)
|
.attr(UncopiableAbilityAbAttr)
|
||||||
.attr(UnswappableAbilityAbAttr)
|
.attr(UnswappableAbilityAbAttr)
|
||||||
.attr(UnsuppressableAbilityAbAttr)
|
.attr(UnsuppressableAbilityAbAttr)
|
||||||
.attr(NoFusionAbilityAbAttr)
|
.attr(NoFusionAbilityAbAttr),
|
||||||
.unimplemented(),
|
|
||||||
new Ability(Abilities.FLOWER_GIFT, 4)
|
new Ability(Abilities.FLOWER_GIFT, 4)
|
||||||
.conditionalAttr(getWeatherCondition(WeatherType.SUNNY || WeatherType.HARSH_SUN), BattleStatMultiplierAbAttr, BattleStat.ATK, 1.5)
|
.conditionalAttr(getWeatherCondition(WeatherType.SUNNY || WeatherType.HARSH_SUN), BattleStatMultiplierAbAttr, BattleStat.ATK, 1.5)
|
||||||
.conditionalAttr(getWeatherCondition(WeatherType.SUNNY || WeatherType.HARSH_SUN), BattleStatMultiplierAbAttr, BattleStat.SPDEF, 1.5)
|
.conditionalAttr(getWeatherCondition(WeatherType.SUNNY || WeatherType.HARSH_SUN), BattleStatMultiplierAbAttr, BattleStat.SPDEF, 1.5)
|
||||||
@ -4396,8 +4395,7 @@ export function initAbilities() {
|
|||||||
.attr(UncopiableAbilityAbAttr)
|
.attr(UncopiableAbilityAbAttr)
|
||||||
.attr(UnswappableAbilityAbAttr)
|
.attr(UnswappableAbilityAbAttr)
|
||||||
.attr(UnsuppressableAbilityAbAttr)
|
.attr(UnsuppressableAbilityAbAttr)
|
||||||
.attr(NoFusionAbilityAbAttr)
|
.attr(NoFusionAbilityAbAttr),
|
||||||
.unimplemented(),
|
|
||||||
new Ability(Abilities.ELECTRIC_SURGE, 7)
|
new Ability(Abilities.ELECTRIC_SURGE, 7)
|
||||||
.attr(PostSummonTerrainChangeAbAttr, TerrainType.ELECTRIC)
|
.attr(PostSummonTerrainChangeAbAttr, TerrainType.ELECTRIC)
|
||||||
.attr(PostBiomeChangeTerrainChangeAbAttr, TerrainType.ELECTRIC),
|
.attr(PostBiomeChangeTerrainChangeAbAttr, TerrainType.ELECTRIC),
|
||||||
|
@ -3328,6 +3328,19 @@ export class VariableMoveTypeAttr extends MoveAttr {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export class FormChangeItemTypeAttr extends VariableMoveTypeAttr {
|
||||||
|
apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean {
|
||||||
|
if ([user.species.speciesId, user.fusionSpecies?.speciesId].includes(Species.ARCEUS) || [user.species.speciesId, user.fusionSpecies?.speciesId].includes(Species.SILVALLY)) {
|
||||||
|
const form = user.species.speciesId === Species.ARCEUS || user.species.speciesId === Species.SILVALLY ? user.formIndex : user.fusionSpecies.formIndex;
|
||||||
|
|
||||||
|
move.type = Type[Type[form]];
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export class TechnoBlastTypeAttr extends VariableMoveTypeAttr {
|
export class TechnoBlastTypeAttr extends VariableMoveTypeAttr {
|
||||||
apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean {
|
apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean {
|
||||||
if ([user.species.speciesId, user.fusionSpecies?.speciesId].includes(Species.GENESECT)) {
|
if ([user.species.speciesId, user.fusionSpecies?.speciesId].includes(Species.GENESECT)) {
|
||||||
@ -6612,7 +6625,7 @@ export function initMoves() {
|
|||||||
.attr(ConfuseAttr)
|
.attr(ConfuseAttr)
|
||||||
.soundBased(),
|
.soundBased(),
|
||||||
new AttackMove(Moves.JUDGMENT, Type.NORMAL, MoveCategory.SPECIAL, 100, 100, 10, -1, 0, 4)
|
new AttackMove(Moves.JUDGMENT, Type.NORMAL, MoveCategory.SPECIAL, 100, 100, 10, -1, 0, 4)
|
||||||
.partial(),
|
.attr(FormChangeItemTypeAttr),
|
||||||
new AttackMove(Moves.BUG_BITE, Type.BUG, MoveCategory.PHYSICAL, 60, 100, 20, -1, 0, 4)
|
new AttackMove(Moves.BUG_BITE, Type.BUG, MoveCategory.PHYSICAL, 60, 100, 20, -1, 0, 4)
|
||||||
.attr(StealEatBerryAttr),
|
.attr(StealEatBerryAttr),
|
||||||
new AttackMove(Moves.CHARGE_BEAM, Type.ELECTRIC, MoveCategory.SPECIAL, 50, 90, 10, 70, 0, 4)
|
new AttackMove(Moves.CHARGE_BEAM, Type.ELECTRIC, MoveCategory.SPECIAL, 50, 90, 10, 70, 0, 4)
|
||||||
@ -7382,7 +7395,7 @@ export function initMoves() {
|
|||||||
new AttackMove(Moves.NATURES_MADNESS, Type.FAIRY, MoveCategory.SPECIAL, -1, 90, 10, -1, 0, 7)
|
new AttackMove(Moves.NATURES_MADNESS, Type.FAIRY, MoveCategory.SPECIAL, -1, 90, 10, -1, 0, 7)
|
||||||
.attr(TargetHalfHpDamageAttr),
|
.attr(TargetHalfHpDamageAttr),
|
||||||
new AttackMove(Moves.MULTI_ATTACK, Type.NORMAL, MoveCategory.PHYSICAL, 120, 100, 10, -1, 0, 7)
|
new AttackMove(Moves.MULTI_ATTACK, Type.NORMAL, MoveCategory.PHYSICAL, 120, 100, 10, -1, 0, 7)
|
||||||
.partial(),
|
.attr(FormChangeItemTypeAttr),
|
||||||
/* Unused */
|
/* Unused */
|
||||||
new AttackMove(Moves.TEN_MILLION_VOLT_THUNDERBOLT, Type.ELECTRIC, MoveCategory.SPECIAL, 195, -1, 1, -1, 0, 7)
|
new AttackMove(Moves.TEN_MILLION_VOLT_THUNDERBOLT, Type.ELECTRIC, MoveCategory.SPECIAL, 195, -1, 1, -1, 0, 7)
|
||||||
.partial()
|
.partial()
|
||||||
|
@ -86,7 +86,45 @@ export enum FormChangeItem {
|
|||||||
SHOCK_DRIVE,
|
SHOCK_DRIVE,
|
||||||
BURN_DRIVE,
|
BURN_DRIVE,
|
||||||
CHILL_DRIVE,
|
CHILL_DRIVE,
|
||||||
DOUSE_DRIVE
|
DOUSE_DRIVE,
|
||||||
|
|
||||||
|
FIST_PLATE = 100,
|
||||||
|
SKY_PLATE,
|
||||||
|
TOXIC_PLATE,
|
||||||
|
EARTH_PLATE,
|
||||||
|
STONE_PLATE,
|
||||||
|
INSECT_PLATE,
|
||||||
|
SPOOKY_PLATE,
|
||||||
|
IRON_PLATE,
|
||||||
|
FLAME_PLATE,
|
||||||
|
SPLASH_PLATE,
|
||||||
|
MEADOW_PLATE,
|
||||||
|
ZAP_PLATE,
|
||||||
|
MIND_PLATE,
|
||||||
|
ICICLE_PLATE,
|
||||||
|
DRACO_PLATE,
|
||||||
|
DREAD_PLATE,
|
||||||
|
PIXIE_PLATE,
|
||||||
|
BLANK_PLATE, // TODO: Find a potential use for this
|
||||||
|
LEGEND_PLATE, // TODO: Find a potential use for this
|
||||||
|
FIGHTING_MEMORY,
|
||||||
|
FLYING_MEMORY,
|
||||||
|
POISON_MEMORY,
|
||||||
|
GROUND_MEMORY,
|
||||||
|
ROCK_MEMORY,
|
||||||
|
BUG_MEMORY,
|
||||||
|
GHOST_MEMORY,
|
||||||
|
STEEL_MEMORY,
|
||||||
|
FIRE_MEMORY,
|
||||||
|
WATER_MEMORY,
|
||||||
|
GRASS_MEMORY,
|
||||||
|
ELECTRIC_MEMORY,
|
||||||
|
PSYCHIC_MEMORY,
|
||||||
|
ICE_MEMORY,
|
||||||
|
DRAGON_MEMORY,
|
||||||
|
DARK_MEMORY,
|
||||||
|
FAIRY_MEMORY,
|
||||||
|
BLANK_MEMORY // TODO: Find a potential use for this
|
||||||
}
|
}
|
||||||
|
|
||||||
export type SpeciesFormChangeConditionPredicate = (p: Pokemon) => boolean;
|
export type SpeciesFormChangeConditionPredicate = (p: Pokemon) => boolean;
|
||||||
@ -533,6 +571,25 @@ export const pokemonFormChanges: PokemonFormChanges = {
|
|||||||
new SpeciesFormChange(Species.SHAYMIN, "sky", "land", new SpeciesFormChangeTimeOfDayTrigger(TimeOfDay.DAWN, TimeOfDay.NIGHT)),
|
new SpeciesFormChange(Species.SHAYMIN, "sky", "land", new SpeciesFormChangeTimeOfDayTrigger(TimeOfDay.DAWN, TimeOfDay.NIGHT)),
|
||||||
new SpeciesFormChange(Species.SHAYMIN, "sky", "land", new SpeciesFormChangeStatusEffectTrigger(StatusEffect.FREEZE))
|
new SpeciesFormChange(Species.SHAYMIN, "sky", "land", new SpeciesFormChangeStatusEffectTrigger(StatusEffect.FREEZE))
|
||||||
],
|
],
|
||||||
|
[Species.ARCEUS]: [
|
||||||
|
new SpeciesFormChange(Species.ARCEUS, "normal", "fighting", new SpeciesFormChangeItemTrigger(FormChangeItem.FIST_PLATE)),
|
||||||
|
new SpeciesFormChange(Species.ARCEUS, "normal", "flying", new SpeciesFormChangeItemTrigger(FormChangeItem.SKY_PLATE)),
|
||||||
|
new SpeciesFormChange(Species.ARCEUS, "normal", "poison", new SpeciesFormChangeItemTrigger(FormChangeItem.TOXIC_PLATE)),
|
||||||
|
new SpeciesFormChange(Species.ARCEUS, "normal", "ground", new SpeciesFormChangeItemTrigger(FormChangeItem.EARTH_PLATE)),
|
||||||
|
new SpeciesFormChange(Species.ARCEUS, "normal", "rock", new SpeciesFormChangeItemTrigger(FormChangeItem.STONE_PLATE)),
|
||||||
|
new SpeciesFormChange(Species.ARCEUS, "normal", "bug", new SpeciesFormChangeItemTrigger(FormChangeItem.INSECT_PLATE)),
|
||||||
|
new SpeciesFormChange(Species.ARCEUS, "normal", "ghost", new SpeciesFormChangeItemTrigger(FormChangeItem.SPOOKY_PLATE)),
|
||||||
|
new SpeciesFormChange(Species.ARCEUS, "normal", "steel", new SpeciesFormChangeItemTrigger(FormChangeItem.IRON_PLATE)),
|
||||||
|
new SpeciesFormChange(Species.ARCEUS, "normal", "fire", new SpeciesFormChangeItemTrigger(FormChangeItem.FLAME_PLATE)),
|
||||||
|
new SpeciesFormChange(Species.ARCEUS, "normal", "water", new SpeciesFormChangeItemTrigger(FormChangeItem.SPLASH_PLATE)),
|
||||||
|
new SpeciesFormChange(Species.ARCEUS, "normal", "grass", new SpeciesFormChangeItemTrigger(FormChangeItem.MEADOW_PLATE)),
|
||||||
|
new SpeciesFormChange(Species.ARCEUS, "normal", "electric", new SpeciesFormChangeItemTrigger(FormChangeItem.ZAP_PLATE)),
|
||||||
|
new SpeciesFormChange(Species.ARCEUS, "normal", "psychic", new SpeciesFormChangeItemTrigger(FormChangeItem.MIND_PLATE)),
|
||||||
|
new SpeciesFormChange(Species.ARCEUS, "normal", "ice", new SpeciesFormChangeItemTrigger(FormChangeItem.ICICLE_PLATE)),
|
||||||
|
new SpeciesFormChange(Species.ARCEUS, "normal", "dragon", new SpeciesFormChangeItemTrigger(FormChangeItem.DRACO_PLATE)),
|
||||||
|
new SpeciesFormChange(Species.ARCEUS, "normal", "dark", new SpeciesFormChangeItemTrigger(FormChangeItem.DREAD_PLATE)),
|
||||||
|
new SpeciesFormChange(Species.ARCEUS, "normal", "fairy", new SpeciesFormChangeItemTrigger(FormChangeItem.PIXIE_PLATE))
|
||||||
|
],
|
||||||
[Species.DARMANITAN]: [
|
[Species.DARMANITAN]: [
|
||||||
new SpeciesFormChange(Species.DARMANITAN, "", "zen", new SpeciesFormChangeManualTrigger(), true),
|
new SpeciesFormChange(Species.DARMANITAN, "", "zen", new SpeciesFormChangeManualTrigger(), true),
|
||||||
new SpeciesFormChange(Species.DARMANITAN, "zen", "", new SpeciesFormChangeManualTrigger(), true)
|
new SpeciesFormChange(Species.DARMANITAN, "zen", "", new SpeciesFormChangeManualTrigger(), true)
|
||||||
@ -597,6 +654,25 @@ export const pokemonFormChanges: PokemonFormChanges = {
|
|||||||
new SpeciesFormChange(Species.WISHIWASHI, "", "school", new SpeciesFormChangeManualTrigger(), true),
|
new SpeciesFormChange(Species.WISHIWASHI, "", "school", new SpeciesFormChangeManualTrigger(), true),
|
||||||
new SpeciesFormChange(Species.WISHIWASHI, "school", "", new SpeciesFormChangeManualTrigger(), true)
|
new SpeciesFormChange(Species.WISHIWASHI, "school", "", new SpeciesFormChangeManualTrigger(), true)
|
||||||
],
|
],
|
||||||
|
[Species.SILVALLY]: [
|
||||||
|
new SpeciesFormChange(Species.SILVALLY, "normal", "fighting", new SpeciesFormChangeItemTrigger(FormChangeItem.FIGHTING_MEMORY)),
|
||||||
|
new SpeciesFormChange(Species.SILVALLY, "normal", "flying", new SpeciesFormChangeItemTrigger(FormChangeItem.FLYING_MEMORY)),
|
||||||
|
new SpeciesFormChange(Species.SILVALLY, "normal", "poison", new SpeciesFormChangeItemTrigger(FormChangeItem.POISON_MEMORY)),
|
||||||
|
new SpeciesFormChange(Species.SILVALLY, "normal", "ground", new SpeciesFormChangeItemTrigger(FormChangeItem.GROUND_MEMORY)),
|
||||||
|
new SpeciesFormChange(Species.SILVALLY, "normal", "rock", new SpeciesFormChangeItemTrigger(FormChangeItem.ROCK_MEMORY)),
|
||||||
|
new SpeciesFormChange(Species.SILVALLY, "normal", "bug", new SpeciesFormChangeItemTrigger(FormChangeItem.BUG_MEMORY)),
|
||||||
|
new SpeciesFormChange(Species.SILVALLY, "normal", "ghost", new SpeciesFormChangeItemTrigger(FormChangeItem.GHOST_MEMORY)),
|
||||||
|
new SpeciesFormChange(Species.SILVALLY, "normal", "steel", new SpeciesFormChangeItemTrigger(FormChangeItem.STEEL_MEMORY)),
|
||||||
|
new SpeciesFormChange(Species.SILVALLY, "normal", "fire", new SpeciesFormChangeItemTrigger(FormChangeItem.FIRE_MEMORY)),
|
||||||
|
new SpeciesFormChange(Species.SILVALLY, "normal", "water", new SpeciesFormChangeItemTrigger(FormChangeItem.WATER_MEMORY)),
|
||||||
|
new SpeciesFormChange(Species.SILVALLY, "normal", "grass", new SpeciesFormChangeItemTrigger(FormChangeItem.GRASS_MEMORY)),
|
||||||
|
new SpeciesFormChange(Species.SILVALLY, "normal", "electric", new SpeciesFormChangeItemTrigger(FormChangeItem.ELECTRIC_MEMORY)),
|
||||||
|
new SpeciesFormChange(Species.SILVALLY, "normal", "psychic", new SpeciesFormChangeItemTrigger(FormChangeItem.PSYCHIC_MEMORY)),
|
||||||
|
new SpeciesFormChange(Species.SILVALLY, "normal", "ice", new SpeciesFormChangeItemTrigger(FormChangeItem.ICE_MEMORY)),
|
||||||
|
new SpeciesFormChange(Species.SILVALLY, "normal", "dragon", new SpeciesFormChangeItemTrigger(FormChangeItem.DRAGON_MEMORY)),
|
||||||
|
new SpeciesFormChange(Species.SILVALLY, "normal", "dark", new SpeciesFormChangeItemTrigger(FormChangeItem.DARK_MEMORY)),
|
||||||
|
new SpeciesFormChange(Species.SILVALLY, "normal", "fairy", new SpeciesFormChangeItemTrigger(FormChangeItem.FAIRY_MEMORY))
|
||||||
|
],
|
||||||
[Species.MINIOR]: [
|
[Species.MINIOR]: [
|
||||||
new SpeciesFormChange(Species.MINIOR, "red-meteor", "red", new SpeciesFormChangeManualTrigger(), true),
|
new SpeciesFormChange(Species.MINIOR, "red-meteor", "red", new SpeciesFormChangeManualTrigger(), true),
|
||||||
new SpeciesFormChange(Species.MINIOR, "red", "red-meteor", new SpeciesFormChangeManualTrigger(), true),
|
new SpeciesFormChange(Species.MINIOR, "red", "red-meteor", new SpeciesFormChangeManualTrigger(), true),
|
||||||
|
@ -1445,21 +1445,21 @@ export const trainerConfigs: TrainerConfigs = {
|
|||||||
p.generateAndPopulateMoveset();
|
p.generateAndPopulateMoveset();
|
||||||
})),
|
})),
|
||||||
|
|
||||||
[TrainerType.RIVAL]: new TrainerConfig((t = TrainerType.RIVAL)).setName("Finn").setHasGenders("Ivy").setHasCharSprite().setTitle("Rival").setStaticParty().setEncounterBgm(TrainerType.RIVAL).setBattleBgm("battle_rival").setPartyTemplates(trainerPartyTemplates.RIVAL)
|
[TrainerType.RIVAL]: new TrainerConfig((t = TrainerType.RIVAL)).setName("Finn").setHasGenders("Ivy").setHasCharSprite().setTitle("Rival").setStaticParty().setEncounterBgm(TrainerType.RIVAL).setBattleBgm("battle_rival").setMixedBattleBgm("battle_rival").setPartyTemplates(trainerPartyTemplates.RIVAL)
|
||||||
.setModifierRewardFuncs(() => modifierTypes.SUPER_EXP_CHARM, () => modifierTypes.EXP_SHARE)
|
.setModifierRewardFuncs(() => modifierTypes.SUPER_EXP_CHARM, () => modifierTypes.EXP_SHARE)
|
||||||
.setPartyMemberFunc(0, getRandomPartyMemberFunc([Species.BULBASAUR, Species.CHARMANDER, Species.SQUIRTLE, Species.CHIKORITA, Species.CYNDAQUIL, Species.TOTODILE, Species.TREECKO, Species.TORCHIC, Species.MUDKIP, Species.TURTWIG, Species.CHIMCHAR, Species.PIPLUP, Species.SNIVY, Species.TEPIG, Species.OSHAWOTT, Species.CHESPIN, Species.FENNEKIN, Species.FROAKIE, Species.ROWLET, Species.LITTEN, Species.POPPLIO, Species.GROOKEY, Species.SCORBUNNY, Species.SOBBLE, Species.SPRIGATITO, Species.FUECOCO, Species.QUAXLY], TrainerSlot.TRAINER, true))
|
.setPartyMemberFunc(0, getRandomPartyMemberFunc([Species.BULBASAUR, Species.CHARMANDER, Species.SQUIRTLE, Species.CHIKORITA, Species.CYNDAQUIL, Species.TOTODILE, Species.TREECKO, Species.TORCHIC, Species.MUDKIP, Species.TURTWIG, Species.CHIMCHAR, Species.PIPLUP, Species.SNIVY, Species.TEPIG, Species.OSHAWOTT, Species.CHESPIN, Species.FENNEKIN, Species.FROAKIE, Species.ROWLET, Species.LITTEN, Species.POPPLIO, Species.GROOKEY, Species.SCORBUNNY, Species.SOBBLE, Species.SPRIGATITO, Species.FUECOCO, Species.QUAXLY], TrainerSlot.TRAINER, true))
|
||||||
.setPartyMemberFunc(1, getRandomPartyMemberFunc([Species.PIDGEY, Species.HOOTHOOT, Species.TAILLOW, Species.STARLY, Species.PIDOVE, Species.FLETCHLING, Species.PIKIPEK, Species.ROOKIDEE, Species.WATTREL], TrainerSlot.TRAINER, true)),
|
.setPartyMemberFunc(1, getRandomPartyMemberFunc([Species.PIDGEY, Species.HOOTHOOT, Species.TAILLOW, Species.STARLY, Species.PIDOVE, Species.FLETCHLING, Species.PIKIPEK, Species.ROOKIDEE, Species.WATTREL], TrainerSlot.TRAINER, true)),
|
||||||
[TrainerType.RIVAL_2]: new TrainerConfig(++t).setName("Finn").setHasGenders("Ivy").setHasCharSprite().setTitle("Rival").setStaticParty().setMoneyMultiplier(1.25).setEncounterBgm(TrainerType.RIVAL).setBattleBgm("battle_rival").setPartyTemplates(trainerPartyTemplates.RIVAL_2)
|
[TrainerType.RIVAL_2]: new TrainerConfig(++t).setName("Finn").setHasGenders("Ivy").setHasCharSprite().setTitle("Rival").setStaticParty().setMoneyMultiplier(1.25).setEncounterBgm(TrainerType.RIVAL).setBattleBgm("battle_rival").setMixedBattleBgm("battle_rival").setPartyTemplates(trainerPartyTemplates.RIVAL_2)
|
||||||
.setModifierRewardFuncs(() => modifierTypes.EXP_SHARE)
|
.setModifierRewardFuncs(() => modifierTypes.EXP_SHARE)
|
||||||
.setPartyMemberFunc(0, getRandomPartyMemberFunc([Species.IVYSAUR, Species.CHARMELEON, Species.WARTORTLE, Species.BAYLEEF, Species.QUILAVA, Species.CROCONAW, Species.GROVYLE, Species.COMBUSKEN, Species.MARSHTOMP, Species.GROTLE, Species.MONFERNO, Species.PRINPLUP, Species.SERVINE, Species.PIGNITE, Species.DEWOTT, Species.QUILLADIN, Species.BRAIXEN, Species.FROGADIER, Species.DARTRIX, Species.TORRACAT, Species.BRIONNE, Species.THWACKEY, Species.RABOOT, Species.DRIZZILE, Species.FLORAGATO, Species.CROCALOR, Species.QUAXWELL], TrainerSlot.TRAINER, true))
|
.setPartyMemberFunc(0, getRandomPartyMemberFunc([Species.IVYSAUR, Species.CHARMELEON, Species.WARTORTLE, Species.BAYLEEF, Species.QUILAVA, Species.CROCONAW, Species.GROVYLE, Species.COMBUSKEN, Species.MARSHTOMP, Species.GROTLE, Species.MONFERNO, Species.PRINPLUP, Species.SERVINE, Species.PIGNITE, Species.DEWOTT, Species.QUILLADIN, Species.BRAIXEN, Species.FROGADIER, Species.DARTRIX, Species.TORRACAT, Species.BRIONNE, Species.THWACKEY, Species.RABOOT, Species.DRIZZILE, Species.FLORAGATO, Species.CROCALOR, Species.QUAXWELL], TrainerSlot.TRAINER, true))
|
||||||
.setPartyMemberFunc(1, getRandomPartyMemberFunc([Species.PIDGEOTTO, Species.HOOTHOOT, Species.TAILLOW, Species.STARAVIA, Species.TRANQUILL, Species.FLETCHINDER, Species.TRUMBEAK, Species.CORVISQUIRE, Species.WATTREL], TrainerSlot.TRAINER, true))
|
.setPartyMemberFunc(1, getRandomPartyMemberFunc([Species.PIDGEOTTO, Species.HOOTHOOT, Species.TAILLOW, Species.STARAVIA, Species.TRANQUILL, Species.FLETCHINDER, Species.TRUMBEAK, Species.CORVISQUIRE, Species.WATTREL], TrainerSlot.TRAINER, true))
|
||||||
.setPartyMemberFunc(2, getSpeciesFilterRandomPartyMemberFunc((species: PokemonSpecies) => !pokemonEvolutions.hasOwnProperty(species.speciesId) && !pokemonPrevolutions.hasOwnProperty(species.speciesId) && species.baseTotal >= 450)),
|
.setPartyMemberFunc(2, getSpeciesFilterRandomPartyMemberFunc((species: PokemonSpecies) => !pokemonEvolutions.hasOwnProperty(species.speciesId) && !pokemonPrevolutions.hasOwnProperty(species.speciesId) && species.baseTotal >= 450)),
|
||||||
[TrainerType.RIVAL_3]: new TrainerConfig(++t).setName("Finn").setHasGenders("Ivy").setHasCharSprite().setTitle("Rival").setStaticParty().setMoneyMultiplier(1.5).setEncounterBgm(TrainerType.RIVAL).setBattleBgm("battle_rival").setPartyTemplates(trainerPartyTemplates.RIVAL_3)
|
[TrainerType.RIVAL_3]: new TrainerConfig(++t).setName("Finn").setHasGenders("Ivy").setHasCharSprite().setTitle("Rival").setStaticParty().setMoneyMultiplier(1.5).setEncounterBgm(TrainerType.RIVAL).setBattleBgm("battle_rival").setMixedBattleBgm("battle_rival").setPartyTemplates(trainerPartyTemplates.RIVAL_3)
|
||||||
.setPartyMemberFunc(0, getRandomPartyMemberFunc([Species.VENUSAUR, Species.CHARIZARD, Species.BLASTOISE, Species.MEGANIUM, Species.TYPHLOSION, Species.FERALIGATR, Species.SCEPTILE, Species.BLAZIKEN, Species.SWAMPERT, Species.TORTERRA, Species.INFERNAPE, Species.EMPOLEON, Species.SERPERIOR, Species.EMBOAR, Species.SAMUROTT, Species.CHESNAUGHT, Species.DELPHOX, Species.GRENINJA, Species.DECIDUEYE, Species.INCINEROAR, Species.PRIMARINA, Species.RILLABOOM, Species.CINDERACE, Species.INTELEON, Species.MEOWSCARADA, Species.SKELEDIRGE, Species.QUAQUAVAL], TrainerSlot.TRAINER, true))
|
.setPartyMemberFunc(0, getRandomPartyMemberFunc([Species.VENUSAUR, Species.CHARIZARD, Species.BLASTOISE, Species.MEGANIUM, Species.TYPHLOSION, Species.FERALIGATR, Species.SCEPTILE, Species.BLAZIKEN, Species.SWAMPERT, Species.TORTERRA, Species.INFERNAPE, Species.EMPOLEON, Species.SERPERIOR, Species.EMBOAR, Species.SAMUROTT, Species.CHESNAUGHT, Species.DELPHOX, Species.GRENINJA, Species.DECIDUEYE, Species.INCINEROAR, Species.PRIMARINA, Species.RILLABOOM, Species.CINDERACE, Species.INTELEON, Species.MEOWSCARADA, Species.SKELEDIRGE, Species.QUAQUAVAL], TrainerSlot.TRAINER, true))
|
||||||
.setPartyMemberFunc(1, getRandomPartyMemberFunc([Species.PIDGEOT, Species.NOCTOWL, Species.SWELLOW, Species.STARAPTOR, Species.UNFEZANT, Species.TALONFLAME, Species.TOUCANNON, Species.CORVIKNIGHT, Species.KILOWATTREL], TrainerSlot.TRAINER, true))
|
.setPartyMemberFunc(1, getRandomPartyMemberFunc([Species.PIDGEOT, Species.NOCTOWL, Species.SWELLOW, Species.STARAPTOR, Species.UNFEZANT, Species.TALONFLAME, Species.TOUCANNON, Species.CORVIKNIGHT, Species.KILOWATTREL], TrainerSlot.TRAINER, true))
|
||||||
.setPartyMemberFunc(2, getSpeciesFilterRandomPartyMemberFunc((species: PokemonSpecies) => !pokemonEvolutions.hasOwnProperty(species.speciesId) && !pokemonPrevolutions.hasOwnProperty(species.speciesId) && species.baseTotal >= 450))
|
.setPartyMemberFunc(2, getSpeciesFilterRandomPartyMemberFunc((species: PokemonSpecies) => !pokemonEvolutions.hasOwnProperty(species.speciesId) && !pokemonPrevolutions.hasOwnProperty(species.speciesId) && species.baseTotal >= 450))
|
||||||
.setSpeciesFilter(species => species.baseTotal >= 540),
|
.setSpeciesFilter(species => species.baseTotal >= 540),
|
||||||
[TrainerType.RIVAL_4]: new TrainerConfig(++t).setName("Finn").setHasGenders("Ivy").setHasCharSprite().setTitle("Rival").setBoss().setStaticParty().setMoneyMultiplier(1.75).setEncounterBgm(TrainerType.RIVAL).setBattleBgm("battle_rival_2").setPartyTemplates(trainerPartyTemplates.RIVAL_4)
|
[TrainerType.RIVAL_4]: new TrainerConfig(++t).setName("Finn").setHasGenders("Ivy").setHasCharSprite().setTitle("Rival").setBoss().setStaticParty().setMoneyMultiplier(1.75).setEncounterBgm(TrainerType.RIVAL).setBattleBgm("battle_rival_2").setMixedBattleBgm("battle_rival_2").setPartyTemplates(trainerPartyTemplates.RIVAL_4)
|
||||||
.setPartyMemberFunc(0, getRandomPartyMemberFunc([Species.VENUSAUR, Species.CHARIZARD, Species.BLASTOISE, Species.MEGANIUM, Species.TYPHLOSION, Species.FERALIGATR, Species.SCEPTILE, Species.BLAZIKEN, Species.SWAMPERT, Species.TORTERRA, Species.INFERNAPE, Species.EMPOLEON, Species.SERPERIOR, Species.EMBOAR, Species.SAMUROTT, Species.CHESNAUGHT, Species.DELPHOX, Species.GRENINJA, Species.DECIDUEYE, Species.INCINEROAR, Species.PRIMARINA, Species.RILLABOOM, Species.CINDERACE, Species.INTELEON, Species.MEOWSCARADA, Species.SKELEDIRGE, Species.QUAQUAVAL], TrainerSlot.TRAINER, true))
|
.setPartyMemberFunc(0, getRandomPartyMemberFunc([Species.VENUSAUR, Species.CHARIZARD, Species.BLASTOISE, Species.MEGANIUM, Species.TYPHLOSION, Species.FERALIGATR, Species.SCEPTILE, Species.BLAZIKEN, Species.SWAMPERT, Species.TORTERRA, Species.INFERNAPE, Species.EMPOLEON, Species.SERPERIOR, Species.EMBOAR, Species.SAMUROTT, Species.CHESNAUGHT, Species.DELPHOX, Species.GRENINJA, Species.DECIDUEYE, Species.INCINEROAR, Species.PRIMARINA, Species.RILLABOOM, Species.CINDERACE, Species.INTELEON, Species.MEOWSCARADA, Species.SKELEDIRGE, Species.QUAQUAVAL], TrainerSlot.TRAINER, true))
|
||||||
.setPartyMemberFunc(1, getRandomPartyMemberFunc([Species.PIDGEOT, Species.NOCTOWL, Species.SWELLOW, Species.STARAPTOR, Species.UNFEZANT, Species.TALONFLAME, Species.TOUCANNON, Species.CORVIKNIGHT, Species.KILOWATTREL], TrainerSlot.TRAINER, true))
|
.setPartyMemberFunc(1, getRandomPartyMemberFunc([Species.PIDGEOT, Species.NOCTOWL, Species.SWELLOW, Species.STARAPTOR, Species.UNFEZANT, Species.TALONFLAME, Species.TOUCANNON, Species.CORVIKNIGHT, Species.KILOWATTREL], TrainerSlot.TRAINER, true))
|
||||||
.setPartyMemberFunc(2, getSpeciesFilterRandomPartyMemberFunc((species: PokemonSpecies) => !pokemonEvolutions.hasOwnProperty(species.speciesId) && !pokemonPrevolutions.hasOwnProperty(species.speciesId) && species.baseTotal >= 450))
|
.setPartyMemberFunc(2, getSpeciesFilterRandomPartyMemberFunc((species: PokemonSpecies) => !pokemonEvolutions.hasOwnProperty(species.speciesId) && !pokemonPrevolutions.hasOwnProperty(species.speciesId) && species.baseTotal >= 450))
|
||||||
@ -1468,7 +1468,7 @@ export const trainerConfigs: TrainerConfigs = {
|
|||||||
const starter = party[0];
|
const starter = party[0];
|
||||||
return [modifierTypes.TERA_SHARD().generateType(null, [starter.species.type1]).withIdFromFunc(modifierTypes.TERA_SHARD).newModifier(starter) as PersistentModifier];
|
return [modifierTypes.TERA_SHARD().generateType(null, [starter.species.type1]).withIdFromFunc(modifierTypes.TERA_SHARD).newModifier(starter) as PersistentModifier];
|
||||||
}),
|
}),
|
||||||
[TrainerType.RIVAL_5]: new TrainerConfig(++t).setName("Finn").setHasGenders("Ivy").setHasCharSprite().setTitle("Rival").setBoss().setStaticParty().setMoneyMultiplier(2.25).setEncounterBgm(TrainerType.RIVAL).setBattleBgm("battle_rival_3").setPartyTemplates(trainerPartyTemplates.RIVAL_5)
|
[TrainerType.RIVAL_5]: new TrainerConfig(++t).setName("Finn").setHasGenders("Ivy").setHasCharSprite().setTitle("Rival").setBoss().setStaticParty().setMoneyMultiplier(2.25).setEncounterBgm(TrainerType.RIVAL).setBattleBgm("battle_rival_3").setMixedBattleBgm("battle_rival_3").setPartyTemplates(trainerPartyTemplates.RIVAL_5)
|
||||||
.setPartyMemberFunc(0, getRandomPartyMemberFunc([Species.VENUSAUR, Species.CHARIZARD, Species.BLASTOISE, Species.MEGANIUM, Species.TYPHLOSION, Species.FERALIGATR, Species.SCEPTILE, Species.BLAZIKEN, Species.SWAMPERT, Species.TORTERRA, Species.INFERNAPE, Species.EMPOLEON, Species.SERPERIOR, Species.EMBOAR, Species.SAMUROTT, Species.CHESNAUGHT, Species.DELPHOX, Species.GRENINJA, Species.DECIDUEYE, Species.INCINEROAR, Species.PRIMARINA, Species.RILLABOOM, Species.CINDERACE, Species.INTELEON, Species.MEOWSCARADA, Species.SKELEDIRGE, Species.QUAQUAVAL], TrainerSlot.TRAINER, true,
|
.setPartyMemberFunc(0, getRandomPartyMemberFunc([Species.VENUSAUR, Species.CHARIZARD, Species.BLASTOISE, Species.MEGANIUM, Species.TYPHLOSION, Species.FERALIGATR, Species.SCEPTILE, Species.BLAZIKEN, Species.SWAMPERT, Species.TORTERRA, Species.INFERNAPE, Species.EMPOLEON, Species.SERPERIOR, Species.EMBOAR, Species.SAMUROTT, Species.CHESNAUGHT, Species.DELPHOX, Species.GRENINJA, Species.DECIDUEYE, Species.INCINEROAR, Species.PRIMARINA, Species.RILLABOOM, Species.CINDERACE, Species.INTELEON, Species.MEOWSCARADA, Species.SKELEDIRGE, Species.QUAQUAVAL], TrainerSlot.TRAINER, true,
|
||||||
p => p.setBoss(true, 2)))
|
p => p.setBoss(true, 2)))
|
||||||
.setPartyMemberFunc(1, getRandomPartyMemberFunc([Species.PIDGEOT, Species.NOCTOWL, Species.SWELLOW, Species.STARAPTOR, Species.UNFEZANT, Species.TALONFLAME, Species.TOUCANNON, Species.CORVIKNIGHT, Species.KILOWATTREL], TrainerSlot.TRAINER, true))
|
.setPartyMemberFunc(1, getRandomPartyMemberFunc([Species.PIDGEOT, Species.NOCTOWL, Species.SWELLOW, Species.STARAPTOR, Species.UNFEZANT, Species.TALONFLAME, Species.TOUCANNON, Species.CORVIKNIGHT, Species.KILOWATTREL], TrainerSlot.TRAINER, true))
|
||||||
@ -1484,7 +1484,7 @@ export const trainerConfigs: TrainerConfigs = {
|
|||||||
const starter = party[0];
|
const starter = party[0];
|
||||||
return [modifierTypes.TERA_SHARD().generateType(null, [starter.species.type1]).withIdFromFunc(modifierTypes.TERA_SHARD).newModifier(starter) as PersistentModifier];
|
return [modifierTypes.TERA_SHARD().generateType(null, [starter.species.type1]).withIdFromFunc(modifierTypes.TERA_SHARD).newModifier(starter) as PersistentModifier];
|
||||||
}),
|
}),
|
||||||
[TrainerType.RIVAL_6]: new TrainerConfig(++t).setName("Finn").setHasGenders("Ivy").setHasCharSprite().setTitle("Rival").setBoss().setStaticParty().setMoneyMultiplier(3).setEncounterBgm("final").setBattleBgm("battle_rival_3").setPartyTemplates(trainerPartyTemplates.RIVAL_6)
|
[TrainerType.RIVAL_6]: new TrainerConfig(++t).setName("Finn").setHasGenders("Ivy").setHasCharSprite().setTitle("Rival").setBoss().setStaticParty().setMoneyMultiplier(3).setEncounterBgm("final").setBattleBgm("battle_rival_3").setMixedBattleBgm("battle_rival_3").setPartyTemplates(trainerPartyTemplates.RIVAL_6)
|
||||||
.setPartyMemberFunc(0, getRandomPartyMemberFunc([Species.VENUSAUR, Species.CHARIZARD, Species.BLASTOISE, Species.MEGANIUM, Species.TYPHLOSION, Species.FERALIGATR, Species.SCEPTILE, Species.BLAZIKEN, Species.SWAMPERT, Species.TORTERRA, Species.INFERNAPE, Species.EMPOLEON, Species.SERPERIOR, Species.EMBOAR, Species.SAMUROTT, Species.CHESNAUGHT, Species.DELPHOX, Species.GRENINJA, Species.DECIDUEYE, Species.INCINEROAR, Species.PRIMARINA, Species.RILLABOOM, Species.CINDERACE, Species.INTELEON, Species.MEOWSCARADA, Species.SKELEDIRGE, Species.QUAQUAVAL], TrainerSlot.TRAINER, true,
|
.setPartyMemberFunc(0, getRandomPartyMemberFunc([Species.VENUSAUR, Species.CHARIZARD, Species.BLASTOISE, Species.MEGANIUM, Species.TYPHLOSION, Species.FERALIGATR, Species.SCEPTILE, Species.BLAZIKEN, Species.SWAMPERT, Species.TORTERRA, Species.INFERNAPE, Species.EMPOLEON, Species.SERPERIOR, Species.EMBOAR, Species.SAMUROTT, Species.CHESNAUGHT, Species.DELPHOX, Species.GRENINJA, Species.DECIDUEYE, Species.INCINEROAR, Species.PRIMARINA, Species.RILLABOOM, Species.CINDERACE, Species.INTELEON, Species.MEOWSCARADA, Species.SKELEDIRGE, Species.QUAQUAVAL], TrainerSlot.TRAINER, true,
|
||||||
p => {
|
p => {
|
||||||
p.setBoss(true, 3);
|
p.setBoss(true, 3);
|
||||||
|
@ -1070,6 +1070,10 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Calculates the effectiveness of a move against the Pokémon.
|
||||||
|
*
|
||||||
|
* @param source - The Pokémon using the move.
|
||||||
|
* @param move - The move being used.
|
||||||
* @returns The type damage multiplier or undefined if it's a status move
|
* @returns The type damage multiplier or undefined if it's a status move
|
||||||
*/
|
*/
|
||||||
getMoveEffectiveness(source: Pokemon, move: PokemonMove): TypeDamageMultiplier | undefined {
|
getMoveEffectiveness(source: Pokemon, move: PokemonMove): TypeDamageMultiplier | undefined {
|
||||||
@ -1077,19 +1081,27 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
|||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
return this.getAttackMoveEffectiveness(source, move);
|
return this.getAttackMoveEffectiveness(source, move, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
getAttackMoveEffectiveness(source: Pokemon, pokemonMove: PokemonMove): TypeDamageMultiplier {
|
/**
|
||||||
|
* Calculates the effectiveness of an attack move against the Pokémon.
|
||||||
|
*
|
||||||
|
* @param source - The attacking Pokémon.
|
||||||
|
* @param pokemonMove - The move being used by the attacking Pokémon.
|
||||||
|
* @param ignoreAbility - Whether to check for abilities that might affect type effectiveness or immunity.
|
||||||
|
* @returns The type damage multiplier, indicating the effectiveness of the move
|
||||||
|
*/
|
||||||
|
getAttackMoveEffectiveness(source: Pokemon, pokemonMove: PokemonMove, ignoreAbility: boolean = false): TypeDamageMultiplier {
|
||||||
const move = pokemonMove.getMove();
|
const move = pokemonMove.getMove();
|
||||||
const typeless = move.hasAttr(TypelessAttr);
|
const typeless = move.hasAttr(TypelessAttr);
|
||||||
const typeMultiplier = new Utils.NumberHolder(this.getAttackTypeEffectiveness(move.type, source));
|
const typeMultiplier = new Utils.NumberHolder(this.getAttackTypeEffectiveness(move.type, source));
|
||||||
const cancelled = new Utils.BooleanHolder(false);
|
const cancelled = new Utils.BooleanHolder(false);
|
||||||
applyMoveAttrs(VariableMoveTypeMultiplierAttr, source, this, move, typeMultiplier);
|
applyMoveAttrs(VariableMoveTypeMultiplierAttr, source, this, move, typeMultiplier);
|
||||||
if (!typeless) {
|
if (!typeless && !ignoreAbility) {
|
||||||
applyPreDefendAbAttrs(TypeImmunityAbAttr, this, source, move, cancelled, typeMultiplier, true);
|
applyPreDefendAbAttrs(TypeImmunityAbAttr, this, source, move, cancelled, typeMultiplier, true);
|
||||||
}
|
}
|
||||||
if (!cancelled.value) {
|
if (!cancelled.value && !ignoreAbility) {
|
||||||
applyPreDefendAbAttrs(MoveImmunityAbAttr, this, source, move, cancelled, typeMultiplier, true);
|
applyPreDefendAbAttrs(MoveImmunityAbAttr, this, source, move, cancelled, typeMultiplier, true);
|
||||||
}
|
}
|
||||||
return (!cancelled.value ? typeMultiplier.value : 0) as TypeDamageMultiplier;
|
return (!cancelled.value ? typeMultiplier.value : 0) as TypeDamageMultiplier;
|
||||||
|
@ -389,5 +389,43 @@ export const modifierType: ModifierTypeTranslationEntries = {
|
|||||||
"BURN_DRIVE": "Flammenmodul",
|
"BURN_DRIVE": "Flammenmodul",
|
||||||
"CHILL_DRIVE": "Gefriermodul",
|
"CHILL_DRIVE": "Gefriermodul",
|
||||||
"DOUSE_DRIVE": "Aquamodul",
|
"DOUSE_DRIVE": "Aquamodul",
|
||||||
|
|
||||||
|
"FIST_PLATE": "Fausttafel",
|
||||||
|
"SKY_PLATE": "Wolkentafel",
|
||||||
|
"TOXIC_PLATE": "Gifttafel",
|
||||||
|
"EARTH_PLATE": "Erdtafel",
|
||||||
|
"STONE_PLATE": "Steintafel",
|
||||||
|
"INSECT_PLATE": "Käfertafel",
|
||||||
|
"SPOOKY_PLATE": "Spuktafel",
|
||||||
|
"IRON_PLATE": "Eisentafel",
|
||||||
|
"FLAME_PLATE": "Feuertafel",
|
||||||
|
"SPLASH_PLATE": "Wassertafel",
|
||||||
|
"MEADOW_PLATE": "Wiesentafel",
|
||||||
|
"ZAP_PLATE": "Blitztafel",
|
||||||
|
"MIND_PLATE": "Hirntafel",
|
||||||
|
"ICICLE_PLATE": "Frosttafel",
|
||||||
|
"DRACO_PLATE": "Dracotafel",
|
||||||
|
"DREAD_PLATE": "Furchttafel",
|
||||||
|
"PIXIE_PLATE": "Feentafel",
|
||||||
|
"BLANK_PLATE": "Neutraltafel",
|
||||||
|
"LEGEND_PLATE": "Legendentafel",
|
||||||
|
"FIGHTING_MEMORY": "Kampf-Disc",
|
||||||
|
"FLYING_MEMORY": "Flug-Disc",
|
||||||
|
"POISON_MEMORY": "Gift-Disc",
|
||||||
|
"GROUND_MEMORY": "Boden-Disc",
|
||||||
|
"ROCK_MEMORY": "Gesteins-Disc",
|
||||||
|
"BUG_MEMORY": "Käfer-Disc",
|
||||||
|
"GHOST_MEMORY": "Geister-Disc",
|
||||||
|
"STEEL_MEMORY": "Stahl-Disc",
|
||||||
|
"FIRE_MEMORY": "Feuer-Disc",
|
||||||
|
"WATER_MEMORY": "Wasser-Disc",
|
||||||
|
"GRASS_MEMORY": "Pflanzen-Disc",
|
||||||
|
"ELECTRIC_MEMORY": "Elektro-Disc",
|
||||||
|
"PSYCHIC_MEMORY": "Psycho-Disc",
|
||||||
|
"ICE_MEMORY": "Eis-Disc",
|
||||||
|
"DRAGON_MEMORY": "Drachen-Disc",
|
||||||
|
"DARK_MEMORY": "Unlicht-Disc",
|
||||||
|
"FAIRY_MEMORY": "Feen-Disc",
|
||||||
|
"BLANK_MEMORY": "Leere-Disc",
|
||||||
},
|
},
|
||||||
} as const;
|
} as const;
|
||||||
|
@ -388,5 +388,43 @@ export const modifierType: ModifierTypeTranslationEntries = {
|
|||||||
"BURN_DRIVE": "Burn Drive",
|
"BURN_DRIVE": "Burn Drive",
|
||||||
"CHILL_DRIVE": "Chill Drive",
|
"CHILL_DRIVE": "Chill Drive",
|
||||||
"DOUSE_DRIVE": "Douse Drive",
|
"DOUSE_DRIVE": "Douse Drive",
|
||||||
|
|
||||||
|
"FIST_PLATE": "Fist Plate",
|
||||||
|
"SKY_PLATE": "Sky Plate",
|
||||||
|
"TOXIC_PLATE": "Toxic Plate",
|
||||||
|
"EARTH_PLATE": "Earth Plate",
|
||||||
|
"STONE_PLATE": "Stone Plate",
|
||||||
|
"INSECT_PLATE": "Insect Plate",
|
||||||
|
"SPOOKY_PLATE": "Spooky Plate",
|
||||||
|
"IRON_PLATE": "Iron Plate",
|
||||||
|
"FLAME_PLATE": "Flame Plate",
|
||||||
|
"SPLASH_PLATE": "Splash Plate",
|
||||||
|
"MEADOW_PLATE": "Meadow Plate",
|
||||||
|
"ZAP_PLATE": "Zap Plate",
|
||||||
|
"MIND_PLATE": "Mind Plate",
|
||||||
|
"ICICLE_PLATE": "Icicle Plate",
|
||||||
|
"DRACO_PLATE": "Draco Plate",
|
||||||
|
"DREAD_PLATE": "Dread Plate",
|
||||||
|
"PIXIE_PLATE": "Pixie Plate",
|
||||||
|
"BLANK_PLATE": "Blank Plate",
|
||||||
|
"LEGEND_PLATE": "Legend Plate",
|
||||||
|
"FIGHTING_MEMORY": "Fighting Memory",
|
||||||
|
"FLYING_MEMORY": "Flying Memory",
|
||||||
|
"POISON_MEMORY": "Poison Memory",
|
||||||
|
"GROUND_MEMORY": "Ground Memory",
|
||||||
|
"ROCK_MEMORY": "Rock Memory",
|
||||||
|
"BUG_MEMORY": "Bug Memory",
|
||||||
|
"GHOST_MEMORY": "Ghost Memory",
|
||||||
|
"STEEL_MEMORY": "Steel Memory",
|
||||||
|
"FIRE_MEMORY": "Fire Memory",
|
||||||
|
"WATER_MEMORY": "Water Memory",
|
||||||
|
"GRASS_MEMORY": "Grass Memory",
|
||||||
|
"ELECTRIC_MEMORY": "Electric Memory",
|
||||||
|
"PSYCHIC_MEMORY": "Psychic Memory",
|
||||||
|
"ICE_MEMORY": "Ice Memory",
|
||||||
|
"DRAGON_MEMORY": "Dragon Memory",
|
||||||
|
"DARK_MEMORY": "Dark Memory",
|
||||||
|
"FAIRY_MEMORY": "Fairy Memory",
|
||||||
|
"BLANK_MEMORY": "Blank Memory",
|
||||||
},
|
},
|
||||||
} as const;
|
} as const;
|
||||||
|
@ -388,5 +388,43 @@ export const modifierType: ModifierTypeTranslationEntries = {
|
|||||||
"BURN_DRIVE": "PiroROM",
|
"BURN_DRIVE": "PiroROM",
|
||||||
"CHILL_DRIVE": "CrioROM",
|
"CHILL_DRIVE": "CrioROM",
|
||||||
"DOUSE_DRIVE": "HidroROM",
|
"DOUSE_DRIVE": "HidroROM",
|
||||||
|
|
||||||
|
"FIST_PLATE": "Tabla Fuerte",
|
||||||
|
"SKY_PLATE": "Tabla Cielo",
|
||||||
|
"TOXIC_PLATE": "Tabla Tóxica",
|
||||||
|
"EARTH_PLATE": "Tabla Terrax",
|
||||||
|
"STONE_PLATE": "Tabla Pétrea",
|
||||||
|
"INSECT_PLATE": "Tabla Bicho",
|
||||||
|
"SPOOKY_PLATE": "Tabla Terror",
|
||||||
|
"IRON_PLATE": "Tabla Acero",
|
||||||
|
"FLAME_PLATE": "Tabla Llama",
|
||||||
|
"SPLASH_PLATE": "Tabla Linfa",
|
||||||
|
"MEADOW_PLATE": "Tabla Pradal",
|
||||||
|
"ZAP_PLATE": "Tabla Trueno",
|
||||||
|
"MIND_PLATE": "Tabla Mental",
|
||||||
|
"ICICLE_PLATE": "Tabla Helada",
|
||||||
|
"DRACO_PLATE": "Tabla Draco",
|
||||||
|
"DREAD_PLATE": "Tabla Oscura",
|
||||||
|
"PIXIE_PLATE": "Tabla Duende",
|
||||||
|
"BLANK_PLATE": "Tabla Neutra",
|
||||||
|
"LEGEND_PLATE": "Tabla Legendaria",
|
||||||
|
"FIGHTING_MEMORY": "Disco Lucha",
|
||||||
|
"FLYING_MEMORY": "Disco Volador",
|
||||||
|
"POISON_MEMORY": "Disco Veneno",
|
||||||
|
"GROUND_MEMORY": "Disco Tierra",
|
||||||
|
"ROCK_MEMORY": "Disco Roca",
|
||||||
|
"BUG_MEMORY": "Disco Bicho",
|
||||||
|
"GHOST_MEMORY": "Disco Fantasma",
|
||||||
|
"STEEL_MEMORY": "Disco Acero",
|
||||||
|
"FIRE_MEMORY": "Disco Fuego",
|
||||||
|
"WATER_MEMORY": "Disco Agua",
|
||||||
|
"GRASS_MEMORY": "Disco Planta",
|
||||||
|
"ELECTRIC_MEMORY": "Disco Eléctrico",
|
||||||
|
"PSYCHIC_MEMORY": "Disco Psíquico",
|
||||||
|
"ICE_MEMORY": "Disco Hielo",
|
||||||
|
"DRAGON_MEMORY": "Disco Dragón",
|
||||||
|
"DARK_MEMORY": "Disco Siniestro",
|
||||||
|
"FAIRY_MEMORY": "Disco Hada",
|
||||||
|
"BLANK_MEMORY": "Disco Blanco",
|
||||||
},
|
},
|
||||||
} as const;
|
} as const;
|
||||||
|
@ -388,5 +388,43 @@ export const modifierType: ModifierTypeTranslationEntries = {
|
|||||||
"BURN_DRIVE": "Module Pyro",
|
"BURN_DRIVE": "Module Pyro",
|
||||||
"CHILL_DRIVE": "Module Cryo",
|
"CHILL_DRIVE": "Module Cryo",
|
||||||
"DOUSE_DRIVE": "Module Aqua",
|
"DOUSE_DRIVE": "Module Aqua",
|
||||||
|
|
||||||
|
"FIST_PLATE": "Plaque Poing",
|
||||||
|
"SKY_PLATE": "Plaque Ciel",
|
||||||
|
"TOXIC_PLATE": "Plaque Toxicité",
|
||||||
|
"EARTH_PLATE": "Plaque Terre",
|
||||||
|
"STONE_PLATE": "Plaque Roc",
|
||||||
|
"INSECT_PLATE": "Plaque Insecte",
|
||||||
|
"SPOOKY_PLATE": "Plaque Fantôme",
|
||||||
|
"IRON_PLATE": "Plaque Fer",
|
||||||
|
"FLAME_PLATE": "Plaque Flamme",
|
||||||
|
"SPLASH_PLATE": "Plaque Hydro",
|
||||||
|
"MEADOW_PLATE": "Plaque Herbe",
|
||||||
|
"ZAP_PLATE": "Plaque Volt",
|
||||||
|
"MIND_PLATE": "Plaque Esprit",
|
||||||
|
"ICICLE_PLATE": "Plaque Glace",
|
||||||
|
"DRACO_PLATE": "Plaque Draco",
|
||||||
|
"DREAD_PLATE": "Plaque Ombre",
|
||||||
|
"PIXIE_PLATE": "Plaque Pixie",
|
||||||
|
"BLANK_PLATE": "Plaque Renouveau",
|
||||||
|
"LEGEND_PLATE": "Plaque Légende",
|
||||||
|
"FIGHTING_MEMORY": "ROM Combat",
|
||||||
|
"FLYING_MEMORY": "ROM Vol",
|
||||||
|
"POISON_MEMORY": "ROM Poison",
|
||||||
|
"GROUND_MEMORY": "ROM Sol",
|
||||||
|
"ROCK_MEMORY": "ROM Roche",
|
||||||
|
"BUG_MEMORY": "ROM Insecte",
|
||||||
|
"GHOST_MEMORY": "ROM Spectre",
|
||||||
|
"STEEL_MEMORY": "ROM Acier",
|
||||||
|
"FIRE_MEMORY": "ROM Feu",
|
||||||
|
"WATER_MEMORY": "ROM Eau",
|
||||||
|
"GRASS_MEMORY": "ROM Plante",
|
||||||
|
"ELECTRIC_MEMORY": "ROM Électrik",
|
||||||
|
"PSYCHIC_MEMORY": "ROM Psy",
|
||||||
|
"ICE_MEMORY": "ROM Glace",
|
||||||
|
"DRAGON_MEMORY": "ROM Dragon",
|
||||||
|
"DARK_MEMORY": "ROM Ténèbres",
|
||||||
|
"FAIRY_MEMORY": "ROM Fée",
|
||||||
|
"BLANK_MEMORY": "ROM Vierge",
|
||||||
},
|
},
|
||||||
} as const;
|
} as const;
|
||||||
|
@ -388,5 +388,43 @@ export const modifierType: ModifierTypeTranslationEntries = {
|
|||||||
"BURN_DRIVE": "Piromodulo",
|
"BURN_DRIVE": "Piromodulo",
|
||||||
"CHILL_DRIVE": "Gelomodulo",
|
"CHILL_DRIVE": "Gelomodulo",
|
||||||
"DOUSE_DRIVE": "Idromodulo",
|
"DOUSE_DRIVE": "Idromodulo",
|
||||||
|
|
||||||
|
"FIST_PLATE": "Lastrapugno",
|
||||||
|
"SKY_PLATE": "Lastracielo",
|
||||||
|
"TOXIC_PLATE": "Lastrafiele",
|
||||||
|
"EARTH_PLATE": "Lastrageo",
|
||||||
|
"STONE_PLATE": "Lastrapietra",
|
||||||
|
"INSECT_PLATE": "Lastrabaco",
|
||||||
|
"SPOOKY_PLATE": "Lastratetra",
|
||||||
|
"IRON_PLATE": "Lastraferro",
|
||||||
|
"FLAME_PLATE": "Lastrarogo",
|
||||||
|
"SPLASH_PLATE": "Lastraidro",
|
||||||
|
"MEADOW_PLATE": "Lastraprato",
|
||||||
|
"ZAP_PLATE": "Lastrasaetta",
|
||||||
|
"MIND_PLATE": "Lastramente",
|
||||||
|
"ICICLE_PLATE": "Lastragelo",
|
||||||
|
"DRACO_PLATE": "Lastradrakon",
|
||||||
|
"DREAD_PLATE": "Lastratimore",
|
||||||
|
"PIXIE_PLATE": "Lastraspiritello",
|
||||||
|
"BLANK_PLATE": "Lastraripristino",
|
||||||
|
"LEGEND_PLATE": "Lastraleggenda",
|
||||||
|
"FIGHTING_MEMORY": "ROM Lotta",
|
||||||
|
"FLYING_MEMORY": "ROM Volante",
|
||||||
|
"POISON_MEMORY": "ROM Veleno",
|
||||||
|
"GROUND_MEMORY": "ROM Terra",
|
||||||
|
"ROCK_MEMORY": "ROM Roccia",
|
||||||
|
"BUG_MEMORY": "ROM Coleottero",
|
||||||
|
"GHOST_MEMORY": "ROM Spettro",
|
||||||
|
"STEEL_MEMORY": "ROM Acciaio",
|
||||||
|
"FIRE_MEMORY": "ROM Fuoco",
|
||||||
|
"WATER_MEMORY": "ROM Acqua",
|
||||||
|
"GRASS_MEMORY": "ROM Erba",
|
||||||
|
"ELECTRIC_MEMORY": "ROM Elettro",
|
||||||
|
"PSYCHIC_MEMORY": "ROM Psico",
|
||||||
|
"ICE_MEMORY": "ROM Ghiaccio",
|
||||||
|
"DRAGON_MEMORY": "ROM Drago",
|
||||||
|
"DARK_MEMORY": "ROM Buio",
|
||||||
|
"FAIRY_MEMORY": "ROM Folletto",
|
||||||
|
"BLANK_MEMORY": "ROM Vuota",
|
||||||
},
|
},
|
||||||
} as const;
|
} as const;
|
||||||
|
@ -425,5 +425,6 @@ export const modifierType: ModifierTypeTranslationEntries = {
|
|||||||
"DRAGON_MEMORY": "드래곤메모리",
|
"DRAGON_MEMORY": "드래곤메모리",
|
||||||
"DARK_MEMORY": "다크메모리",
|
"DARK_MEMORY": "다크메모리",
|
||||||
"FAIRY_MEMORY": "페어리메모리",
|
"FAIRY_MEMORY": "페어리메모리",
|
||||||
|
"BLANK_MEMORY": "빈메모리",
|
||||||
},
|
},
|
||||||
} as const;
|
} as const;
|
||||||
|
@ -388,5 +388,43 @@ export const modifierType: ModifierTypeTranslationEntries = {
|
|||||||
"BURN_DRIVE": "IgneDisco",
|
"BURN_DRIVE": "IgneDisco",
|
||||||
"CHILL_DRIVE": "CrioDisco",
|
"CHILL_DRIVE": "CrioDisco",
|
||||||
"DOUSE_DRIVE": "HidroDisco",
|
"DOUSE_DRIVE": "HidroDisco",
|
||||||
|
|
||||||
|
"FIST_PLATE": "Placa de Punho",
|
||||||
|
"SKY_PLATE": "Placa do Céu",
|
||||||
|
"TOXIC_PLATE": "Placa Tóxica",
|
||||||
|
"EARTH_PLATE": "Placa Terrestre",
|
||||||
|
"STONE_PLATE": "Placa de Pedra",
|
||||||
|
"INSECT_PLATE": "Placa de Insetos",
|
||||||
|
"SPOOKY_PLATE": "Placa Assustadora",
|
||||||
|
"IRON_PLATE": "Placa de Ferro",
|
||||||
|
"FLAME_PLATE": "Placa da Chama",
|
||||||
|
"SPLASH_PLATE": "Placa de Respingo",
|
||||||
|
"MEADOW_PLATE": "Placa de Prado",
|
||||||
|
"ZAP_PLATE": "Placa Elétrica",
|
||||||
|
"MIND_PLATE": "Placa Mental",
|
||||||
|
"ICICLE_PLATE": "Placa de Gelo",
|
||||||
|
"DRACO_PLATE": "Placa de Draco",
|
||||||
|
"DREAD_PLATE": "Placa do Pavor",
|
||||||
|
"PIXIE_PLATE": "Placa Duende",
|
||||||
|
"BLANK_PLATE": "Placa em Branco",
|
||||||
|
"LEGEND_PLATE": "Placa de Legenda",
|
||||||
|
"FIGHTING_MEMORY": "Memória de Lutador",
|
||||||
|
"FLYING_MEMORY": "Memória Voadora",
|
||||||
|
"POISON_MEMORY": "Memória Venenosa",
|
||||||
|
"GROUND_MEMORY": "Memória Terrestre",
|
||||||
|
"ROCK_MEMORY": "Memória da Rocha",
|
||||||
|
"BUG_MEMORY": "Memória de Insetos",
|
||||||
|
"GHOST_MEMORY": "Memória Fantasma",
|
||||||
|
"STEEL_MEMORY": "Memória de Aço",
|
||||||
|
"FIRE_MEMORY": "Memória de Fogo",
|
||||||
|
"WATER_MEMORY": "Memória da Água",
|
||||||
|
"GRASS_MEMORY": "Memória de Planta",
|
||||||
|
"ELECTRIC_MEMORY": "Memória Elétrica",
|
||||||
|
"PSYCHIC_MEMORY": "Memória Psíquica",
|
||||||
|
"ICE_MEMORY": "Memória de Gelo",
|
||||||
|
"DRAGON_MEMORY": "Memória do Dragão",
|
||||||
|
"DARK_MEMORY": "Memória Negra",
|
||||||
|
"FAIRY_MEMORY": "Memória de Fada",
|
||||||
|
"BLANK_MEMORY": "Memória Vazia",
|
||||||
},
|
},
|
||||||
} as const;
|
} as const;
|
||||||
|
@ -388,5 +388,43 @@ export const modifierType: ModifierTypeTranslationEntries = {
|
|||||||
"BURN_DRIVE": "火焰卡带",
|
"BURN_DRIVE": "火焰卡带",
|
||||||
"CHILL_DRIVE": "冰冻卡带",
|
"CHILL_DRIVE": "冰冻卡带",
|
||||||
"DOUSE_DRIVE": "水流卡带",
|
"DOUSE_DRIVE": "水流卡带",
|
||||||
|
|
||||||
|
"FIST_PLATE": "拳頭石板",
|
||||||
|
"SKY_PLATE": "藍天石板",
|
||||||
|
"TOXIC_PLATE": "劇毒石板",
|
||||||
|
"EARTH_PLATE": "大地石板",
|
||||||
|
"STONE_PLATE": "岩石石板",
|
||||||
|
"INSECT_PLATE": "玉蟲石板",
|
||||||
|
"SPOOKY_PLATE": "妖怪石板",
|
||||||
|
"IRON_PLATE": "鋼鐵石板",
|
||||||
|
"FLAME_PLATE": "火球石板",
|
||||||
|
"SPLASH_PLATE": "水滴石板",
|
||||||
|
"MEADOW_PLATE": "碧綠石板",
|
||||||
|
"ZAP_PLATE": "雷電石板",
|
||||||
|
"MIND_PLATE": "神奇石板",
|
||||||
|
"ICICLE_PLATE": "冰柱石板",
|
||||||
|
"DRACO_PLATE": "龍之石板",
|
||||||
|
"DREAD_PLATE": "惡顏石板",
|
||||||
|
"PIXIE_PLATE": "妖精石板",
|
||||||
|
"BLANK_PLATE": "淨空石板",
|
||||||
|
"LEGEND_PLATE": "傳說石板",
|
||||||
|
"FIGHTING_MEMORY": "戰鬥記憶碟",
|
||||||
|
"FLYING_MEMORY": "飛翔記憶碟",
|
||||||
|
"POISON_MEMORY": "毒記憶碟",
|
||||||
|
"GROUND_MEMORY": "大地記憶碟",
|
||||||
|
"ROCK_MEMORY": "岩石記憶碟",
|
||||||
|
"BUG_MEMORY": "蟲子記憶碟",
|
||||||
|
"GHOST_MEMORY": "幽靈記憶碟",
|
||||||
|
"STEEL_MEMORY": "鋼鐵記憶碟",
|
||||||
|
"FIRE_MEMORY": "火焰記憶碟",
|
||||||
|
"WATER_MEMORY": "清水記憶碟",
|
||||||
|
"GRASS_MEMORY": "青草記憶碟",
|
||||||
|
"ELECTRIC_MEMORY": "電子記憶碟",
|
||||||
|
"PSYCHIC_MEMORY": "精神記憶碟",
|
||||||
|
"ICE_MEMORY": "冰雪記憶碟",
|
||||||
|
"DRAGON_MEMORY": "龍記憶碟",
|
||||||
|
"DARK_MEMORY": "黑暗記憶碟",
|
||||||
|
"FAIRY_MEMORY": "妖精記憶碟",
|
||||||
|
"BLANK_MEMORY": "空白記憶碟",
|
||||||
},
|
},
|
||||||
} as const;
|
} as const;
|
||||||
|
@ -442,5 +442,43 @@ export const modifierType: ModifierTypeTranslationEntries = {
|
|||||||
BURN_DRIVE: "火焰卡帶",
|
BURN_DRIVE: "火焰卡帶",
|
||||||
CHILL_DRIVE: "冰凍卡帶",
|
CHILL_DRIVE: "冰凍卡帶",
|
||||||
DOUSE_DRIVE: "水流卡帶",
|
DOUSE_DRIVE: "水流卡帶",
|
||||||
|
|
||||||
|
"FIST_PLATE": "拳頭石板",
|
||||||
|
"SKY_PLATE": "藍天石板",
|
||||||
|
"TOXIC_PLATE": "劇毒石板",
|
||||||
|
"EARTH_PLATE": "大地石板",
|
||||||
|
"STONE_PLATE": "岩石石板",
|
||||||
|
"INSECT_PLATE": "玉蟲石板",
|
||||||
|
"SPOOKY_PLATE": "妖怪石板",
|
||||||
|
"IRON_PLATE": "鋼鐵石板",
|
||||||
|
"FLAME_PLATE": "火球石板",
|
||||||
|
"SPLASH_PLATE": "水滴石板",
|
||||||
|
"MEADOW_PLATE": "碧綠石板",
|
||||||
|
"ZAP_PLATE": "雷電石板",
|
||||||
|
"MIND_PLATE": "神奇石板",
|
||||||
|
"ICICLE_PLATE": "冰柱石板",
|
||||||
|
"DRACO_PLATE": "龍之石板",
|
||||||
|
"DREAD_PLATE": "惡顏石板",
|
||||||
|
"PIXIE_PLATE": "妖精石板",
|
||||||
|
"BLANK_PLATE": "淨空石板",
|
||||||
|
"LEGEND_PLATE": "傳說石板",
|
||||||
|
"FIGHTING_MEMORY": "戰鬥記憶碟",
|
||||||
|
"FLYING_MEMORY": "飛翔記憶碟",
|
||||||
|
"POISON_MEMORY": "毒記憶碟",
|
||||||
|
"GROUND_MEMORY": "大地記憶碟",
|
||||||
|
"ROCK_MEMORY": "岩石記憶碟",
|
||||||
|
"BUG_MEMORY": "蟲子記憶碟",
|
||||||
|
"GHOST_MEMORY": "幽靈記憶碟",
|
||||||
|
"STEEL_MEMORY": "鋼鐵記憶碟",
|
||||||
|
"FIRE_MEMORY": "火焰記憶碟",
|
||||||
|
"WATER_MEMORY": "清水記憶碟",
|
||||||
|
"GRASS_MEMORY": "青草記憶碟",
|
||||||
|
"ELECTRIC_MEMORY": "電子記憶碟",
|
||||||
|
"PSYCHIC_MEMORY": "精神記憶碟",
|
||||||
|
"ICE_MEMORY": "冰雪記憶碟",
|
||||||
|
"DRAGON_MEMORY": "龍記憶碟",
|
||||||
|
"DARK_MEMORY": "黑暗記憶碟",
|
||||||
|
"FAIRY_MEMORY": "妖精記憶碟",
|
||||||
|
"BLANK_MEMORY": "空白記憶碟",
|
||||||
},
|
},
|
||||||
} as const;
|
} as const;
|
||||||
|
@ -1079,6 +1079,10 @@ export class NextEncounterPhase extends EncounterPhase {
|
|||||||
super(scene);
|
super(scene);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
start() {
|
||||||
|
super.start();
|
||||||
|
}
|
||||||
|
|
||||||
doEncounter(): void {
|
doEncounter(): void {
|
||||||
this.scene.playBgm(undefined, true);
|
this.scene.playBgm(undefined, true);
|
||||||
|
|
||||||
@ -1158,6 +1162,9 @@ export class PostSummonPhase extends PokemonPhase {
|
|||||||
|
|
||||||
const pokemon = this.getPokemon();
|
const pokemon = this.getPokemon();
|
||||||
|
|
||||||
|
if (pokemon.status?.effect === StatusEffect.TOXIC) {
|
||||||
|
pokemon.status.turnCount = 0;
|
||||||
|
}
|
||||||
this.scene.arena.applyTags(ArenaTrapTag, pokemon);
|
this.scene.arena.applyTags(ArenaTrapTag, pokemon);
|
||||||
applyPostSummonAbAttrs(PostSummonAbAttr, pokemon).then(() => this.end());
|
applyPostSummonAbAttrs(PostSummonAbAttr, pokemon).then(() => this.end());
|
||||||
}
|
}
|
||||||
@ -1497,6 +1504,10 @@ export class SwitchSummonPhase extends SummonPhase {
|
|||||||
this.batonPass = batonPass;
|
this.batonPass = batonPass;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
start(): void {
|
||||||
|
super.start();
|
||||||
|
}
|
||||||
|
|
||||||
preSummon(): void {
|
preSummon(): void {
|
||||||
if (!this.player) {
|
if (!this.player) {
|
||||||
if (this.slotIndex === -1) {
|
if (this.slotIndex === -1) {
|
||||||
|
142
src/test/abilities/zen_mode.test.ts
Normal file
@ -0,0 +1,142 @@
|
|||||||
|
import {afterEach, beforeAll, beforeEach, describe, expect, it, vi} from "vitest";
|
||||||
|
import Phaser from "phaser";
|
||||||
|
import GameManager from "#app/test/utils/gameManager";
|
||||||
|
import * as overrides from "#app/overrides";
|
||||||
|
import {Abilities} from "#app/data/enums/abilities";
|
||||||
|
import {Species} from "#app/data/enums/species";
|
||||||
|
import {
|
||||||
|
CommandPhase,
|
||||||
|
DamagePhase,
|
||||||
|
EnemyCommandPhase,
|
||||||
|
MessagePhase,
|
||||||
|
PostSummonPhase,
|
||||||
|
SwitchPhase,
|
||||||
|
SwitchSummonPhase,
|
||||||
|
TurnEndPhase, TurnInitPhase,
|
||||||
|
TurnStartPhase,
|
||||||
|
} from "#app/phases";
|
||||||
|
import {Mode} from "#app/ui/ui";
|
||||||
|
import {Stat} from "#app/data/pokemon-stat";
|
||||||
|
import {Moves} from "#app/data/enums/moves";
|
||||||
|
import {getMovePosition} from "#app/test/utils/gameManagerUtils";
|
||||||
|
import {Command} from "#app/ui/command-ui-handler";
|
||||||
|
import {QuietFormChangePhase} from "#app/form-change-phase";
|
||||||
|
|
||||||
|
|
||||||
|
describe("Abilities - Zen mode", () => {
|
||||||
|
let phaserGame: Phaser.Game;
|
||||||
|
let game: GameManager;
|
||||||
|
|
||||||
|
beforeAll(() => {
|
||||||
|
phaserGame = new Phaser.Game({
|
||||||
|
type: Phaser.HEADLESS,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
game.phaseInterceptor.restoreOg();
|
||||||
|
});
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
game = new GameManager(phaserGame);
|
||||||
|
const moveToUse = Moves.SPLASH;
|
||||||
|
vi.spyOn(overrides, "SINGLE_BATTLE_OVERRIDE", "get").mockReturnValue(true);
|
||||||
|
vi.spyOn(overrides, "OPP_SPECIES_OVERRIDE", "get").mockReturnValue(Species.RATTATA);
|
||||||
|
vi.spyOn(overrides, "OPP_ABILITY_OVERRIDE", "get").mockReturnValue(Abilities.HYDRATION);
|
||||||
|
vi.spyOn(overrides, "ABILITY_OVERRIDE", "get").mockReturnValue(Abilities.ZEN_MODE);
|
||||||
|
vi.spyOn(overrides, "STARTING_LEVEL_OVERRIDE", "get").mockReturnValue(100);
|
||||||
|
vi.spyOn(overrides, "MOVESET_OVERRIDE", "get").mockReturnValue([moveToUse]);
|
||||||
|
vi.spyOn(overrides, "OPP_MOVESET_OVERRIDE", "get").mockReturnValue([Moves.TACKLE,Moves.TACKLE,Moves.TACKLE,Moves.TACKLE]);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("ZEN MODE - not enough damage to change form", async() => {
|
||||||
|
const moveToUse = Moves.SPLASH;
|
||||||
|
await game.startBattle([
|
||||||
|
Species.DARMANITAN,
|
||||||
|
]);
|
||||||
|
game.scene.getParty()[0].stats[Stat.SPD] = 1;
|
||||||
|
game.scene.getParty()[0].stats[Stat.HP] = 100;
|
||||||
|
game.scene.getParty()[0].hp = 100;
|
||||||
|
expect(game.scene.getParty()[0].formIndex).toBe(0);
|
||||||
|
|
||||||
|
game.onNextPrompt("CommandPhase", Mode.COMMAND, () => {
|
||||||
|
game.scene.ui.setMode(Mode.FIGHT, (game.scene.getCurrentPhase() as CommandPhase).getFieldIndex());
|
||||||
|
});
|
||||||
|
game.onNextPrompt("CommandPhase", Mode.FIGHT, () => {
|
||||||
|
const movePosition = getMovePosition(game.scene, 0, moveToUse);
|
||||||
|
(game.scene.getCurrentPhase() as CommandPhase).handleCommand(Command.FIGHT, movePosition, false);
|
||||||
|
});
|
||||||
|
await game.phaseInterceptor.runFrom(EnemyCommandPhase).to(DamagePhase, false);
|
||||||
|
// await game.phaseInterceptor.runFrom(DamagePhase).to(DamagePhase, false);
|
||||||
|
const damagePhase = game.scene.getCurrentPhase() as DamagePhase;
|
||||||
|
damagePhase.updateAmount(40);
|
||||||
|
await game.phaseInterceptor.runFrom(DamagePhase).to(TurnEndPhase, false);
|
||||||
|
expect(game.scene.getParty()[0].hp).toBeLessThan(100);
|
||||||
|
expect(game.scene.getParty()[0].formIndex).toBe(0);
|
||||||
|
}, 20000);
|
||||||
|
|
||||||
|
it("ZEN MODE - enough damage to change form", async() => {
|
||||||
|
const moveToUse = Moves.SPLASH;
|
||||||
|
await game.startBattle([
|
||||||
|
Species.DARMANITAN,
|
||||||
|
]);
|
||||||
|
game.scene.getParty()[0].stats[Stat.SPD] = 1;
|
||||||
|
game.scene.getParty()[0].stats[Stat.HP] = 1000;
|
||||||
|
game.scene.getParty()[0].hp = 100;
|
||||||
|
expect(game.scene.getParty()[0].formIndex).toBe(0);
|
||||||
|
|
||||||
|
game.onNextPrompt("CommandPhase", Mode.COMMAND, () => {
|
||||||
|
game.scene.ui.setMode(Mode.FIGHT, (game.scene.getCurrentPhase() as CommandPhase).getFieldIndex());
|
||||||
|
});
|
||||||
|
game.onNextPrompt("CommandPhase", Mode.FIGHT, () => {
|
||||||
|
const movePosition = getMovePosition(game.scene, 0, moveToUse);
|
||||||
|
(game.scene.getCurrentPhase() as CommandPhase).handleCommand(Command.FIGHT, movePosition, false);
|
||||||
|
});
|
||||||
|
await game.phaseInterceptor.runFrom(EnemyCommandPhase).to(QuietFormChangePhase);
|
||||||
|
await game.phaseInterceptor.to(TurnInitPhase, false);
|
||||||
|
expect(game.scene.getParty()[0].hp).not.toBe(100);
|
||||||
|
expect(game.scene.getParty()[0].formIndex).not.toBe(0);
|
||||||
|
}, 20000);
|
||||||
|
|
||||||
|
it("ZEN MODE - kill pokemon while on zen mode", async() => {
|
||||||
|
const moveToUse = Moves.SPLASH;
|
||||||
|
await game.startBattle([
|
||||||
|
Species.DARMANITAN,
|
||||||
|
Species.CHARIZARD,
|
||||||
|
]);
|
||||||
|
game.scene.getParty()[0].stats[Stat.SPD] = 1;
|
||||||
|
game.scene.getParty()[0].stats[Stat.HP] = 1000;
|
||||||
|
game.scene.getParty()[0].hp = 100;
|
||||||
|
expect(game.scene.getParty()[0].formIndex).toBe(0);
|
||||||
|
|
||||||
|
game.onNextPrompt("CommandPhase", Mode.COMMAND, () => {
|
||||||
|
game.scene.ui.setMode(Mode.FIGHT, (game.scene.getCurrentPhase() as CommandPhase).getFieldIndex());
|
||||||
|
});
|
||||||
|
game.onNextPrompt("CommandPhase", Mode.FIGHT, () => {
|
||||||
|
const movePosition = getMovePosition(game.scene, 0, moveToUse);
|
||||||
|
(game.scene.getCurrentPhase() as CommandPhase).handleCommand(Command.FIGHT, movePosition, false);
|
||||||
|
});
|
||||||
|
await game.phaseInterceptor.runFrom(EnemyCommandPhase).to(DamagePhase, false);
|
||||||
|
// await game.phaseInterceptor.runFrom(DamagePhase).to(DamagePhase, false);
|
||||||
|
const damagePhase = game.scene.getCurrentPhase() as DamagePhase;
|
||||||
|
damagePhase.updateAmount(80);
|
||||||
|
await game.phaseInterceptor.runFrom(DamagePhase).to(QuietFormChangePhase);
|
||||||
|
expect(game.scene.getParty()[0].hp).not.toBe(100);
|
||||||
|
expect(game.scene.getParty()[0].formIndex).not.toBe(0);
|
||||||
|
await game.killPokemon(game.scene.getParty()[0]);
|
||||||
|
expect(game.scene.getParty()[0].isFainted()).toBe(true);
|
||||||
|
await game.phaseInterceptor.run(MessagePhase);
|
||||||
|
await game.phaseInterceptor.run(EnemyCommandPhase);
|
||||||
|
await game.phaseInterceptor.run(TurnStartPhase);
|
||||||
|
game.onNextPrompt("SwitchPhase", Mode.PARTY, () => {
|
||||||
|
game.scene.unshiftPhase(new SwitchSummonPhase(game.scene, 0, 1, false, false));
|
||||||
|
game.scene.ui.setMode(Mode.MESSAGE);
|
||||||
|
});
|
||||||
|
game.onNextPrompt("SwitchPhase", Mode.MESSAGE, () => {
|
||||||
|
game.endPhase();
|
||||||
|
});
|
||||||
|
await game.phaseInterceptor.run(SwitchPhase);
|
||||||
|
await game.phaseInterceptor.to(PostSummonPhase);
|
||||||
|
expect(game.scene.getParty()[1].formIndex).toBe(1);
|
||||||
|
}, 20000);
|
||||||
|
});
|
@ -6,7 +6,7 @@ import {Species} from "#app/data/enums/species";
|
|||||||
import * as overrides from "../../overrides";
|
import * as overrides from "../../overrides";
|
||||||
import {Command} from "#app/ui/command-ui-handler";
|
import {Command} from "#app/ui/command-ui-handler";
|
||||||
import {
|
import {
|
||||||
CommandPhase,
|
CommandPhase, DamagePhase,
|
||||||
EncounterPhase,
|
EncounterPhase,
|
||||||
EnemyCommandPhase,
|
EnemyCommandPhase,
|
||||||
LoginPhase,
|
LoginPhase,
|
||||||
@ -15,7 +15,7 @@ import {
|
|||||||
SelectStarterPhase,
|
SelectStarterPhase,
|
||||||
SummonPhase,
|
SummonPhase,
|
||||||
TitlePhase,
|
TitlePhase,
|
||||||
TurnInitPhase,
|
TurnInitPhase, VictoryPhase,
|
||||||
} from "#app/phases";
|
} from "#app/phases";
|
||||||
import {Moves} from "#app/data/enums/moves";
|
import {Moves} from "#app/data/enums/moves";
|
||||||
import GameManager from "#app/test/utils/gameManager";
|
import GameManager from "#app/test/utils/gameManager";
|
||||||
@ -106,9 +106,7 @@ describe("Test Battle Phase", () => {
|
|||||||
const movePosition = getMovePosition(game.scene, 0, Moves.TACKLE);
|
const movePosition = getMovePosition(game.scene, 0, Moves.TACKLE);
|
||||||
(game.scene.getCurrentPhase() as CommandPhase).handleCommand(Command.FIGHT, movePosition, false);
|
(game.scene.getCurrentPhase() as CommandPhase).handleCommand(Command.FIGHT, movePosition, false);
|
||||||
});
|
});
|
||||||
await game.phaseInterceptor.runFrom(EnemyCommandPhase).to(SelectModifierPhase);
|
await game.phaseInterceptor.runFrom(EnemyCommandPhase).to(SelectModifierPhase, false);
|
||||||
expect(game.scene.ui?.getMode()).toBe(Mode.MODIFIER_SELECT);
|
|
||||||
expect(game.scene.getCurrentPhase().constructor.name).toBe(SelectModifierPhase.name);
|
|
||||||
}, 20000);
|
}, 20000);
|
||||||
|
|
||||||
it("do attack wave 3 - single battle - regular - NO OHKO with opponent using non damage attack", async() => {
|
it("do attack wave 3 - single battle - regular - NO OHKO with opponent using non damage attack", async() => {
|
||||||
@ -128,7 +126,7 @@ describe("Test Battle Phase", () => {
|
|||||||
const movePosition = getMovePosition(game.scene, 0, Moves.TACKLE);
|
const movePosition = getMovePosition(game.scene, 0, Moves.TACKLE);
|
||||||
(game.scene.getCurrentPhase() as CommandPhase).handleCommand(Command.FIGHT, movePosition, false);
|
(game.scene.getCurrentPhase() as CommandPhase).handleCommand(Command.FIGHT, movePosition, false);
|
||||||
});
|
});
|
||||||
await game.phaseInterceptor.runFrom(EnemyCommandPhase).to(TurnInitPhase);
|
await game.phaseInterceptor.runFrom(EnemyCommandPhase).to(TurnInitPhase, false);
|
||||||
}, 20000);
|
}, 20000);
|
||||||
|
|
||||||
it("load 100% data file", async() => {
|
it("load 100% data file", async() => {
|
||||||
@ -259,5 +257,71 @@ describe("Test Battle Phase", () => {
|
|||||||
expect(game.scene.ui?.getMode()).toBe(Mode.COMMAND);
|
expect(game.scene.ui?.getMode()).toBe(Mode.COMMAND);
|
||||||
expect(game.scene.getCurrentPhase().constructor.name).toBe(CommandPhase.name);
|
expect(game.scene.getCurrentPhase().constructor.name).toBe(CommandPhase.name);
|
||||||
}, 20000);
|
}, 20000);
|
||||||
|
|
||||||
|
it("kill opponent pokemon", async() => {
|
||||||
|
const moveToUse = Moves.SPLASH;
|
||||||
|
vi.spyOn(overrides, "SINGLE_BATTLE_OVERRIDE", "get").mockReturnValue(true);
|
||||||
|
vi.spyOn(overrides, "STARTER_SPECIES_OVERRIDE", "get").mockReturnValue(Species.MEWTWO);
|
||||||
|
vi.spyOn(overrides, "OPP_SPECIES_OVERRIDE", "get").mockReturnValue(Species.RATTATA);
|
||||||
|
vi.spyOn(overrides, "OPP_ABILITY_OVERRIDE", "get").mockReturnValue(Abilities.HYDRATION);
|
||||||
|
vi.spyOn(overrides, "ABILITY_OVERRIDE", "get").mockReturnValue(Abilities.ZEN_MODE);
|
||||||
|
vi.spyOn(overrides, "STARTING_LEVEL_OVERRIDE", "get").mockReturnValue(2000);
|
||||||
|
vi.spyOn(overrides, "STARTING_WAVE_OVERRIDE", "get").mockReturnValue(3);
|
||||||
|
vi.spyOn(overrides, "MOVESET_OVERRIDE", "get").mockReturnValue([moveToUse]);
|
||||||
|
vi.spyOn(overrides, "OPP_MOVESET_OVERRIDE", "get").mockReturnValue([Moves.TACKLE,Moves.TACKLE,Moves.TACKLE,Moves.TACKLE]);
|
||||||
|
await game.startBattle([
|
||||||
|
Species.DARMANITAN,
|
||||||
|
Species.CHARIZARD,
|
||||||
|
]);
|
||||||
|
|
||||||
|
game.onNextPrompt("CommandPhase", Mode.COMMAND, () => {
|
||||||
|
game.scene.ui.setMode(Mode.FIGHT, (game.scene.getCurrentPhase() as CommandPhase).getFieldIndex());
|
||||||
|
});
|
||||||
|
game.onNextPrompt("CommandPhase", Mode.FIGHT, () => {
|
||||||
|
const movePosition = getMovePosition(game.scene, 0, moveToUse);
|
||||||
|
(game.scene.getCurrentPhase() as CommandPhase).handleCommand(Command.FIGHT, movePosition, false);
|
||||||
|
});
|
||||||
|
await game.phaseInterceptor.to(DamagePhase, false);
|
||||||
|
await game.killPokemon(game.scene.currentBattle.enemyParty[0]);
|
||||||
|
expect(game.scene.currentBattle.enemyParty[0].isFainted()).toBe(true);
|
||||||
|
await game.phaseInterceptor.to(VictoryPhase, false);
|
||||||
|
}, 200000);
|
||||||
|
|
||||||
|
it("to next turn", async() => {
|
||||||
|
const moveToUse = Moves.SPLASH;
|
||||||
|
vi.spyOn(overrides, "SINGLE_BATTLE_OVERRIDE", "get").mockReturnValue(true);
|
||||||
|
vi.spyOn(overrides, "STARTER_SPECIES_OVERRIDE", "get").mockReturnValue(Species.MEWTWO);
|
||||||
|
vi.spyOn(overrides, "OPP_SPECIES_OVERRIDE", "get").mockReturnValue(Species.RATTATA);
|
||||||
|
vi.spyOn(overrides, "OPP_ABILITY_OVERRIDE", "get").mockReturnValue(Abilities.HYDRATION);
|
||||||
|
vi.spyOn(overrides, "ABILITY_OVERRIDE", "get").mockReturnValue(Abilities.ZEN_MODE);
|
||||||
|
vi.spyOn(overrides, "STARTING_LEVEL_OVERRIDE", "get").mockReturnValue(2000);
|
||||||
|
vi.spyOn(overrides, "STARTING_WAVE_OVERRIDE", "get").mockReturnValue(3);
|
||||||
|
vi.spyOn(overrides, "MOVESET_OVERRIDE", "get").mockReturnValue([moveToUse]);
|
||||||
|
vi.spyOn(overrides, "OPP_MOVESET_OVERRIDE", "get").mockReturnValue([Moves.TACKLE,Moves.TACKLE,Moves.TACKLE,Moves.TACKLE]);
|
||||||
|
await game.startBattle();
|
||||||
|
const turn = game.scene.currentBattle.turn;
|
||||||
|
game.doAttack(0);
|
||||||
|
await game.toNextTurn();
|
||||||
|
expect(game.scene.currentBattle.turn).toBeGreaterThan(turn);
|
||||||
|
}, 20000);
|
||||||
|
|
||||||
|
it("to next wave with pokemon killed, single", async() => {
|
||||||
|
const moveToUse = Moves.SPLASH;
|
||||||
|
vi.spyOn(overrides, "SINGLE_BATTLE_OVERRIDE", "get").mockReturnValue(true);
|
||||||
|
vi.spyOn(overrides, "STARTER_SPECIES_OVERRIDE", "get").mockReturnValue(Species.MEWTWO);
|
||||||
|
vi.spyOn(overrides, "OPP_SPECIES_OVERRIDE", "get").mockReturnValue(Species.RATTATA);
|
||||||
|
vi.spyOn(overrides, "OPP_ABILITY_OVERRIDE", "get").mockReturnValue(Abilities.HYDRATION);
|
||||||
|
vi.spyOn(overrides, "ABILITY_OVERRIDE", "get").mockReturnValue(Abilities.ZEN_MODE);
|
||||||
|
vi.spyOn(overrides, "STARTING_LEVEL_OVERRIDE", "get").mockReturnValue(2000);
|
||||||
|
vi.spyOn(overrides, "STARTING_WAVE_OVERRIDE", "get").mockReturnValue(3);
|
||||||
|
vi.spyOn(overrides, "MOVESET_OVERRIDE", "get").mockReturnValue([moveToUse]);
|
||||||
|
vi.spyOn(overrides, "OPP_MOVESET_OVERRIDE", "get").mockReturnValue([Moves.TACKLE,Moves.TACKLE,Moves.TACKLE,Moves.TACKLE]);
|
||||||
|
await game.startBattle();
|
||||||
|
const waveIndex = game.scene.currentBattle.waveIndex;
|
||||||
|
game.doAttack(0);
|
||||||
|
await game.doKillOpponents();
|
||||||
|
await game.toNextWave();
|
||||||
|
expect(game.scene.currentBattle.waveIndex).toBeGreaterThan(waveIndex);
|
||||||
|
}, 20000);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import {afterEach, beforeAll, beforeEach, describe, it, vi} from "vitest";
|
import {afterEach, beforeAll, beforeEach, describe, expect, it, vi} from "vitest";
|
||||||
import GameManager from "#app/test/utils/gameManager";
|
import GameManager from "#app/test/utils/gameManager";
|
||||||
import Phaser from "phaser";
|
import Phaser from "phaser";
|
||||||
import * as overrides from "#app/overrides";
|
import * as overrides from "#app/overrides";
|
||||||
@ -22,18 +22,24 @@ describe("Test Battle Phase", () => {
|
|||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
game = new GameManager(phaserGame);
|
game = new GameManager(phaserGame);
|
||||||
});
|
const moveToUse = Moves.SPLASH;
|
||||||
|
vi.spyOn(overrides, "SINGLE_BATTLE_OVERRIDE", "get").mockReturnValue(true);
|
||||||
it("should start phase", async() => {
|
|
||||||
vi.spyOn(overrides, "STARTER_SPECIES_OVERRIDE", "get").mockReturnValue(Species.MEWTWO);
|
vi.spyOn(overrides, "STARTER_SPECIES_OVERRIDE", "get").mockReturnValue(Species.MEWTWO);
|
||||||
vi.spyOn(overrides, "OPP_SPECIES_OVERRIDE", "get").mockReturnValue(Species.RATTATA);
|
vi.spyOn(overrides, "OPP_SPECIES_OVERRIDE", "get").mockReturnValue(Species.RATTATA);
|
||||||
|
vi.spyOn(overrides, "OPP_ABILITY_OVERRIDE", "get").mockReturnValue(Abilities.HYDRATION);
|
||||||
|
vi.spyOn(overrides, "ABILITY_OVERRIDE", "get").mockReturnValue(Abilities.ZEN_MODE);
|
||||||
vi.spyOn(overrides, "STARTING_LEVEL_OVERRIDE", "get").mockReturnValue(2000);
|
vi.spyOn(overrides, "STARTING_LEVEL_OVERRIDE", "get").mockReturnValue(2000);
|
||||||
vi.spyOn(overrides, "STARTING_WAVE_OVERRIDE", "get").mockReturnValue(3);
|
vi.spyOn(overrides, "STARTING_WAVE_OVERRIDE", "get").mockReturnValue(3);
|
||||||
vi.spyOn(overrides, "MOVESET_OVERRIDE", "get").mockReturnValue([Moves.TACKLE]);
|
vi.spyOn(overrides, "MOVESET_OVERRIDE", "get").mockReturnValue([moveToUse]);
|
||||||
vi.spyOn(overrides, "OPP_ABILITY_OVERRIDE", "get").mockReturnValue(Abilities.HYDRATION);
|
vi.spyOn(overrides, "OPP_MOVESET_OVERRIDE", "get").mockReturnValue([Moves.TACKLE,Moves.TACKLE,Moves.TACKLE,Moves.TACKLE]);
|
||||||
vi.spyOn(overrides, "OPP_MOVESET_OVERRIDE", "get").mockReturnValue([Moves.TACKLE, Moves.TACKLE, Moves.TACKLE, Moves.TACKLE]);
|
});
|
||||||
vi.spyOn(overrides, "SINGLE_BATTLE_OVERRIDE", "get").mockReturnValue(true);
|
|
||||||
|
it.skip("to next turn", async() => {
|
||||||
await game.startBattle();
|
await game.startBattle();
|
||||||
}, 100000);
|
const turn = game.scene.currentBattle.turn;
|
||||||
|
game.doAttack(0);
|
||||||
|
await game.toNextTurn();
|
||||||
|
expect(game.scene.currentBattle.turn).toBeGreaterThan(turn);
|
||||||
|
}, 20000);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
137
src/test/battle/special_battle.test.ts
Normal file
@ -0,0 +1,137 @@
|
|||||||
|
import {afterEach, beforeAll, beforeEach, describe, expect, it, vi} from "vitest";
|
||||||
|
import {Mode} from "#app/ui/ui";
|
||||||
|
import {Species} from "#app/data/enums/species";
|
||||||
|
import * as overrides from "../../overrides";
|
||||||
|
import {
|
||||||
|
CommandPhase,
|
||||||
|
} from "#app/phases";
|
||||||
|
import {Moves} from "#app/data/enums/moves";
|
||||||
|
import GameManager from "#app/test/utils/gameManager";
|
||||||
|
import Phaser from "phaser";
|
||||||
|
import {Abilities} from "#app/data/enums/abilities";
|
||||||
|
|
||||||
|
describe("Test Battle Phase", () => {
|
||||||
|
let phaserGame: Phaser.Game;
|
||||||
|
let game: GameManager;
|
||||||
|
|
||||||
|
beforeAll(() => {
|
||||||
|
phaserGame = new Phaser.Game({
|
||||||
|
type: Phaser.HEADLESS,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
game.phaseInterceptor.restoreOg();
|
||||||
|
});
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
game = new GameManager(phaserGame);
|
||||||
|
vi.spyOn(overrides, "OPP_SPECIES_OVERRIDE", "get").mockReturnValue(Species.RATTATA);
|
||||||
|
vi.spyOn(overrides, "STARTING_LEVEL_OVERRIDE", "get").mockReturnValue(2000);
|
||||||
|
vi.spyOn(overrides, "MOVESET_OVERRIDE", "get").mockReturnValue([Moves.TACKLE]);
|
||||||
|
vi.spyOn(overrides, "OPP_ABILITY_OVERRIDE", "get").mockReturnValue(Abilities.HYDRATION);
|
||||||
|
vi.spyOn(overrides, "ABILITY_OVERRIDE", "get").mockReturnValue(Abilities.HYDRATION);
|
||||||
|
vi.spyOn(overrides, "OPP_MOVESET_OVERRIDE", "get").mockReturnValue([Moves.TACKLE, Moves.TACKLE, Moves.TACKLE, Moves.TACKLE]);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("startBattle 2vs1 boss", async() => {
|
||||||
|
vi.spyOn(overrides, "SINGLE_BATTLE_OVERRIDE", "get").mockReturnValue(true);
|
||||||
|
vi.spyOn(overrides, "STARTING_WAVE_OVERRIDE", "get").mockReturnValue(10);
|
||||||
|
await game.startBattle([
|
||||||
|
Species.BLASTOISE,
|
||||||
|
Species.CHARIZARD,
|
||||||
|
]);
|
||||||
|
expect(game.scene.ui?.getMode()).toBe(Mode.COMMAND);
|
||||||
|
expect(game.scene.getCurrentPhase().constructor.name).toBe(CommandPhase.name);
|
||||||
|
}, 20000);
|
||||||
|
|
||||||
|
it("startBattle 2vs2 boss", async() => {
|
||||||
|
vi.spyOn(overrides, "DOUBLE_BATTLE_OVERRIDE", "get").mockReturnValue(true);
|
||||||
|
vi.spyOn(overrides, "STARTING_WAVE_OVERRIDE", "get").mockReturnValue(10);
|
||||||
|
await game.startBattle([
|
||||||
|
Species.BLASTOISE,
|
||||||
|
Species.CHARIZARD,
|
||||||
|
]);
|
||||||
|
expect(game.scene.ui?.getMode()).toBe(Mode.COMMAND);
|
||||||
|
expect(game.scene.getCurrentPhase().constructor.name).toBe(CommandPhase.name);
|
||||||
|
}, 20000);
|
||||||
|
|
||||||
|
it("startBattle 2vs2 trainer", async() => {
|
||||||
|
vi.spyOn(overrides, "DOUBLE_BATTLE_OVERRIDE", "get").mockReturnValue(true);
|
||||||
|
vi.spyOn(overrides, "STARTING_WAVE_OVERRIDE", "get").mockReturnValue(5);
|
||||||
|
await game.startBattle([
|
||||||
|
Species.BLASTOISE,
|
||||||
|
Species.CHARIZARD,
|
||||||
|
]);
|
||||||
|
expect(game.scene.ui?.getMode()).toBe(Mode.COMMAND);
|
||||||
|
expect(game.scene.getCurrentPhase().constructor.name).toBe(CommandPhase.name);
|
||||||
|
}, 20000);
|
||||||
|
|
||||||
|
it("startBattle 2vs1 trainer", async() => {
|
||||||
|
vi.spyOn(overrides, "SINGLE_BATTLE_OVERRIDE", "get").mockReturnValue(true);
|
||||||
|
vi.spyOn(overrides, "STARTING_WAVE_OVERRIDE", "get").mockReturnValue(5);
|
||||||
|
await game.startBattle([
|
||||||
|
Species.BLASTOISE,
|
||||||
|
Species.CHARIZARD,
|
||||||
|
]);
|
||||||
|
expect(game.scene.ui?.getMode()).toBe(Mode.COMMAND);
|
||||||
|
expect(game.scene.getCurrentPhase().constructor.name).toBe(CommandPhase.name);
|
||||||
|
}, 20000);
|
||||||
|
|
||||||
|
it("startBattle 2vs1 rival", async() => {
|
||||||
|
vi.spyOn(overrides, "SINGLE_BATTLE_OVERRIDE", "get").mockReturnValue(true);
|
||||||
|
vi.spyOn(overrides, "STARTING_WAVE_OVERRIDE", "get").mockReturnValue(8);
|
||||||
|
await game.startBattle([
|
||||||
|
Species.BLASTOISE,
|
||||||
|
Species.CHARIZARD,
|
||||||
|
]);
|
||||||
|
expect(game.scene.ui?.getMode()).toBe(Mode.COMMAND);
|
||||||
|
expect(game.scene.getCurrentPhase().constructor.name).toBe(CommandPhase.name);
|
||||||
|
}, 20000);
|
||||||
|
|
||||||
|
it("startBattle 2vs2 rival", async() => {
|
||||||
|
vi.spyOn(overrides, "DOUBLE_BATTLE_OVERRIDE", "get").mockReturnValue(true);
|
||||||
|
vi.spyOn(overrides, "STARTING_WAVE_OVERRIDE", "get").mockReturnValue(8);
|
||||||
|
await game.startBattle([
|
||||||
|
Species.BLASTOISE,
|
||||||
|
Species.CHARIZARD,
|
||||||
|
]);
|
||||||
|
expect(game.scene.ui?.getMode()).toBe(Mode.COMMAND);
|
||||||
|
expect(game.scene.getCurrentPhase().constructor.name).toBe(CommandPhase.name);
|
||||||
|
}, 20000);
|
||||||
|
|
||||||
|
it("startBattle 1vs1 trainer", async() => {
|
||||||
|
vi.spyOn(overrides, "SINGLE_BATTLE_OVERRIDE", "get").mockReturnValue(true);
|
||||||
|
vi.spyOn(overrides, "STARTING_WAVE_OVERRIDE", "get").mockReturnValue(5);
|
||||||
|
await game.startBattle([
|
||||||
|
Species.BLASTOISE,
|
||||||
|
]);
|
||||||
|
expect(game.scene.ui?.getMode()).toBe(Mode.COMMAND);
|
||||||
|
expect(game.scene.getCurrentPhase().constructor.name).toBe(CommandPhase.name);
|
||||||
|
}, 20000);
|
||||||
|
|
||||||
|
it("startBattle 2vs2 trainer", async() => {
|
||||||
|
vi.spyOn(overrides, "DOUBLE_BATTLE_OVERRIDE", "get").mockReturnValue(true);
|
||||||
|
vi.spyOn(overrides, "STARTING_WAVE_OVERRIDE", "get").mockReturnValue(5);
|
||||||
|
await game.startBattle([
|
||||||
|
Species.BLASTOISE,
|
||||||
|
Species.CHARIZARD,
|
||||||
|
]);
|
||||||
|
expect(game.scene.ui?.getMode()).toBe(Mode.COMMAND);
|
||||||
|
expect(game.scene.getCurrentPhase().constructor.name).toBe(CommandPhase.name);
|
||||||
|
}, 20000);
|
||||||
|
|
||||||
|
it("startBattle 4vs2 trainer", async() => {
|
||||||
|
vi.spyOn(overrides, "DOUBLE_BATTLE_OVERRIDE", "get").mockReturnValue(true);
|
||||||
|
vi.spyOn(overrides, "STARTING_WAVE_OVERRIDE", "get").mockReturnValue(5);
|
||||||
|
await game.startBattle([
|
||||||
|
Species.BLASTOISE,
|
||||||
|
Species.CHARIZARD,
|
||||||
|
Species.DARKRAI,
|
||||||
|
Species.GABITE,
|
||||||
|
]);
|
||||||
|
expect(game.scene.ui?.getMode()).toBe(Mode.COMMAND);
|
||||||
|
expect(game.scene.getCurrentPhase().constructor.name).toBe(CommandPhase.name);
|
||||||
|
}, 20000);
|
||||||
|
});
|
||||||
|
|
@ -11,6 +11,6 @@ export default class TextInterceptor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
getLatestMessage(): string {
|
getLatestMessage(): string {
|
||||||
return this.logs[this.logs.length - 1];
|
return this.logs.pop();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,18 +4,18 @@ import {generateStarter, waitUntil} from "#app/test/utils/gameManagerUtils";
|
|||||||
import {
|
import {
|
||||||
CommandPhase,
|
CommandPhase,
|
||||||
EncounterPhase,
|
EncounterPhase,
|
||||||
LoginPhase,
|
FaintPhase,
|
||||||
PostSummonPhase,
|
LoginPhase, NewBattlePhase,
|
||||||
SelectGenderPhase,
|
SelectGenderPhase,
|
||||||
SelectStarterPhase,
|
SelectStarterPhase,
|
||||||
TitlePhase,
|
TitlePhase, TurnInitPhase,
|
||||||
} from "#app/phases";
|
} from "#app/phases";
|
||||||
import BattleScene from "#app/battle-scene.js";
|
import BattleScene from "#app/battle-scene.js";
|
||||||
import PhaseInterceptor from "#app/test/utils/phaseInterceptor";
|
import PhaseInterceptor from "#app/test/utils/phaseInterceptor";
|
||||||
import TextInterceptor from "#app/test/utils/TextInterceptor";
|
import TextInterceptor from "#app/test/utils/TextInterceptor";
|
||||||
import {GameModes, getGameMode} from "#app/game-mode";
|
import {GameModes, getGameMode} from "#app/game-mode";
|
||||||
import fs from "fs";
|
import fs from "fs";
|
||||||
import { AES, enc } from "crypto-js";
|
import {AES, enc} from "crypto-js";
|
||||||
import {updateUserInfo} from "#app/account";
|
import {updateUserInfo} from "#app/account";
|
||||||
import {Species} from "#app/data/enums/species";
|
import {Species} from "#app/data/enums/species";
|
||||||
import {PlayerGender} from "#app/data/enums/player-gender";
|
import {PlayerGender} from "#app/data/enums/player-gender";
|
||||||
@ -23,6 +23,11 @@ import {GameDataType} from "#app/data/enums/game-data-type";
|
|||||||
import InputsHandler from "#app/test/utils/inputsHandler";
|
import InputsHandler from "#app/test/utils/inputsHandler";
|
||||||
import {ExpNotification} from "#app/enums/exp-notification";
|
import {ExpNotification} from "#app/enums/exp-notification";
|
||||||
import ErrorInterceptor from "#app/test/utils/errorInterceptor";
|
import ErrorInterceptor from "#app/test/utils/errorInterceptor";
|
||||||
|
import {EnemyPokemon, PlayerPokemon} from "#app/field/pokemon";
|
||||||
|
import {MockClock} from "#app/test/utils/mocks/mockClock";
|
||||||
|
import {Command} from "#app/ui/command-ui-handler";
|
||||||
|
import ModifierSelectUiHandler from "#app/ui/modifier-select-ui-handler";
|
||||||
|
import {Button} from "#app/enums/buttons";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class to manage the game state and transitions between phases.
|
* Class to manage the game state and transitions between phases.
|
||||||
@ -84,31 +89,31 @@ export default class GameManager {
|
|||||||
* @param callback - The callback to execute.
|
* @param callback - The callback to execute.
|
||||||
* @param expireFn - Optional function to determine if the prompt has expired.
|
* @param expireFn - Optional function to determine if the prompt has expired.
|
||||||
*/
|
*/
|
||||||
onNextPrompt(phaseTarget: string, mode: Mode, callback: () => void, expireFn?: () => void) {
|
onNextPrompt(phaseTarget: string, mode: Mode, callback: () => void, expireFn?: () => void, awaitingActionInput: boolean = false) {
|
||||||
this.phaseInterceptor.addToNextPrompt(phaseTarget, mode, callback, expireFn);
|
this.phaseInterceptor.addToNextPrompt(phaseTarget, mode, callback, expireFn, awaitingActionInput);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Runs the game to the title phase.
|
* Runs the game to the title phase.
|
||||||
* @returns A promise that resolves when the title phase is reached.
|
* @returns A promise that resolves when the title phase is reached.
|
||||||
*/
|
*/
|
||||||
runToTitle(): Promise<void> {
|
async runToTitle(): Promise<void> {
|
||||||
return new Promise(async(resolve, reject) => {
|
await this.phaseInterceptor.run(LoginPhase);
|
||||||
await this.phaseInterceptor.run(LoginPhase).catch((e) => reject(e));
|
|
||||||
this.onNextPrompt("SelectGenderPhase", Mode.OPTION_SELECT, () => {
|
this.onNextPrompt("SelectGenderPhase", Mode.OPTION_SELECT, () => {
|
||||||
this.scene.gameData.gender = PlayerGender.MALE;
|
this.scene.gameData.gender = PlayerGender.MALE;
|
||||||
this.endPhase();
|
this.endPhase();
|
||||||
}, () => this.isCurrentPhase(TitlePhase));
|
}, () => this.isCurrentPhase(TitlePhase));
|
||||||
await this.phaseInterceptor.run(SelectGenderPhase, () => this.isCurrentPhase(TitlePhase)).catch((e) => reject(e));
|
|
||||||
await this.phaseInterceptor.run(TitlePhase).catch((e) => reject(e));
|
await this.phaseInterceptor.run(SelectGenderPhase, () => this.isCurrentPhase(TitlePhase));
|
||||||
this.scene.gameSpeed = 5;
|
await this.phaseInterceptor.run(TitlePhase);
|
||||||
this.scene.moveAnimations = false;
|
|
||||||
this.scene.showLevelUpStats = false;
|
this.scene.gameSpeed = 5;
|
||||||
this.scene.expGainsSpeed = 3;
|
this.scene.moveAnimations = false;
|
||||||
this.scene.expParty = ExpNotification.SKIP;
|
this.scene.showLevelUpStats = false;
|
||||||
this.scene.hpBarSpeed = 3;
|
this.scene.expGainsSpeed = 3;
|
||||||
resolve();
|
this.scene.expParty = ExpNotification.SKIP;
|
||||||
});
|
this.scene.hpBarSpeed = 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -116,41 +121,91 @@ export default class GameManager {
|
|||||||
* @param species - Optional array of species to summon.
|
* @param species - Optional array of species to summon.
|
||||||
* @returns A promise that resolves when the summon phase is reached.
|
* @returns A promise that resolves when the summon phase is reached.
|
||||||
*/
|
*/
|
||||||
runToSummon(species?: Species[]): Promise<void> {
|
async runToSummon(species?: Species[]) {
|
||||||
return new Promise(async(resolve, reject) => {
|
await this.runToTitle();
|
||||||
await this.runToTitle().catch((e) => reject(e));
|
|
||||||
this.onNextPrompt("TitlePhase", Mode.TITLE, () => {
|
this.onNextPrompt("TitlePhase", Mode.TITLE, () => {
|
||||||
this.scene.gameMode = getGameMode(GameModes.CLASSIC);
|
this.scene.gameMode = getGameMode(GameModes.CLASSIC);
|
||||||
const starters = generateStarter(this.scene, species);
|
const starters = generateStarter(this.scene, species);
|
||||||
const selectStarterPhase = new SelectStarterPhase(this.scene);
|
const selectStarterPhase = new SelectStarterPhase(this.scene);
|
||||||
this.scene.pushPhase(new EncounterPhase(this.scene, false));
|
this.scene.pushPhase(new EncounterPhase(this.scene, false));
|
||||||
selectStarterPhase.initBattle(starters);
|
selectStarterPhase.initBattle(starters);
|
||||||
});
|
|
||||||
await this.phaseInterceptor.run(EncounterPhase).catch((e) => reject(e));
|
|
||||||
resolve();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
await this.phaseInterceptor.run(EncounterPhase);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Starts a battle.
|
* Transitions to the start of a battle.
|
||||||
* @param species - Optional array of species to start the battle with.
|
* @param species - Optional array of species to start the battle with.
|
||||||
* @returns A promise that resolves when the battle is started.
|
* @returns A promise that resolves when the battle is started.
|
||||||
*/
|
*/
|
||||||
startBattle(species?: Species[]): Promise<void> {
|
async startBattle(species?: Species[]) {
|
||||||
return new Promise(async(resolve, reject) => {
|
await this.runToSummon(species);
|
||||||
await this.runToSummon(species).catch((e) => reject(e));
|
|
||||||
this.onNextPrompt("CheckSwitchPhase", Mode.CONFIRM, () => {
|
this.onNextPrompt("CheckSwitchPhase", Mode.CONFIRM, () => {
|
||||||
this.setMode(Mode.MESSAGE);
|
this.setMode(Mode.MESSAGE);
|
||||||
this.endPhase();
|
this.endPhase();
|
||||||
}, () => this.isCurrentPhase(CommandPhase));
|
}, () => this.isCurrentPhase(CommandPhase) || this.isCurrentPhase(TurnInitPhase));
|
||||||
this.onNextPrompt("CheckSwitchPhase", Mode.CONFIRM, () => {
|
|
||||||
this.setMode(Mode.MESSAGE);
|
this.onNextPrompt("CheckSwitchPhase", Mode.CONFIRM, () => {
|
||||||
this.endPhase();
|
this.setMode(Mode.MESSAGE);
|
||||||
}, () => this.isCurrentPhase(CommandPhase));
|
this.endPhase();
|
||||||
await this.phaseInterceptor.runFrom(PostSummonPhase).to(CommandPhase).catch((e) => reject(e));
|
}, () => this.isCurrentPhase(CommandPhase) || this.isCurrentPhase(TurnInitPhase));
|
||||||
console.log("==================[New Turn]==================");
|
|
||||||
return resolve();
|
await this.phaseInterceptor.to(CommandPhase);
|
||||||
|
console.log("==================[New Turn]==================");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Emulate a player attack
|
||||||
|
* @param movePosition the index of the move in the pokemon's moveset array
|
||||||
|
*/
|
||||||
|
doAttack(movePosition: integer) {
|
||||||
|
this.onNextPrompt("CommandPhase", Mode.COMMAND, () => {
|
||||||
|
this.scene.ui.setMode(Mode.FIGHT, (this.scene.getCurrentPhase() as CommandPhase).getFieldIndex());
|
||||||
});
|
});
|
||||||
|
this.onNextPrompt("CommandPhase", Mode.FIGHT, () => {
|
||||||
|
(this.scene.getCurrentPhase() as CommandPhase).handleCommand(Command.FIGHT, movePosition, false);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Faint all opponents currently on the field */
|
||||||
|
async doKillOpponents() {
|
||||||
|
await this.killPokemon(this.scene.currentBattle.enemyParty[0]);
|
||||||
|
if (this.scene.currentBattle.double) {
|
||||||
|
await this.killPokemon(this.scene.currentBattle.enemyParty[1]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Emulate selecting a modifier (item) */
|
||||||
|
doSelectModifier() {
|
||||||
|
this.onNextPrompt("SelectModifierPhase", Mode.MODIFIER_SELECT, () => {
|
||||||
|
const handler = this.scene.ui.getHandler() as ModifierSelectUiHandler;
|
||||||
|
handler.processInput(Button.CANCEL);
|
||||||
|
}, () => this.isCurrentPhase(CommandPhase) || this.isCurrentPhase(NewBattlePhase), true);
|
||||||
|
|
||||||
|
this.onNextPrompt("SelectModifierPhase", Mode.CONFIRM, () => {
|
||||||
|
const handler = this.scene.ui.getHandler() as ModifierSelectUiHandler;
|
||||||
|
handler.processInput(Button.ACTION);
|
||||||
|
}, () => this.isCurrentPhase(CommandPhase) || this.isCurrentPhase(NewBattlePhase));
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Transition to the next upcoming {@linkcode CommandPhase} */
|
||||||
|
async toNextTurn() {
|
||||||
|
await this.phaseInterceptor.to(CommandPhase);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Emulate selecting a modifier (item) and transition to the next upcoming {@linkcode CommandPhase} */
|
||||||
|
async toNextWave() {
|
||||||
|
this.doSelectModifier();
|
||||||
|
|
||||||
|
this.onNextPrompt("CheckSwitchPhase", Mode.CONFIRM, () => {
|
||||||
|
this.setMode(Mode.MESSAGE);
|
||||||
|
this.endPhase();
|
||||||
|
}, () => this.isCurrentPhase(TurnInitPhase));
|
||||||
|
|
||||||
|
await this.toNextTurn();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -213,4 +268,15 @@ export default class GameManager {
|
|||||||
}
|
}
|
||||||
return updateUserInfo();
|
return updateUserInfo();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async killPokemon(pokemon: PlayerPokemon | EnemyPokemon) {
|
||||||
|
(this.scene.time as MockClock).overrideDelay = 0.01;
|
||||||
|
return new Promise<void>(async(resolve, reject) => {
|
||||||
|
pokemon.hp = 0;
|
||||||
|
this.scene.pushPhase(new FaintPhase(this.scene, pokemon.getBattlerIndex(), true));
|
||||||
|
await this.phaseInterceptor.to(FaintPhase).catch((e) => reject(e));
|
||||||
|
(this.scene.time as MockClock).overrideDelay = undefined;
|
||||||
|
resolve();
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -120,7 +120,7 @@ export default class GameWrapper {
|
|||||||
pause: () => null,
|
pause: () => null,
|
||||||
setRate: () => null,
|
setRate: () => null,
|
||||||
add: () => this.scene.sound,
|
add: () => this.scene.sound,
|
||||||
get: () => this.scene.sound,
|
get: () => ({...this.scene.sound, totalDuration: 0}),
|
||||||
getAllPlaying: () => [],
|
getAllPlaying: () => [],
|
||||||
manager: {
|
manager: {
|
||||||
game: this.game,
|
game: this.game,
|
||||||
@ -131,6 +131,13 @@ export default class GameWrapper {
|
|||||||
key: "",
|
key: "",
|
||||||
};
|
};
|
||||||
|
|
||||||
|
this.scene.cameras = {
|
||||||
|
main: {
|
||||||
|
setPostPipeline: () => null,
|
||||||
|
removePostPipeline: () => null,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
this.scene.tweens = {
|
this.scene.tweens = {
|
||||||
add: (data) => {
|
add: (data) => {
|
||||||
if (data.onComplete) {
|
if (data.onComplete) {
|
||||||
|
@ -2,8 +2,10 @@ import Clock = Phaser.Time.Clock;
|
|||||||
|
|
||||||
|
|
||||||
export class MockClock extends Clock {
|
export class MockClock extends Clock {
|
||||||
|
public overrideDelay: number;
|
||||||
constructor(scene) {
|
constructor(scene) {
|
||||||
super(scene);
|
super(scene);
|
||||||
|
this.overrideDelay = undefined;
|
||||||
setInterval(() => {
|
setInterval(() => {
|
||||||
/*
|
/*
|
||||||
To simulate frame update
|
To simulate frame update
|
||||||
@ -14,4 +16,9 @@ export class MockClock extends Clock {
|
|||||||
this.update(this.systems.game.loop.time, 100);
|
this.update(this.systems.game.loop.time, 100);
|
||||||
}, 100);
|
}, 100);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
addEvent(config: Phaser.Time.TimerEvent | Phaser.Types.Time.TimerEventConfig): Phaser.Time.TimerEvent {
|
||||||
|
const cfg = { ...config, delay: this.overrideDelay || config.delay};
|
||||||
|
return super.addEvent(cfg);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -143,6 +143,7 @@ export default class MockSprite {
|
|||||||
|
|
||||||
play() {
|
play() {
|
||||||
// return this.phaserSprite.play();
|
// return this.phaserSprite.play();
|
||||||
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
setPipelineData(key, value) {
|
setPipelineData(key, value) {
|
||||||
|
@ -8,6 +8,7 @@ export default class MockText {
|
|||||||
private textureManager;
|
private textureManager;
|
||||||
public list = [];
|
public list = [];
|
||||||
public style;
|
public style;
|
||||||
|
|
||||||
constructor(textureManager, x, y, content, styleOptions) {
|
constructor(textureManager, x, y, content, styleOptions) {
|
||||||
this.scene = textureManager.scene;
|
this.scene = textureManager.scene;
|
||||||
this.textureManager = textureManager;
|
this.textureManager = textureManager;
|
||||||
@ -138,6 +139,15 @@ export default class MockText {
|
|||||||
// return this.phaserText.setX(x);
|
// return this.phaserText.setX(x);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the position of this Game Object.
|
||||||
|
* @param x The x position of this Game Object. Default 0.
|
||||||
|
* @param y The y position of this Game Object. If not set it will use the `x` value. Default x.
|
||||||
|
* @param z The z position of this Game Object. Default 0.
|
||||||
|
* @param w The w position of this Game Object. Default 0.
|
||||||
|
*/
|
||||||
|
setPosition(x?: number, y?: number, z?: number, w?: number) { }
|
||||||
|
|
||||||
setText(text) {
|
setText(text) {
|
||||||
// Sets the text this Game Object will display.
|
// Sets the text this Game Object will display.
|
||||||
// return this.phaserText.setText(text);
|
// return this.phaserText.setText(text);
|
||||||
|
@ -1,17 +1,43 @@
|
|||||||
import {
|
import {
|
||||||
BattleEndPhase,
|
BattleEndPhase,
|
||||||
BerryPhase,
|
BerryPhase,
|
||||||
CheckSwitchPhase, CommandPhase, DamagePhase, EggLapsePhase,
|
CheckSwitchPhase,
|
||||||
EncounterPhase, EnemyCommandPhase, FaintPhase,
|
CommandPhase,
|
||||||
LoginPhase, MessagePhase, MoveEffectPhase, MoveEndPhase, MovePhase, NewBattlePhase, NextEncounterPhase,
|
DamagePhase,
|
||||||
|
EggLapsePhase,
|
||||||
|
EncounterPhase,
|
||||||
|
EnemyCommandPhase,
|
||||||
|
FaintPhase,
|
||||||
|
LoginPhase,
|
||||||
|
MessagePhase,
|
||||||
|
MoveEffectPhase,
|
||||||
|
MoveEndPhase,
|
||||||
|
MovePhase,
|
||||||
|
NewBattlePhase,
|
||||||
|
NextEncounterPhase,
|
||||||
PostSummonPhase,
|
PostSummonPhase,
|
||||||
SelectGenderPhase, SelectModifierPhase,
|
SelectGenderPhase,
|
||||||
SelectStarterPhase, SelectTargetPhase, ShinySparklePhase, ShowAbilityPhase, StatChangePhase, SummonPhase,
|
SelectModifierPhase,
|
||||||
TitlePhase, ToggleDoublePositionPhase, TurnEndPhase, TurnInitPhase, TurnStartPhase, UnavailablePhase, VictoryPhase
|
SelectStarterPhase,
|
||||||
|
SelectTargetPhase,
|
||||||
|
ShinySparklePhase,
|
||||||
|
ShowAbilityPhase,
|
||||||
|
StatChangePhase,
|
||||||
|
SummonPhase,
|
||||||
|
SwitchPhase,
|
||||||
|
SwitchSummonPhase,
|
||||||
|
TitlePhase,
|
||||||
|
ToggleDoublePositionPhase,
|
||||||
|
TurnEndPhase,
|
||||||
|
TurnInitPhase,
|
||||||
|
TurnStartPhase,
|
||||||
|
UnavailablePhase,
|
||||||
|
VictoryPhase
|
||||||
} from "#app/phases";
|
} from "#app/phases";
|
||||||
import UI, {Mode} from "#app/ui/ui";
|
import UI, {Mode} from "#app/ui/ui";
|
||||||
import {Phase} from "#app/phase";
|
import {Phase} from "#app/phase";
|
||||||
import ErrorInterceptor from "#app/test/utils/errorInterceptor";
|
import ErrorInterceptor from "#app/test/utils/errorInterceptor";
|
||||||
|
import {QuietFormChangePhase} from "#app/form-change-phase";
|
||||||
|
|
||||||
export default class PhaseInterceptor {
|
export default class PhaseInterceptor {
|
||||||
public scene;
|
public scene;
|
||||||
@ -63,10 +89,13 @@ export default class PhaseInterceptor {
|
|||||||
[ShinySparklePhase, this.startPhase],
|
[ShinySparklePhase, this.startPhase],
|
||||||
[SelectTargetPhase, this.startPhase],
|
[SelectTargetPhase, this.startPhase],
|
||||||
[UnavailablePhase, this.startPhase],
|
[UnavailablePhase, this.startPhase],
|
||||||
|
[QuietFormChangePhase, this.startPhase],
|
||||||
|
[SwitchPhase, this.startPhase],
|
||||||
|
[SwitchSummonPhase, this.startPhase],
|
||||||
];
|
];
|
||||||
|
|
||||||
private endBySetMode = [
|
private endBySetMode = [
|
||||||
TitlePhase, SelectGenderPhase, CommandPhase, SelectModifierPhase
|
TitlePhase, SelectGenderPhase, CommandPhase
|
||||||
];
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -78,8 +107,8 @@ export default class PhaseInterceptor {
|
|||||||
this.log = [];
|
this.log = [];
|
||||||
this.onHold = [];
|
this.onHold = [];
|
||||||
this.prompts = [];
|
this.prompts = [];
|
||||||
|
this.startPromptHandler();
|
||||||
this.initPhases();
|
this.initPhases();
|
||||||
this.startPromptHander();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
rejectAll(error) {
|
rejectAll(error) {
|
||||||
@ -109,8 +138,10 @@ export default class PhaseInterceptor {
|
|||||||
async to(phaseTo, runTarget: boolean = true): Promise<void> {
|
async to(phaseTo, runTarget: boolean = true): Promise<void> {
|
||||||
return new Promise(async (resolve, reject) => {
|
return new Promise(async (resolve, reject) => {
|
||||||
ErrorInterceptor.getInstance().add(this);
|
ErrorInterceptor.getInstance().add(this);
|
||||||
await this.run(this.phaseFrom).catch((e) => reject(e));
|
if (this.phaseFrom) {
|
||||||
this.phaseFrom = null;
|
await this.run(this.phaseFrom).catch((e) => reject(e));
|
||||||
|
this.phaseFrom = null;
|
||||||
|
}
|
||||||
const targetName = typeof phaseTo === "string" ? phaseTo : phaseTo.name;
|
const targetName = typeof phaseTo === "string" ? phaseTo : phaseTo.name;
|
||||||
this.intervalRun = setInterval(async() => {
|
this.intervalRun = setInterval(async() => {
|
||||||
const currentPhase = this.onHold?.length && this.onHold[0];
|
const currentPhase = this.onHold?.length && this.onHold[0];
|
||||||
@ -238,7 +269,6 @@ export default class PhaseInterceptor {
|
|||||||
*/
|
*/
|
||||||
superEndPhase() {
|
superEndPhase() {
|
||||||
const instance = this.scene.getCurrentPhase();
|
const instance = this.scene.getCurrentPhase();
|
||||||
console.log(`%c INTERCEPTED Super End Phase ${instance.constructor.name}`, "color:red;");
|
|
||||||
this.originalSuperEnd.apply(instance);
|
this.originalSuperEnd.apply(instance);
|
||||||
this.inProgress?.callback();
|
this.inProgress?.callback();
|
||||||
this.inProgress = undefined;
|
this.inProgress = undefined;
|
||||||
@ -253,6 +283,9 @@ export default class PhaseInterceptor {
|
|||||||
const instance = this.scene.ui;
|
const instance = this.scene.ui;
|
||||||
console.log("setMode", mode, args);
|
console.log("setMode", mode, args);
|
||||||
const ret = this.originalSetMode.apply(instance, [mode, ...args]);
|
const ret = this.originalSetMode.apply(instance, [mode, ...args]);
|
||||||
|
if (!this.phases[currentPhase.constructor.name]) {
|
||||||
|
throw new Error(`missing ${currentPhase.constructor.name} in phaseInterceptior PHASES list`);
|
||||||
|
}
|
||||||
if (this.phases[currentPhase.constructor.name].endBySetMode) {
|
if (this.phases[currentPhase.constructor.name].endBySetMode) {
|
||||||
this.inProgress?.callback();
|
this.inProgress?.callback();
|
||||||
this.inProgress = undefined;
|
this.inProgress = undefined;
|
||||||
@ -263,16 +296,17 @@ export default class PhaseInterceptor {
|
|||||||
/**
|
/**
|
||||||
* Method to start the prompt handler.
|
* Method to start the prompt handler.
|
||||||
*/
|
*/
|
||||||
startPromptHander() {
|
startPromptHandler() {
|
||||||
this.promptInterval = setInterval(() => {
|
this.promptInterval = setInterval(() => {
|
||||||
if (this.prompts.length) {
|
if (this.prompts.length) {
|
||||||
const actionForNextPrompt = this.prompts[0];
|
const actionForNextPrompt = this.prompts[0];
|
||||||
const expireFn = actionForNextPrompt.expireFn && actionForNextPrompt.expireFn();
|
const expireFn = actionForNextPrompt.expireFn && actionForNextPrompt.expireFn();
|
||||||
const currentMode = this.scene.ui.getMode();
|
const currentMode = this.scene.ui.getMode();
|
||||||
const currentPhase = this.scene.getCurrentPhase().constructor.name;
|
const currentPhase = this.scene.getCurrentPhase().constructor.name;
|
||||||
|
const currentHandler = this.scene.ui.getHandler();
|
||||||
if (expireFn) {
|
if (expireFn) {
|
||||||
this.prompts.shift();
|
this.prompts.shift();
|
||||||
} else if (currentMode === actionForNextPrompt.mode && currentPhase === actionForNextPrompt.phaseTarget) {
|
} else if (currentMode === actionForNextPrompt.mode && currentPhase === actionForNextPrompt.phaseTarget && currentHandler.active && (!actionForNextPrompt.awaitingActionInput || (actionForNextPrompt.awaitingActionInput && currentHandler.awaitingActionInput))) {
|
||||||
this.prompts.shift().callback();
|
this.prompts.shift().callback();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -286,12 +320,13 @@ export default class PhaseInterceptor {
|
|||||||
* @param callback - The callback function to execute.
|
* @param callback - The callback function to execute.
|
||||||
* @param expireFn - The function to determine if the prompt has expired.
|
* @param expireFn - The function to determine if the prompt has expired.
|
||||||
*/
|
*/
|
||||||
addToNextPrompt(phaseTarget: string, mode: Mode, callback: () => void, expireFn: () => void) {
|
addToNextPrompt(phaseTarget: string, mode: Mode, callback: () => void, expireFn: () => void, awaitingActionInput: boolean = false) {
|
||||||
this.prompts.push({
|
this.prompts.push({
|
||||||
phaseTarget,
|
phaseTarget,
|
||||||
mode,
|
mode,
|
||||||
callback,
|
callback,
|
||||||
expireFn
|
expireFn,
|
||||||
|
awaitingActionInput
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -179,21 +179,25 @@ export default class FightUiHandler extends UiHandler {
|
|||||||
const pp = maxPP - pokemonMove.ppUsed;
|
const pp = maxPP - pokemonMove.ppUsed;
|
||||||
|
|
||||||
this.ppText.setText(`${Utils.padInt(pp, 2, " ")}/${Utils.padInt(maxPP, 2, " ")}`);
|
this.ppText.setText(`${Utils.padInt(pp, 2, " ")}/${Utils.padInt(maxPP, 2, " ")}`);
|
||||||
const ppPercentLeft = pp / maxPP;
|
|
||||||
let ppColor = "white";
|
|
||||||
if (ppPercentLeft <= 0.5) {
|
|
||||||
ppColor = "yellow";
|
|
||||||
}
|
|
||||||
if (ppPercentLeft <= 0.25) {
|
|
||||||
ppColor = "orange";
|
|
||||||
}
|
|
||||||
if (pp === 0) {
|
|
||||||
ppColor = "red";
|
|
||||||
}
|
|
||||||
this.ppText.setColor(ppColor);
|
|
||||||
this.powerText.setText(`${power >= 0 ? power : "---"}`);
|
this.powerText.setText(`${power >= 0 ? power : "---"}`);
|
||||||
this.accuracyText.setText(`${accuracy >= 0 ? accuracy : "---"}`);
|
this.accuracyText.setText(`${accuracy >= 0 ? accuracy : "---"}`);
|
||||||
|
|
||||||
|
const ppPercentLeft = pp / maxPP;
|
||||||
|
|
||||||
|
//** Determines TextStyle according to percentage of PP remaining */
|
||||||
|
let ppColorStyle = TextStyle.MOVE_PP_FULL;
|
||||||
|
if (ppPercentLeft > 0.25 && ppPercentLeft <= 0.5) {
|
||||||
|
ppColorStyle = TextStyle.MOVE_PP_HALF_FULL;
|
||||||
|
} else if (ppPercentLeft > 0 && ppPercentLeft <= 0.25) {
|
||||||
|
ppColorStyle = TextStyle.MOVE_PP_NEAR_EMPTY;
|
||||||
|
} else if (ppPercentLeft === 0) {
|
||||||
|
ppColorStyle = TextStyle.MOVE_PP_EMPTY;
|
||||||
|
}
|
||||||
|
|
||||||
|
//** Changes the text color and shadow according to the determined TextStyle */
|
||||||
|
this.ppText.setColor(this.getTextColor(ppColorStyle, false));
|
||||||
|
this.ppText.setShadowColor(this.getTextColor(ppColorStyle, true));
|
||||||
|
|
||||||
pokemon.getOpponents().forEach((opponent) => {
|
pokemon.getOpponents().forEach((opponent) => {
|
||||||
opponent.updateEffectiveness(this.getEffectivenessText(pokemon, opponent, pokemonMove));
|
opponent.updateEffectiveness(this.getEffectivenessText(pokemon, opponent, pokemonMove));
|
||||||
});
|
});
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
import i18next from "i18next";
|
||||||
import BattleScene from "../battle-scene";
|
import BattleScene from "../battle-scene";
|
||||||
import { ModalUiHandler } from "./modal-ui-handler";
|
import { ModalUiHandler } from "./modal-ui-handler";
|
||||||
import { addTextObject, TextStyle } from "./text";
|
import { addTextObject, TextStyle } from "./text";
|
||||||
@ -31,7 +32,7 @@ export default class LoadingModalUiHandler extends ModalUiHandler {
|
|||||||
setup(): void {
|
setup(): void {
|
||||||
super.setup();
|
super.setup();
|
||||||
|
|
||||||
const label = addTextObject(this.scene, this.getWidth() / 2, this.getHeight() / 2, "Loading…", TextStyle.WINDOW);
|
const label = addTextObject(this.scene, this.getWidth() / 2, this.getHeight() / 2, i18next.t("menu:loading"), TextStyle.WINDOW);
|
||||||
label.setOrigin(0.5, 0.5);
|
label.setOrigin(0.5, 0.5);
|
||||||
|
|
||||||
this.modalContainer.add(label);
|
this.modalContainer.add(label);
|
||||||
|
@ -6,12 +6,12 @@ import { getNatureName } from "../data/nature";
|
|||||||
import { Type } from "../data/type";
|
import { Type } from "../data/type";
|
||||||
import Pokemon from "../field/pokemon";
|
import Pokemon from "../field/pokemon";
|
||||||
import i18next from "../plugins/i18n";
|
import i18next from "../plugins/i18n";
|
||||||
|
import { DexAttr } from "../system/game-data";
|
||||||
import * as Utils from "../utils";
|
import * as Utils from "../utils";
|
||||||
import ConfirmUiHandler from "./confirm-ui-handler";
|
import ConfirmUiHandler from "./confirm-ui-handler";
|
||||||
import { StatsContainer } from "./stats-container";
|
import { StatsContainer } from "./stats-container";
|
||||||
import { TextStyle, addBBCodeTextObject, addTextObject, getTextColor } from "./text";
|
import { TextStyle, addBBCodeTextObject, addTextObject, getTextColor } from "./text";
|
||||||
import { addWindow } from "./ui-theme";
|
import { addWindow } from "./ui-theme";
|
||||||
import { DexAttr } from "../system/game-data";
|
|
||||||
|
|
||||||
interface LanguageSetting {
|
interface LanguageSetting {
|
||||||
infoContainerTextSize: string;
|
infoContainerTextSize: string;
|
||||||
@ -40,7 +40,7 @@ const languageSettings: { [key: string]: LanguageSetting } = {
|
|||||||
},
|
},
|
||||||
"pt": {
|
"pt": {
|
||||||
infoContainerTextSize: "60px",
|
infoContainerTextSize: "60px",
|
||||||
infoContainerLabelXPos: -16,
|
infoContainerLabelXPos: -15,
|
||||||
infoContainerTextXPos: -12,
|
infoContainerTextXPos: -12,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
@ -193,8 +193,21 @@ export default class StarterSelectUiHandler extends MessageUiHandler {
|
|||||||
private pokemonHatchedIcon : Phaser.GameObjects.Sprite;
|
private pokemonHatchedIcon : Phaser.GameObjects.Sprite;
|
||||||
private pokemonHatchedCountText: Phaser.GameObjects.Text;
|
private pokemonHatchedCountText: Phaser.GameObjects.Text;
|
||||||
private genOptionsText: Phaser.GameObjects.Text;
|
private genOptionsText: Phaser.GameObjects.Text;
|
||||||
|
|
||||||
private instructionsContainer: Phaser.GameObjects.Container;
|
private instructionsContainer: Phaser.GameObjects.Container;
|
||||||
private instructionsText: Phaser.GameObjects.Text;
|
private shinyIconElement: Phaser.GameObjects.Sprite;
|
||||||
|
private formIconElement: Phaser.GameObjects.Sprite;
|
||||||
|
private abilityIconElement: Phaser.GameObjects.Sprite;
|
||||||
|
private genderIconElement: Phaser.GameObjects.Sprite;
|
||||||
|
private natureIconElement: Phaser.GameObjects.Sprite;
|
||||||
|
private variantIconElement: Phaser.GameObjects.Sprite;
|
||||||
|
private shinyLabel: Phaser.GameObjects.Text;
|
||||||
|
private formLabel: Phaser.GameObjects.Text;
|
||||||
|
private genderLabel: Phaser.GameObjects.Text;
|
||||||
|
private abilityLabel: Phaser.GameObjects.Text;
|
||||||
|
private natureLabel: Phaser.GameObjects.Text;
|
||||||
|
private variantLabel: Phaser.GameObjects.Text;
|
||||||
|
|
||||||
private starterSelectMessageBox: Phaser.GameObjects.NineSlice;
|
private starterSelectMessageBox: Phaser.GameObjects.NineSlice;
|
||||||
private starterSelectMessageBoxContainer: Phaser.GameObjects.Container;
|
private starterSelectMessageBoxContainer: Phaser.GameObjects.Container;
|
||||||
private statsContainer: StatsContainer;
|
private statsContainer: StatsContainer;
|
||||||
@ -656,10 +669,45 @@ export default class StarterSelectUiHandler extends MessageUiHandler {
|
|||||||
this.starterSelectContainer.add(this.pokemonEggMovesContainer);
|
this.starterSelectContainer.add(this.pokemonEggMovesContainer);
|
||||||
|
|
||||||
// The font size should be set per language
|
// The font size should be set per language
|
||||||
|
const instructionTextSize = textSettings.instructionTextSize;
|
||||||
|
|
||||||
this.instructionsContainer = this.scene.add.container(4, 156);
|
this.instructionsContainer = this.scene.add.container(4, 156);
|
||||||
this.instructionsContainer.setVisible(true);
|
this.instructionsContainer.setVisible(true);
|
||||||
this.starterSelectContainer.add(this.instructionsContainer);
|
this.starterSelectContainer.add(this.instructionsContainer);
|
||||||
|
|
||||||
|
// instruction rows that will be pushed into the container dynamically based on need
|
||||||
|
this.shinyIconElement = this.scene.add.sprite(this.instructionRowX, this.instructionRowY, "keyboard", "R.png");
|
||||||
|
this.shinyIconElement.setScale(0.675);
|
||||||
|
this.shinyIconElement.setOrigin(0.0, 0.0);
|
||||||
|
this.shinyLabel = addTextObject(this.scene, this.instructionRowX + this.instructionRowTextOffset, this.instructionRowY, i18next.t("starterSelectUiHandler:cycleShiny"), TextStyle.PARTY, { fontSize: instructionTextSize });
|
||||||
|
|
||||||
|
this.formIconElement = this.scene.add.sprite(this.instructionRowX, this.instructionRowY, "keyboard", "F.png");
|
||||||
|
this.formIconElement.setScale(0.675);
|
||||||
|
this.formIconElement.setOrigin(0.0, 0.0);
|
||||||
|
this.formLabel = addTextObject(this.scene, this.instructionRowX + this.instructionRowTextOffset, this.instructionRowY, i18next.t("starterSelectUiHandler:cycleForm"), TextStyle.PARTY, { fontSize: instructionTextSize });
|
||||||
|
|
||||||
|
this.genderIconElement = this.scene.add.sprite(this.instructionRowX, this.instructionRowY, "keyboard", "G.png");
|
||||||
|
this.genderIconElement.setScale(0.675);
|
||||||
|
this.genderIconElement.setOrigin(0.0, 0.0);
|
||||||
|
this.genderLabel = addTextObject(this.scene, this.instructionRowX + this.instructionRowTextOffset, this.instructionRowY, i18next.t("starterSelectUiHandler:cycleGender"), TextStyle.PARTY, { fontSize: instructionTextSize });
|
||||||
|
|
||||||
|
this.abilityIconElement = this.scene.add.sprite(this.instructionRowX, this.instructionRowY, "keyboard", "E.png");
|
||||||
|
this.abilityIconElement.setScale(0.675);
|
||||||
|
this.abilityIconElement.setOrigin(0.0, 0.0);
|
||||||
|
this.abilityLabel = addTextObject(this.scene, this.instructionRowX + this.instructionRowTextOffset, this.instructionRowY, i18next.t("starterSelectUiHandler:cycleAbility"), TextStyle.PARTY, { fontSize: instructionTextSize });
|
||||||
|
|
||||||
|
this.natureIconElement = this.scene.add.sprite(this.instructionRowX, this.instructionRowY, "keyboard", "N.png");
|
||||||
|
this.natureIconElement.setScale(0.675);
|
||||||
|
this.natureIconElement.setOrigin(0.0, 0.0);
|
||||||
|
this.natureLabel = addTextObject(this.scene, this.instructionRowX + this.instructionRowTextOffset, this.instructionRowY, i18next.t("starterSelectUiHandler:cycleNature"), TextStyle.PARTY, { fontSize: instructionTextSize });
|
||||||
|
|
||||||
|
this.variantIconElement = this.scene.add.sprite(this.instructionRowX, this.instructionRowY, "keyboard", "V.png");
|
||||||
|
this.variantIconElement.setScale(0.675);
|
||||||
|
this.variantIconElement.setOrigin(0.0, 0.0);
|
||||||
|
this.variantLabel = addTextObject(this.scene, this.instructionRowX + this.instructionRowTextOffset, this.instructionRowY, i18next.t("starterSelectUiHandler:cycleVariant"), TextStyle.PARTY, { fontSize: instructionTextSize });
|
||||||
|
|
||||||
|
this.hideInstructions();
|
||||||
|
|
||||||
this.starterSelectMessageBoxContainer = this.scene.add.container(0, this.scene.game.canvas.height / 6);
|
this.starterSelectMessageBoxContainer = this.scene.add.container(0, this.scene.game.canvas.height / 6);
|
||||||
this.starterSelectMessageBoxContainer.setVisible(false);
|
this.starterSelectMessageBoxContainer.setVisible(false);
|
||||||
this.starterSelectContainer.add(this.starterSelectMessageBoxContainer);
|
this.starterSelectContainer.add(this.starterSelectMessageBoxContainer);
|
||||||
@ -1494,7 +1542,7 @@ export default class StarterSelectUiHandler extends MessageUiHandler {
|
|||||||
this.setSpeciesDetails(this.lastSpecies, undefined, undefined, undefined, undefined, undefined, undefined, false);
|
this.setSpeciesDetails(this.lastSpecies, undefined, undefined, undefined, undefined, undefined, undefined, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
createButtonFromIconText(iconSetting, gamepadType, translatedText, instructionTextSize): void {
|
updateButtonIcon(iconSetting, gamepadType, iconElement, controlLabel): void {
|
||||||
let iconPath;
|
let iconPath;
|
||||||
// touch controls cannot be rebound as is, and are just emulating a keyboard event.
|
// touch controls cannot be rebound as is, and are just emulating a keyboard event.
|
||||||
// Additionally, since keyboard controls can be rebound (and will be displayed when they are), we need to have special handling for the touch controls
|
// Additionally, since keyboard controls can be rebound (and will be displayed when they are), we need to have special handling for the touch controls
|
||||||
@ -1525,10 +1573,11 @@ export default class StarterSelectUiHandler extends MessageUiHandler {
|
|||||||
} else {
|
} else {
|
||||||
iconPath = this.scene.inputController?.getIconForLatestInputRecorded(iconSetting);
|
iconPath = this.scene.inputController?.getIconForLatestInputRecorded(iconSetting);
|
||||||
}
|
}
|
||||||
const iconElement = this.scene.add.sprite(this.instructionRowX, this.instructionRowY, gamepadType, iconPath);
|
iconElement.setTexture(gamepadType, iconPath);
|
||||||
iconElement.setScale(0.675);
|
iconElement.setPosition(this.instructionRowX, this.instructionRowY);
|
||||||
iconElement.setOrigin(0.0, 0.0);
|
controlLabel.setPosition(this.instructionRowX + this.instructionRowTextOffset, this.instructionRowY);
|
||||||
const controlLabel = addTextObject(this.scene, this.instructionRowX + this.instructionRowTextOffset, this.instructionRowY, translatedText, TextStyle.PARTY, { fontSize: instructionTextSize });
|
iconElement.setVisible(true);
|
||||||
|
controlLabel.setVisible(true);
|
||||||
this.instructionsContainer.add([iconElement, controlLabel]);
|
this.instructionsContainer.add([iconElement, controlLabel]);
|
||||||
this.instructionRowY += 8;
|
this.instructionRowY += 8;
|
||||||
if (this.instructionRowY >= 24) {
|
if (this.instructionRowY >= 24) {
|
||||||
@ -1538,12 +1587,9 @@ export default class StarterSelectUiHandler extends MessageUiHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
updateInstructions(): void {
|
updateInstructions(): void {
|
||||||
const currentLanguage = i18next.resolvedLanguage;
|
|
||||||
const langSettingKey = Object.keys(languageSettings).find(lang => currentLanguage.includes(lang));
|
|
||||||
const textSettings = languageSettings[langSettingKey];
|
|
||||||
const instructionTextSize = textSettings.instructionTextSize;
|
|
||||||
this.instructionRowX = 0;
|
this.instructionRowX = 0;
|
||||||
this.instructionRowY = 0;
|
this.instructionRowY = 0;
|
||||||
|
this.hideInstructions();
|
||||||
this.instructionsContainer.removeAll();
|
this.instructionsContainer.removeAll();
|
||||||
let gamepadType;
|
let gamepadType;
|
||||||
if (this.scene.inputMethod === "gamepad") {
|
if (this.scene.inputMethod === "gamepad") {
|
||||||
@ -1554,22 +1600,22 @@ export default class StarterSelectUiHandler extends MessageUiHandler {
|
|||||||
|
|
||||||
if (this.speciesStarterDexEntry?.caughtAttr) {
|
if (this.speciesStarterDexEntry?.caughtAttr) {
|
||||||
if (this.canCycleShiny) {
|
if (this.canCycleShiny) {
|
||||||
this.createButtonFromIconText(SettingKeyboard.Button_Cycle_Shiny, gamepadType, i18next.t("starterSelectUiHandler:cycleShiny"), instructionTextSize);
|
this.updateButtonIcon(SettingKeyboard.Button_Cycle_Shiny, gamepadType, this.shinyIconElement, this.shinyLabel);
|
||||||
}
|
}
|
||||||
if (this.canCycleForm) {
|
if (this.canCycleForm) {
|
||||||
this.createButtonFromIconText(SettingKeyboard.Button_Cycle_Form, gamepadType, i18next.t("starterSelectUiHandler:cycleForm"), instructionTextSize);
|
this.updateButtonIcon(SettingKeyboard.Button_Cycle_Form, gamepadType, this.formIconElement, this.formLabel);
|
||||||
}
|
}
|
||||||
if (this.canCycleGender) {
|
if (this.canCycleGender) {
|
||||||
this.createButtonFromIconText(SettingKeyboard.Button_Cycle_Gender, gamepadType, i18next.t("starterSelectUiHandler:cycleGender"), instructionTextSize);
|
this.updateButtonIcon(SettingKeyboard.Button_Cycle_Gender, gamepadType, this.genderIconElement, this.genderLabel);
|
||||||
}
|
}
|
||||||
if (this.canCycleAbility) {
|
if (this.canCycleAbility) {
|
||||||
this.createButtonFromIconText(SettingKeyboard.Button_Cycle_Ability, gamepadType, i18next.t("starterSelectUiHandler:cycleAbility"), instructionTextSize);
|
this.updateButtonIcon(SettingKeyboard.Button_Cycle_Ability, gamepadType, this.abilityIconElement, this.abilityLabel);
|
||||||
}
|
}
|
||||||
if (this.canCycleNature) {
|
if (this.canCycleNature) {
|
||||||
this.createButtonFromIconText(SettingKeyboard.Button_Cycle_Nature, gamepadType, i18next.t("starterSelectUiHandler:cycleNature"), instructionTextSize);
|
this.updateButtonIcon(SettingKeyboard.Button_Cycle_Nature, gamepadType, this.natureIconElement, this.natureLabel);
|
||||||
}
|
}
|
||||||
if (this.canCycleVariant) {
|
if (this.canCycleVariant) {
|
||||||
this.createButtonFromIconText(SettingKeyboard.Button_Cycle_Variant, gamepadType, i18next.t("starterSelectUiHandler:cycleVariant"), instructionTextSize);
|
this.updateButtonIcon(SettingKeyboard.Button_Cycle_Variant, gamepadType, this.variantIconElement, this.variantLabel);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2341,9 +2387,25 @@ export default class StarterSelectUiHandler extends MessageUiHandler {
|
|||||||
super.clearText();
|
super.clearText();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
hideInstructions(): void {
|
||||||
|
this.shinyIconElement.setVisible(false);
|
||||||
|
this.shinyLabel.setVisible(false);
|
||||||
|
this.formIconElement.setVisible(false);
|
||||||
|
this.formLabel.setVisible(false);
|
||||||
|
this.genderIconElement.setVisible(false);
|
||||||
|
this.genderLabel.setVisible(false);
|
||||||
|
this.abilityIconElement.setVisible(false);
|
||||||
|
this.abilityLabel.setVisible(false);
|
||||||
|
this.natureIconElement.setVisible(false);
|
||||||
|
this.natureLabel.setVisible(false);
|
||||||
|
this.variantIconElement.setVisible(false);
|
||||||
|
this.variantLabel.setVisible(false);
|
||||||
|
}
|
||||||
|
|
||||||
clear(): void {
|
clear(): void {
|
||||||
super.clear();
|
super.clear();
|
||||||
this.cursor = -1;
|
this.cursor = -1;
|
||||||
|
this.hideInstructions();
|
||||||
this.starterSelectContainer.setVisible(false);
|
this.starterSelectContainer.setVisible(false);
|
||||||
this.blockInput = false;
|
this.blockInput = false;
|
||||||
|
|
||||||
|
@ -29,7 +29,11 @@ export enum TextStyle {
|
|||||||
SETTINGS_LOCKED,
|
SETTINGS_LOCKED,
|
||||||
TOOLTIP_TITLE,
|
TOOLTIP_TITLE,
|
||||||
TOOLTIP_CONTENT,
|
TOOLTIP_CONTENT,
|
||||||
MOVE_INFO_CONTENT
|
MOVE_INFO_CONTENT,
|
||||||
|
MOVE_PP_FULL,
|
||||||
|
MOVE_PP_HALF_FULL,
|
||||||
|
MOVE_PP_NEAR_EMPTY,
|
||||||
|
MOVE_PP_EMPTY
|
||||||
}
|
}
|
||||||
|
|
||||||
interface LanguageSetting {
|
interface LanguageSetting {
|
||||||
@ -204,11 +208,27 @@ export function getTextColor(textStyle: TextStyle, shadow?: boolean, uiTheme: Ui
|
|||||||
return !shadow ? "#f8f8f8" : "#6b5a73";
|
return !shadow ? "#f8f8f8" : "#6b5a73";
|
||||||
case TextStyle.WINDOW:
|
case TextStyle.WINDOW:
|
||||||
case TextStyle.MOVE_INFO_CONTENT:
|
case TextStyle.MOVE_INFO_CONTENT:
|
||||||
|
case TextStyle.MOVE_PP_FULL:
|
||||||
case TextStyle.TOOLTIP_CONTENT:
|
case TextStyle.TOOLTIP_CONTENT:
|
||||||
if (uiTheme) {
|
if (uiTheme) {
|
||||||
return !shadow ? "#484848" : "#d0d0c8";
|
return !shadow ? "#484848" : "#d0d0c8";
|
||||||
}
|
}
|
||||||
return !shadow ? "#f8f8f8" : "#6b5a73";
|
return !shadow ? "#f8f8f8" : "#6b5a73";
|
||||||
|
case TextStyle.MOVE_PP_HALF_FULL:
|
||||||
|
if (uiTheme) {
|
||||||
|
return !shadow ? "#a68e17" : "#ebd773";
|
||||||
|
}
|
||||||
|
return !shadow ? "#ccbe00" : "#6e672c";
|
||||||
|
case TextStyle.MOVE_PP_NEAR_EMPTY:
|
||||||
|
if (uiTheme) {
|
||||||
|
return !shadow ? "#d64b00" : "#f7b18b";
|
||||||
|
}
|
||||||
|
return !shadow ? "#d64b00" : "#69402a";
|
||||||
|
case TextStyle.MOVE_PP_EMPTY:
|
||||||
|
if (uiTheme) {
|
||||||
|
return !shadow ? "#e13d3d" : "#fca2a2";
|
||||||
|
}
|
||||||
|
return !shadow ? "#e13d3d" : "#632929";
|
||||||
case TextStyle.WINDOW_ALT:
|
case TextStyle.WINDOW_ALT:
|
||||||
return !shadow ? "#484848" : "#d0d0c8";
|
return !shadow ? "#484848" : "#d0d0c8";
|
||||||
case TextStyle.BATTLE_INFO:
|
case TextStyle.BATTLE_INFO:
|
||||||
|