Add evolution items and new modifiers
Before Width: | Height: | Size: 28 KiB After Width: | Height: | Size: 34 KiB |
After Width: | Height: | Size: 258 B |
After Width: | Height: | Size: 253 B |
After Width: | Height: | Size: 329 B |
After Width: | Height: | Size: 289 B |
After Width: | Height: | Size: 269 B |
After Width: | Height: | Size: 571 B |
After Width: | Height: | Size: 272 B |
After Width: | Height: | Size: 252 B |
After Width: | Height: | Size: 227 B |
After Width: | Height: | Size: 347 B |
After Width: | Height: | Size: 238 B |
After Width: | Height: | Size: 274 B |
After Width: | Height: | Size: 200 B |
After Width: | Height: | Size: 261 B |
After Width: | Height: | Size: 308 B |
After Width: | Height: | Size: 242 B |
After Width: | Height: | Size: 287 B |
After Width: | Height: | Size: 242 B |
After Width: | Height: | Size: 222 B |
After Width: | Height: | Size: 222 B |
|
@ -5,7 +5,7 @@ import { EncounterPhase, SummonPhase, CommandPhase, NextEncounterPhase, SwitchBi
|
|||
import { PlayerPokemon, EnemyPokemon } from './pokemon';
|
||||
import PokemonSpecies, { allSpecies, getPokemonSpecies } from './pokemon-species';
|
||||
import * as Utils from './utils';
|
||||
import { Modifier, ModifierBar, ConsumablePokemonModifier, ConsumableModifier, PartyShareModifier, PokemonHpRestoreModifier, HealingBoosterModifier, PersistentModifier, PokemonHeldItemModifier, ConsumablePokemonMoveModifier } from './modifier';
|
||||
import { Modifier, ModifierBar, ConsumablePokemonModifier, ConsumableModifier, PartyShareModifier, PokemonHpRestoreModifier, HealingBoosterModifier, PersistentModifier, PokemonHeldItemModifier, ConsumablePokemonMoveModifier, ModifierPredicate } from './modifier';
|
||||
import { PokeballType } from './pokeball';
|
||||
import { Species } from './species';
|
||||
import { initAutoPlay } from './auto-play';
|
||||
|
@ -279,7 +279,7 @@ export default class BattleScene extends Phaser.Scene {
|
|||
let loadPokemonAssets = [];
|
||||
|
||||
const isRandom = this.isButtonPressed(Button.RANDOM); // For testing purposes
|
||||
this.quickStart = isRandom || this.isButtonPressed(Button.QUICK_START);
|
||||
this.quickStart = this.quickStart || isRandom || this.isButtonPressed(Button.QUICK_START);
|
||||
|
||||
if (isRandom) {
|
||||
const biomes = Utils.getEnumValues(Biome);
|
||||
|
@ -617,6 +617,10 @@ export default class BattleScene extends Phaser.Scene {
|
|||
return this.modifiers.find(m => m instanceof modifierType);
|
||||
}
|
||||
|
||||
findModifier(modifierFilter: ModifierPredicate): Modifier {
|
||||
return this.modifiers.find(m => (modifierFilter as ModifierPredicate)(m));
|
||||
}
|
||||
|
||||
applyModifiers(modifierType: { new(...args: any[]): Modifier }, ...args: any[]): void {
|
||||
const modifiers = this.modifiers.filter(m => m instanceof modifierType && m.shouldApply(args));
|
||||
for (let modifier of modifiers) {
|
||||
|
|
16
src/biome.ts
|
@ -187,6 +187,22 @@ export class BiomeArena {
|
|||
return Biome[this.biomeType].toLowerCase();
|
||||
}
|
||||
|
||||
isDaytime() {
|
||||
switch (this.biomeType) {
|
||||
case Biome.PLAINS:
|
||||
case Biome.GRASS:
|
||||
case Biome.SEA:
|
||||
case Biome.BEACH:
|
||||
case Biome.LAKE:
|
||||
case Biome.MOUNTAIN:
|
||||
case Biome.LAND:
|
||||
case Biome.DESERT:
|
||||
case Biome.MEADOW:
|
||||
case Biome.DOJO:
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
preloadBgm(): void {
|
||||
this.scene.loadBgm(this.bgm);
|
||||
}
|
||||
|
|
|
@ -15,7 +15,7 @@ const config: Phaser.Types.Core.GameConfig = {
|
|||
scene: [ BattleScene ]
|
||||
};
|
||||
|
||||
const setPositionRelative = function(guideObject: any, x: number, y: number) {
|
||||
const setPositionRelative = function (guideObject: any, x: number, y: number) {
|
||||
if (guideObject && guideObject.hasOwnProperty('width') && guideObject.hasOwnProperty('height')) {
|
||||
const offsetX = guideObject.width * (-0.5 + (0.5 - guideObject.originX));
|
||||
const offsetY = guideObject.height * (-0.5 + (0.5 - guideObject.originY));
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
import * as Modifiers from './modifier';
|
||||
import { Moves, allMoves } from './move';
|
||||
import { AttackMove, Moves, allMoves } from './move';
|
||||
import { PokeballType, getPokeballName } from './pokeball';
|
||||
import { PlayerPokemon, PokemonMove } from './pokemon';
|
||||
import { EvolutionItem, pokemonEvolutions } from './pokemon-evolutions';
|
||||
import { Stat, getStatName } from './pokemon-stat';
|
||||
import { tmSpecies } from './tms';
|
||||
import { Type } from './type';
|
||||
|
@ -137,6 +138,61 @@ export class PokemonAllMovePpRestoreModifierType extends PokemonModifierType {
|
|||
}
|
||||
}
|
||||
|
||||
function getAttackTypeBoosterItemName(type: Type) {
|
||||
switch (type) {
|
||||
case Type.NORMAL:
|
||||
return 'Silk Scarf';
|
||||
case Type.FIGHTING:
|
||||
return 'Black Belt';
|
||||
case Type.FLYING:
|
||||
return 'Sharp Beak';
|
||||
case Type.POISON:
|
||||
return 'Poison Barb';
|
||||
case Type.GROUND:
|
||||
return 'Soft Sand';
|
||||
case Type.ROCK:
|
||||
return 'Hard Stone';
|
||||
case Type.BUG:
|
||||
return 'Silver Powder';
|
||||
case Type.GHOST:
|
||||
return 'Spell Tag';
|
||||
case Type.STEEL:
|
||||
return 'Metal Coat';
|
||||
case Type.FIRE:
|
||||
return 'Charcoal';
|
||||
case Type.WATER:
|
||||
return 'Mystic Water';
|
||||
case Type.GRASS:
|
||||
return 'Miracle Seed';
|
||||
case Type.ELECTRIC:
|
||||
return 'Magnet';
|
||||
case Type.PSYCHIC:
|
||||
return 'Twisted Spoon';
|
||||
case Type.ICE:
|
||||
return 'Never-Melt Ice'
|
||||
case Type.DRAGON:
|
||||
return 'Dragon Fang';
|
||||
case Type.DARK:
|
||||
return 'Black Glasses';
|
||||
case Type.FAIRY:
|
||||
return 'Clefairy Doll';
|
||||
}
|
||||
}
|
||||
|
||||
export class AttackTypeBoosterModifierType extends PokemonModifierType {
|
||||
public moveType: Type;
|
||||
public boostPercent: integer;
|
||||
|
||||
constructor(moveType: Type, boostPercent: integer) {
|
||||
super(getAttackTypeBoosterItemName(moveType), `Inceases the power of a POKéMON's ${Type[moveType]}-type moves by 20%`,
|
||||
(_type, args) => new Modifiers.AttackTypeBoosterModifier(this, (args[0] as PlayerPokemon).id, moveType, boostPercent),
|
||||
null, `${getAttackTypeBoosterItemName(moveType).replace(/[ \-]/g, '_').toLowerCase()}`);
|
||||
|
||||
this.moveType = moveType;
|
||||
this.boostPercent = boostPercent;
|
||||
}
|
||||
}
|
||||
|
||||
export class PokemonLevelIncrementModifierType extends PokemonModifierType {
|
||||
constructor(name: string, iconImage?: string) {
|
||||
super(name, `Increase a POKéMON\'s level by 1`, (_type, args) => new Modifiers.PokemonLevelIncrementModifier(this, (args[0] as PlayerPokemon).id),
|
||||
|
@ -187,6 +243,50 @@ export class TmModifierType extends PokemonModifierType {
|
|||
}
|
||||
}
|
||||
|
||||
function getEvolutionItemName(evolutionItem: EvolutionItem) {
|
||||
switch (evolutionItem) {
|
||||
case EvolutionItem.LINKING_CORD:
|
||||
return 'Linking Cord';
|
||||
case EvolutionItem.SUN_STONE:
|
||||
return 'Sun Stone';
|
||||
case EvolutionItem.MOON_STONE:
|
||||
return 'Moon Stone';
|
||||
case EvolutionItem.LEAF_STONE:
|
||||
return 'Leaf Stone';
|
||||
case EvolutionItem.FIRE_STONE:
|
||||
return 'Fire Stone';
|
||||
case EvolutionItem.WATER_STONE:
|
||||
return 'Water Stone';
|
||||
case EvolutionItem.THUNDER_STONE:
|
||||
return 'Thunder Stone';
|
||||
case EvolutionItem.ICE_STONE:
|
||||
return 'Ice Stone';
|
||||
case EvolutionItem.DUSK_STONE:
|
||||
return 'Dusk Stone';
|
||||
case EvolutionItem.DAWN_STONE:
|
||||
return 'Dawn Stone';
|
||||
case EvolutionItem.SHINY_STONE:
|
||||
return 'Shiny Stone';
|
||||
}
|
||||
}
|
||||
|
||||
export class EvolutionItemModifierType extends PokemonModifierType {
|
||||
public evolutionItem: EvolutionItem;
|
||||
|
||||
constructor(evolutionItem: EvolutionItem) {
|
||||
super(getEvolutionItemName(evolutionItem), `Causes certain POKéMON to evolve`, (_type, args) => new Modifiers.EvolutionItemModifier(this, (args[0] as PlayerPokemon).id),
|
||||
(pokemon: PlayerPokemon) => {
|
||||
if (pokemonEvolutions.hasOwnProperty(pokemon.species.speciesId) && pokemonEvolutions[pokemon.species.speciesId].filter(e => e.item === this.evolutionItem
|
||||
&& (!e.condition || e.condition.predicate(pokemon))).length)
|
||||
return null;
|
||||
|
||||
return PartyUiHandler.NoEffectMessage;
|
||||
}, getEvolutionItemName(evolutionItem).replace(/[ \-]/g, '_').toLowerCase());
|
||||
|
||||
this.evolutionItem = evolutionItem;
|
||||
}
|
||||
}
|
||||
|
||||
class ModifierTypeGenerator extends ModifierType {
|
||||
private genTypeFunc: Function;
|
||||
|
||||
|
@ -197,11 +297,69 @@ class ModifierTypeGenerator extends ModifierType {
|
|||
|
||||
generateType(party: PlayerPokemon[]) {
|
||||
const ret = this.genTypeFunc(party);
|
||||
ret.setTier(this.tier);
|
||||
if (ret) {
|
||||
console.log(ret);
|
||||
ret.setTier(this.tier);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
class AttackTypeBoosterModifierTypeGenerator extends ModifierTypeGenerator {
|
||||
constructor() {
|
||||
super((party: PlayerPokemon[]) => {
|
||||
const attackMoveTypes = party.map(p => p.moveset.map(m => m.getMove()).filter(m => m instanceof AttackMove).map(m => m.type)).flat();
|
||||
const attackMoveTypeWeights = new Map<Type, integer>();
|
||||
let totalWeight = 0;
|
||||
for (let t of attackMoveTypes) {
|
||||
if (attackMoveTypeWeights.has(t)) {
|
||||
if (attackMoveTypeWeights.get(t) < 3)
|
||||
attackMoveTypeWeights.set(t, attackMoveTypeWeights.get(t) + 1);
|
||||
else
|
||||
continue;
|
||||
} else
|
||||
attackMoveTypeWeights.set(t, 1);
|
||||
totalWeight++;
|
||||
}
|
||||
|
||||
if (!totalWeight)
|
||||
return null;
|
||||
|
||||
let type: Type;
|
||||
|
||||
const randInt = Utils.randInt(totalWeight);
|
||||
let weight = 0;
|
||||
|
||||
for (let t of attackMoveTypeWeights.keys()) {
|
||||
const typeWeight = attackMoveTypeWeights.get(t);
|
||||
if (randInt <= weight + typeWeight) {
|
||||
type = t;
|
||||
break;
|
||||
}
|
||||
weight += typeWeight;
|
||||
}
|
||||
|
||||
return new AttackTypeBoosterModifierType(type, 20);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
class EvolutionItemModifierTypeGenerator extends ModifierTypeGenerator {
|
||||
constructor() {
|
||||
super((party: PlayerPokemon[]) => {
|
||||
const evolutionItemPool = party.filter(p => pokemonEvolutions.hasOwnProperty(p.species.speciesId)).map(p => {
|
||||
const evolutions = pokemonEvolutions[p.species.speciesId]
|
||||
return evolutions.filter(e => e.item !== EvolutionItem.NONE && (!e.condition || e.condition.predicate(p)));
|
||||
}).flat().flatMap(e => e.item);
|
||||
|
||||
if (!evolutionItemPool.length)
|
||||
return null;
|
||||
|
||||
return new EvolutionItemModifierType(evolutionItemPool[Utils.randInt(evolutionItemPool.length)]);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
class WeightedModifierType {
|
||||
public modifierType: ModifierType;
|
||||
public weight: integer | Function;
|
||||
|
@ -237,56 +395,58 @@ const modifierPool = {
|
|||
})
|
||||
].map(m => { m.setTier(ModifierTier.COMMON); return m; }),
|
||||
[ModifierTier.GREAT]: [
|
||||
new WeightedModifierType(new AddPokeballModifierType(PokeballType.GREAT_BALL, 5, 'gb'), 3),
|
||||
new WeightedModifierType(new AddPokeballModifierType(PokeballType.GREAT_BALL, 5, 'gb'), 12),
|
||||
new WeightedModifierType(new PokemonReviveModifierType('REVIVE', 50), (party: PlayerPokemon[]) => {
|
||||
const faintedPartyMemberCount = party.filter(p => !p.hp).length;
|
||||
return faintedPartyMemberCount * 3;
|
||||
return faintedPartyMemberCount * 6;
|
||||
}),
|
||||
new WeightedModifierType(new PokemonReviveModifierType('MAX REVIVE', 100), (party: PlayerPokemon[]) => {
|
||||
const faintedPartyMemberCount = party.filter(p => !p.hp).length;
|
||||
return faintedPartyMemberCount;
|
||||
return faintedPartyMemberCount * 2;
|
||||
}),
|
||||
new WeightedModifierType(new AllPokemonFullReviveModifierType('SACRED ASH'), (party: PlayerPokemon[]) => {
|
||||
return party.filter(p => !p.hp).length >= Math.ceil(party.length / 2) ? 1 : 0;
|
||||
}),
|
||||
new WeightedModifierType(new PokemonHpRestoreModifierType('HYPER POTION', 200), (party: PlayerPokemon[]) => {
|
||||
const thresholdPartyMemberCount = party.filter(p => p.getInverseHp() >= 100 || p.getHpRatio() <= 0.625).length;
|
||||
return thresholdPartyMemberCount;
|
||||
return thresholdPartyMemberCount * 2;
|
||||
}),
|
||||
new WeightedModifierType(new PokemonHpRestoreModifierType('MAX POTION', 100, true), (party: PlayerPokemon[]) => {
|
||||
const thresholdPartyMemberCount = party.filter(p => p.getInverseHp() >= 150 || p.getHpRatio() <= 0.5).length;
|
||||
return Math.ceil(thresholdPartyMemberCount / 3);
|
||||
return Math.ceil(thresholdPartyMemberCount / 1.5);
|
||||
}),
|
||||
new WeightedModifierType(new PokemonAllMovePpRestoreModifierType('ELIXIR', 10), (party: PlayerPokemon[]) => {
|
||||
const thresholdPartyMemberCount = party.filter(p => p.moveset.filter(m => m.ppUsed >= 5).length).length;
|
||||
return thresholdPartyMemberCount;
|
||||
return thresholdPartyMemberCount * 2;
|
||||
}),
|
||||
new WeightedModifierType(new PokemonAllMovePpRestoreModifierType('MAX ELIXIR', -1), (party: PlayerPokemon[]) => {
|
||||
const thresholdPartyMemberCount = party.filter(p => p.moveset.filter(m => m.ppUsed > 10).length).length;
|
||||
return Math.ceil(thresholdPartyMemberCount / 3);
|
||||
return Math.ceil(thresholdPartyMemberCount / 1.5);
|
||||
}),
|
||||
new WeightedModifierType(new ModifierTypeGenerator((party: PlayerPokemon[]) => {
|
||||
const partyMemberCompatibleTms = party.map(p => p.compatibleTms);
|
||||
const uniqueCompatibleTms = partyMemberCompatibleTms.flat().filter((tm, i, array) => array.indexOf(tm) === i);
|
||||
const randTmIndex = Utils.randInt(uniqueCompatibleTms.length);
|
||||
return new TmModifierType(uniqueCompatibleTms[randTmIndex]);
|
||||
}), 2),
|
||||
new PokemonLevelIncrementModifierType('RARE CANDY'),
|
||||
new PokemonBaseStatBoosterModifierType('HP-UP', Stat.HP),
|
||||
new PokemonBaseStatBoosterModifierType('PROTEIN', Stat.ATK),
|
||||
new PokemonBaseStatBoosterModifierType('IRON', Stat.DEF),
|
||||
new PokemonBaseStatBoosterModifierType('CALCIUM', Stat.SPATK),
|
||||
new PokemonBaseStatBoosterModifierType('ZINC', Stat.SPDEF),
|
||||
new PokemonBaseStatBoosterModifierType('CARBOS', Stat.SPD)
|
||||
}), 4),
|
||||
new WeightedModifierType(new PokemonLevelIncrementModifierType('RARE CANDY'), 4),
|
||||
new WeightedModifierType(new PokemonBaseStatBoosterModifierType('HP-UP', Stat.HP), 1),
|
||||
new WeightedModifierType(new PokemonBaseStatBoosterModifierType('PROTEIN', Stat.ATK), 1),
|
||||
new WeightedModifierType(new PokemonBaseStatBoosterModifierType('IRON', Stat.DEF), 1),
|
||||
new WeightedModifierType(new PokemonBaseStatBoosterModifierType('CALCIUM', Stat.SPATK), 1),
|
||||
new WeightedModifierType(new PokemonBaseStatBoosterModifierType('ZINC', Stat.SPDEF), 1),
|
||||
new WeightedModifierType(new PokemonBaseStatBoosterModifierType('CARBOS', Stat.SPD), 1)
|
||||
].map(m => { m.setTier(ModifierTier.GREAT); return m; }),
|
||||
[ModifierTier.ULTRA]: [
|
||||
new AddPokeballModifierType(PokeballType.ULTRA_BALL, 5, 'ub'),
|
||||
new WeightedModifierType(new AllPokemonFullReviveModifierType('SACRED ASH'), (party: PlayerPokemon[]) => {
|
||||
return party.filter(p => !p.hp).length >= Math.ceil(party.length / 2) ? 1 : 0;
|
||||
}),
|
||||
new WeightedModifierType(new AddPokeballModifierType(PokeballType.ULTRA_BALL, 5, 'ub'), 8),
|
||||
new WeightedModifierType(new EvolutionItemModifierTypeGenerator(), 5),
|
||||
new WeightedModifierType(new AttackTypeBoosterModifierTypeGenerator(), 3),
|
||||
new ModifierType('OVAL CHARM', 'For every X (no. of party members) items in a POKéMON\'s held item stack, give one to each other party member',
|
||||
(type, _args) => new Modifiers.PartyShareModifier(type), 'oval_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'),
|
||||
new WeightedModifierType(new PokemonModifierType('SHELL BELL', 'Heals 1/8 of a POKéMON\'s damage dealt', (type, args) => new Modifiers.HitHealModifier(type, (args[0] as PlayerPokemon).id)), 8),
|
||||
new ExpBoosterModifierType('LUCKY EGG', 25),
|
||||
new ModifierType('EXP. SHARE', 'All POKéMON in your party gain an additional 10% of a battle\'s EXP. Points', (type, _args) => new Modifiers.ExpShareModifier(type), 'exp_share')
|
||||
new WeightedModifierType(new PokemonModifierType('SHELL BELL', 'Heals 1/8 of a POKéMON\'s dealt damage', (type, args) => new Modifiers.HitHealModifier(type, (args[0] as PlayerPokemon).id)), 8),
|
||||
new WeightedModifierType(new ExpBoosterModifierType('LUCKY EGG', 25), 4),
|
||||
new WeightedModifierType(new ModifierType('EXP. SHARE', 'All POKéMON in your party gain an additional 10% of a battle\'s EXP. Points', (type, _args) => new Modifiers.ExpShareModifier(type), 'exp_share'), 3)
|
||||
].map(m => { m.setTier(ModifierTier.ULTRA); return m; }),
|
||||
[ModifierTier.MASTER]: [
|
||||
new AddPokeballModifierType(PokeballType.MASTER_BALL, 1, 'mb'),
|
||||
|
@ -335,10 +495,12 @@ export function getModifierTypeOptionsForWave(waveIndex: integer, count: integer
|
|||
return new Array(count).fill(0).map(() => getNewModifierTypeOption(party));
|
||||
}
|
||||
|
||||
function getNewModifierTypeOption(party: PlayerPokemon[]): ModifierTypeOption {
|
||||
function getNewModifierTypeOption(party: PlayerPokemon[], tier?: ModifierTier, upgrade?: boolean): ModifierTypeOption {
|
||||
const tierValue = Utils.randInt(256);
|
||||
const upgrade = Utils.randInt(32) === 0;
|
||||
const tier: ModifierTier = (tierValue >= 52 ? ModifierTier.COMMON : tierValue >= 8 ? ModifierTier.GREAT : tierValue >= 1 ? ModifierTier.ULTRA : ModifierTier.MASTER) + (upgrade ? 1 : 0);
|
||||
if (tier === undefined) {
|
||||
tier = (tierValue >= 52 ? ModifierTier.COMMON : tierValue >= 8 ? ModifierTier.GREAT : tierValue >= 1 ? ModifierTier.ULTRA : ModifierTier.MASTER) + (upgrade ? 1 : 0);
|
||||
upgrade = Utils.randInt(32) === 0;
|
||||
}
|
||||
const thresholds = Object.keys(modifierPoolThresholds[tier]);
|
||||
const totalWeight = parseInt(thresholds[thresholds.length - 1]);
|
||||
const value = Utils.randInt(totalWeight);
|
||||
|
@ -354,8 +516,14 @@ function getNewModifierTypeOption(party: PlayerPokemon[]): ModifierTypeOption {
|
|||
let modifierType: ModifierType | WeightedModifierType = modifierPool[tier][index];
|
||||
if (modifierType instanceof WeightedModifierType)
|
||||
modifierType = (modifierType as WeightedModifierType).modifierType;
|
||||
if (modifierType instanceof ModifierTypeGenerator)
|
||||
if (modifierType instanceof ModifierTypeGenerator) {
|
||||
modifierType = (modifierType as ModifierTypeGenerator).generateType(party);
|
||||
if (modifierType === null) {
|
||||
console.log(ModifierTier[tier], upgrade);
|
||||
return getNewModifierTypeOption(party, tier, upgrade);
|
||||
}
|
||||
}
|
||||
console.log(modifierType);
|
||||
return new ModifierTypeOption(modifierType as ModifierType, upgrade);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import * as ModifierTypes from './modifier-type';
|
||||
import { CommonAnimPhase, LearnMovePhase, LevelUpPhase, MessagePhase, PokemonHealPhase } from "./battle-phases";
|
||||
import { LearnMovePhase, LevelUpPhase, MessagePhase, PokemonHealPhase } from "./battle-phases";
|
||||
import BattleScene from "./battle-scene";
|
||||
import { getLevelTotalExp } from "./exp";
|
||||
import { PokeballType } from "./pokeball";
|
||||
|
@ -7,9 +7,12 @@ import Pokemon, { PlayerPokemon } from "./pokemon";
|
|||
import { Stat } from "./pokemon-stat";
|
||||
import { addTextObject, TextStyle } from "./text";
|
||||
import * as Utils from "./utils";
|
||||
import { CommonAnim } from './battle-anims';
|
||||
import { Type } from './type';
|
||||
import { EvolutionPhase } from './evolution-phase';
|
||||
import { pokemonEvolutions } from './pokemon-evolutions';
|
||||
|
||||
type ModifierType = ModifierTypes.ModifierType;
|
||||
export type ModifierPredicate = (modifier: Modifier) => boolean;
|
||||
|
||||
export class ModifierBar extends Phaser.GameObjects.Container {
|
||||
constructor(scene: BattleScene) {
|
||||
|
@ -253,6 +256,36 @@ export class PokemonBaseStatModifier extends PokemonHeldItemModifier {
|
|||
}
|
||||
}
|
||||
|
||||
export class AttackTypeBoosterModifier extends PokemonHeldItemModifier {
|
||||
private moveType: Type;
|
||||
private boostMultiplier: number;
|
||||
|
||||
constructor(type: ModifierType, pokemonId: integer, moveType: Type, boostPercent: integer) {
|
||||
super(type, pokemonId);
|
||||
|
||||
this.moveType = moveType;
|
||||
this.boostMultiplier = boostPercent * 0.01;
|
||||
}
|
||||
|
||||
match(modifier: Modifier) {
|
||||
return modifier instanceof AttackTypeBoosterModifier;
|
||||
}
|
||||
|
||||
clone() {
|
||||
return new AttackTypeBoosterModifier(this.type, this.pokemonId, this.moveType, this.boostMultiplier * 100);
|
||||
}
|
||||
|
||||
shouldApply(args: any[]): boolean {
|
||||
return super.shouldApply(args) && args.length === 2 && args[1] instanceof Utils.NumberHolder;
|
||||
}
|
||||
|
||||
apply(args: any[]): boolean {
|
||||
(args[1] as Utils.NumberHolder).value = Math.floor((args[1] as Utils.NumberHolder).value * (1 + (this.getStackCount() * this.boostMultiplier)));
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
export class HitHealModifier extends PokemonHeldItemModifier {
|
||||
constructor(type: ModifierType, pokemonId: integer) {
|
||||
super(type, pokemonId);
|
||||
|
@ -270,7 +303,7 @@ export class HitHealModifier extends PokemonHeldItemModifier {
|
|||
const pokemon = args[0] as PlayerPokemon;
|
||||
|
||||
if (pokemon.turnData.damageDealt && pokemon.getHpRatio() < 1) {
|
||||
const scene = pokemon.scene as BattleScene;
|
||||
const scene = pokemon.scene;
|
||||
|
||||
const hpRestoreMultiplier = new Utils.IntegerHolder(1);
|
||||
scene.applyModifiers(HealingBoosterModifier, hpRestoreMultiplier);
|
||||
|
@ -388,8 +421,7 @@ export class PokemonLevelIncrementModifier extends ConsumablePokemonModifier {
|
|||
pokemon.exp = getLevelTotalExp(pokemon.level, pokemon.species.growthRate);
|
||||
pokemon.levelExp = 0;
|
||||
|
||||
const scene = pokemon.scene as BattleScene;
|
||||
scene.unshiftPhase(new LevelUpPhase(scene, scene.getParty().indexOf(pokemon), pokemon.level - 1, pokemon.level));
|
||||
pokemon.scene.unshiftPhase(new LevelUpPhase(pokemon.scene, pokemon.scene.getParty().indexOf(pokemon), pokemon.level - 1, pokemon.level));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -403,13 +435,32 @@ export class TmModifier extends ConsumablePokemonModifier {
|
|||
apply(args: any[]): boolean {
|
||||
const pokemon = args[0] as PlayerPokemon;
|
||||
|
||||
const scene = pokemon.scene as BattleScene;
|
||||
scene.unshiftPhase(new LearnMovePhase(scene, scene.getParty().indexOf(pokemon), (this.type as ModifierTypes.TmModifierType).moveId));
|
||||
pokemon.scene.unshiftPhase(new LearnMovePhase(pokemon.scene, pokemon.scene.getParty().indexOf(pokemon), (this.type as ModifierTypes.TmModifierType).moveId));
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
export class EvolutionItemModifier extends ConsumablePokemonModifier {
|
||||
constructor(type: ModifierTypes.EvolutionItemModifierType, pokemonId: integer) {
|
||||
super(type, pokemonId);
|
||||
}
|
||||
|
||||
apply(args: any[]): boolean {
|
||||
const pokemon = args[0] as PlayerPokemon;
|
||||
|
||||
const matchingEvolution = pokemonEvolutions[pokemon.species.speciesId].find(e => e.item === (this.type as ModifierTypes.EvolutionItemModifierType).evolutionItem
|
||||
&& (!e.condition || e.condition.predicate(pokemon)));
|
||||
|
||||
if (matchingEvolution) {
|
||||
pokemon.scene.unshiftPhase(new EvolutionPhase(pokemon.scene, pokemon.scene.getParty().indexOf(pokemon), matchingEvolution, pokemon.level - 1));
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
export class PartyShareModifier extends PersistentModifier {
|
||||
constructor(type: ModifierType) {
|
||||
super(type);
|
||||
|
|
|
@ -1,6 +1,13 @@
|
|||
import { Biome } from "./biome";
|
||||
import { AttackTypeBoosterModifier } from "./modifier";
|
||||
import { AttackTypeBoosterModifierType } from "./modifier-type";
|
||||
import { Moves } from "./move";
|
||||
import { PokeballType } from "./pokeball";
|
||||
import Pokemon from "./pokemon";
|
||||
import { Stat } from "./pokemon-stat";
|
||||
import { Species } from "./species";
|
||||
import { Type } from "./type";
|
||||
import * as Utils from "./utils";
|
||||
|
||||
export enum SpeciesWildEvolutionDelay {
|
||||
NONE,
|
||||
|
@ -10,17 +17,32 @@ export enum SpeciesWildEvolutionDelay {
|
|||
VERY_LONG
|
||||
}
|
||||
|
||||
export enum EvolutionItem {
|
||||
NONE,
|
||||
LINKING_CORD,
|
||||
SUN_STONE,
|
||||
MOON_STONE,
|
||||
LEAF_STONE,
|
||||
FIRE_STONE,
|
||||
WATER_STONE,
|
||||
THUNDER_STONE,
|
||||
ICE_STONE,
|
||||
DUSK_STONE,
|
||||
DAWN_STONE,
|
||||
SHINY_STONE
|
||||
}
|
||||
|
||||
export class SpeciesEvolution {
|
||||
public speciesId: Species;
|
||||
public level: integer;
|
||||
public item: string;
|
||||
public condition: SpeciesEvolutionCondition | string;
|
||||
public item: EvolutionItem;
|
||||
public condition: SpeciesEvolutionCondition;
|
||||
public wildDelay: SpeciesWildEvolutionDelay;
|
||||
|
||||
constructor(speciesId: Species, level: integer, item: string, condition: SpeciesEvolutionCondition | string, wildDelay?: SpeciesWildEvolutionDelay) {
|
||||
constructor(speciesId: Species, level: integer, item: EvolutionItem, condition: SpeciesEvolutionCondition, wildDelay?: SpeciesWildEvolutionDelay) {
|
||||
this.speciesId = speciesId;
|
||||
this.level = level;
|
||||
this.item = item;
|
||||
this.item = item || EvolutionItem.NONE;
|
||||
this.condition = condition;
|
||||
this.wildDelay = wildDelay || SpeciesWildEvolutionDelay.NONE;
|
||||
}
|
||||
|
@ -142,7 +164,7 @@ export const pokemonEvolutions: PokemonEvolutions = {
|
|||
],
|
||||
[Species.SLOWPOKE]: [
|
||||
new SpeciesEvolution(Species.SLOWBRO, 37, null, null),
|
||||
new SpeciesEvolution(Species.SLOWKING, 1, "Link Cable", new SpeciesEvolutionCondition((p: Pokemon) => true /* King's rock*/), SpeciesWildEvolutionDelay.VERY_LONG)
|
||||
new SpeciesEvolution(Species.SLOWKING, 1, EvolutionItem.LINKING_CORD, new SpeciesEvolutionCondition((p: Pokemon) => true /* King's rock*/), SpeciesWildEvolutionDelay.VERY_LONG)
|
||||
],
|
||||
[Species.MAGNEMITE]: [
|
||||
new SpeciesEvolution(Species.MAGNETON, 30, null, null)
|
||||
|
@ -324,8 +346,8 @@ export const pokemonEvolutions: PokemonEvolutions = {
|
|||
new SpeciesEvolution(Species.LINOONE, 20, null, null)
|
||||
],
|
||||
[Species.WURMPLE]: [
|
||||
new SpeciesEvolution(Species.SILCOON, 7, null, 'random based on personality'),
|
||||
new SpeciesEvolution(Species.CASCOON, 7, null, 'random based on personality')
|
||||
new SpeciesEvolution(Species.SILCOON, 7, null, new SpeciesEvolutionCondition((p: Pokemon) => Utils.randInt(2) === 0, true)), // TODO: Improve these conditions
|
||||
new SpeciesEvolution(Species.CASCOON, 7, null, new SpeciesEvolutionCondition((p: Pokemon) => Utils.randInt(2) === 0, true))
|
||||
],
|
||||
[Species.SILCOON]: [
|
||||
new SpeciesEvolution(Species.BEAUTIFLY, 10, null, null)
|
||||
|
@ -350,7 +372,7 @@ export const pokemonEvolutions: PokemonEvolutions = {
|
|||
],
|
||||
[Species.KIRLIA]: [
|
||||
new SpeciesEvolution(Species.GARDEVOIR, 30, null, new SpeciesEvolutionCondition((p: Pokemon) => !p.gender, true)),
|
||||
new SpeciesEvolution(Species.GALLADE, 1, "Dawn Stone", new SpeciesEvolutionCondition((p: Pokemon) => p.gender, true), SpeciesWildEvolutionDelay.LONG)
|
||||
new SpeciesEvolution(Species.GALLADE, 1, EvolutionItem.DAWN_STONE, new SpeciesEvolutionCondition((p: Pokemon) => p.gender, true), SpeciesWildEvolutionDelay.LONG)
|
||||
],
|
||||
[Species.SURSKIT]: [
|
||||
new SpeciesEvolution(Species.MASQUERAIN, 22, null, null)
|
||||
|
@ -366,7 +388,7 @@ export const pokemonEvolutions: PokemonEvolutions = {
|
|||
],
|
||||
[Species.NINCADA]: [
|
||||
new SpeciesEvolution(Species.NINJASK, 20, null, null),
|
||||
new SpeciesEvolution(Species.SHEDINJA, 20, null, 'empty spot in party, Pokéball in bag')
|
||||
new SpeciesEvolution(Species.SHEDINJA, 20, null, new SpeciesEvolutionCondition((p: Pokemon) => p.scene.getParty().length < 6 && p.scene.pokeballCounts[PokeballType.POKEBALL], true))
|
||||
],
|
||||
[Species.WHISMUR]: [
|
||||
new SpeciesEvolution(Species.LOUDRED, 20, null, null)
|
||||
|
@ -439,7 +461,7 @@ export const pokemonEvolutions: PokemonEvolutions = {
|
|||
],
|
||||
[Species.SNORUNT]: [
|
||||
new SpeciesEvolution(Species.GLALIE, 42, null, null),
|
||||
new SpeciesEvolution(Species.FROSLASS, 1, "Dawn Stone", new SpeciesEvolutionCondition((p: Pokemon) => !p.gender, true), SpeciesWildEvolutionDelay.VERY_LONG)
|
||||
new SpeciesEvolution(Species.FROSLASS, 1, EvolutionItem.DAWN_STONE, new SpeciesEvolutionCondition((p: Pokemon) => !p.gender, true), SpeciesWildEvolutionDelay.VERY_LONG)
|
||||
],
|
||||
[Species.SPHEAL]: [
|
||||
new SpeciesEvolution(Species.SEALEO, 32, null, null)
|
||||
|
@ -503,9 +525,9 @@ export const pokemonEvolutions: PokemonEvolutions = {
|
|||
],
|
||||
[Species.BURMY]: [
|
||||
new SpeciesEvolution(Species.MOTHIM, 20, null, new SpeciesEvolutionCondition((p: Pokemon) => p.gender, true)),
|
||||
new SpeciesEvolution(Species.WORMADAM, 20, null, new SpeciesEvolutionCondition((p: Pokemon) => !p.gender/* && grass*/, true)),
|
||||
new SpeciesEvolution(Species.WORMADAM, 20, null, new SpeciesEvolutionCondition((p: Pokemon) => !p.gender/* && cave*/, true)),
|
||||
new SpeciesEvolution(Species.WORMADAM, 20, null, new SpeciesEvolutionCondition((p: Pokemon) => !p.gender/* && building*/, true))
|
||||
new SpeciesEvolution(Species.WORMADAM, 20, null, new SpeciesEvolutionCondition((p: Pokemon) => !p.gender && p.scene.arena.biomeType === Biome.FOREST, true)),
|
||||
new SpeciesEvolution(Species.WORMADAM, 20, null, new SpeciesEvolutionCondition((p: Pokemon) => !p.gender && p.scene.arena.biomeType === Biome.CAVE, true)),
|
||||
new SpeciesEvolution(Species.WORMADAM, 20, null, new SpeciesEvolutionCondition((p: Pokemon) => !p.gender && p.scene.arena.biomeType === Biome.CITY, true))
|
||||
],
|
||||
[Species.COMBEE]: [
|
||||
new SpeciesEvolution(Species.VESPIQUEN, 21, null, new SpeciesEvolutionCondition((p: Pokemon) => !p.gender, true))
|
||||
|
@ -730,199 +752,203 @@ export const pokemonEvolutions: PokemonEvolutions = {
|
|||
new SpeciesEvolution(Species.VOLCARONA, 59, null, null)
|
||||
],
|
||||
[Species.PIKACHU]: [
|
||||
new SpeciesEvolution(Species.RAICHU, 1, "Thunder Stone", null, SpeciesWildEvolutionDelay.LONG)
|
||||
new SpeciesEvolution(Species.RAICHU, 1, EvolutionItem.THUNDER_STONE, null, SpeciesWildEvolutionDelay.LONG)
|
||||
],
|
||||
[Species.NIDORINA]: [
|
||||
new SpeciesEvolution(Species.NIDOQUEEN, 1, "Moon Stone", null, SpeciesWildEvolutionDelay.LONG)
|
||||
new SpeciesEvolution(Species.NIDOQUEEN, 1, EvolutionItem.MOON_STONE, null, SpeciesWildEvolutionDelay.LONG)
|
||||
],
|
||||
[Species.NIDORINO]: [
|
||||
new SpeciesEvolution(Species.NIDOKING, 1, "Moon Stone", null, SpeciesWildEvolutionDelay.LONG)
|
||||
new SpeciesEvolution(Species.NIDOKING, 1, EvolutionItem.MOON_STONE, null, SpeciesWildEvolutionDelay.LONG)
|
||||
],
|
||||
[Species.CLEFAIRY]: [
|
||||
new SpeciesEvolution(Species.CLEFABLE, 1, "Moon Stone", null, SpeciesWildEvolutionDelay.LONG)
|
||||
new SpeciesEvolution(Species.CLEFABLE, 1, EvolutionItem.MOON_STONE, null, SpeciesWildEvolutionDelay.LONG)
|
||||
],
|
||||
[Species.VULPIX]: [
|
||||
new SpeciesEvolution(Species.NINETALES, 1, "Fire Stone", null, SpeciesWildEvolutionDelay.LONG)
|
||||
new SpeciesEvolution(Species.NINETALES, 1, EvolutionItem.FIRE_STONE, null, SpeciesWildEvolutionDelay.LONG)
|
||||
],
|
||||
[Species.JIGGLYPUFF]: [
|
||||
new SpeciesEvolution(Species.WIGGLYTUFF, 1, "Moon Stone", null, SpeciesWildEvolutionDelay.LONG)
|
||||
new SpeciesEvolution(Species.WIGGLYTUFF, 1, EvolutionItem.MOON_STONE, null, SpeciesWildEvolutionDelay.LONG)
|
||||
],
|
||||
[Species.GLOOM]: [
|
||||
new SpeciesEvolution(Species.VILEPLUME, 1, "Leaf Stone", null, SpeciesWildEvolutionDelay.LONG),
|
||||
new SpeciesEvolution(Species.BELLOSSOM, 1, "Sun Stone", null, SpeciesWildEvolutionDelay.LONG)
|
||||
new SpeciesEvolution(Species.VILEPLUME, 1, EvolutionItem.LEAF_STONE, null, SpeciesWildEvolutionDelay.LONG),
|
||||
new SpeciesEvolution(Species.BELLOSSOM, 1, EvolutionItem.SUN_STONE, null, SpeciesWildEvolutionDelay.LONG)
|
||||
],
|
||||
[Species.GROWLITHE]: [
|
||||
new SpeciesEvolution(Species.ARCANINE, 1, "Fire Stone", null, SpeciesWildEvolutionDelay.LONG)
|
||||
new SpeciesEvolution(Species.ARCANINE, 1, EvolutionItem.FIRE_STONE, null, SpeciesWildEvolutionDelay.LONG)
|
||||
],
|
||||
[Species.POLIWHIRL]: [
|
||||
new SpeciesEvolution(Species.POLIWRATH, 1, "Water Stone", null, SpeciesWildEvolutionDelay.LONG),
|
||||
new SpeciesEvolution(Species.POLITOED, 1, "Link Cable", new SpeciesEvolutionCondition((p: Pokemon) => true /* King's rock*/), SpeciesWildEvolutionDelay.VERY_LONG)
|
||||
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)
|
||||
],
|
||||
[Species.WEEPINBELL]: [
|
||||
new SpeciesEvolution(Species.VICTREEBEL, 1, "Leaf Stone", null, SpeciesWildEvolutionDelay.LONG)
|
||||
new SpeciesEvolution(Species.VICTREEBEL, 1, EvolutionItem.LEAF_STONE, null, SpeciesWildEvolutionDelay.LONG)
|
||||
],
|
||||
[Species.MAGNETON]: [
|
||||
new SpeciesEvolution(Species.MAGNEZONE, 1, "Thunder Stone", null, SpeciesWildEvolutionDelay.VERY_LONG)
|
||||
new SpeciesEvolution(Species.MAGNEZONE, 1, EvolutionItem.THUNDER_STONE, null, SpeciesWildEvolutionDelay.LONG)
|
||||
],
|
||||
[Species.SHELLDER]: [
|
||||
new SpeciesEvolution(Species.CLOYSTER, 1, "Water Stone", null, SpeciesWildEvolutionDelay.MEDIUM)
|
||||
new SpeciesEvolution(Species.CLOYSTER, 1, EvolutionItem.WATER_STONE, null, SpeciesWildEvolutionDelay.MEDIUM)
|
||||
],
|
||||
[Species.EXEGGCUTE]: [
|
||||
new SpeciesEvolution(Species.EXEGGUTOR, 1, "Leaf Stone", null, SpeciesWildEvolutionDelay.LONG)
|
||||
new SpeciesEvolution(Species.EXEGGUTOR, 1, EvolutionItem.LEAF_STONE, null, SpeciesWildEvolutionDelay.LONG)
|
||||
],
|
||||
[Species.TANGELA]: [
|
||||
new SpeciesEvolution(Species.TANGROWTH, 1, null, new SpeciesEvolutionCondition((p: Pokemon) => true /* Ancient power learned*/), SpeciesWildEvolutionDelay.LONG)
|
||||
new SpeciesEvolution(Species.TANGROWTH, 1, null, new SpeciesEvolutionCondition((p: Pokemon) => p.moveset.filter(m => m.moveId === Moves.ANCIENT_POWER).length), SpeciesWildEvolutionDelay.LONG)
|
||||
],
|
||||
[Species.LICKITUNG]: [
|
||||
new SpeciesEvolution(Species.LICKILICKY, 1, null, new SpeciesEvolutionCondition((p: Pokemon) => true /* Rollout learned*/), SpeciesWildEvolutionDelay.LONG)
|
||||
new SpeciesEvolution(Species.LICKILICKY, 1, null, new SpeciesEvolutionCondition((p: Pokemon) => p.moveset.filter(m => m.moveId === Moves.ROLLOUT).length), SpeciesWildEvolutionDelay.LONG)
|
||||
],
|
||||
[Species.STARYU]: [
|
||||
new SpeciesEvolution(Species.STARMIE, 1, "Water Stone", null, SpeciesWildEvolutionDelay.MEDIUM)
|
||||
new SpeciesEvolution(Species.STARMIE, 1, EvolutionItem.WATER_STONE, null, SpeciesWildEvolutionDelay.MEDIUM)
|
||||
],
|
||||
[Species.EEVEE]: [
|
||||
new SpeciesEvolution(Species.ESPEON, 1, null, new SpeciesEvolutionCondition((p: Pokemon) => p.winCount >= 10 /* daytime */), SpeciesWildEvolutionDelay.MEDIUM),
|
||||
new SpeciesEvolution(Species.UMBREON, 1, null, new SpeciesEvolutionCondition((p: Pokemon) => p.winCount >= 10 /* nighttime */), SpeciesWildEvolutionDelay.MEDIUM),
|
||||
new SpeciesEvolution(Species.VAPOREON, 1, "Water Stone", null, SpeciesWildEvolutionDelay.MEDIUM),
|
||||
new SpeciesEvolution(Species.JOLTEON, 1, "Thunder Stone", null, SpeciesWildEvolutionDelay.MEDIUM),
|
||||
new SpeciesEvolution(Species.FLAREON, 1, "Fire Stone", null, SpeciesWildEvolutionDelay.MEDIUM),
|
||||
new SpeciesEvolution(Species.LEAFEON, 1, "Leaf Stone", null, SpeciesWildEvolutionDelay.MEDIUM),
|
||||
new SpeciesEvolution(Species.GLACEON, 1, "Ice Stone", null, SpeciesWildEvolutionDelay.MEDIUM)
|
||||
new SpeciesEvolution(Species.ESPEON, 1, null, new SpeciesEvolutionCondition((p: Pokemon) => p.winCount >= 10 && p.scene.arena.isDaytime()), SpeciesWildEvolutionDelay.MEDIUM),
|
||||
new SpeciesEvolution(Species.UMBREON, 1, null, new SpeciesEvolutionCondition((p: Pokemon) => p.winCount >= 10 && !p.scene.arena.isDaytime()), SpeciesWildEvolutionDelay.MEDIUM),
|
||||
new SpeciesEvolution(Species.VAPOREON, 1, EvolutionItem.WATER_STONE, null, SpeciesWildEvolutionDelay.MEDIUM),
|
||||
new SpeciesEvolution(Species.JOLTEON, 1, EvolutionItem.THUNDER_STONE, null, SpeciesWildEvolutionDelay.MEDIUM),
|
||||
new SpeciesEvolution(Species.FLAREON, 1, EvolutionItem.FIRE_STONE, null, SpeciesWildEvolutionDelay.MEDIUM),
|
||||
new SpeciesEvolution(Species.LEAFEON, 1, EvolutionItem.LEAF_STONE, null, SpeciesWildEvolutionDelay.MEDIUM),
|
||||
new SpeciesEvolution(Species.GLACEON, 1, EvolutionItem.ICE_STONE, null, SpeciesWildEvolutionDelay.MEDIUM)
|
||||
],
|
||||
[Species.TOGETIC]: [
|
||||
new SpeciesEvolution(Species.TOGEKISS, 1, "Shiny Stone", null, SpeciesWildEvolutionDelay.VERY_LONG)
|
||||
new SpeciesEvolution(Species.TOGEKISS, 1, EvolutionItem.SHINY_STONE, null, SpeciesWildEvolutionDelay.VERY_LONG)
|
||||
],
|
||||
[Species.AIPOM]: [
|
||||
new SpeciesEvolution(Species.AMBIPOM, 1, null, new SpeciesEvolutionCondition((p: Pokemon) => true /* Double hit learned*/), SpeciesWildEvolutionDelay.LONG)
|
||||
new SpeciesEvolution(Species.AMBIPOM, 1, null, new SpeciesEvolutionCondition((p: Pokemon) => p.moveset.filter(m => m.moveId === Moves.DOUBLE_HIT).length), SpeciesWildEvolutionDelay.LONG)
|
||||
],
|
||||
[Species.SUNKERN]: [
|
||||
new SpeciesEvolution(Species.SUNFLORA, 1, "Sun Stone", null, SpeciesWildEvolutionDelay.MEDIUM)
|
||||
new SpeciesEvolution(Species.SUNFLORA, 1, EvolutionItem.SUN_STONE, null, SpeciesWildEvolutionDelay.MEDIUM)
|
||||
],
|
||||
[Species.YANMA]: [
|
||||
new SpeciesEvolution(Species.YANMEGA, 1, null, new SpeciesEvolutionCondition((p: Pokemon) => true /* Rollout learned*/), SpeciesWildEvolutionDelay.LONG)
|
||||
new SpeciesEvolution(Species.YANMEGA, 1, null, new SpeciesEvolutionCondition((p: Pokemon) => p.moveset.filter(m => m.moveId === Moves.ROLLOUT).length), SpeciesWildEvolutionDelay.LONG)
|
||||
],
|
||||
[Species.MURKROW]: [
|
||||
new SpeciesEvolution(Species.HONCHKROW, 1, "Dusk Stone", null, SpeciesWildEvolutionDelay.VERY_LONG)
|
||||
new SpeciesEvolution(Species.HONCHKROW, 1, EvolutionItem.DUSK_STONE, null, SpeciesWildEvolutionDelay.VERY_LONG)
|
||||
],
|
||||
[Species.MISDREAVUS]: [
|
||||
new SpeciesEvolution(Species.MISMAGIUS, 1, "Dusk Stone", null, SpeciesWildEvolutionDelay.VERY_LONG)
|
||||
new SpeciesEvolution(Species.MISMAGIUS, 1, EvolutionItem.DUSK_STONE, null, SpeciesWildEvolutionDelay.VERY_LONG)
|
||||
],
|
||||
[Species.GLIGAR]: [
|
||||
new SpeciesEvolution(Species.GLISCOR, 1, null, new SpeciesEvolutionCondition((p: Pokemon) => true /* Razor fang at night*/), SpeciesWildEvolutionDelay.LONG)
|
||||
new SpeciesEvolution(Species.GLISCOR, 1, null, new SpeciesEvolutionCondition((p: Pokemon) => !p.scene.arena.isDaytime() /* Razor fang at night*/), SpeciesWildEvolutionDelay.LONG)
|
||||
],
|
||||
[Species.SNEASEL]: [
|
||||
new SpeciesEvolution(Species.WEAVILE, 1, null, new SpeciesEvolutionCondition((p: Pokemon) => true /* Razor claw at night*/), SpeciesWildEvolutionDelay.LONG)
|
||||
new SpeciesEvolution(Species.WEAVILE, 1, null, new SpeciesEvolutionCondition((p: Pokemon) => !p.scene.arena.isDaytime() /* Razor claw at night*/), SpeciesWildEvolutionDelay.LONG)
|
||||
],
|
||||
[Species.PILOSWINE]: [
|
||||
new SpeciesEvolution(Species.MAMOSWINE, 1, null, new SpeciesEvolutionCondition((p: Pokemon) => true /* Ancient power learned*/), SpeciesWildEvolutionDelay.VERY_LONG)
|
||||
new SpeciesEvolution(Species.MAMOSWINE, 1, null, new SpeciesEvolutionCondition((p: Pokemon) => p.moveset.filter(m => m.moveId === Moves.ANCIENT_POWER).length), SpeciesWildEvolutionDelay.VERY_LONG)
|
||||
],
|
||||
[Species.LOMBRE]: [
|
||||
new SpeciesEvolution(Species.LUDICOLO, 1, "Water Stone", null, SpeciesWildEvolutionDelay.LONG)
|
||||
new SpeciesEvolution(Species.LUDICOLO, 1, EvolutionItem.WATER_STONE, null, SpeciesWildEvolutionDelay.LONG)
|
||||
],
|
||||
[Species.NUZLEAF]: [
|
||||
new SpeciesEvolution(Species.SHIFTRY, 1, "Leaf Stone", null, SpeciesWildEvolutionDelay.LONG)
|
||||
new SpeciesEvolution(Species.SHIFTRY, 1, EvolutionItem.LEAF_STONE, null, SpeciesWildEvolutionDelay.LONG)
|
||||
],
|
||||
[Species.NOSEPASS]: [
|
||||
new SpeciesEvolution(Species.PROBOPASS, 1, null, new SpeciesEvolutionCondition((p: Pokemon) => true /* Magnetic field??*/), SpeciesWildEvolutionDelay.LONG)
|
||||
new SpeciesEvolution(Species.PROBOPASS, 1, EvolutionItem.THUNDER_STONE, null, SpeciesWildEvolutionDelay.LONG)
|
||||
],
|
||||
[Species.SKITTY]: [
|
||||
new SpeciesEvolution(Species.DELCATTY, 1, "Moon Stone", null, SpeciesWildEvolutionDelay.MEDIUM)
|
||||
new SpeciesEvolution(Species.DELCATTY, 1, EvolutionItem.MOON_STONE, null, SpeciesWildEvolutionDelay.MEDIUM)
|
||||
],
|
||||
[Species.ROSELIA]: [
|
||||
new SpeciesEvolution(Species.ROSERADE, 1, "Shiny Stone", null, SpeciesWildEvolutionDelay.VERY_LONG)
|
||||
new SpeciesEvolution(Species.ROSERADE, 1, EvolutionItem.SHINY_STONE, null, SpeciesWildEvolutionDelay.VERY_LONG)
|
||||
],
|
||||
[Species.BONSLY]: [
|
||||
new SpeciesEvolution(Species.SUDOWOODO, 1, null, new SpeciesEvolutionCondition((p: Pokemon) => true /* Mimic learned */), SpeciesWildEvolutionDelay.MEDIUM)
|
||||
new SpeciesEvolution(Species.SUDOWOODO, 1, null, new SpeciesEvolutionCondition((p: Pokemon) => p.moveset.filter(m => m.moveId === Moves.MIMIC).length), SpeciesWildEvolutionDelay.MEDIUM)
|
||||
],
|
||||
[Species.MIME_JR]: [
|
||||
new SpeciesEvolution(Species.MR_MIME, 1, null, new SpeciesEvolutionCondition((p: Pokemon) => true /* Mimic learned */), SpeciesWildEvolutionDelay.MEDIUM)
|
||||
new SpeciesEvolution(Species.MR_MIME, 1, null, new SpeciesEvolutionCondition((p: Pokemon) => p.moveset.filter(m => m.moveId === Moves.MIMIC).length), SpeciesWildEvolutionDelay.MEDIUM)
|
||||
],
|
||||
[Species.MANTYKE]: [
|
||||
new SpeciesEvolution(Species.MANTINE, 1, null, new SpeciesEvolutionCondition((p: Pokemon) => true /* Remoraid in party */), SpeciesWildEvolutionDelay.MEDIUM)
|
||||
new SpeciesEvolution(Species.MANTINE, 1, null, new SpeciesEvolutionCondition((p: Pokemon) => p.scene.getParty().find(p => p.species.speciesId === Species.REMORAID)), SpeciesWildEvolutionDelay.MEDIUM)
|
||||
],
|
||||
[Species.PANSAGE]: [
|
||||
new SpeciesEvolution(Species.SIMISAGE, 1, "Leaf Stone", null, SpeciesWildEvolutionDelay.MEDIUM)
|
||||
new SpeciesEvolution(Species.SIMISAGE, 1, EvolutionItem.LEAF_STONE, null, SpeciesWildEvolutionDelay.MEDIUM)
|
||||
],
|
||||
[Species.PANSEAR]: [
|
||||
new SpeciesEvolution(Species.SIMISEAR, 1, "Fire Stone", null, SpeciesWildEvolutionDelay.MEDIUM)
|
||||
new SpeciesEvolution(Species.SIMISEAR, 1, EvolutionItem.FIRE_STONE, null, SpeciesWildEvolutionDelay.MEDIUM)
|
||||
],
|
||||
[Species.PANPOUR]: [
|
||||
new SpeciesEvolution(Species.SIMIPOUR, 1, "Water Stone", null, SpeciesWildEvolutionDelay.MEDIUM)
|
||||
new SpeciesEvolution(Species.SIMIPOUR, 1, EvolutionItem.WATER_STONE, null, SpeciesWildEvolutionDelay.MEDIUM)
|
||||
],
|
||||
[Species.MUNNA]: [
|
||||
new SpeciesEvolution(Species.MUSHARNA, 1, "Moon Stone", null, SpeciesWildEvolutionDelay.LONG)
|
||||
new SpeciesEvolution(Species.MUSHARNA, 1, EvolutionItem.MOON_STONE, null, SpeciesWildEvolutionDelay.LONG)
|
||||
],
|
||||
[Species.COTTONEE]: [
|
||||
new SpeciesEvolution(Species.WHIMSICOTT, 1, "Sun Stone", null, SpeciesWildEvolutionDelay.MEDIUM)
|
||||
new SpeciesEvolution(Species.WHIMSICOTT, 1, EvolutionItem.SUN_STONE, null, SpeciesWildEvolutionDelay.MEDIUM)
|
||||
],
|
||||
[Species.PETILIL]: [
|
||||
new SpeciesEvolution(Species.LILLIGANT, 1, "Sun Stone", null, SpeciesWildEvolutionDelay.MEDIUM)
|
||||
new SpeciesEvolution(Species.LILLIGANT, 1, EvolutionItem.SUN_STONE, null, SpeciesWildEvolutionDelay.MEDIUM)
|
||||
],
|
||||
[Species.MINCCINO]: [
|
||||
new SpeciesEvolution(Species.CINCCINO, 1, "Shiny Stone", null, SpeciesWildEvolutionDelay.SHORT)
|
||||
new SpeciesEvolution(Species.CINCCINO, 1, EvolutionItem.SHINY_STONE, null, SpeciesWildEvolutionDelay.SHORT)
|
||||
],
|
||||
[Species.EELEKTRIK]: [
|
||||
new SpeciesEvolution(Species.EELEKTROSS, 1, "Thunder Stone", null, SpeciesWildEvolutionDelay.VERY_LONG)
|
||||
new SpeciesEvolution(Species.EELEKTROSS, 1, EvolutionItem.THUNDER_STONE, null, SpeciesWildEvolutionDelay.VERY_LONG)
|
||||
],
|
||||
[Species.LAMPENT]: [
|
||||
new SpeciesEvolution(Species.CHANDELURE, 1, "Dusk Stone", null, SpeciesWildEvolutionDelay.VERY_LONG)
|
||||
new SpeciesEvolution(Species.CHANDELURE, 1, EvolutionItem.DUSK_STONE, null, SpeciesWildEvolutionDelay.VERY_LONG)
|
||||
],
|
||||
[Species.KADABRA]: [
|
||||
new SpeciesEvolution(Species.ALAKAZAM, 1, "Link Cable", null, SpeciesWildEvolutionDelay.VERY_LONG)
|
||||
new SpeciesEvolution(Species.ALAKAZAM, 1, EvolutionItem.LINKING_CORD, null, SpeciesWildEvolutionDelay.VERY_LONG)
|
||||
],
|
||||
[Species.MACHOKE]: [
|
||||
new SpeciesEvolution(Species.MACHAMP, 1, "Link Cable", null, SpeciesWildEvolutionDelay.VERY_LONG)
|
||||
new SpeciesEvolution(Species.MACHAMP, 1, EvolutionItem.LINKING_CORD, null, SpeciesWildEvolutionDelay.VERY_LONG)
|
||||
],
|
||||
[Species.GRAVELER]: [
|
||||
new SpeciesEvolution(Species.GOLEM, 1, "Link Cable", null, SpeciesWildEvolutionDelay.VERY_LONG)
|
||||
new SpeciesEvolution(Species.GOLEM, 1, EvolutionItem.LINKING_CORD, null, SpeciesWildEvolutionDelay.VERY_LONG)
|
||||
],
|
||||
[Species.HAUNTER]: [
|
||||
new SpeciesEvolution(Species.GENGAR, 1, "Link Cable", new SpeciesEvolutionCondition((p: Pokemon) => true), SpeciesWildEvolutionDelay.VERY_LONG)
|
||||
new SpeciesEvolution(Species.GENGAR, 1, EvolutionItem.LINKING_CORD, null, SpeciesWildEvolutionDelay.VERY_LONG)
|
||||
],
|
||||
[Species.ONIX]: [
|
||||
new SpeciesEvolution(Species.STEELIX, 1, "Link Cable", new SpeciesEvolutionCondition((p: Pokemon) => true /* Metal coat*/ ), SpeciesWildEvolutionDelay.VERY_LONG)
|
||||
new SpeciesEvolution(Species.STEELIX, 1, EvolutionItem.LINKING_CORD, new SpeciesEvolutionCondition(
|
||||
(p: Pokemon) => p.scene.findModifier(m => m instanceof AttackTypeBoosterModifier && (m.type as AttackTypeBoosterModifierType).moveType === Type.STEEL)),
|
||||
SpeciesWildEvolutionDelay.VERY_LONG)
|
||||
],
|
||||
[Species.RHYDON]: [
|
||||
new SpeciesEvolution(Species.RHYPERIOR, 1, "Link Cable", new SpeciesEvolutionCondition((p: Pokemon) => true /* Protector */), SpeciesWildEvolutionDelay.VERY_LONG)
|
||||
new SpeciesEvolution(Species.RHYPERIOR, 1, EvolutionItem.LINKING_CORD, new SpeciesEvolutionCondition((p: Pokemon) => true /* Protector */), SpeciesWildEvolutionDelay.VERY_LONG)
|
||||
],
|
||||
[Species.SEADRA]: [
|
||||
new SpeciesEvolution(Species.KINGDRA, 1, "Link Cable", new SpeciesEvolutionCondition((p: Pokemon) => true /* Dragon scale*/), SpeciesWildEvolutionDelay.VERY_LONG)
|
||||
new SpeciesEvolution(Species.KINGDRA, 1, EvolutionItem.LINKING_CORD, new SpeciesEvolutionCondition((p: Pokemon) => true /* Dragon scale*/), SpeciesWildEvolutionDelay.VERY_LONG)
|
||||
],
|
||||
[Species.SCYTHER]: [
|
||||
new SpeciesEvolution(Species.SCIZOR, 1, "Link Cable", new SpeciesEvolutionCondition((p: Pokemon) => true /* Metal coat*/), SpeciesWildEvolutionDelay.VERY_LONG)
|
||||
new SpeciesEvolution(Species.SCIZOR, 1, EvolutionItem.LINKING_CORD, new SpeciesEvolutionCondition(
|
||||
(p: Pokemon) => p.scene.findModifier(m => m instanceof AttackTypeBoosterModifier && (m.type as AttackTypeBoosterModifierType).moveType === Type.STEEL) ),
|
||||
SpeciesWildEvolutionDelay.VERY_LONG)
|
||||
],
|
||||
[Species.ELECTABUZZ]: [
|
||||
new SpeciesEvolution(Species.ELECTIVIRE, 1, "Link Cable", new SpeciesEvolutionCondition((p: Pokemon) => true /* Electirizer*/), SpeciesWildEvolutionDelay.VERY_LONG)
|
||||
new SpeciesEvolution(Species.ELECTIVIRE, 1, EvolutionItem.LINKING_CORD, new SpeciesEvolutionCondition((p: Pokemon) => true /* Electirizer*/), SpeciesWildEvolutionDelay.VERY_LONG)
|
||||
],
|
||||
[Species.MAGMAR]: [
|
||||
new SpeciesEvolution(Species.MAGMORTAR, 1, "Link Cable", new SpeciesEvolutionCondition((p: Pokemon) => true /* Magmarizer*/), SpeciesWildEvolutionDelay.VERY_LONG)
|
||||
new SpeciesEvolution(Species.MAGMORTAR, 1, EvolutionItem.LINKING_CORD, new SpeciesEvolutionCondition((p: Pokemon) => true /* Magmarizer*/), SpeciesWildEvolutionDelay.VERY_LONG)
|
||||
],
|
||||
[Species.PORYGON]: [
|
||||
new SpeciesEvolution(Species.PORYGON2, 1, "Link Cable", new SpeciesEvolutionCondition((p: Pokemon) => true /*Upgrade*/), SpeciesWildEvolutionDelay.MEDIUM)
|
||||
new SpeciesEvolution(Species.PORYGON2, 1, EvolutionItem.LINKING_CORD, new SpeciesEvolutionCondition((p: Pokemon) => true /*Upgrade*/), SpeciesWildEvolutionDelay.MEDIUM)
|
||||
],
|
||||
[Species.PORYGON2]: [
|
||||
new SpeciesEvolution(Species.PORYGON_Z, 1, "Link Cable", new SpeciesEvolutionCondition((p: Pokemon) => true /* Dubious disc*/), SpeciesWildEvolutionDelay.VERY_LONG)
|
||||
new SpeciesEvolution(Species.PORYGON_Z, 1, EvolutionItem.LINKING_CORD, new SpeciesEvolutionCondition((p: Pokemon) => true /* Dubious disc*/), SpeciesWildEvolutionDelay.VERY_LONG)
|
||||
],
|
||||
[Species.FEEBAS]: [
|
||||
new SpeciesEvolution(Species.MILOTIC, 1, "Link Cable", new SpeciesEvolutionCondition((p: Pokemon) => true /* Prism scale*/), SpeciesWildEvolutionDelay.VERY_LONG)
|
||||
new SpeciesEvolution(Species.MILOTIC, 1, EvolutionItem.LINKING_CORD, new SpeciesEvolutionCondition((p: Pokemon) => true /* Prism scale*/), SpeciesWildEvolutionDelay.VERY_LONG)
|
||||
],
|
||||
[Species.DUSCLOPS]: [
|
||||
new SpeciesEvolution(Species.DUSKNOIR, 1, "Link Cable", new SpeciesEvolutionCondition((p: Pokemon) => true /* Reaper cloth*/), SpeciesWildEvolutionDelay.VERY_LONG)
|
||||
new SpeciesEvolution(Species.DUSKNOIR, 1, EvolutionItem.LINKING_CORD, new SpeciesEvolutionCondition((p: Pokemon) => true /* Reaper cloth*/), SpeciesWildEvolutionDelay.VERY_LONG)
|
||||
],
|
||||
[Species.CLAMPERL]: [
|
||||
new SpeciesEvolution(Species.HUNTAIL, 1, "Link Cable", new SpeciesEvolutionCondition((p: Pokemon) => true /* Deep sea tooth*/), SpeciesWildEvolutionDelay.MEDIUM),
|
||||
new SpeciesEvolution(Species.GOREBYSS, 1, "Link Cable", new SpeciesEvolutionCondition((p: Pokemon) => true /* Deep sea scale*/), SpeciesWildEvolutionDelay.MEDIUM)
|
||||
new SpeciesEvolution(Species.HUNTAIL, 1, EvolutionItem.LINKING_CORD, new SpeciesEvolutionCondition((p: Pokemon) => true /* Deep sea tooth*/), SpeciesWildEvolutionDelay.MEDIUM),
|
||||
new SpeciesEvolution(Species.GOREBYSS, 1, EvolutionItem.LINKING_CORD, new SpeciesEvolutionCondition((p: Pokemon) => true /* Deep sea scale*/), SpeciesWildEvolutionDelay.MEDIUM)
|
||||
],
|
||||
[Species.BOLDORE]: [
|
||||
new SpeciesEvolution(Species.GIGALITH, 1, "Link Cable", null, SpeciesWildEvolutionDelay.VERY_LONG)
|
||||
new SpeciesEvolution(Species.GIGALITH, 1, EvolutionItem.LINKING_CORD, null, SpeciesWildEvolutionDelay.VERY_LONG)
|
||||
],
|
||||
[Species.GURDURR]: [
|
||||
new SpeciesEvolution(Species.CONKELDURR, 1, "Link Cable", null, SpeciesWildEvolutionDelay.VERY_LONG)
|
||||
new SpeciesEvolution(Species.CONKELDURR, 1, EvolutionItem.LINKING_CORD, null, SpeciesWildEvolutionDelay.VERY_LONG)
|
||||
],
|
||||
[Species.KARRABLAST]: [
|
||||
new SpeciesEvolution(Species.ESCAVALIER, 1, "Link Cable", new SpeciesEvolutionCondition((p: Pokemon) => true /* Trade with shelmet??*/), SpeciesWildEvolutionDelay.LONG)
|
||||
new SpeciesEvolution(Species.ESCAVALIER, 1, EvolutionItem.LINKING_CORD, new SpeciesEvolutionCondition((p: Pokemon) => p.scene.getParty().find(p => p.species.speciesId === Species.SHELMET)), SpeciesWildEvolutionDelay.LONG)
|
||||
],
|
||||
[Species.SHELMET]: [
|
||||
new SpeciesEvolution(Species.ACCELGOR, 1, "Link Cable", new SpeciesEvolutionCondition((p: Pokemon) => true /* Trade with karrablast??*/), SpeciesWildEvolutionDelay.LONG)
|
||||
new SpeciesEvolution(Species.ACCELGOR, 1, EvolutionItem.LINKING_CORD, new SpeciesEvolutionCondition((p: Pokemon) => p.scene.getParty().find(p => p.species.speciesId === Species.KARRABLAST)), SpeciesWildEvolutionDelay.LONG)
|
||||
],
|
||||
[Species.PICHU]: [
|
||||
new SpeciesEvolution(Species.PIKACHU, 1, null, new SpeciesEvolutionCondition((p: Pokemon) => p.winCount >= 10), SpeciesWildEvolutionDelay.SHORT)
|
||||
|
@ -949,16 +975,16 @@ export const pokemonEvolutions: PokemonEvolutions = {
|
|||
new SpeciesEvolution(Species.MARILL, 1, null, new SpeciesEvolutionCondition((p: Pokemon) => p.winCount >= 10), SpeciesWildEvolutionDelay.SHORT)
|
||||
],
|
||||
[Species.BUDEW]: [
|
||||
new SpeciesEvolution(Species.ROSELIA, 1, null, new SpeciesEvolutionCondition((p: Pokemon) => p.winCount > 10 /* daytime */), SpeciesWildEvolutionDelay.SHORT)
|
||||
new SpeciesEvolution(Species.ROSELIA, 1, null, new SpeciesEvolutionCondition((p: Pokemon) => p.winCount > 10 && p.scene.arena.isDaytime()), SpeciesWildEvolutionDelay.SHORT)
|
||||
],
|
||||
[Species.CHINGLING]: [
|
||||
new SpeciesEvolution(Species.CHIMECHO, 1, null, new SpeciesEvolutionCondition((p: Pokemon) => p.winCount >= 10 /* nighttime */), SpeciesWildEvolutionDelay.MEDIUM)
|
||||
new SpeciesEvolution(Species.CHIMECHO, 1, null, new SpeciesEvolutionCondition((p: Pokemon) => p.winCount >= 10 && !p.scene.arena.isDaytime()), SpeciesWildEvolutionDelay.MEDIUM)
|
||||
],
|
||||
[Species.BUNEARY]: [
|
||||
new SpeciesEvolution(Species.LOPUNNY, 1, null, new SpeciesEvolutionCondition((p: Pokemon) => p.winCount >= 10), SpeciesWildEvolutionDelay.MEDIUM)
|
||||
],
|
||||
[Species.RIOLU]: [
|
||||
new SpeciesEvolution(Species.LUCARIO, 1, null, new SpeciesEvolutionCondition((p: Pokemon) => p.winCount >= 10 /* daytime */), SpeciesWildEvolutionDelay.MEDIUM)
|
||||
new SpeciesEvolution(Species.LUCARIO, 1, null, new SpeciesEvolutionCondition((p: Pokemon) => p.winCount >= 10 && p.scene.arena.isDaytime()), SpeciesWildEvolutionDelay.MEDIUM)
|
||||
],
|
||||
[Species.WOOBAT]: [
|
||||
new SpeciesEvolution(Species.SWOOBAT, 1, null, new SpeciesEvolutionCondition((p: Pokemon) => p.winCount >= 10), SpeciesWildEvolutionDelay.MEDIUM)
|
||||
|
|
|
@ -8,7 +8,7 @@ import * as Utils from './utils';
|
|||
import { Type, getTypeDamageMultiplier } from './type';
|
||||
import { getLevelTotalExp } from './exp';
|
||||
import { Stat } from './pokemon-stat';
|
||||
import { PokemonBaseStatModifier as PokemonBaseStatBoosterModifier, ShinyRateBoosterModifier } from './modifier';
|
||||
import { AttackTypeBoosterModifier, PokemonBaseStatModifier as PokemonBaseStatBoosterModifier, ShinyRateBoosterModifier } from './modifier';
|
||||
import { PokeballType } from './pokeball';
|
||||
import { Gender } from './gender';
|
||||
import { initMoveAnim, loadMoveAnimAssets } from './battle-anims';
|
||||
|
@ -18,6 +18,7 @@ import { pokemonEvolutions, SpeciesEvolution, SpeciesEvolutionCondition } from '
|
|||
import { MessagePhase } from './battle-phases';
|
||||
import { BattleStat } from './battle-stat';
|
||||
import { BattleTag, BattleTagLapseType, BattleTagType } from './battle-tag';
|
||||
import { Species } from './species';
|
||||
|
||||
export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
||||
public id: integer;
|
||||
|
@ -95,11 +96,11 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
|||
const rand1 = Utils.binToDec(Utils.decToBin(this.id).substring(0, 16));
|
||||
const rand2 = Utils.binToDec(Utils.decToBin(this.id).substring(16, 32));
|
||||
|
||||
const E = (this.scene as BattleScene).trainerId ^ (this.scene as BattleScene).secretId;
|
||||
const E = this.scene.trainerId ^ this.scene.secretId;
|
||||
const F = rand1 ^ rand2;
|
||||
|
||||
let shinyThreshold = new Utils.IntegerHolder(32);
|
||||
(this.scene as BattleScene).applyModifiers(ShinyRateBoosterModifier, shinyThreshold);
|
||||
this.scene.applyModifiers(ShinyRateBoosterModifier, shinyThreshold);
|
||||
console.log(shinyThreshold.value);
|
||||
|
||||
this.shiny = (E ^ F) < shinyThreshold.value;
|
||||
|
@ -113,11 +114,11 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
|||
this.winCount = 0;
|
||||
}
|
||||
|
||||
//this.setPipeline((this.scene as BattleScene).spritePipeline);
|
||||
//this.setPipeline(this.scene).spritePipeline);
|
||||
|
||||
this.calculateStats();
|
||||
|
||||
(scene as BattleScene).fieldUI.addAt(this.battleInfo, 0);
|
||||
scene.fieldUI.addAt(this.battleInfo, 0);
|
||||
|
||||
this.battleInfo.initInfo(this);
|
||||
|
||||
|
@ -163,10 +164,10 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
|||
const moveIds = this.moveset.map(m => m.getMove().id);
|
||||
Promise.allSettled(moveIds.map(m => initMoveAnim(m)))
|
||||
.then(() => {
|
||||
loadMoveAnimAssets(this.scene as BattleScene, moveIds);
|
||||
this.species.loadAssets(this.scene as BattleScene, this.gender === Gender.FEMALE);
|
||||
loadMoveAnimAssets(this.scene, moveIds);
|
||||
this.species.loadAssets(this.scene, this.gender === Gender.FEMALE);
|
||||
if (this.isPlayer())
|
||||
(this.scene as BattleScene).loadAtlas(this.getBattleSpriteKey(), 'pokemon', this.getBattleSpriteAtlasPath());
|
||||
this.scene.loadAtlas(this.getBattleSpriteKey(), 'pokemon', this.getBattleSpriteAtlasPath());
|
||||
this.scene.load.once(Phaser.Loader.Events.COMPLETE, () => {
|
||||
if (this.isPlayer()) {
|
||||
const originalWarn = console.warn;
|
||||
|
@ -260,7 +261,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
|||
this.stats = [ 0, 0, 0, 0, 0, 0 ];
|
||||
const baseStats = this.species.baseStats.slice(0);
|
||||
console.log(this.id);
|
||||
(this.scene as BattleScene).applyModifiers(PokemonBaseStatBoosterModifier, this, baseStats);
|
||||
this.scene.applyModifiers(PokemonBaseStatBoosterModifier, this, baseStats);
|
||||
const stats = Utils.getEnumValues(Stat);
|
||||
for (let s of stats) {
|
||||
const isHp = s === Stat.HP;
|
||||
|
@ -412,7 +413,6 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
|||
|
||||
apply(source: Pokemon, battlerMove: PokemonMove): Promise<MoveResult> {
|
||||
return new Promise(resolve => {
|
||||
const battleScene = this.scene as BattleScene;
|
||||
let result: MoveResult = MoveResult.STATUS;
|
||||
let success = false;
|
||||
const move = battlerMove.getMove();
|
||||
|
@ -422,15 +422,17 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
|||
case MoveCategory.PHYSICAL:
|
||||
case MoveCategory.SPECIAL:
|
||||
const isPhysical = moveCategory === MoveCategory.PHYSICAL;
|
||||
const power = new Utils.NumberHolder(move.power);
|
||||
this.scene.applyModifiers(AttackTypeBoosterModifier, source, power);
|
||||
const critChance = new Utils.IntegerHolder(16);
|
||||
applyMoveAttrs(HighCritAttr, this.scene as BattleScene, source, this, move, critChance);
|
||||
applyMoveAttrs(HighCritAttr, this.scene, source, this, move, critChance);
|
||||
const isCritical = Utils.randInt(critChance.value) === 0;
|
||||
const sourceAtk = source.getBattleStat(isPhysical ? Stat.ATK : Stat.SPATK);
|
||||
const targetDef = this.getBattleStat(isPhysical ? Stat.DEF : Stat.SPDEF);
|
||||
const stabMultiplier = source.species.type1 === move.type || (source.species.type2 > -1 && source.species.type2 === move.type) ? 1.5 : 1;
|
||||
const typeMultiplier = getTypeDamageMultiplier(move.type, this.species.type1) * (this.species.type2 > -1 ? getTypeDamageMultiplier(move.type, this.species.type2) : 1);
|
||||
const criticalMultiplier = isCritical ? 2 : 1;
|
||||
damage = Math.ceil(((((2 * source.level / 5 + 2) * move.power * sourceAtk / targetDef) / 50) + 2) * stabMultiplier * typeMultiplier * ((Utils.randInt(15) + 85) / 100)) * criticalMultiplier;
|
||||
damage = Math.ceil(((((2 * source.level / 5 + 2) * power.value * sourceAtk / targetDef) / 50) + 2) * stabMultiplier * typeMultiplier * ((Utils.randInt(15) + 85) / 100)) * criticalMultiplier;
|
||||
if (isPhysical && source.status && source.status.effect === StatusEffect.BURN)
|
||||
damage = Math.floor(damage / 2);
|
||||
move.getAttrs(HitsTagAttr).map(hta => hta as HitsTagAttr).filter(hta => hta.doubleDamage).forEach(hta => {
|
||||
|
@ -444,7 +446,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
|||
this.hp = Math.max(this.hp - damage, 0);
|
||||
source.turnData.damageDealt += damage;
|
||||
if (isCritical)
|
||||
battleScene.unshiftPhase(new MessagePhase(battleScene, 'A critical hit!'));
|
||||
this.scene.unshiftPhase(new MessagePhase(this.scene, 'A critical hit!'));
|
||||
}
|
||||
if (typeMultiplier >= 2)
|
||||
result = MoveResult.SUPER_EFFECTIVE;
|
||||
|
@ -462,16 +464,16 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
|||
break;
|
||||
case MoveResult.SUPER_EFFECTIVE:
|
||||
this.scene.sound.play('hit_strong');
|
||||
battleScene.unshiftPhase(new MessagePhase(battleScene, 'It\'s super effective!'));
|
||||
this.scene.unshiftPhase(new MessagePhase(this.scene, 'It\'s super effective!'));
|
||||
success = true;
|
||||
break;
|
||||
case MoveResult.NOT_VERY_EFFECTIVE:
|
||||
this.scene.sound.play('hit_weak');
|
||||
battleScene.unshiftPhase(new MessagePhase(battleScene, 'It\'s not very effective!'))
|
||||
this.scene.unshiftPhase(new MessagePhase(this.scene, 'It\'s not very effective!'))
|
||||
success = true;
|
||||
break;
|
||||
case MoveResult.NO_EFFECT:
|
||||
battleScene.unshiftPhase(new MessagePhase(battleScene, `It doesn\'t affect ${this.name}!`))
|
||||
this.scene.unshiftPhase(new MessagePhase(this.scene, `It doesn\'t affect ${this.name}!`))
|
||||
success = true;
|
||||
break;
|
||||
}
|
||||
|
@ -546,7 +548,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
|||
}
|
||||
|
||||
cry(soundConfig?: Phaser.Types.Sound.SoundConfig): integer {
|
||||
return this.species.cry(this.scene as BattleScene, soundConfig);
|
||||
return this.species.cry(this.scene, soundConfig);
|
||||
}
|
||||
|
||||
faintCry(callback: Function) {
|
||||
|
@ -724,6 +726,10 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
|||
}
|
||||
}
|
||||
|
||||
export default interface Pokemon {
|
||||
scene: BattleScene
|
||||
}
|
||||
|
||||
export class PlayerPokemon extends Pokemon {
|
||||
public compatibleTms: Moves[];
|
||||
|
||||
|
@ -760,9 +766,10 @@ export class PlayerPokemon extends Pokemon {
|
|||
|
||||
evolve(evolution: SpeciesEvolution): Promise<void> {
|
||||
return new Promise(resolve => {
|
||||
this.handleSpecialEvolutions(evolution);
|
||||
this.species = getPokemonSpecies(evolution.speciesId);
|
||||
this.name = this.species.name.toUpperCase();
|
||||
this.species.generateIconAnim(this.scene as BattleScene);
|
||||
this.species.generateIconAnim(this.scene);
|
||||
this.compatibleTms.splice(0, this.compatibleTms.length);
|
||||
this.generateCompatibleTms();
|
||||
this.loadAssets().then(() => {
|
||||
|
@ -771,6 +778,17 @@ export class PlayerPokemon extends Pokemon {
|
|||
});
|
||||
});
|
||||
}
|
||||
|
||||
private handleSpecialEvolutions(evolution: SpeciesEvolution) {
|
||||
if (this.species.speciesId === Species.NINCADA && evolution.speciesId === Species.NINJASK) {
|
||||
const newEvolution = pokemonEvolutions[this.species.speciesId][1];
|
||||
if (newEvolution.condition.predicate(this)) {
|
||||
const newPokemon = new PlayerPokemon(this.scene, this.species, this.level);
|
||||
this.scene.getParty().push(newPokemon);
|
||||
newPokemon.evolve(newEvolution);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export class EnemyPokemon extends Pokemon {
|
||||
|
@ -798,7 +816,7 @@ export class EnemyPokemon extends Pokemon {
|
|||
return movePool[Utils.randInt(movePool.length)];
|
||||
case AiType.SMART_RANDOM:
|
||||
case AiType.SMART:
|
||||
const target = (this.scene as BattleScene).getPlayerPokemon();
|
||||
const target = this.scene.getPlayerPokemon();
|
||||
const moveScores = movePool.map(() => 0);
|
||||
for (let m in movePool) {
|
||||
const pokemonMove = movePool[m];
|
||||
|
@ -868,11 +886,11 @@ export class EnemyPokemon extends Pokemon {
|
|||
}
|
||||
|
||||
addToParty() {
|
||||
const party = (this.scene as BattleScene).getParty();
|
||||
const party = this.scene.getParty();
|
||||
let ret: PlayerPokemon = null;
|
||||
|
||||
if (party.length < 6) {
|
||||
const newPokemon = new PlayerPokemon(this.scene as BattleScene, this.species, this.level, this);
|
||||
const newPokemon = new PlayerPokemon(this.scene, this.species, this.level, this);
|
||||
party.push(newPokemon);
|
||||
ret = newPokemon;
|
||||
}
|
||||
|
|
|
@ -43,7 +43,7 @@ export default class CommandUiHandler extends UiHandler {
|
|||
const messageHandler = this.getUi().getMessageHandler();
|
||||
messageHandler.bg.setTexture('bg_command');
|
||||
messageHandler.message.setWordWrapWidth(1110);
|
||||
messageHandler.showText(`What will\n${(this.scene as BattleScene).getPlayerPokemon().name} do?`, 0);
|
||||
messageHandler.showText(`What will\n${this.scene.getPlayerPokemon().name} do?`, 0);
|
||||
this.setCursor(this.cursor);
|
||||
}
|
||||
|
||||
|
|
|
@ -49,7 +49,7 @@ export default class FightUiHandler extends UiHandler {
|
|||
|
||||
if (button === Button.CANCEL || button === Button.ACTION) {
|
||||
if (button === Button.ACTION) {
|
||||
if (((this.scene as BattleScene).getCurrentPhase() as CommandPhase).handleCommand(Command.FIGHT, this.cursor))
|
||||
if ((this.scene.getCurrentPhase() as CommandPhase).handleCommand(Command.FIGHT, this.cursor))
|
||||
success = true;
|
||||
else
|
||||
ui.playError();
|
||||
|
@ -91,7 +91,7 @@ export default class FightUiHandler extends UiHandler {
|
|||
ui.add(this.cursorObj);
|
||||
}
|
||||
|
||||
const moveset = (this.scene as BattleScene).getPlayerPokemon().moveset;
|
||||
const moveset = this.scene.getPlayerPokemon().moveset;
|
||||
|
||||
const hasMove = cursor < moveset.length;
|
||||
|
||||
|
@ -114,7 +114,7 @@ export default class FightUiHandler extends UiHandler {
|
|||
}
|
||||
|
||||
displayMoves() {
|
||||
const moveset = (this.scene as BattleScene).getPlayerPokemon().moveset;
|
||||
const moveset = this.scene.getPlayerPokemon().moveset;
|
||||
for (let m = 0; m < 4; m++) {
|
||||
const moveText = addTextObject(this.scene, m % 2 === 0 ? 0 : 100, m < 2 ? 0 : 16, '-', TextStyle.WINDOW);
|
||||
if (m < moveset.length)
|
||||
|
|
|
@ -280,7 +280,7 @@ export default class PartyUiHandler extends MessageUiHandler {
|
|||
}
|
||||
|
||||
populatePartySlots() {
|
||||
const party = (this.scene as BattleScene).getParty();
|
||||
const party = this.scene.getParty();
|
||||
|
||||
if (this.cursor < 6 && this.cursor >= party.length)
|
||||
this.cursor = party.length - 1;
|
||||
|
@ -289,7 +289,7 @@ export default class PartyUiHandler extends MessageUiHandler {
|
|||
|
||||
for (let p in party) {
|
||||
const slotIndex = parseInt(p);
|
||||
const partySlot = new PartySlot(this.scene as BattleScene, slotIndex, party[p]);
|
||||
const partySlot = new PartySlot(this.scene, slotIndex, party[p]);
|
||||
this.scene.add.existing(partySlot);
|
||||
this.partySlotsContainer.add(partySlot);
|
||||
this.partySlots.push(partySlot);
|
||||
|
|