Add King's Rock and more berry types

This commit is contained in:
Flashfyre committed 2023-04-25 01:32:48 -04:00
1 parent 3753ea73be
commit a148ecab80
19 files changed
+1417 -1104

No files matched your search

+26 -1
View File
@@ -5,7 +5,7 @@ import Pokemon from "../pokemon";
import { Stat } from "./pokemon-stat";
import { StatusEffect } from "./status-effect";
import * as Utils from "../utils";
import { Moves, allMoves } from "./move";
import { LapseBattlerTagAttr, Moves, allMoves } from "./move";
import { Type } from "./type";
export enum BattlerTagType {
@@ -30,6 +30,7 @@ export enum BattlerTagType {
PROTECTED,
FLYING,
UNDERGROUND,
CRIT_BOOST,
NO_CRIT,
BYPASS_SLEEP,
IGNORE_FLYING
@@ -462,6 +463,28 @@ export class HideSpriteTag extends BattlerTag {
}
}
export class CritBoostTag extends BattlerTag {
constructor(tagType: BattlerTagType, sourceMove: Moves) {
super(tagType, BattlerTagLapseType.TURN_END, 1, sourceMove);
}
onAdd(pokemon: Pokemon): void {
super.onAdd(pokemon);
pokemon.scene.queueMessage(getPokemonMessage(pokemon, ' is getting\npumped!'));
}
lapse(pokemon: Pokemon, lapseType: BattlerTagLapseType): boolean {
return lapseType !== BattlerTagLapseType.CUSTOM || super.lapse(pokemon, lapseType);
}
onRemove(pokemon: Pokemon): void {
super.onRemove(pokemon);
pokemon.scene.queueMessage(getPokemonMessage(pokemon, ' relaxed.'));
}
}
export function getBattlerTag(tagType: BattlerTagType, turnCount: integer, sourceMove: Moves, sourceId: integer): BattlerTag {
switch (tagType) {
case BattlerTagType.RECHARGING:
@@ -501,6 +524,8 @@ export function getBattlerTag(tagType: BattlerTagType, turnCount: integer, sourc
case BattlerTagType.FLYING:
case BattlerTagType.UNDERGROUND:
return new HideSpriteTag(tagType, turnCount, sourceMove);
case BattlerTagType.CRIT_BOOST:
return new CritBoostTag(tagType, sourceMove);
case BattlerTagType.NO_CRIT:
return new BattlerTag(tagType, BattlerTagLapseType.AFTER_MOVE, turnCount, sourceMove);
case BattlerTagType.BYPASS_SLEEP:
+63 -9
View File
@@ -1,21 +1,26 @@
import { MessagePhase, PokemonHealPhase } from "../battle-phases";
import { PokemonHealPhase, StatChangePhase } from "../battle-phases";
import { getPokemonMessage } from "../messages";
import Pokemon from "../pokemon";
import Pokemon, { MoveResult } from "../pokemon";
import { getBattleStatName } from "./battle-stat";
import { BattleStat } from "./battle-stat";
import { BattlerTagType } from "./battler-tag";
import { getStatusEffectHealText } from "./status-effect";
export enum BerryType {
SITRUS,
LUM
LUM,
ENIGMA,
LIECHI,
GANLON,
SALAC,
PETAYA,
APICOT,
LANSAT,
STARF
}
export function getBerryName(berryType: BerryType) {
switch (berryType) {
case BerryType.SITRUS:
return 'SITRUS BERRY';
case BerryType.LUM:
return 'LUM BERRY';
}
return `${BerryType[berryType]} BERRY`;
}
export function getBerryEffectDescription(berryType: BerryType) {
@@ -24,6 +29,19 @@ export function getBerryEffectDescription(berryType: BerryType) {
return 'Restores 25% HP if HP is below 50%';
case BerryType.LUM:
return 'Cures any non-volatile status condition and confusion';
case BerryType.ENIGMA:
return 'Restores 25% HP if hit by a super effective move';
case BerryType.LIECHI:
case BerryType.GANLON:
case BerryType.SALAC:
case BerryType.PETAYA:
case BerryType.APICOT:
const stat = (berryType - BerryType.LIECHI) as BattleStat;
return `Raises ${getBattleStatName(stat)} if HP is below 25%`;
case BerryType.LANSAT:
return 'Raises critical hit ratio if HP is below 25%';
case BerryType.STARF:
return 'Sharply raises a random stat if HP is below 25%';
}
}
@@ -35,6 +53,26 @@ export function getBerryPredicate(berryType: BerryType): BerryPredicate {
return (pokemon: Pokemon) => pokemon.getHpRatio() < 0.5;
case BerryType.LUM:
return (pokemon: Pokemon) => !!pokemon.status || !!pokemon.getTag(BattlerTagType.CONFUSED);
case BerryType.ENIGMA:
return (pokemon: Pokemon) => {
const opponent = pokemon.isPlayer() ? pokemon.scene.getEnemyPokemon() : pokemon.scene.getPlayerPokemon();
const opponentLastMove = opponent ? opponent.getLastXMoves(1).find(() => true) : null; // TODO: Update so this works even if opponent has fainted
return opponentLastMove && opponentLastMove.turn === pokemon.scene.currentBattle?.turn - 1 && opponentLastMove.result === MoveResult.SUPER_EFFECTIVE;
};
case BerryType.LIECHI:
case BerryType.GANLON:
case BerryType.SALAC:
case BerryType.PETAYA:
case BerryType.APICOT:
return (pokemon: Pokemon) => {
const battleStat = (berryType - BerryType.LIECHI) as BattleStat;
return pokemon.getHpRatio() < 0.25 && pokemon.summonData.battleStats[battleStat] < 6;
};
case BerryType.LANSAT:
return (pokemon: Pokemon) => pokemon.getHpRatio() < 0.25 && !pokemon.getTag(BattlerTagType.CRIT_BOOST);
case BerryType.STARF:
return (pokemon: Pokemon) => pokemon.getHpRatio() < 0.25;
}
}
@@ -43,6 +81,7 @@ export type BerryEffectFunc = (pokemon: Pokemon) => void;
export function getBerryEffectFunc(berryType: BerryType): BerryEffectFunc {
switch (berryType) {
case BerryType.SITRUS:
case BerryType.ENIGMA:
return (pokemon: Pokemon) => {
pokemon.scene.unshiftPhase(new PokemonHealPhase(pokemon.scene, pokemon.isPlayer(), Math.floor(pokemon.getMaxHp() / 4), getPokemonMessage(pokemon, `'s ${getBerryName(berryType)}\nrestored its HP!`), true));
};
@@ -55,5 +94,20 @@ export function getBerryEffectFunc(berryType: BerryType): BerryEffectFunc {
} else if (pokemon.getTag(BattlerTagType.CONFUSED))
pokemon.lapseTag(BattlerTagType.CONFUSED);
};
case BerryType.LIECHI:
case BerryType.GANLON:
case BerryType.SALAC:
case BerryType.PETAYA:
case BerryType.APICOT:
return (pokemon: Pokemon) => {
const battleStat = (berryType - BerryType.LIECHI) as BattleStat;
pokemon.scene.unshiftPhase(new StatChangePhase(pokemon.scene, pokemon.isPlayer(), [ battleStat ], 1));
};
case BerryType.LANSAT:
return (pokemon: Pokemon) => {
pokemon.addTag(BattlerTagType.CRIT_BOOST);
};
case BerryType.STARF:
return (pokemon: Pokemon) => pokemon.scene.unshiftPhase(new StatChangePhase(pokemon.scene, pokemon.isPlayer(), [ BattleStat.RAND ], 2));
}
}
+10 -3
View File
@@ -9,6 +9,7 @@ import { Type } from "./type";
import * as Utils from "../utils";
import { WeatherType } from "./weather";
import { ArenaTagType, ArenaTrapTag } from "./arena-tag";
import { FlinchChanceModifier } from "../modifier/modifier";
export enum MoveCategory {
PHYSICAL,
@@ -1037,7 +1038,7 @@ export class ChargeAttr extends OverrideMoveEffectAttr {
user.addTag(this.tagType, 1, move.id, user.id);
if (this.chargeEffect)
applyMoveAttrs(MoveEffectAttr, user, target, move);
user.getMoveHistory().push({ move: move.id, result: MoveResult.OTHER });
user.pushMoveHistory({ move: move.id, result: MoveResult.OTHER });
user.getMoveQueue().push({ move: move.id, ignorePP: true });
resolve(true);
});
@@ -1427,7 +1428,8 @@ export class AddBattlerTagAttr extends MoveEffectAttr {
if (!super.apply(user, target, move, args))
return false;
if (move.chance < 0 || move.chance === 100 || Utils.randInt(100) < move.chance) {
const chance = this.getTagChance(user, target, move);
if (chance < 0 || chance === 100 || Utils.randInt(100) < chance) {
(this.selfTarget ? user : target).addTag(this.tagType, this.turnCount, move.id, user.id);
return true;
}
@@ -1435,6 +1437,10 @@ export class AddBattlerTagAttr extends MoveEffectAttr {
return false;
}
getTagChance(user: Pokemon, target: Pokemon, move: Move): integer {
return move.chance;
}
getCondition(): MoveCondition {
return this.failOnOverlap
? (user: Pokemon, target: Pokemon, move: Move) => !(this.selfTarget ? user : target).getTag(this.tagType)
@@ -1925,7 +1931,8 @@ export const allMoves = [
new SelfStatusMove(Moves.LIGHT_SCREEN, "Light Screen (N)", Type.PSYCHIC, -1, 30, 75, "Halves damage from Special attacks for 5 turns.", -1, 0, 1),
new SelfStatusMove(Moves.HAZE, "Haze (N)", Type.ICE, -1, 30, -1, "Resets all stat changes.", -1, 0, 1),
new SelfStatusMove(Moves.REFLECT, "Reflect (N)", Type.PSYCHIC, -1, 20, 74, "Halves damage from Physical attacks for 5 turns.", -1, 0, 1),
new SelfStatusMove(Moves.FOCUS_ENERGY, "Focus Energy (N)", Type.NORMAL, -1, 30, -1, "Increases critical hit ratio.", -1, 0, 1),
new SelfStatusMove(Moves.FOCUS_ENERGY, "Focus Energy", Type.NORMAL, -1, 30, -1, "Increases critical hit ratio.", -1, 0, 1)
.attr(AddBattlerTagAttr, BattlerTagType.CRIT_BOOST, true, undefined, true),
new AttackMove(Moves.BIDE, "Bide (N)", Type.NORMAL, MoveCategory.PHYSICAL, -1, -1, 10, -1, "User takes damage for two turns then strikes back double.", -1, 0, 1),
new SelfStatusMove(Moves.METRONOME, "Metronome", Type.NORMAL, -1, 10, 80, "User performs almost any move in the game at random.", -1, 0, 1)
.attr(RandomMoveAttr),
+3 -3
View File
@@ -1,5 +1,5 @@
import { Gender } from "./gender";
import { AttackTypeBoosterModifier } from "../modifier/modifier";
import { AttackTypeBoosterModifier, FlinchChanceModifier } from "../modifier/modifier";
import { AttackTypeBoosterModifierType } from "../modifier/modifier-type";
import { Moves } from "./move";
import { PokeballType } from "./pokeball";
@@ -167,7 +167,7 @@ export const pokemonEvolutions: PokemonEvolutions = {
],
[Species.SLOWPOKE]: [
new SpeciesEvolution(Species.SLOWBRO, 37, null, null),
new SpeciesEvolution(Species.SLOWKING, 1, EvolutionItem.LINKING_CORD, new SpeciesEvolutionCondition((p: Pokemon) => true /* King's rock*/), SpeciesWildEvolutionDelay.VERY_LONG)
new SpeciesEvolution(Species.SLOWKING, 1, EvolutionItem.LINKING_CORD, new SpeciesEvolutionCondition((p: Pokemon) => !!p.scene.findModifier(m => (m instanceof FlinchChanceModifier) && (m as FlinchChanceModifier).pokemonId === p.id, true)), SpeciesWildEvolutionDelay.VERY_LONG)
],
[Species.MAGNEMITE]: [
new SpeciesEvolution(Species.MAGNETON, 30, null, null)
@@ -779,7 +779,7 @@ export const pokemonEvolutions: PokemonEvolutions = {
],
[Species.POLIWHIRL]: [
new SpeciesEvolution(Species.POLIWRATH, 1, EvolutionItem.WATER_STONE, null, SpeciesWildEvolutionDelay.LONG),
new SpeciesEvolution(Species.POLITOED, 1, EvolutionItem.LINKING_CORD, new SpeciesEvolutionCondition((p: Pokemon) => true /* King's rock*/), SpeciesWildEvolutionDelay.VERY_LONG)
new SpeciesEvolution(Species.POLITOED, 1, EvolutionItem.LINKING_CORD, new SpeciesEvolutionCondition((p: Pokemon) => !!p.scene.findModifier(m => (m instanceof FlinchChanceModifier) && (m as FlinchChanceModifier).pokemonId === p.id, true)), SpeciesWildEvolutionDelay.VERY_LONG)
],
[Species.WEEPINBELL]: [
new SpeciesEvolution(Species.VICTREEBEL, 1, EvolutionItem.LEAF_STONE, null, SpeciesWildEvolutionDelay.LONG)