Add King's Rock and more berry types
This commit is contained in:
1 parent
3753ea73be
commit
a148ecab80
19 files changed
+1417
-1104
No files matched your search
+26
-1
@@ -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
@@ -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
@@ -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),
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in new issue
Block a user