Implement Pickup ability
This commit is contained in:
parent
bc236cd048
commit
113ac10c1b
|
@ -1604,9 +1604,9 @@ export default class BattleScene extends Phaser.Scene {
|
||||||
|
|
||||||
tryTransferHeldItemModifier(itemModifier: PokemonHeldItemModifier, target: Pokemon, transferStack: boolean, playSound: boolean, instant?: boolean, ignoreUpdate?: boolean): Promise<boolean> {
|
tryTransferHeldItemModifier(itemModifier: PokemonHeldItemModifier, target: Pokemon, transferStack: boolean, playSound: boolean, instant?: boolean, ignoreUpdate?: boolean): Promise<boolean> {
|
||||||
return new Promise(resolve => {
|
return new Promise(resolve => {
|
||||||
const source = itemModifier.getPokemon(target.scene);
|
const source = itemModifier.pokemonId ? itemModifier.getPokemon(target.scene) : null;
|
||||||
const cancelled = new Utils.BooleanHolder(false);
|
const cancelled = new Utils.BooleanHolder(false);
|
||||||
applyAbAttrs(BlockItemTheftAbAttr, source, cancelled).then(() => {
|
Utils.executeIf(!!source, () => applyAbAttrs(BlockItemTheftAbAttr, source, cancelled)).then(() => {
|
||||||
if (cancelled.value)
|
if (cancelled.value)
|
||||||
return resolve(false);
|
return resolve(false);
|
||||||
const newItemModifier = itemModifier.clone() as PokemonHeldItemModifier;
|
const newItemModifier = itemModifier.clone() as PokemonHeldItemModifier;
|
||||||
|
@ -1615,7 +1615,7 @@ export default class BattleScene extends Phaser.Scene {
|
||||||
&& (m as PokemonHeldItemModifier).matchType(itemModifier) && m.pokemonId === target.id, target.isPlayer()) as PokemonHeldItemModifier;
|
&& (m as PokemonHeldItemModifier).matchType(itemModifier) && m.pokemonId === target.id, target.isPlayer()) as PokemonHeldItemModifier;
|
||||||
let removeOld = true;
|
let removeOld = true;
|
||||||
if (matchingModifier) {
|
if (matchingModifier) {
|
||||||
const maxStackCount = matchingModifier.getMaxStackCount(source.scene);
|
const maxStackCount = matchingModifier.getMaxStackCount(target.scene);
|
||||||
if (matchingModifier.stackCount >= maxStackCount)
|
if (matchingModifier.stackCount >= maxStackCount)
|
||||||
return resolve(false);
|
return resolve(false);
|
||||||
const countTaken = transferStack ? Math.min(itemModifier.stackCount, maxStackCount - matchingModifier.stackCount) : 1;
|
const countTaken = transferStack ? Math.min(itemModifier.stackCount, maxStackCount - matchingModifier.stackCount) : 1;
|
||||||
|
@ -1626,7 +1626,7 @@ export default class BattleScene extends Phaser.Scene {
|
||||||
newItemModifier.stackCount = 1;
|
newItemModifier.stackCount = 1;
|
||||||
removeOld = !(--itemModifier.stackCount);
|
removeOld = !(--itemModifier.stackCount);
|
||||||
}
|
}
|
||||||
if (!removeOld || this.removeModifier(itemModifier, !source.isPlayer())) {
|
if (!removeOld || !source || this.removeModifier(itemModifier, !source.isPlayer())) {
|
||||||
const addModifier = () => {
|
const addModifier = () => {
|
||||||
if (!matchingModifier || this.removeModifier(matchingModifier, !target.isPlayer())) {
|
if (!matchingModifier || this.removeModifier(matchingModifier, !target.isPlayer())) {
|
||||||
if (target.isPlayer())
|
if (target.isPlayer())
|
||||||
|
@ -1636,7 +1636,7 @@ export default class BattleScene extends Phaser.Scene {
|
||||||
} else
|
} else
|
||||||
resolve(false);
|
resolve(false);
|
||||||
};
|
};
|
||||||
if (source.isPlayer() !== target.isPlayer() && !ignoreUpdate)
|
if (source && source.isPlayer() !== target.isPlayer() && !ignoreUpdate)
|
||||||
this.updateModifiers(source.isPlayer(), instant).then(() => addModifier());
|
this.updateModifiers(source.isPlayer(), instant).then(() => addModifier());
|
||||||
else
|
else
|
||||||
addModifier();
|
addModifier();
|
||||||
|
|
|
@ -9,6 +9,7 @@ import { TrainerType } from "./data/enums/trainer-type";
|
||||||
import { GameMode } from "./game-mode";
|
import { GameMode } from "./game-mode";
|
||||||
import { BattleSpec } from "./enums/battle-spec";
|
import { BattleSpec } from "./enums/battle-spec";
|
||||||
import { PlayerGender } from "./system/game-data";
|
import { PlayerGender } from "./system/game-data";
|
||||||
|
import { PersistentModifier, PokemonHeldItemModifier } from "./modifier/modifier";
|
||||||
|
|
||||||
export enum BattleType {
|
export enum BattleType {
|
||||||
WILD,
|
WILD,
|
||||||
|
@ -49,8 +50,9 @@ export default class Battle {
|
||||||
public started: boolean;
|
public started: boolean;
|
||||||
public turn: integer;
|
public turn: integer;
|
||||||
public turnCommands: TurnCommands;
|
public turnCommands: TurnCommands;
|
||||||
public playerParticipantIds: Set<integer> = new Set<integer>();
|
public playerParticipantIds: Set<integer>;
|
||||||
public escapeAttempts: integer = 0;
|
public postBattleLoot: PokemonHeldItemModifier[];
|
||||||
|
public escapeAttempts: integer;
|
||||||
public lastMove: Moves;
|
public lastMove: Moves;
|
||||||
public battleSeed: string;
|
public battleSeed: string;
|
||||||
private battleSeedState: string;
|
private battleSeedState: string;
|
||||||
|
@ -68,6 +70,9 @@ export default class Battle {
|
||||||
this.seenEnemyPartyMemberIds = new Set<integer>();
|
this.seenEnemyPartyMemberIds = new Set<integer>();
|
||||||
this.double = double;
|
this.double = double;
|
||||||
this.turn = 0;
|
this.turn = 0;
|
||||||
|
this.playerParticipantIds = new Set<integer>();
|
||||||
|
this.postBattleLoot = [];
|
||||||
|
this.escapeAttempts = 0;
|
||||||
this.started = false;
|
this.started = false;
|
||||||
this.battleSeed = Utils.randomString(16, true);
|
this.battleSeed = Utils.randomString(16, true);
|
||||||
this.battleSeedState = null;
|
this.battleSeedState = null;
|
||||||
|
@ -123,6 +128,14 @@ export default class Battle {
|
||||||
this.playerParticipantIds.delete(playerPokemon.id);
|
this.playerParticipantIds.delete(playerPokemon.id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
addPostBattleLoot(enemyPokemon: EnemyPokemon): void {
|
||||||
|
this.postBattleLoot.push(...enemyPokemon.scene.findModifiers(m => m instanceof PokemonHeldItemModifier && m.pokemonId === enemyPokemon.id, false).map(i => {
|
||||||
|
const ret = i as PokemonHeldItemModifier;
|
||||||
|
ret.pokemonId = null;
|
||||||
|
return ret;
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
getBgmOverride(scene: BattleScene): string {
|
getBgmOverride(scene: BattleScene): string {
|
||||||
const battlers = this.enemyParty.slice(0, this.getBattlerCount());
|
const battlers = this.enemyParty.slice(0, this.getBattlerCount());
|
||||||
if (this.battleType === BattleType.TRAINER) {
|
if (this.battleType === BattleType.TRAINER) {
|
||||||
|
|
|
@ -1020,6 +1020,31 @@ export class MaxMultiHitAbAttr extends AbAttr {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export class PostBattleAbAttr extends AbAttr {
|
||||||
|
constructor() {
|
||||||
|
super(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
applyPostBattle(pokemon: Pokemon, args: any[]): boolean {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class PostBattleLootAbAttr extends PostBattleAbAttr {
|
||||||
|
applyPostBattle(pokemon: Pokemon, args: any[]): boolean {
|
||||||
|
const postBattleLoot = pokemon.scene.currentBattle.postBattleLoot;
|
||||||
|
if (postBattleLoot.length) {
|
||||||
|
const randItem = Utils.randSeedItem(postBattleLoot);
|
||||||
|
if (pokemon.scene.tryTransferHeldItemModifier(randItem, pokemon, false, true, true)) {
|
||||||
|
pokemon.scene.queueMessage(getPokemonMessage(pokemon, ` picked up\n${randItem.type.name}!`));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export class ReduceStatusEffectDurationAbAttr extends AbAttr {
|
export class ReduceStatusEffectDurationAbAttr extends AbAttr {
|
||||||
private statusEffect: StatusEffect;
|
private statusEffect: StatusEffect;
|
||||||
|
|
||||||
|
@ -1247,6 +1272,11 @@ export function applyCheckTrappedAbAttrs(attrType: { new(...args: any[]): CheckT
|
||||||
return applyAbAttrsInternal<CheckTrappedAbAttr>(attrType, pokemon, attr => attr.applyCheckTrapped(pokemon, trapped, args), true);
|
return applyAbAttrsInternal<CheckTrappedAbAttr>(attrType, pokemon, attr => attr.applyCheckTrapped(pokemon, trapped, args), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function applyPostBattleAbAttrs(attrType: { new(...args: any[]): PostBattleAbAttr },
|
||||||
|
pokemon: Pokemon, ...args: any[]): Promise<void> {
|
||||||
|
return applyAbAttrsInternal<PostBattleAbAttr>(attrType, pokemon, attr => attr.applyPostBattle(pokemon, args));
|
||||||
|
}
|
||||||
|
|
||||||
function canApplyAttr(pokemon: Pokemon, attr: AbAttr): boolean {
|
function canApplyAttr(pokemon: Pokemon, attr: AbAttr): boolean {
|
||||||
const condition = attr.getCondition();
|
const condition = attr.getCondition();
|
||||||
return !condition || condition(pokemon);
|
return !condition || condition(pokemon);
|
||||||
|
@ -1676,7 +1706,8 @@ export function initAbilities() {
|
||||||
.attr(ProtectStatAbAttr, BattleStat.ACC),
|
.attr(ProtectStatAbAttr, BattleStat.ACC),
|
||||||
new Ability(Abilities.HYPER_CUTTER, "Hyper Cutter", "The Pokémon's proud of its powerful pincers. They prevent other Pokémon from lowering its Attack stat.", 3)
|
new Ability(Abilities.HYPER_CUTTER, "Hyper Cutter", "The Pokémon's proud of its powerful pincers. They prevent other Pokémon from lowering its Attack stat.", 3)
|
||||||
.attr(ProtectStatAbAttr, BattleStat.ATK),
|
.attr(ProtectStatAbAttr, BattleStat.ATK),
|
||||||
new Ability(Abilities.PICKUP, "Pickup (N)", "The Pokémon may pick up the item an opposing Pokémon used during a battle. It may pick up items outside of battle, too.", 3),
|
new Ability(Abilities.PICKUP, "Pickup", "The Pokémon may pick up the item an opposing Pokémon held during a battle.", 3)
|
||||||
|
.attr(PostBattleLootAbAttr),
|
||||||
new Ability(Abilities.TRUANT, "Truant", "The Pokémon can't use a move if it had used a move on the previous turn.", 3)
|
new Ability(Abilities.TRUANT, "Truant", "The Pokémon can't use a move if it had used a move on the previous turn.", 3)
|
||||||
.attr(PostSummonAddBattlerTagAbAttr, BattlerTagType.TRUANT, 1, false),
|
.attr(PostSummonAddBattlerTagAbAttr, BattlerTagType.TRUANT, 1, false),
|
||||||
new Ability(Abilities.HUSTLE, "Hustle", "Boosts the Attack stat, but lowers accuracy.", 3)
|
new Ability(Abilities.HUSTLE, "Hustle", "Boosts the Attack stat, but lowers accuracy.", 3)
|
||||||
|
|
|
@ -30,7 +30,7 @@ import { Weather, WeatherType, getRandomWeatherType, getWeatherDamageMessage, ge
|
||||||
import { TempBattleStat } from "./data/temp-battle-stat";
|
import { TempBattleStat } from "./data/temp-battle-stat";
|
||||||
import { ArenaTagSide, ArenaTrapTag, MistTag, TrickRoomTag } from "./data/arena-tag";
|
import { ArenaTagSide, ArenaTrapTag, MistTag, TrickRoomTag } from "./data/arena-tag";
|
||||||
import { ArenaTagType } from "./data/enums/arena-tag-type";
|
import { ArenaTagType } from "./data/enums/arena-tag-type";
|
||||||
import { Abilities, CheckTrappedAbAttr, IgnoreOpponentStatChangesAbAttr, PostAttackAbAttr, PostDefendAbAttr, PostSummonAbAttr, PostTurnAbAttr, PostWeatherLapseAbAttr, PreSwitchOutAbAttr, PreWeatherDamageAbAttr, ProtectStatAbAttr, RunSuccessAbAttr, StatChangeMultiplierAbAttr, SuppressWeatherEffectAbAttr, SyncEncounterNatureAbAttr, applyAbAttrs, applyCheckTrappedAbAttrs, applyPostAttackAbAttrs, applyPostDefendAbAttrs, applyPostSummonAbAttrs, applyPostTurnAbAttrs, applyPostWeatherLapseAbAttrs, applyPreStatChangeAbAttrs, applyPreSwitchOutAbAttrs, applyPreWeatherEffectAbAttrs } from "./data/ability";
|
import { Abilities, CheckTrappedAbAttr, IgnoreOpponentStatChangesAbAttr, PostAttackAbAttr, PostBattleAbAttr, PostDefendAbAttr, PostSummonAbAttr, PostTurnAbAttr, PostWeatherLapseAbAttr, PreSwitchOutAbAttr, PreWeatherDamageAbAttr, ProtectStatAbAttr, RunSuccessAbAttr, StatChangeMultiplierAbAttr, SuppressWeatherEffectAbAttr, SyncEncounterNatureAbAttr, applyAbAttrs, applyCheckTrappedAbAttrs, applyPostAttackAbAttrs, applyPostBattleAbAttrs, applyPostDefendAbAttrs, applyPostSummonAbAttrs, applyPostTurnAbAttrs, applyPostWeatherLapseAbAttrs, applyPreStatChangeAbAttrs, applyPreSwitchOutAbAttrs, applyPreWeatherEffectAbAttrs } from "./data/ability";
|
||||||
import { Unlockables, getUnlockableName } from "./system/unlockables";
|
import { Unlockables, getUnlockableName } from "./system/unlockables";
|
||||||
import { getBiomeKey } from "./field/arena";
|
import { getBiomeKey } from "./field/arena";
|
||||||
import { BattleType, BattlerIndex, TurnCommand } from "./battle";
|
import { BattleType, BattlerIndex, TurnCommand } from "./battle";
|
||||||
|
@ -1772,6 +1772,9 @@ export class BattleEndPhase extends BattlePhase {
|
||||||
pokemon.resetBattleSummonData();
|
pokemon.resetBattleSummonData();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (let pokemon of this.scene.getParty())
|
||||||
|
applyPostBattleAbAttrs(PostBattleAbAttr, pokemon);
|
||||||
|
|
||||||
this.scene.clearEnemyHeldItemModifiers();
|
this.scene.clearEnemyHeldItemModifiers();
|
||||||
|
|
||||||
const lapsingModifiers = this.scene.findModifiers(m => m instanceof LapsingPersistentModifier || m instanceof LapsingPokemonHeldItemModifier) as (LapsingPersistentModifier | LapsingPokemonHeldItemModifier)[];
|
const lapsingModifiers = this.scene.findModifiers(m => m instanceof LapsingPersistentModifier || m instanceof LapsingPokemonHeldItemModifier) as (LapsingPersistentModifier | LapsingPokemonHeldItemModifier)[];
|
||||||
|
@ -2688,6 +2691,8 @@ export class FaintPhase extends PokemonPhase {
|
||||||
pokemon.trySetStatus(StatusEffect.FAINT);
|
pokemon.trySetStatus(StatusEffect.FAINT);
|
||||||
if (pokemon.isPlayer())
|
if (pokemon.isPlayer())
|
||||||
this.scene.currentBattle.removeFaintedParticipant(pokemon as PlayerPokemon);
|
this.scene.currentBattle.removeFaintedParticipant(pokemon as PlayerPokemon);
|
||||||
|
else
|
||||||
|
this.scene.currentBattle.addPostBattleLoot(pokemon as EnemyPokemon);
|
||||||
this.scene.field.remove(pokemon);
|
this.scene.field.remove(pokemon);
|
||||||
this.end();
|
this.end();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue