Add Baton modifier

pull/1/head
Flashfyre 2023-04-28 19:26:41 -04:00
parent 140e759486
commit 2b95d4ce51
6 changed files with 86 additions and 22 deletions

View File

@ -5,7 +5,7 @@ import { allMoves, applyMoveAttrs, BypassSleepAttr, ChargeAttr, HitsTagAttr, Mis
import { Mode } from './ui/ui';
import { Command } from "./ui/command-ui-handler";
import { Stat } from "./data/pokemon-stat";
import { BerryModifier, ExpBalanceModifier, ExpBoosterModifier, ExpShareModifier, ExtraModifierModifier, FlinchChanceModifier, HealingBoosterModifier, HeldItemTransferModifier, HitHealModifier, MapModifier, MultipleParticipantExpBonusModifier, PokemonExpBoosterModifier, PokemonHeldItemModifier, TempBattleStatBoosterModifier, TurnHealModifier } from "./modifier/modifier";
import { BerryModifier, ExpBalanceModifier, ExpBoosterModifier, ExpShareModifier, ExtraModifierModifier, FlinchChanceModifier, HealingBoosterModifier, HeldItemTransferModifier, HitHealModifier, MapModifier, MultipleParticipantExpBonusModifier, PokemonExpBoosterModifier, PokemonHeldItemModifier, SwitchEffectTransferModifier, TempBattleStatBoosterModifier, TurnHealModifier } from "./modifier/modifier";
import PartyUiHandler, { PartyOption, PartyUiMode } from "./ui/party-ui-handler";
import { doPokeballBounceAnim, getPokeballAtlasKey, getPokeballCatchMultiplier, getPokeballTintColor, PokeballType } from "./data/pokeball";
import { CommonAnim, CommonBattleAnim, MoveAnim, initMoveAnim, loadMoveAnimAssets } from "./data/battle-anims";
@ -18,7 +18,7 @@ import { BattleStat, getBattleStatLevelChangeDescription, getBattleStatName } fr
import { Biome, biomeLinks } from "./data/biome";
import { ModifierTypeOption, PokemonModifierType, PokemonMoveModifierType, getPlayerModifierTypeOptionsForWave, regenerateModifierPoolThresholds } from "./modifier/modifier-type";
import SoundFade from "phaser3-rex-plugins/plugins/soundfade";
import { BattlerTagLapseType, BattlerTagType, HideSpriteTag as HiddenTag, IgnoreAccuracyTag, TrappedTag as TrapTag } from "./data/battler-tag";
import { BattlerTagLapseType, BattlerTagType, HideSpriteTag as HiddenTag, TrappedTag } from "./data/battler-tag";
import { getPokemonMessage } from "./messages";
import { Starter } from "./ui/starter-select-ui-handler";
import { Gender } from "./data/gender";
@ -420,12 +420,16 @@ export class SummonPhase extends BattlePhase {
export class SwitchSummonPhase extends SummonPhase {
private slotIndex: integer;
private doReturn: boolean;
private batonPass: boolean;
constructor(scene: BattleScene, slotIndex: integer, doReturn: boolean) {
private lastPokemon: PlayerPokemon;
constructor(scene: BattleScene, slotIndex: integer, doReturn: boolean, batonPass: boolean) {
super(scene);
this.slotIndex = slotIndex;
this.doReturn = doReturn;
this.batonPass = batonPass;
}
start() {
@ -440,7 +444,8 @@ export class SwitchSummonPhase extends SummonPhase {
const playerPokemon = this.scene.getPlayerPokemon();
this.scene.getEnemyPokemon()?.removeTagsBySourceId(playerPokemon.id);
if (!this.batonPass)
this.scene.getEnemyPokemon()?.removeTagsBySourceId(playerPokemon.id);
this.scene.ui.showText(`Come back, ${this.scene.getPlayerPokemon().name}!`);
this.scene.sound.play('pb_rel');
@ -462,11 +467,29 @@ export class SwitchSummonPhase extends SummonPhase {
switchAndSummon() {
const party = this.scene.getParty();
const switchedPokemon = party[this.slotIndex];
party[this.slotIndex] = this.scene.getPlayerPokemon();
this.lastPokemon = this.scene.getPlayerPokemon();
if (this.batonPass) {
this.scene.getEnemyPokemon()?.transferTagsBySourceId(this.lastPokemon.id, switchedPokemon.id);
if (!this.scene.findModifier(m => m instanceof SwitchEffectTransferModifier && (m as SwitchEffectTransferModifier).pokemonId === switchedPokemon.id)) {
const batonPassModifier = this.scene.findModifier(m => m instanceof SwitchEffectTransferModifier
&& (m as SwitchEffectTransferModifier).pokemonId === this.lastPokemon.id) as SwitchEffectTransferModifier;
this.scene.tryTransferHeldItemModifier(batonPassModifier, switchedPokemon, false, false);
}
}
party[this.slotIndex] = this.lastPokemon;
party[0] = switchedPokemon;
this.scene.ui.showText(`Go! ${switchedPokemon.name}!`);
this.summon();
}
end() {
if (this.batonPass)
this.scene.getPlayerPokemon().transferSummon(this.lastPokemon);
this.lastPokemon.resetSummonData();
super.end();
}
}
export class CheckSwitchPhase extends BattlePhase {
@ -581,7 +604,7 @@ export class CommandPhase extends FieldPhase {
this.scene.ui.setMode(Mode.COMMAND);
}
handleCommand(command: Command, cursor: integer): boolean {
handleCommand(command: Command, cursor: integer, ...args: any[]): boolean {
const playerPokemon = this.scene.getPlayerPokemon();
const enemyPokemon = this.scene.getEnemyPokemon();
let success: boolean;
@ -640,9 +663,10 @@ export class CommandPhase extends FieldPhase {
}
break;
case Command.POKEMON:
const trapTag = playerPokemon.findTag(t => t instanceof TrapTag) as TrapTag;
if (!trapTag) {
this.scene.unshiftPhase(new SwitchSummonPhase(this.scene, cursor, true));
const trapTag = playerPokemon.findTag(t => t instanceof TrappedTag) as TrappedTag;
const batonPass = args[0] as boolean;
if (batonPass || !trapTag) {
this.scene.unshiftPhase(new SwitchSummonPhase(this.scene, cursor, true, args[0] as boolean));
success = true;
} else
this.scene.ui.showText(`${this.scene.getPokemonById(trapTag.sourceId).name}'s ${trapTag.getMoveName()}\nprevents switching!`, null, () => {
@ -1594,9 +1618,9 @@ export class SwitchPhase extends BattlePhase {
start() {
super.start();
this.scene.ui.setMode(Mode.PARTY, this.isModal ? PartyUiMode.FAINT_SWITCH : PartyUiMode.POST_BATTLE_SWITCH, (slotIndex: integer, _option: PartyOption) => {
this.scene.ui.setMode(Mode.PARTY, this.isModal ? PartyUiMode.FAINT_SWITCH : PartyUiMode.POST_BATTLE_SWITCH, (slotIndex: integer, option: PartyOption) => {
if (slotIndex && slotIndex < 6)
this.scene.unshiftPhase(new SwitchSummonPhase(this.scene, slotIndex, this.doReturn));
this.scene.unshiftPhase(new SwitchSummonPhase(this.scene, slotIndex, this.doReturn, option === PartyOption.PASS_BATON));
this.scene.ui.setMode(Mode.MESSAGE).then(() => super.end());
}, PartyUiHandler.FilterNonFainted);
}

View File

@ -201,8 +201,8 @@ export class ConfusedTag extends BattlerTag {
}
export class SeedTag extends BattlerTag {
constructor() {
super(BattlerTagType.SEEDED, BattlerTagLapseType.AFTER_MOVE, 1, Moves.LEECH_SEED);
constructor(sourceId: integer) {
super(BattlerTagType.SEEDED, BattlerTagLapseType.AFTER_MOVE, 1, Moves.LEECH_SEED, sourceId);
}
onAdd(pokemon: Pokemon): void {
@ -517,7 +517,7 @@ export function getBattlerTag(tagType: BattlerTagType, turnCount: integer, sourc
case BattlerTagType.CONFUSED:
return new ConfusedTag(turnCount, sourceMove);
case BattlerTagType.SEEDED:
return new SeedTag();
return new SeedTag(sourceId);
case BattlerTagType.NIGHTMARE:
return new NightmareTag();
case BattlerTagType.INGRAIN:

View File

@ -607,6 +607,9 @@ const modifierTypes = {
SHELL_BELL: () => new PokemonHeldItemModifierType('SHELL BELL', 'Heals 1/8 of a POKéMON\'s dealt damage',
(type, args) => new Modifiers.HitHealModifier(type, (args[0] as Pokemon).id)),
BATON: () => new PokemonHeldItemModifierType('BATON', 'Allows passing along effects when switching POKéMON, which also bypasses traps',
(type, args) => new Modifiers.SwitchEffectTransferModifier(type, (args[0] as Pokemon).id), 'stick'),
SHINY_CHARM: () => new ModifierType('SHINY CHARM', 'Dramatically increases the chance of a wild POKéMON being shiny', (type, _args) => new Modifiers.ShinyRateBoosterModifier(type)),
MINI_BLACK_HOLE: () => new HeldItemTransferModifierType('MINI BLACK HOLE'),
@ -684,6 +687,7 @@ const modifierPool = {
new WeightedModifierType(modifierTypes.ATTACK_TYPE_BOOSTER, 5),
new WeightedModifierType(modifierTypes.CANDY_JAR, 3),
new WeightedModifierType(modifierTypes.HEALING_CHARM, 1),
new WeightedModifierType(modifierTypes.BATON, 1),
new WeightedModifierType(modifierTypes.FOCUS_BAND, 3),
new WeightedModifierType(modifierTypes.KINGS_ROCK, 2),
new WeightedModifierType(modifierTypes.LEFTOVERS, 2),

View File

@ -972,6 +972,28 @@ export class ShinyRateBoosterModifier extends PersistentModifier {
}
}
export class SwitchEffectTransferModifier extends PokemonHeldItemModifier {
constructor(type: ModifierType, pokemonId: integer, stackCount?: integer) {
super(type, pokemonId, stackCount);
}
matchType(modifier: Modifier): boolean {
return modifier instanceof SwitchEffectTransferModifier;
}
clone(): SwitchEffectTransferModifier {
return new SwitchEffectTransferModifier(this.type, this.pokemonId, this.stackCount);
}
apply(args: any[]): boolean {
return true;
}
getMaxStackCount(): integer {
return 1;
}
}
export class HeldItemTransferModifier extends PokemonHeldItemModifier {
constructor(type: ModifierType, pokemonId: integer, stackCount?: integer) {
super(type, pokemonId, stackCount);
@ -1030,7 +1052,7 @@ export class ExtraModifierModifier extends PersistentModifier {
return true;
}
getMaxStackCount(): integer {
getMaxStackCount(): integer {
return 3;
}
}

View File

@ -666,6 +666,19 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
});
}
transferTagsBySourceId(sourceId: integer, newSourceId: integer): void {
const tags = this.summonData.tags;
tags.filter(t => t.sourceId === sourceId).forEach(t => t.sourceId = newSourceId);
}
transferSummon(source: Pokemon): void {
const battleStats = Utils.getEnumValues(BattleStat);
for (let stat of battleStats)
this.summonData.battleStats[stat] = source.summonData.battleStats[stat];
for (let tag of source.summonData.tags)
this.summonData.tags.push(tag);
}
getMoveHistory(): TurnMove[] {
return this.battleSummonData.moveHistory;
}

View File

@ -6,7 +6,7 @@ import { Command } from "./command-ui-handler";
import MessageUiHandler from "./message-ui-handler";
import { Mode } from "./ui";
import * as Utils from "../utils";
import { PokemonHeldItemModifier } from "../modifier/modifier";
import { PokemonHeldItemModifier, SwitchEffectTransferModifier } from "../modifier/modifier";
const defaultMessage = 'Choose a Pokémon.';
@ -22,8 +22,8 @@ export enum PartyUiMode {
export enum PartyOption {
CANCEL = -1,
SHIFT,
SEND_OUT,
PASS_BATON,
APPLY,
TRANSFER,
SUMMARY,
@ -212,7 +212,7 @@ export default class PartyUiHandler extends MessageUiHandler {
selectCallback(this.cursor, option);
}
} else if (this.cursor)
(this.scene.getCurrentPhase() as CommandPhase).handleCommand(Command.POKEMON, this.cursor);
(this.scene.getCurrentPhase() as CommandPhase).handleCommand(Command.POKEMON, this.cursor, option === PartyOption.PASS_BATON);
if (this.partyUiMode !== PartyUiMode.MODIFIER && this.partyUiMode !== PartyUiMode.MOVE_MODIFIER)
ui.playSelect();
return;
@ -409,13 +409,14 @@ export default class PartyUiHandler extends MessageUiHandler {
if (this.partyUiMode !== PartyUiMode.MOVE_MODIFIER && (this.transferMode || this.partyUiMode !== PartyUiMode.MODIFIER_TRANSFER)) {
switch (this.partyUiMode) {
case PartyUiMode.SWITCH:
if (this.cursor)
this.options.push(PartyOption.SHIFT);
break;
case PartyUiMode.FAINT_SWITCH:
case PartyUiMode.POST_BATTLE_SWITCH:
if (this.cursor)
if (this.cursor) {
this.options.push(PartyOption.SEND_OUT);
if (this.partyUiMode !== PartyUiMode.FAINT_SWITCH
&& this.scene.findModifier(m => m instanceof SwitchEffectTransferModifier && (m as SwitchEffectTransferModifier).pokemonId === this.scene.getPlayerPokemon().id))
this.options.push(PartyOption.PASS_BATON);
}
break;
case PartyUiMode.MODIFIER:
this.options.push(PartyOption.APPLY);