2023-04-12 11:57:15 -04:00
|
|
|
import * as ModifierTypes from './modifier-type';
|
2023-04-10 14:12:01 -04:00
|
|
|
import { LearnMovePhase, LevelUpPhase } from "./battle-phases";
|
2023-03-28 14:54:52 -04:00
|
|
|
import BattleScene from "./battle-scene";
|
2023-04-04 18:28:21 -04:00
|
|
|
import { getLevelTotalExp } from "./exp";
|
2023-04-12 11:57:15 -04:00
|
|
|
import { PokeballType } from "./pokeball";
|
|
|
|
import Pokemon, { PlayerPokemon } from "./pokemon";
|
|
|
|
import { Stat } from "./pokemon-stat";
|
2023-03-28 14:54:52 -04:00
|
|
|
import { addTextObject, TextStyle } from "./text";
|
|
|
|
import * as Utils from "./utils";
|
|
|
|
|
2023-04-12 11:57:15 -04:00
|
|
|
type ModifierType = ModifierTypes.ModifierType;
|
|
|
|
|
2023-03-28 14:54:52 -04:00
|
|
|
export class ModifierBar extends Phaser.GameObjects.Container {
|
|
|
|
constructor(scene: BattleScene) {
|
|
|
|
super(scene, 1, 2);
|
|
|
|
|
|
|
|
this.setScale(0.5);
|
|
|
|
}
|
|
|
|
|
2023-04-09 19:15:21 -04:00
|
|
|
updateModifiers(modifiers: PersistentModifier[]) {
|
|
|
|
this.removeAll(true);
|
|
|
|
|
|
|
|
for (let modifier of modifiers) {
|
|
|
|
const icon = modifier.getIcon(this.scene as BattleScene);
|
|
|
|
this.add(icon);
|
|
|
|
this.setModifierIconPosition(icon);
|
2023-03-28 14:54:52 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
setModifierIconPosition(icon: Phaser.GameObjects.Container) {
|
|
|
|
const x = (this.getIndex(icon) % 12) * 26;
|
|
|
|
const y = Math.floor((this.getIndex(icon) * 6) / (this.scene.game.canvas.width / 6)) * 20;
|
|
|
|
|
|
|
|
icon.setPosition(x, y);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
export abstract class Modifier {
|
|
|
|
public type: ModifierType;
|
|
|
|
|
|
|
|
constructor(type: ModifierType) {
|
|
|
|
this.type = type;
|
|
|
|
}
|
|
|
|
|
2023-04-09 19:15:21 -04:00
|
|
|
match(_modifier: Modifier): boolean {
|
|
|
|
return false;
|
2023-03-28 14:54:52 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
shouldApply(_args: any[]): boolean {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
abstract apply(args: any[]): boolean;
|
2023-04-09 19:15:21 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
export abstract class PersistentModifier extends Modifier {
|
|
|
|
public stackCount: integer;
|
|
|
|
public virtualStackCount: integer;
|
|
|
|
|
|
|
|
constructor(type: ModifierType) {
|
|
|
|
super(type);
|
|
|
|
this.stackCount = 1;
|
|
|
|
this.virtualStackCount = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
add(modifiers: PersistentModifier[], virtual: boolean): boolean {
|
|
|
|
for (let modifier of modifiers) {
|
|
|
|
if (this.match(modifier)) {
|
|
|
|
modifier.incrementStack(virtual);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (virtual) {
|
|
|
|
this.virtualStackCount += this.stackCount;
|
|
|
|
this.stackCount = 0;
|
|
|
|
}
|
|
|
|
modifiers.push(this);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
abstract clone(): PersistentModifier;
|
|
|
|
|
|
|
|
incrementStack(virtual: boolean): void {
|
|
|
|
if (this.getStackCount() < this.getMaxStackCount()) {
|
|
|
|
if (!virtual)
|
|
|
|
this.stackCount++;
|
|
|
|
else
|
|
|
|
this.virtualStackCount++;
|
|
|
|
}
|
|
|
|
}
|
2023-03-28 14:54:52 -04:00
|
|
|
|
2023-04-09 19:15:21 -04:00
|
|
|
getStackCount(): integer {
|
|
|
|
return this.stackCount + this.virtualStackCount;
|
2023-03-30 23:02:35 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
getMaxStackCount(): integer {
|
|
|
|
return 99;
|
2023-03-28 14:54:52 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
getIcon(scene: BattleScene): Phaser.GameObjects.Container {
|
|
|
|
const container = scene.add.container(0, 0);
|
|
|
|
|
|
|
|
const item = scene.add.sprite(0, 12, 'items');
|
|
|
|
item.setFrame(this.type.iconImage);
|
|
|
|
item.setOrigin(0, 0.5);
|
|
|
|
container.add(item);
|
|
|
|
|
|
|
|
const stackText = this.getIconStackText(scene);
|
|
|
|
if (stackText)
|
|
|
|
container.add(stackText);
|
|
|
|
|
2023-04-09 19:15:21 -04:00
|
|
|
const virtualStackText = this.getIconStackText(scene, true);
|
|
|
|
if (virtualStackText)
|
|
|
|
container.add(virtualStackText);
|
|
|
|
|
2023-03-28 14:54:52 -04:00
|
|
|
return container;
|
|
|
|
}
|
|
|
|
|
2023-04-09 19:15:21 -04:00
|
|
|
getIconStackText(scene: BattleScene, virtual?: boolean): Phaser.GameObjects.Text {
|
|
|
|
if (this.getMaxStackCount() === 1 || (virtual && !this.virtualStackCount))
|
2023-03-28 14:54:52 -04:00
|
|
|
return null;
|
|
|
|
|
2023-04-09 19:15:21 -04:00
|
|
|
const isStackMax = this.getStackCount() >= this.getMaxStackCount();
|
|
|
|
const maxColor = '#f89890';
|
|
|
|
const maxStrokeColor = '#984038';
|
|
|
|
|
|
|
|
if (virtual) {
|
|
|
|
const virtualText = addTextObject(scene, 1 * 11 + 16, 12, `+${this.virtualStackCount.toString()}`, TextStyle.PARTY, { fontSize: '66px', color: !isStackMax ? '#40c8f8' : maxColor });
|
|
|
|
virtualText.setShadow(0, 0, null);
|
|
|
|
virtualText.setStroke(!isStackMax ? '#006090' : maxStrokeColor, 16)
|
|
|
|
virtualText.setOrigin(1, 0);
|
|
|
|
|
|
|
|
return virtualText;
|
|
|
|
}
|
|
|
|
|
|
|
|
const text = addTextObject(scene, 8, 12, this.stackCount.toString(), TextStyle.PARTY, { fontSize: '66px', color: !isStackMax ? '#f8f8f8' : maxColor });
|
|
|
|
text.setShadow(0, 0, null);
|
2023-03-28 14:54:52 -04:00
|
|
|
text.setStroke('#424242', 16)
|
2023-04-09 19:15:21 -04:00
|
|
|
text.setOrigin(0, 0);
|
2023-03-28 14:54:52 -04:00
|
|
|
|
|
|
|
return text;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
export abstract class ConsumableModifier extends Modifier {
|
|
|
|
constructor(type: ModifierType) {
|
|
|
|
super(type);
|
|
|
|
}
|
|
|
|
|
2023-04-09 19:15:21 -04:00
|
|
|
add(_modifiers: Modifier[]): boolean {
|
2023-03-28 14:54:52 -04:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
shouldApply(args: any[]): boolean {
|
2023-03-30 23:02:35 -04:00
|
|
|
return super.shouldApply(args) && args.length === 1 && args[0] instanceof BattleScene;
|
2023-03-28 14:54:52 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-04-12 11:57:15 -04:00
|
|
|
export class AddPokeballModifier extends ConsumableModifier {
|
2023-03-28 14:54:52 -04:00
|
|
|
private pokeballType: PokeballType;
|
|
|
|
private count: integer;
|
|
|
|
|
|
|
|
constructor(type: ModifierType, pokeballType: PokeballType, count: integer) {
|
|
|
|
super(type);
|
|
|
|
|
|
|
|
this.pokeballType = pokeballType;
|
|
|
|
this.count = count;
|
|
|
|
}
|
|
|
|
|
|
|
|
apply(args: any[]): boolean {
|
2023-04-01 22:59:07 -04:00
|
|
|
const pokeballCounts = (args[0] as BattleScene).pokeballCounts;
|
|
|
|
pokeballCounts[this.pokeballType] = Math.min(pokeballCounts[this.pokeballType] + this.count, 99);
|
2023-03-28 14:54:52 -04:00
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-04-09 19:15:21 -04:00
|
|
|
export abstract class PokemonHeldItemModifier extends PersistentModifier {
|
2023-03-28 14:54:52 -04:00
|
|
|
public pokemonId: integer;
|
|
|
|
|
|
|
|
constructor(type: ModifierType, pokemonId: integer) {
|
|
|
|
super(type);
|
|
|
|
|
|
|
|
this.pokemonId = pokemonId;
|
|
|
|
}
|
|
|
|
|
|
|
|
shouldApply(args: any[]): boolean {
|
2023-03-30 23:02:35 -04:00
|
|
|
return super.shouldApply(args) && args.length && args[0] instanceof Pokemon && (this.pokemonId === -1 || (args[0] as Pokemon).id === this.pokemonId);
|
2023-03-28 14:54:52 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
getIcon(scene: BattleScene): Phaser.GameObjects.Container {
|
|
|
|
const container = scene.add.container(0, 0);
|
|
|
|
|
|
|
|
const pokemon = this.getPokemon(scene);
|
2023-04-09 19:15:21 -04:00
|
|
|
const pokemonIcon = scene.add.sprite(0, 8, pokemon.species.getIconAtlasKey());
|
|
|
|
pokemonIcon.play(pokemon.species.getIconKey()).stop();
|
2023-03-28 14:54:52 -04:00
|
|
|
pokemonIcon.setOrigin(0, 0.5);
|
|
|
|
|
|
|
|
container.add(pokemonIcon);
|
|
|
|
|
|
|
|
return container;
|
|
|
|
}
|
|
|
|
|
|
|
|
getPokemon(scene: BattleScene) {
|
|
|
|
return scene.getParty().find(p => p.id === this.pokemonId);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-04-09 19:15:21 -04:00
|
|
|
export class PokemonBaseStatModifier extends PokemonHeldItemModifier {
|
2023-03-28 14:54:52 -04:00
|
|
|
protected stat: Stat;
|
|
|
|
|
2023-04-12 11:57:15 -04:00
|
|
|
constructor(type: ModifierTypes.PokemonBaseStatBoosterModifierType, pokemonId: integer, stat: Stat) {
|
2023-03-28 14:54:52 -04:00
|
|
|
super(type, pokemonId);
|
|
|
|
this.stat = stat;
|
|
|
|
}
|
|
|
|
|
2023-04-09 19:15:21 -04:00
|
|
|
match(modifier: Modifier): boolean {
|
|
|
|
if (modifier instanceof PokemonBaseStatModifier) {
|
|
|
|
const pokemonStatModifier = modifier as PokemonBaseStatModifier;
|
|
|
|
return pokemonStatModifier.pokemonId === this.pokemonId && pokemonStatModifier.stat === this.stat;
|
2023-03-28 14:54:52 -04:00
|
|
|
}
|
2023-04-09 19:15:21 -04:00
|
|
|
return false;
|
|
|
|
}
|
2023-03-28 14:54:52 -04:00
|
|
|
|
2023-04-09 19:15:21 -04:00
|
|
|
clone(): PersistentModifier {
|
2023-04-12 11:57:15 -04:00
|
|
|
return new PokemonBaseStatModifier(this.type as ModifierTypes.PokemonBaseStatBoosterModifierType, this.pokemonId, this.stat);
|
2023-03-28 14:54:52 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
shouldApply(args: any[]): boolean {
|
|
|
|
return super.shouldApply(args) && args.length === 2 && args[1] instanceof Array<integer>;
|
|
|
|
}
|
|
|
|
|
|
|
|
apply(args: any[]): boolean {
|
2023-04-09 19:15:21 -04:00
|
|
|
args[1][this.stat] = Math.min(Math.floor(args[1][this.stat] * (1 + this.getStackCount() * 0.2)), 999999);
|
2023-03-28 14:54:52 -04:00
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
getIcon(scene: BattleScene): Phaser.GameObjects.Container {
|
|
|
|
const container = super.getIcon(scene);
|
|
|
|
|
2023-04-09 19:15:21 -04:00
|
|
|
const item = scene.add.sprite(16, this.virtualStackCount ? 8 : 16, 'items');
|
2023-03-28 14:54:52 -04:00
|
|
|
item.setScale(0.5);
|
|
|
|
item.setOrigin(0, 0.5);
|
|
|
|
item.setTexture('items', this.type.iconImage);
|
|
|
|
container.add(item);
|
|
|
|
|
|
|
|
const stackText = this.getIconStackText(scene);
|
|
|
|
if (stackText)
|
|
|
|
container.add(stackText);
|
|
|
|
|
2023-04-09 19:15:21 -04:00
|
|
|
const virtualStackText = this.getIconStackText(scene, true);
|
|
|
|
if (virtualStackText)
|
|
|
|
container.add(virtualStackText);
|
|
|
|
|
2023-03-28 14:54:52 -04:00
|
|
|
return container;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-04-09 19:15:21 -04:00
|
|
|
export abstract class ConsumablePokemonModifier extends ConsumableModifier {
|
|
|
|
public pokemonId: integer;
|
|
|
|
|
2023-03-28 14:54:52 -04:00
|
|
|
constructor(type: ModifierType, pokemonId: integer) {
|
2023-04-09 19:15:21 -04:00
|
|
|
super(type);
|
|
|
|
|
|
|
|
this.pokemonId = pokemonId;
|
2023-03-28 14:54:52 -04:00
|
|
|
}
|
|
|
|
|
2023-04-09 19:15:21 -04:00
|
|
|
shouldApply(args: any[]): boolean {
|
|
|
|
return args.length && args[0] instanceof Pokemon && (this.pokemonId === -1 || (args[0] as Pokemon).id === this.pokemonId);
|
|
|
|
}
|
|
|
|
|
|
|
|
getPokemon(scene: BattleScene) {
|
|
|
|
return scene.getParty().find(p => p.id === this.pokemonId);
|
2023-03-28 14:54:52 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
export class PokemonHpRestoreModifier extends ConsumablePokemonModifier {
|
2023-04-09 19:15:21 -04:00
|
|
|
private restorePoints: integer;
|
|
|
|
private percent: boolean;
|
2023-03-30 10:50:46 -04:00
|
|
|
private fainted: boolean;
|
2023-03-28 14:54:52 -04:00
|
|
|
|
2023-04-09 19:15:21 -04:00
|
|
|
constructor(type: ModifierType, pokemonId: integer, restorePoints: integer, percent: boolean, fainted?: boolean) {
|
2023-03-28 14:54:52 -04:00
|
|
|
super(type, pokemonId);
|
|
|
|
|
2023-04-09 19:15:21 -04:00
|
|
|
this.restorePoints = restorePoints;
|
|
|
|
this.percent = percent;
|
2023-03-30 10:50:46 -04:00
|
|
|
this.fainted = !!fainted;
|
2023-03-28 14:54:52 -04:00
|
|
|
}
|
|
|
|
|
2023-04-09 19:15:21 -04:00
|
|
|
shouldApply(args: any[]): boolean {
|
|
|
|
return super.shouldApply(args) && (this.fainted || (args.length > 1 && typeof(args[1]) === 'number'));
|
|
|
|
}
|
|
|
|
|
2023-03-28 14:54:52 -04:00
|
|
|
apply(args: any[]): boolean {
|
|
|
|
const pokemon = args[0] as Pokemon;
|
2023-04-09 19:15:21 -04:00
|
|
|
if (!pokemon.hp === this.fainted) {
|
|
|
|
let restorePoints = this.restorePoints;
|
|
|
|
if (!this.fainted)
|
|
|
|
restorePoints = Math.floor(restorePoints * (args[1] as number));
|
|
|
|
pokemon.hp = Math.min(pokemon.hp + (this.percent ? (restorePoints * 0.01) * pokemon.getMaxHp() : restorePoints), pokemon.getMaxHp());
|
|
|
|
}
|
2023-03-28 14:54:52 -04:00
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-04-11 11:04:39 -04:00
|
|
|
export abstract class ConsumablePokemonMoveModifier extends ConsumablePokemonModifier {
|
|
|
|
public moveIndex: integer;
|
2023-04-04 21:10:11 -04:00
|
|
|
|
2023-04-11 11:04:39 -04:00
|
|
|
constructor(type: ModifierType, pokemonId: integer, moveIndex: integer) {
|
2023-04-04 21:10:11 -04:00
|
|
|
super(type, pokemonId);
|
|
|
|
|
2023-04-11 11:04:39 -04:00
|
|
|
this.moveIndex = moveIndex;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
export class PokemonPpRestoreModifier extends ConsumablePokemonMoveModifier {
|
|
|
|
private restorePoints: integer;
|
|
|
|
|
|
|
|
constructor(type: ModifierType, pokemonId: integer, moveIndex: integer, restorePoints: integer) {
|
|
|
|
super(type, pokemonId, moveIndex);
|
|
|
|
|
2023-04-04 21:10:11 -04:00
|
|
|
this.restorePoints = restorePoints;
|
|
|
|
}
|
|
|
|
|
2023-04-11 11:04:39 -04:00
|
|
|
apply(args: any[]): boolean {
|
|
|
|
const pokemon = args[0] as Pokemon;
|
|
|
|
const move = pokemon.moveset[this.moveIndex];
|
|
|
|
console.log(move.ppUsed, this.restorePoints, this.restorePoints >= -1 ? Math.max(move.ppUsed - this.restorePoints, 0) : 0);
|
|
|
|
move.ppUsed = this.restorePoints >= -1 ? Math.max(move.ppUsed - this.restorePoints, 0) : 0;
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
export class PokemonAllMovePpRestoreModifier extends ConsumablePokemonModifier {
|
|
|
|
private restorePoints: integer;
|
|
|
|
|
|
|
|
constructor(type: ModifierType, pokemonId: integer, restorePoints: integer) {
|
|
|
|
super(type, pokemonId);
|
|
|
|
|
|
|
|
this.restorePoints = restorePoints;
|
2023-04-04 21:10:11 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
apply(args: any[]): boolean {
|
|
|
|
const pokemon = args[0] as Pokemon;
|
2023-04-11 11:04:39 -04:00
|
|
|
for (let move of pokemon.moveset)
|
|
|
|
move.ppUsed = this.restorePoints >= -1 ? Math.max(move.ppUsed - this.restorePoints, 0) : 0;
|
2023-04-04 21:10:11 -04:00
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-04-04 18:28:21 -04:00
|
|
|
export class PokemonLevelIncrementModifier extends ConsumablePokemonModifier {
|
|
|
|
constructor(type: ModifierType, pokemonId: integer) {
|
|
|
|
super(type, pokemonId);
|
|
|
|
}
|
|
|
|
|
|
|
|
apply(args: any[]): boolean {
|
|
|
|
const pokemon = args[0] as PlayerPokemon;
|
|
|
|
pokemon.level++;
|
|
|
|
pokemon.exp = getLevelTotalExp(pokemon.level, pokemon.species.growthRate);
|
|
|
|
pokemon.levelExp = 0;
|
|
|
|
|
|
|
|
const scene = pokemon.scene as BattleScene;
|
2023-04-10 13:54:06 -04:00
|
|
|
scene.unshiftPhase(new LevelUpPhase(scene, scene.getParty().indexOf(pokemon), pokemon.level - 1, pokemon.level));
|
2023-04-04 18:28:21 -04:00
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-04-08 00:21:44 -04:00
|
|
|
export class TmModifier extends ConsumablePokemonModifier {
|
2023-04-12 11:57:15 -04:00
|
|
|
constructor(type: ModifierTypes.TmModifierType, pokemonId: integer) {
|
2023-04-08 00:21:44 -04:00
|
|
|
super(type, pokemonId);
|
|
|
|
}
|
|
|
|
|
|
|
|
apply(args: any[]): boolean {
|
|
|
|
const pokemon = args[0] as PlayerPokemon;
|
|
|
|
|
|
|
|
const scene = pokemon.scene as BattleScene;
|
2023-04-12 11:57:15 -04:00
|
|
|
scene.unshiftPhase(new LearnMovePhase(scene, scene.getParty().indexOf(pokemon), (this.type as ModifierTypes.TmModifierType).moveId));
|
2023-04-08 00:21:44 -04:00
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-04-09 19:15:21 -04:00
|
|
|
export class PartyShareModifier extends PersistentModifier {
|
|
|
|
constructor(type: ModifierType) {
|
|
|
|
super(type);
|
|
|
|
}
|
|
|
|
|
|
|
|
match(modifier: Modifier) {
|
|
|
|
return modifier instanceof PartyShareModifier;
|
|
|
|
}
|
|
|
|
|
|
|
|
clone(): PartyShareModifier {
|
|
|
|
return new PartyShareModifier(this.type);
|
|
|
|
}
|
|
|
|
|
|
|
|
shouldApply(args: any[]): boolean {
|
|
|
|
return super.shouldApply(args) && args.length === 2 && args[0] instanceof BattleScene && args[1] instanceof Array<Modifier>;
|
|
|
|
}
|
|
|
|
|
|
|
|
apply(args: any[]): boolean {
|
|
|
|
const scene = args[0] as BattleScene;
|
|
|
|
const modifiers = args[1] as Modifier[];
|
|
|
|
const party = scene.getParty();
|
|
|
|
for (let modifier of modifiers) {
|
|
|
|
if (modifier instanceof PokemonHeldItemModifier) {
|
|
|
|
const heldItemModifier = modifier as PokemonHeldItemModifier;
|
|
|
|
const extraStacks = Math.floor(modifier.stackCount / Math.max(party.length - (this.getStackCount() - 1), 1));
|
|
|
|
for (let s = 0; s < extraStacks; s++) {
|
|
|
|
for (let p of party) {
|
|
|
|
if (p.id === heldItemModifier.pokemonId)
|
|
|
|
continue;
|
|
|
|
const newHeldItemModifier = heldItemModifier.clone() as PokemonHeldItemModifier;
|
|
|
|
newHeldItemModifier.pokemonId = p.id;
|
|
|
|
scene.addModifier(newHeldItemModifier, true);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
getMaxStackCount(): number {
|
|
|
|
return 6;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
export class HealingBoosterModifier extends PersistentModifier {
|
|
|
|
private multiplier: number;
|
|
|
|
|
|
|
|
constructor(type: ModifierType, multiplier: number) {
|
|
|
|
super(type);
|
|
|
|
|
|
|
|
this.multiplier = multiplier;
|
|
|
|
}
|
|
|
|
|
|
|
|
match(modifier: Modifier): boolean {
|
|
|
|
return modifier instanceof HealingBoosterModifier;
|
|
|
|
}
|
|
|
|
|
|
|
|
clone(): HealingBoosterModifier {
|
|
|
|
return new HealingBoosterModifier(this.type, this.multiplier);
|
|
|
|
}
|
|
|
|
|
|
|
|
apply(args: any[]): boolean {
|
|
|
|
const healingMultiplier = args[0] as Utils.IntegerHolder;
|
|
|
|
for (let s = 0; s < this.getStackCount(); s++)
|
|
|
|
healingMultiplier.value *= this.multiplier;
|
|
|
|
healingMultiplier.value = Math.floor(healingMultiplier.value);
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
export class ExpBoosterModifier extends PersistentModifier {
|
2023-03-30 00:13:56 -04:00
|
|
|
private boostMultiplier: integer;
|
|
|
|
|
|
|
|
constructor(type: ModifierType, boostPercent: integer) {
|
2023-03-28 14:54:52 -04:00
|
|
|
super(type);
|
2023-03-30 00:13:56 -04:00
|
|
|
|
|
|
|
this.boostMultiplier = boostPercent * 0.01;
|
2023-03-28 14:54:52 -04:00
|
|
|
}
|
|
|
|
|
2023-04-09 19:15:21 -04:00
|
|
|
match(modifier: Modifier): boolean {
|
|
|
|
if (modifier instanceof ExpBoosterModifier) {
|
|
|
|
const expModifier = modifier as ExpBoosterModifier;
|
|
|
|
return expModifier.boostMultiplier === this.boostMultiplier;
|
2023-03-28 14:54:52 -04:00
|
|
|
}
|
2023-04-09 19:15:21 -04:00
|
|
|
return false;
|
|
|
|
}
|
2023-03-28 14:54:52 -04:00
|
|
|
|
2023-04-09 19:15:21 -04:00
|
|
|
clone(): ExpBoosterModifier {
|
|
|
|
return new ExpBoosterModifier(this.type, this.boostMultiplier * 100);
|
2023-03-28 14:54:52 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
apply(args: any[]): boolean {
|
2023-04-09 19:15:21 -04:00
|
|
|
(args[0] as Utils.NumberHolder).value = Math.floor((args[0] as Utils.NumberHolder).value * (1 + (this.getStackCount() * this.boostMultiplier)));
|
2023-03-30 23:02:35 -04:00
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-04-09 19:15:21 -04:00
|
|
|
export class ExpShareModifier extends PersistentModifier {
|
2023-03-30 23:02:35 -04:00
|
|
|
constructor(type: ModifierType) {
|
|
|
|
super(type);
|
|
|
|
}
|
2023-03-28 14:54:52 -04:00
|
|
|
|
2023-03-30 23:02:35 -04:00
|
|
|
apply(_args: any[]): boolean {
|
2023-03-28 14:54:52 -04:00
|
|
|
return true;
|
|
|
|
}
|
2023-03-30 23:02:35 -04:00
|
|
|
|
2023-04-09 19:15:21 -04:00
|
|
|
clone(): ExpShareModifier {
|
|
|
|
return new ExpShareModifier(this.type);
|
|
|
|
}
|
|
|
|
|
2023-03-30 23:02:35 -04:00
|
|
|
getMaxStackCount(): integer {
|
|
|
|
return 5;
|
|
|
|
}
|
2023-03-28 14:54:52 -04:00
|
|
|
}
|
|
|
|
|
2023-04-09 19:15:21 -04:00
|
|
|
export class ShinyRateBoosterModifier extends PersistentModifier {
|
2023-03-28 14:54:52 -04:00
|
|
|
constructor(type: ModifierType) {
|
|
|
|
super(type);
|
|
|
|
}
|
|
|
|
|
2023-04-09 19:15:21 -04:00
|
|
|
match(modifier: Modifier): boolean {
|
|
|
|
return modifier instanceof ShinyRateBoosterModifier;
|
|
|
|
}
|
2023-03-28 14:54:52 -04:00
|
|
|
|
2023-04-09 19:15:21 -04:00
|
|
|
clone(): ShinyRateBoosterModifier {
|
|
|
|
return new ShinyRateBoosterModifier(this.type);
|
2023-03-28 14:54:52 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
apply(args: any[]): boolean {
|
2023-04-09 19:15:21 -04:00
|
|
|
(args[0] as Utils.IntegerHolder).value = Math.pow((args[0] as Utils.IntegerHolder).value * 0.5, this.getStackCount() + 1);
|
2023-03-28 14:54:52 -04:00
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
2023-03-30 23:02:35 -04:00
|
|
|
|
|
|
|
getMaxStackCount(): integer {
|
|
|
|
return 5;
|
|
|
|
}
|
2023-03-28 14:54:52 -04:00
|
|
|
}
|
|
|
|
|
2023-04-09 19:15:21 -04:00
|
|
|
export class ExtraModifierModifier extends PersistentModifier {
|
2023-03-30 10:50:46 -04:00
|
|
|
constructor(type: ModifierType) {
|
|
|
|
super(type);
|
|
|
|
}
|
|
|
|
|
2023-04-09 19:15:21 -04:00
|
|
|
clone(): ExtraModifierModifier {
|
|
|
|
return new ExtraModifierModifier(this.type);
|
|
|
|
}
|
|
|
|
|
2023-03-30 10:50:46 -04:00
|
|
|
apply(args: any[]): boolean {
|
2023-04-09 19:15:21 -04:00
|
|
|
(args[0] as Utils.IntegerHolder).value += this.getStackCount();
|
2023-03-30 10:50:46 -04:00
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
2023-03-28 14:54:52 -04:00
|
|
|
}
|