Add King's Rock and more berry types
Before Width: | Height: | Size: 19 KiB After Width: | Height: | Size: 21 KiB |
After Width: | Height: | Size: 290 B |
After Width: | Height: | Size: 295 B |
After Width: | Height: | Size: 336 B |
After Width: | Height: | Size: 322 B |
After Width: | Height: | Size: 347 B |
After Width: | Height: | Size: 375 B |
After Width: | Height: | Size: 345 B |
After Width: | Height: | Size: 320 B |
|
@ -5,7 +5,7 @@ import { allMoves, applyMoveAttrs, BypassSleepAttr, ChargeAttr, HitsTagAttr, Mis
|
|||
import { Mode } from './ui/ui';
|
||||
import { Command } from "./ui/command-ui-handler";
|
||||
import { Stat } from "./data/pokemon-stat";
|
||||
import { BerryModifier, ExpBalanceModifier, ExpBoosterModifier, ExpShareModifier, ExtraModifierModifier, HealingBoosterModifier, HeldItemTransferModifier, HitHealModifier, PokemonExpBoosterModifier, PokemonHeldItemModifier, TempBattleStatBoosterModifier, TurnHealModifier } from "./modifier/modifier";
|
||||
import { BerryModifier, ExpBalanceModifier, ExpBoosterModifier, ExpShareModifier, ExtraModifierModifier, FlinchChanceModifier, HealingBoosterModifier, HeldItemTransferModifier, HitHealModifier, PokemonExpBoosterModifier, PokemonHeldItemModifier, TempBattleStatBoosterModifier, TurnHealModifier } from "./modifier/modifier";
|
||||
import PartyUiHandler, { PartyOption, PartyUiMode } from "./ui/party-ui-handler";
|
||||
import { doPokeballBounceAnim, getPokeballAtlasKey, getPokeballCatchMultiplier, getPokeballTintColor, PokeballType } from "./data/pokeball";
|
||||
import { CommonAnim, CommonBattleAnim, MoveAnim, initMoveAnim, loadMoveAnimAssets } from "./data/battle-anims";
|
||||
|
@ -768,7 +768,7 @@ export abstract class MovePhase extends BattlePhase {
|
|||
}
|
||||
|
||||
if (this.cancelled) {
|
||||
this.pokemon.getMoveHistory().push({ move: Moves.NONE, result: MoveResult.FAILED });
|
||||
this.pokemon.pushMoveHistory({ move: Moves.NONE, result: MoveResult.FAILED });
|
||||
this.end();
|
||||
return;
|
||||
}
|
||||
|
@ -783,7 +783,7 @@ export abstract class MovePhase extends BattlePhase {
|
|||
if (success)
|
||||
this.scene.unshiftPhase(this.getEffectPhase());
|
||||
else {
|
||||
this.pokemon.getMoveHistory().push({ move: this.move.moveId, result: MoveResult.FAILED, virtual: this.move.virtual });
|
||||
this.pokemon.pushMoveHistory({ move: this.move.moveId, result: MoveResult.FAILED, virtual: this.move.virtual });
|
||||
this.scene.queueMessage('But it failed!');
|
||||
}
|
||||
|
||||
|
@ -900,7 +900,7 @@ abstract class MoveEffectPhase extends PokemonPhase {
|
|||
|
||||
if (!this.hitCheck()) {
|
||||
this.scene.queueMessage(getPokemonMessage(user, '\'s\nattack missed!'));
|
||||
user.getMoveHistory().push({ move: this.move.moveId, result: MoveResult.MISSED, virtual: this.move.virtual });
|
||||
user.pushMoveHistory({ move: this.move.moveId, result: MoveResult.MISSED, virtual: this.move.virtual });
|
||||
applyMoveAttrs(MissEffectAttr, user, target, this.move.getMove());
|
||||
this.end();
|
||||
return;
|
||||
|
@ -911,9 +911,15 @@ abstract class MoveEffectPhase extends PokemonPhase {
|
|||
new MoveAnim(this.move.getMove().id as Moves, user, target).play(this.scene, () => {
|
||||
const result = !isProtected ? target.apply(user, this.move) : MoveResult.NO_EFFECT;
|
||||
++user.turnData.hitCount;
|
||||
user.getMoveHistory().push({ move: this.move.moveId, result: result, virtual: this.move.virtual });
|
||||
user.pushMoveHistory({ move: this.move.moveId, result: result, virtual: this.move.virtual });
|
||||
if (result !== MoveResult.NO_EFFECT && result !== MoveResult.FAILED) {
|
||||
applyMoveAttrs(MoveEffectAttr, user, target, this.move.getMove());
|
||||
if (result < MoveResult.NO_EFFECT) {
|
||||
const flinched = new Utils.BooleanHolder(false);
|
||||
user.scene.applyModifiers(FlinchChanceModifier, user.isPlayer(), user, flinched);
|
||||
if (flinched.value)
|
||||
target.addTag(BattlerTagType.FLINCHED, undefined, this.move.moveId, user.id);
|
||||
}
|
||||
// Charge attribute with charge effect takes all effect attributes and applies them to charge stage, so ignore them if this is present
|
||||
if (!isProtected && target.hp && !this.move.getMove().getAttrs(ChargeAttr).filter(ca => (ca as ChargeAttr).chargeEffect).length)
|
||||
applyMoveAttrs(MoveHitEffectAttr, user, target, this.move.getMove());
|
||||
|
|
|
@ -470,7 +470,7 @@ export default class BattleScene extends Phaser.Scene {
|
|||
|
||||
this.arenaBgTransition.setPosition(0, 0);
|
||||
this.arenaPlayer.setPosition(340, 20);
|
||||
this.arenaPlayerTransition.setPosition(40, 2);
|
||||
this.arenaPlayerTransition.setPosition(40, 20);
|
||||
this.arenaEnemy.setPosition(-240, 13);
|
||||
this.arenaNextEnemy.setPosition(-240, 13);
|
||||
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
}
|
|
@ -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)
|
||||
|
|
|
@ -35,7 +35,7 @@ export class ModifierType {
|
|||
constructor(name: string, description: string, newModifierFunc: NewModifierFunc, iconImage?: string, group?: string, soundName?: string) {
|
||||
this.name = name;
|
||||
this.description = description;
|
||||
this.iconImage = iconImage || name?.replace(/[ \-]/g, '_')?.toLowerCase();
|
||||
this.iconImage = iconImage || name?.replace(/[ \-]/g, '_')?.replace(/'/g, '')?.toLowerCase();
|
||||
this.group = group || '';
|
||||
this.soundName = soundName || 'restore';
|
||||
this.newModifierFunc = newModifierFunc;
|
||||
|
@ -497,7 +497,14 @@ const modifierTypes = {
|
|||
|
||||
BERRY: () => new ModifierTypeGenerator((party: Pokemon[]) => {
|
||||
const berryTypes = Utils.getEnumValues(BerryType);
|
||||
const randBerryType = berryTypes[Utils.randInt(berryTypes.length)];
|
||||
let randBerryType;
|
||||
let rand = Utils.randInt(10);
|
||||
if (rand < 2)
|
||||
randBerryType = BerryType.SITRUS;
|
||||
else if (rand < 4)
|
||||
randBerryType = BerryType.LUM;
|
||||
else
|
||||
randBerryType = berryTypes[Utils.randInt(berryTypes.length - 2) + 2];
|
||||
return new PokemonHeldItemModifierType(getBerryName(randBerryType), getBerryEffectDescription(randBerryType),
|
||||
(type, args) => new Modifiers.BerryModifier(type, (args[0] as Pokemon).id, randBerryType),
|
||||
null, 'berry');
|
||||
|
@ -521,6 +528,7 @@ const modifierTypes = {
|
|||
GOLDEN_EXP_CHARM: () => new ExpBoosterModifierType('GOLDEN EXP CHARM', 100),
|
||||
|
||||
LUCKY_EGG: () => new PokemonExpBoosterModifierType('LUCKY EGG', 50),
|
||||
GOLDEN_EGG: () => new PokemonExpBoosterModifierType('GOLDEN EGG', 200),
|
||||
|
||||
HEALING_CHARM: () => new ModifierType('HEALING CHARM', 'Doubles the effectiveness of HP restoring moves and items (excludes revives)',
|
||||
(type, _args) => new Modifiers.HealingBoosterModifier(type, 2), 'healing_charm'),
|
||||
|
@ -536,6 +544,9 @@ const modifierTypes = {
|
|||
FOCUS_BAND: () => new PokemonHeldItemModifierType('FOCUS BAND', 'Adds a 10% chance to survive with 1 HP after being damaged enough to faint',
|
||||
(type, args) => new Modifiers.SurviveDamageModifier(type, (args[0] as Pokemon).id)),
|
||||
|
||||
KINGS_ROCK: () => new PokemonHeldItemModifierType('KING\'S ROCK', 'Adds a 10% chance an attack move will cause the opponent to flinch',
|
||||
(type, args) => new Modifiers.FlinchChanceModifier(type, (args[0] as Pokemon).id)),
|
||||
|
||||
LEFTOVERS: () => new PokemonHeldItemModifierType('LEFTOVERS', 'Heals 1/16 of a POKéMON\'s maximum HP every turn',
|
||||
(type, args) => new Modifiers.TurnHealModifier(type, (args[0] as Pokemon).id)),
|
||||
SHELL_BELL: () => new PokemonHeldItemModifierType('SHELL BELL', 'Heals 1/8 of a POKéMON\'s dealt damage',
|
||||
|
@ -570,7 +581,7 @@ const modifierPool = {
|
|||
return thresholdPartyMemberCount;
|
||||
}),
|
||||
new WeightedModifierType(modifierTypes.TEMP_STAT_BOOSTER, 4),
|
||||
new WeightedModifierType(modifierTypes.BERRY, 2)
|
||||
new WeightedModifierType(modifierTypes.BERRY, 20)
|
||||
].map(m => { m.setTier(ModifierTier.COMMON); return m; }),
|
||||
[ModifierTier.GREAT]: [
|
||||
new WeightedModifierType(modifierTypes.GREAT_BALL, 6),
|
||||
|
@ -617,6 +628,7 @@ const modifierPool = {
|
|||
//new WeightedModifierType(modifierTypes.OVAL_CHARM, 1),
|
||||
new WeightedModifierType(modifierTypes.HEALING_CHARM, 1),
|
||||
new WeightedModifierType(modifierTypes.FOCUS_BAND, 3),
|
||||
new WeightedModifierType(modifierTypes.KINGS_ROCK, 2),
|
||||
new WeightedModifierType(modifierTypes.LEFTOVERS, 2),
|
||||
new WeightedModifierType(modifierTypes.SHELL_BELL, 2),
|
||||
new WeightedModifierType(modifierTypes.BERRY_POUCH, 3),
|
||||
|
@ -644,13 +656,15 @@ const enemyModifierPool = {
|
|||
new WeightedModifierType(modifierTypes.BASE_STAT_BOOSTER, 1)
|
||||
].map(m => { m.setTier(ModifierTier.GREAT); return m; }),
|
||||
[ModifierTier.ULTRA]: [
|
||||
new WeightedModifierType(modifierTypes.ATTACK_TYPE_BOOSTER, 5),
|
||||
new WeightedModifierType(modifierTypes.ATTACK_TYPE_BOOSTER, 10),
|
||||
new WeightedModifierType(modifierTypes.FOCUS_BAND, 2),
|
||||
new WeightedModifierType(modifierTypes.LUCKY_EGG, 2),
|
||||
new WeightedModifierType(modifierTypes.LUCKY_EGG, 4),
|
||||
new WeightedModifierType(modifierTypes.KINGS_ROCK, 1),
|
||||
new WeightedModifierType(modifierTypes.LEFTOVERS, 1),
|
||||
new WeightedModifierType(modifierTypes.SHELL_BELL, 1),
|
||||
].map(m => { m.setTier(ModifierTier.ULTRA); return m; }),
|
||||
[ModifierTier.MASTER]: [
|
||||
new WeightedModifierType(modifierTypes.LEFTOVERS, 4),
|
||||
new WeightedModifierType(modifierTypes.SHELL_BELL, 4),
|
||||
new WeightedModifierType(modifierTypes.GOLDEN_EGG, 1),
|
||||
new WeightedModifierType(modifierTypes.MINI_BLACK_HOLE, 1)
|
||||
].map(m => { m.setTier(ModifierTier.MASTER); return m; })
|
||||
};
|
||||
|
|
|
@ -370,7 +370,7 @@ export class SurviveDamageModifier extends PokemonHeldItemModifier {
|
|||
const pokemon = args[0] as Pokemon;
|
||||
const surviveDamage = args[1] as Utils.BooleanHolder;
|
||||
|
||||
if (!surviveDamage.value && (this.getStackCount() === this.getMaxStackCount() || Utils.randInt(10) < this.getStackCount())) {
|
||||
if (!surviveDamage.value && Utils.randInt(10) < this.getStackCount()) {
|
||||
surviveDamage.value = true;
|
||||
|
||||
pokemon.scene.queueMessage(getPokemonMessage(pokemon, ` hung on\nusing its ${this.type.name}!`));
|
||||
|
@ -384,6 +384,37 @@ export class SurviveDamageModifier extends PokemonHeldItemModifier {
|
|||
}
|
||||
}
|
||||
|
||||
export class FlinchChanceModifier extends PokemonHeldItemModifier {
|
||||
constructor(type: ModifierType, pokemonId: integer, stackCount?: integer) {
|
||||
super(type, pokemonId, stackCount);
|
||||
}
|
||||
|
||||
matchType(modifier: Modifier) {
|
||||
return modifier instanceof FlinchChanceModifier;
|
||||
}
|
||||
|
||||
clone() {
|
||||
return new FlinchChanceModifier(this.type, this.pokemonId, this.stackCount);
|
||||
}
|
||||
|
||||
shouldApply(args: any[]): boolean {
|
||||
return super.shouldApply(args) && args.length === 2 && args[1] instanceof Utils.BooleanHolder;
|
||||
}
|
||||
|
||||
apply(args: any[]): boolean {
|
||||
const flinched = args[1] as Utils.BooleanHolder;
|
||||
|
||||
if (!flinched.value && Utils.randInt(10) < this.getStackCount())
|
||||
flinched.value = true;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
getMaxStackCount(): number {
|
||||
return 3;
|
||||
}
|
||||
}
|
||||
|
||||
export class TurnHealModifier extends PokemonHeldItemModifier {
|
||||
constructor(type: ModifierType, pokemonId: integer, stackCount?: integer) {
|
||||
super(type, pokemonId, stackCount);
|
||||
|
|
|
@ -491,6 +491,8 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
|||
const critLevel = new Utils.IntegerHolder(0);
|
||||
applyMoveAttrs(HighCritAttr, source, this, move, critLevel);
|
||||
this.scene.applyModifiers(TempBattleStatBoosterModifier, source.isPlayer(), TempBattleStat.CRIT, critLevel);
|
||||
if (source.getTag(BattlerTagType.CRIT_BOOST))
|
||||
critLevel.value += 2;
|
||||
const critChance = Math.ceil(16 / Math.pow(2, critLevel.value));
|
||||
let isCritical = !source.getTag(BattlerTagType.NO_CRIT) && (critChance === 1 || !Utils.randInt(critChance));
|
||||
const sourceAtk = source.getBattleStat(isPhysical ? Stat.ATK : Stat.SPATK);
|
||||
|
@ -642,6 +644,11 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
|||
return this.summonData.moveHistory;
|
||||
}
|
||||
|
||||
pushMoveHistory(turnMove: TurnMove) {
|
||||
turnMove.turn = this.scene.currentBattle?.turn;
|
||||
this.getMoveHistory().push(turnMove);
|
||||
}
|
||||
|
||||
getLastXMoves(turnCount?: integer): TurnMove[] {
|
||||
const moveHistory = this.getMoveHistory();
|
||||
return moveHistory.slice(turnCount >= 0 ? Math.max(moveHistory.length - (turnCount || 1), 0) : 0, moveHistory.length).reverse();
|
||||
|
@ -1035,6 +1042,7 @@ export interface TurnMove {
|
|||
move: Moves;
|
||||
result: MoveResult;
|
||||
virtual?: boolean;
|
||||
turn?: integer;
|
||||
}
|
||||
|
||||
export interface QueuedMove {
|
||||
|
|