Implement Slow Start ability

pull/14/head
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(); const pokemon = this.getPokemon();
this.scene.arena.applyTags(ArenaTrapTag, pokemon); this.scene.arena.applyTags(ArenaTrapTag, pokemon);
applyPostSummonAbAttrs(PostSummonAbAttr, pokemon); applyPostSummonAbAttrs(PostSummonAbAttr, pokemon).then(() => this.end());
this.end();
} }
} }

View File

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

View File

@ -530,8 +530,8 @@ export class PostSummonAddBattlerTagAbAttr extends PostSummonAbAttr {
private tagType: BattlerTagType; private tagType: BattlerTagType;
private turnCount: integer; private turnCount: integer;
constructor(tagType: BattlerTagType, turnCount: integer) { constructor(tagType: BattlerTagType, turnCount: integer, showAbility?: boolean) {
super(false); super(showAbility);
this.tagType = tagType; this.tagType = tagType;
this.turnCount = turnCount; this.turnCount = turnCount;
@ -1498,7 +1498,7 @@ export function initAbilities() {
.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 (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) 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) new Ability(Abilities.HUSTLE, "Hustle", "Boosts the Attack stat, but lowers accuracy.", 3)
.attr(BattleStatMultiplierAbAttr, BattleStat.ATK, 1.5) .attr(BattleStatMultiplierAbAttr, BattleStat.ATK, 1.5)
.attr(BattleStatMultiplierAbAttr, BattleStat.ACC, 0.8), .attr(BattleStatMultiplierAbAttr, BattleStat.ACC, 0.8),
@ -1591,7 +1591,8 @@ export function initAbilities() {
.attr(IgnoreOpponentStatChangesAbAttr), .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.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.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.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) 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), .attr(TypeImmunityStatChangeAbAttr, Type.WATER, BattleStat.SPATK, 1),

View File

@ -10,38 +10,39 @@ import { Type } from "./type";
import { Abilities } from "./ability"; import { Abilities } from "./ability";
export enum BattlerTagType { export enum BattlerTagType {
NONE, NONE = "NONE",
RECHARGING, RECHARGING = "RECHARGING",
FLINCHED, FLINCHED = "FLINCHED",
CONFUSED, CONFUSED = "CONFUSED",
INFATUATED, INFATUATED = "INFATUATED",
SEEDED, SEEDED = "SEEDED",
NIGHTMARE, NIGHTMARE = "NIGHTMARE",
FRENZY, FRENZY = "FRENZY",
ENCORE, ENCORE = "ENCORE",
INGRAIN, INGRAIN = "INGRAIN",
AQUA_RING, AQUA_RING = "AQUA_RING",
DROWSY, DROWSY = "DROWSY",
TRAPPED, TRAPPED = "TRAPPED",
BIND, BIND = "BIND",
WRAP, WRAP = "WRAP",
FIRE_SPIN, FIRE_SPIN = "FIRE_SPIN",
WHIRLPOOL, WHIRLPOOL = "WHIRLPOOL",
CLAMP, CLAMP = "CLAMP",
SAND_TOMB, SAND_TOMB = "SAND_TOMB",
MAGMA_STORM, MAGMA_STORM = "MAGMA_STORM",
PROTECTED, PROTECTED = "PROTECTED",
PERISH_SONG, PERISH_SONG = "PERISH_SONG",
TRUANT, TRUANT = "TRUANT",
FLYING, SLOW_START = "SLOW_START",
UNDERGROUND, FLYING = "FLYING",
HIDDEN, UNDERGROUND = "UNDERGROUND",
FIRE_BOOST, HIDDEN = "HIDDEN",
CRIT_BOOST, FIRE_BOOST = "FIRE_BOOST",
NO_CRIT, CRIT_BOOST = "CRIT_BOOST",
IGNORE_ACCURACY, NO_CRIT = "NO_CRIT",
BYPASS_SLEEP, IGNORE_ACCURACY = "IGNORE_ACCURACY",
IGNORE_FLYING BYPASS_SLEEP = "BYPASS_SLEEP",
IGNORE_FLYING = "IGNORE_FLYING"
} }
export enum BattlerTagLapseType { 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() { constructor() {
super(BattlerTagType.TRUANT, BattlerTagLapseType.MOVE, 1, undefined); super(BattlerTagType.TRUANT, Abilities.TRUANT, BattlerTagLapseType.MOVE, 1);
} }
lapse(pokemon: Pokemon, lapseType: BattlerTagLapseType): boolean { 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 { export class HideSpriteTag extends BattlerTag {
constructor(tagType: BattlerTagType, turnCount: integer, sourceMove: Moves) { constructor(tagType: BattlerTagType, turnCount: integer, sourceMove: Moves) {
super(tagType, BattlerTagLapseType.MOVE_EFFECT, turnCount, sourceMove); super(tagType, BattlerTagLapseType.MOVE_EFFECT, turnCount, sourceMove);
@ -745,6 +781,8 @@ export function getBattlerTag(tagType: BattlerTagType, turnCount: integer, sourc
return new PerishSongTag(turnCount); return new PerishSongTag(turnCount);
case BattlerTagType.TRUANT: case BattlerTagType.TRUANT:
return new TruantTag(); return new TruantTag();
case BattlerTagType.SLOW_START:
return new SlowStartTag();
case BattlerTagType.FLYING: case BattlerTagType.FLYING:
case BattlerTagType.UNDERGROUND: case BattlerTagType.UNDERGROUND:
case BattlerTagType.HIDDEN: 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)); const statValue = new Utils.NumberHolder(this.getStat(stat));
applyBattleStatMultiplierAbAttrs(BattleStatMultiplierAbAttr, this, battleStat, statValue); applyBattleStatMultiplierAbAttrs(BattleStatMultiplierAbAttr, this, battleStat, statValue);
let ret = statValue.value * (Math.max(2, 2 + statLevel.value) / Math.max(2, 2 - statLevel.value)); 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) 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; ret *= 1.5;
if (stat === Stat.SPD && this.status && this.status.effect === StatusEffect.PARALYSIS) break;
case Stat.SPD:
if (this.getTag(BattlerTagType.SLOW_START))
ret >>= 1;
if (this.status && this.status.effect === StatusEffect.PARALYSIS)
ret >>= 2; ret >>= 2;
break;
}
return Math.floor(ret); 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 { getTag(tagType: BattlerTagType | { new(...args: any[]): BattlerTag }): BattlerTag {
if (!this.summonData) if (!this.summonData)
return null; return null;
return typeof(tagType) === 'number' return typeof(tagType) === 'string'
? this.summonData.tags.find(t => t.tagType === tagType) ? this.summonData.tags.find(t => t.tagType === tagType)
: this.summonData.tags.find(t => t instanceof 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[] { getTags(tagType: BattlerTagType | { new(...args: any[]): BattlerTag }): BattlerTag[] {
if (!this.summonData) if (!this.summonData)
return []; return [];
return typeof(tagType) === 'number' return typeof(tagType) === 'string'
? this.summonData.tags.filter(t => t.tagType === tagType) ? this.summonData.tags.filter(t => t.tagType === tagType)
: this.summonData.tags.filter(t => t instanceof tagType); : this.summonData.tags.filter(t => t instanceof tagType);
} }