Implement Slow Start ability

This commit is contained in:
Flashfyre 2023-12-22 22:46:05 -05:00
parent 0b5adbb43c
commit 2bb1676d82
5 changed files with 108 additions and 49 deletions

View File

@ -512,9 +512,7 @@ export class PostSummonPhase extends PokemonPhase {
const pokemon = this.getPokemon();
this.scene.arena.applyTags(ArenaTrapTag, pokemon);
applyPostSummonAbAttrs(PostSummonAbAttr, pokemon);
this.end();
applyPostSummonAbAttrs(PostSummonAbAttr, pokemon).then(() => this.end());
}
}

View File

@ -1197,8 +1197,12 @@ export default class BattleScene extends Phaser.Scene {
this.currentPhase.start();
}
queueMessage(message: string, callbackDelay?: integer, prompt?: boolean, promptDelay?: integer) {
this.unshiftPhase(new MessagePhase(this, message, callbackDelay, prompt, promptDelay));
queueMessage(message: string, callbackDelay?: integer, prompt?: boolean, promptDelay?: integer, defer?: boolean) {
const phase = new MessagePhase(this, message, callbackDelay, prompt, promptDelay);
if (!defer)
this.unshiftPhase(phase);
else
this.pushPhase(phase);
}
populatePhaseQueue(): void {

View File

@ -530,8 +530,8 @@ export class PostSummonAddBattlerTagAbAttr extends PostSummonAbAttr {
private tagType: BattlerTagType;
private turnCount: integer;
constructor(tagType: BattlerTagType, turnCount: integer) {
super(false);
constructor(tagType: BattlerTagType, turnCount: integer, showAbility?: boolean) {
super(showAbility);
this.tagType = tagType;
this.turnCount = turnCount;
@ -1498,7 +1498,7 @@ export function initAbilities() {
.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.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),
.attr(PostSummonAddBattlerTagAbAttr, BattlerTagType.TRUANT, 1, false),
new Ability(Abilities.HUSTLE, "Hustle", "Boosts the Attack stat, but lowers accuracy.", 3)
.attr(BattleStatMultiplierAbAttr, BattleStat.ATK, 1.5)
.attr(BattleStatMultiplierAbAttr, BattleStat.ACC, 0.8),
@ -1591,7 +1591,8 @@ export function initAbilities() {
.attr(IgnoreOpponentStatChangesAbAttr),
new Ability(Abilities.TINTED_LENS, "Tinted Lens (N)", "The Pokémon can use \"not very effective\" moves to deal regular damage.", 4),
new Ability(Abilities.FILTER, "Filter (N)", "Reduces the power of supereffective attacks taken.", 4),
new Ability(Abilities.SLOW_START, "Slow Start (N)", "For five turns, the Pokémon's Attack and Speed stats are halved.", 4),
new Ability(Abilities.SLOW_START, "Slow Start", "For five turns, the Pokémon's Attack and Speed stats are halved.", 4)
.attr(PostSummonAddBattlerTagAbAttr, BattlerTagType.SLOW_START, 5),
new Ability(Abilities.SCRAPPY, "Scrappy (N)", "The Pokémon can hit Ghost-type Pokémon with Normal- and Fighting-type moves.", 4),
new Ability(Abilities.STORM_DRAIN, "Storm Drain", "Draws in all Water-type moves. Instead of being hit by Water-type moves, it boosts its Sp. Atk.", 4)
.attr(TypeImmunityStatChangeAbAttr, Type.WATER, BattleStat.SPATK, 1),

View File

@ -10,38 +10,39 @@ import { Type } from "./type";
import { Abilities } from "./ability";
export enum BattlerTagType {
NONE,
RECHARGING,
FLINCHED,
CONFUSED,
INFATUATED,
SEEDED,
NIGHTMARE,
FRENZY,
ENCORE,
INGRAIN,
AQUA_RING,
DROWSY,
TRAPPED,
BIND,
WRAP,
FIRE_SPIN,
WHIRLPOOL,
CLAMP,
SAND_TOMB,
MAGMA_STORM,
PROTECTED,
PERISH_SONG,
TRUANT,
FLYING,
UNDERGROUND,
HIDDEN,
FIRE_BOOST,
CRIT_BOOST,
NO_CRIT,
IGNORE_ACCURACY,
BYPASS_SLEEP,
IGNORE_FLYING
NONE = "NONE",
RECHARGING = "RECHARGING",
FLINCHED = "FLINCHED",
CONFUSED = "CONFUSED",
INFATUATED = "INFATUATED",
SEEDED = "SEEDED",
NIGHTMARE = "NIGHTMARE",
FRENZY = "FRENZY",
ENCORE = "ENCORE",
INGRAIN = "INGRAIN",
AQUA_RING = "AQUA_RING",
DROWSY = "DROWSY",
TRAPPED = "TRAPPED",
BIND = "BIND",
WRAP = "WRAP",
FIRE_SPIN = "FIRE_SPIN",
WHIRLPOOL = "WHIRLPOOL",
CLAMP = "CLAMP",
SAND_TOMB = "SAND_TOMB",
MAGMA_STORM = "MAGMA_STORM",
PROTECTED = "PROTECTED",
PERISH_SONG = "PERISH_SONG",
TRUANT = "TRUANT",
SLOW_START = "SLOW_START",
FLYING = "FLYING",
UNDERGROUND = "UNDERGROUND",
HIDDEN = "HIDDEN",
FIRE_BOOST = "FIRE_BOOST",
CRIT_BOOST = "CRIT_BOOST",
NO_CRIT = "NO_CRIT",
IGNORE_ACCURACY = "IGNORE_ACCURACY",
BYPASS_SLEEP = "BYPASS_SLEEP",
IGNORE_FLYING = "IGNORE_FLYING"
}
export enum BattlerTagLapseType {
@ -616,9 +617,19 @@ export class PerishSongTag extends BattlerTag {
}
}
export class TruantTag extends BattlerTag {
export class AbilityBattlerTag extends BattlerTag {
public ability: Abilities;
constructor(tagType: BattlerTagType, ability: Abilities, lapseType: BattlerTagLapseType, turnCount: integer) {
super(tagType, lapseType, turnCount, undefined);
this.ability = ability;
}
}
export class TruantTag extends AbilityBattlerTag {
constructor() {
super(BattlerTagType.TRUANT, BattlerTagLapseType.MOVE, 1, undefined);
super(BattlerTagType.TRUANT, Abilities.TRUANT, BattlerTagLapseType.MOVE, 1);
}
lapse(pokemon: Pokemon, lapseType: BattlerTagLapseType): boolean {
@ -637,6 +648,31 @@ export class TruantTag extends BattlerTag {
}
}
export class SlowStartTag extends AbilityBattlerTag {
constructor() {
super(BattlerTagType.SLOW_START, Abilities.SLOW_START, BattlerTagLapseType.TURN_END, 5);
}
onAdd(pokemon: Pokemon): void {
super.onAdd(pokemon);
pokemon.scene.queueMessage(getPokemonMessage(pokemon, ' can\'t\nget it going!'), null, false, null, true);
}
lapse(pokemon: Pokemon, lapseType: BattlerTagLapseType): boolean {
if (pokemon.getAbility().id !== this.ability)
this.turnCount = 1;
return super.lapse(pokemon, lapseType);
}
onRemove(pokemon: Pokemon): void {
super.onRemove(pokemon);
pokemon.scene.queueMessage(getPokemonMessage(pokemon, ' finally\ngot its act together!'), null, false, null);
}
}
export class HideSpriteTag extends BattlerTag {
constructor(tagType: BattlerTagType, turnCount: integer, sourceMove: Moves) {
super(tagType, BattlerTagLapseType.MOVE_EFFECT, turnCount, sourceMove);
@ -745,6 +781,8 @@ export function getBattlerTag(tagType: BattlerTagType, turnCount: integer, sourc
return new PerishSongTag(turnCount);
case BattlerTagType.TRUANT:
return new TruantTag();
case BattlerTagType.SLOW_START:
return new SlowStartTag();
case BattlerTagType.FLYING:
case BattlerTagType.UNDERGROUND:
case BattlerTagType.HIDDEN:

View File

@ -451,10 +451,28 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
const statValue = new Utils.NumberHolder(this.getStat(stat));
applyBattleStatMultiplierAbAttrs(BattleStatMultiplierAbAttr, this, battleStat, statValue);
let ret = statValue.value * (Math.max(2, 2 + statLevel.value) / Math.max(2, 2 - statLevel.value));
if (stat === Stat.SPDEF && this.scene.arena.weather?.weatherType === WeatherType.SANDSTORM)
ret *= 1.5;
if (stat === Stat.SPD && this.status && this.status.effect === StatusEffect.PARALYSIS)
ret >>= 2;
switch (stat) {
case Stat.ATK:
if (this.getTag(BattlerTagType.SLOW_START))
ret >>= 1;
console.log(ret, this.name);
break;
case Stat.DEF:
break;
case Stat.SPATK:
break;
case Stat.SPDEF:
if (this.scene.arena.weather?.weatherType === WeatherType.SANDSTORM)
ret *= 1.5;
break;
case Stat.SPD:
if (this.getTag(BattlerTagType.SLOW_START))
ret >>= 1;
if (this.status && this.status.effect === StatusEffect.PARALYSIS)
ret >>= 2;
break;
}
return Math.floor(ret);
}
@ -1071,7 +1089,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
getTag(tagType: BattlerTagType | { new(...args: any[]): BattlerTag }): BattlerTag {
if (!this.summonData)
return null;
return typeof(tagType) === 'number'
return typeof(tagType) === 'string'
? this.summonData.tags.find(t => t.tagType === tagType)
: this.summonData.tags.find(t => t instanceof tagType);
}
@ -1085,7 +1103,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
getTags(tagType: BattlerTagType | { new(...args: any[]): BattlerTag }): BattlerTag[] {
if (!this.summonData)
return [];
return typeof(tagType) === 'number'
return typeof(tagType) === 'string'
? this.summonData.tags.filter(t => t.tagType === tagType)
: this.summonData.tags.filter(t => t instanceof tagType);
}