Add DNA splicers and Pokemon fusing
parent
0ad1a9d25a
commit
e07339e3eb
Binary file not shown.
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
Before Width: | Height: | Size: 56 KiB After Width: | Height: | Size: 25 KiB |
Binary file not shown.
After Width: | Height: | Size: 293 B |
Binary file not shown.
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 4.1 KiB |
|
@ -5,7 +5,7 @@ import { allMoves, applyMoveAttrs, BypassSleepAttr, ChargeAttr, applyFilteredMov
|
||||||
import { Mode } from './ui/ui';
|
import { Mode } from './ui/ui';
|
||||||
import { Command } from "./ui/command-ui-handler";
|
import { Command } from "./ui/command-ui-handler";
|
||||||
import { Stat } from "./data/pokemon-stat";
|
import { Stat } from "./data/pokemon-stat";
|
||||||
import { BerryModifier, ContactHeldItemTransferChanceModifier, EnemyAttackStatusEffectChanceModifier, EnemyInstantReviveChanceModifier, EnemyStatusEffectHealChanceModifier, EnemyTurnHealModifier, ExpBalanceModifier, ExpBoosterModifier, ExpShareModifier, ExtraModifierModifier, FlinchChanceModifier, HealingBoosterModifier, HitHealModifier, LapsingPersistentModifier, MapModifier, Modifier, MultipleParticipantExpBonusModifier, PersistentModifier, PokemonExpBoosterModifier, PokemonHeldItemModifier, PokemonInstantReviveModifier, SwitchEffectTransferModifier, TempBattleStatBoosterModifier, TurnHealModifier, TurnHeldItemTransferModifier } from "./modifier/modifier";
|
import { BerryModifier, ContactHeldItemTransferChanceModifier, EnemyAttackStatusEffectChanceModifier, EnemyInstantReviveChanceModifier, EnemyStatusEffectHealChanceModifier, EnemyTurnHealModifier, ExpBalanceModifier, ExpBoosterModifier, ExpShareModifier, ExtraModifierModifier, FlinchChanceModifier, FusePokemonModifier, HealingBoosterModifier, HitHealModifier, LapsingPersistentModifier, MapModifier, Modifier, MultipleParticipantExpBonusModifier, PersistentModifier, PokemonExpBoosterModifier, PokemonHeldItemModifier, PokemonInstantReviveModifier, SwitchEffectTransferModifier, TempBattleStatBoosterModifier, TurnHealModifier, TurnHeldItemTransferModifier } from "./modifier/modifier";
|
||||||
import PartyUiHandler, { PartyOption, PartyUiMode } from "./ui/party-ui-handler";
|
import PartyUiHandler, { PartyOption, PartyUiMode } from "./ui/party-ui-handler";
|
||||||
import { doPokeballBounceAnim, getPokeballAtlasKey, getPokeballCatchMultiplier, getPokeballTintColor, PokeballType } from "./data/pokeball";
|
import { doPokeballBounceAnim, getPokeballAtlasKey, getPokeballCatchMultiplier, getPokeballTintColor, PokeballType } from "./data/pokeball";
|
||||||
import { CommonAnim, CommonBattleAnim, MoveAnim, initMoveAnim, loadMoveAnimAssets } from "./data/battle-anims";
|
import { CommonAnim, CommonBattleAnim, MoveAnim, initMoveAnim, loadMoveAnimAssets } from "./data/battle-anims";
|
||||||
|
@ -16,7 +16,7 @@ import { EvolutionPhase } from "./evolution-phase";
|
||||||
import { BattlePhase } from "./battle-phase";
|
import { BattlePhase } from "./battle-phase";
|
||||||
import { BattleStat, getBattleStatLevelChangeDescription, getBattleStatName } from "./data/battle-stat";
|
import { BattleStat, getBattleStatLevelChangeDescription, getBattleStatName } from "./data/battle-stat";
|
||||||
import { Biome, biomeLinks } from "./data/biome";
|
import { Biome, biomeLinks } from "./data/biome";
|
||||||
import { ModifierPoolType, ModifierType, ModifierTypeFunc, ModifierTypeOption, PokemonModifierType, PokemonMoveModifierType, TmModifierType, getEnemyBuffModifierTypeOptionsForWave, getModifierType, getPlayerModifierTypeOptionsForWave, modifierTypes, regenerateModifierPoolThresholds } from "./modifier/modifier-type";
|
import { FusePokemonModifierType, ModifierPoolType, ModifierType, ModifierTypeFunc, ModifierTypeOption, PokemonModifierType, PokemonMoveModifierType, TmModifierType, getEnemyBuffModifierTypeOptionsForWave, getModifierType, getPlayerModifierTypeOptionsForWave, modifierTypes, regenerateModifierPoolThresholds } from "./modifier/modifier-type";
|
||||||
import SoundFade from "phaser3-rex-plugins/plugins/soundfade";
|
import SoundFade from "phaser3-rex-plugins/plugins/soundfade";
|
||||||
import { BattlerTagLapseType, BattlerTagType, HideSpriteTag as HiddenTag, TrappedTag } from "./data/battler-tag";
|
import { BattlerTagLapseType, BattlerTagType, HideSpriteTag as HiddenTag, TrappedTag } from "./data/battler-tag";
|
||||||
import { getPokemonMessage } from "./messages";
|
import { getPokemonMessage } from "./messages";
|
||||||
|
@ -118,7 +118,7 @@ export class SelectStarterPhase extends BattlePhase {
|
||||||
Promise.all(loadPokemonAssets).then(() => {
|
Promise.all(loadPokemonAssets).then(() => {
|
||||||
this.scene.ui.clearText();
|
this.scene.ui.clearText();
|
||||||
this.scene.ui.setMode(Mode.MESSAGE).then(() => {
|
this.scene.ui.setMode(Mode.MESSAGE).then(() => {
|
||||||
SoundFade.fadeOut(this.scene.sound.get('menu'), 500, true);
|
SoundFade.fadeOut(this.scene, this.scene.sound.get('menu'), 500, true);
|
||||||
this.scene.time.delayedCall(500, () => this.scene.playBgm());
|
this.scene.time.delayedCall(500, () => this.scene.playBgm());
|
||||||
this.end();
|
this.end();
|
||||||
});
|
});
|
||||||
|
@ -2819,6 +2819,7 @@ export class AttemptRunPhase extends PokemonPhase {
|
||||||
enemyField.forEach(enemyPokemon => {
|
enemyField.forEach(enemyPokemon => {
|
||||||
enemyPokemon.hideInfo().then(() => enemyPokemon.destroy());
|
enemyPokemon.hideInfo().then(() => enemyPokemon.destroy());
|
||||||
enemyPokemon.hp = 0;
|
enemyPokemon.hp = 0;
|
||||||
|
enemyPokemon.trySetStatus(StatusEffect.FAINT);
|
||||||
});
|
});
|
||||||
|
|
||||||
this.scene.clearEnemyHeldItemModifiers();
|
this.scene.clearEnemyHeldItemModifiers();
|
||||||
|
@ -2878,28 +2879,42 @@ export class SelectModifierPhase extends BattlePhase {
|
||||||
|
|
||||||
const modifierType = typeOptions[cursor].type;
|
const modifierType = typeOptions[cursor].type;
|
||||||
if (modifierType instanceof PokemonModifierType) {
|
if (modifierType instanceof PokemonModifierType) {
|
||||||
const pokemonModifierType = modifierType as PokemonModifierType;
|
if (modifierType instanceof FusePokemonModifierType) {
|
||||||
const isMoveModifier = modifierType instanceof PokemonMoveModifierType;
|
this.scene.ui.setModeWithoutClear(Mode.PARTY, PartyUiMode.SPLICE, -1, (fromSlotIndex: integer, spliceSlotIndex: integer) => {
|
||||||
const isTmModifier = modifierType instanceof TmModifierType;
|
if (spliceSlotIndex !== undefined && fromSlotIndex < 6 && spliceSlotIndex < 6 && fromSlotIndex !== spliceSlotIndex) {
|
||||||
const partyUiMode = isMoveModifier ? PartyUiMode.MOVE_MODIFIER
|
this.scene.ui.setMode(Mode.MODIFIER_SELECT, this.isPlayer()).then(() => {
|
||||||
: isTmModifier ? PartyUiMode.TM_MODIFIER : PartyUiMode.MODIFIER;
|
const modifier = modifierType.newModifier(party[fromSlotIndex], party[spliceSlotIndex]);
|
||||||
const tmMoveId = isTmModifier
|
this.scene.ui.clearText();
|
||||||
? (modifierType as TmModifierType).moveId
|
this.scene.ui.setMode(Mode.MESSAGE);
|
||||||
: undefined;
|
this.scene.addModifier(modifier, false, true).then(() => super.end());
|
||||||
this.scene.ui.setModeWithoutClear(Mode.PARTY, partyUiMode, -1, (slotIndex: integer, option: PartyOption) => {
|
});
|
||||||
if (slotIndex < 6) {
|
} else
|
||||||
this.scene.ui.setMode(Mode.MODIFIER_SELECT, this.isPlayer()).then(() => {
|
this.scene.ui.setMode(Mode.MODIFIER_SELECT, this.isPlayer(), typeOptions, modifierSelectCallback);
|
||||||
const modifierType = typeOptions[cursor].type;
|
}, modifierType.selectFilter);
|
||||||
const modifier = !isMoveModifier
|
} else {
|
||||||
? modifierType.newModifier(party[slotIndex])
|
const pokemonModifierType = modifierType as PokemonModifierType;
|
||||||
: modifierType.newModifier(party[slotIndex], option - PartyOption.MOVE_1);
|
const isMoveModifier = modifierType instanceof PokemonMoveModifierType;
|
||||||
this.scene.ui.clearText();
|
const isTmModifier = modifierType instanceof TmModifierType;
|
||||||
this.scene.ui.setMode(Mode.MESSAGE);
|
const partyUiMode = isMoveModifier ? PartyUiMode.MOVE_MODIFIER
|
||||||
this.scene.addModifier(modifier, false, true).then(() => super.end());
|
: isTmModifier ? PartyUiMode.TM_MODIFIER : PartyUiMode.MODIFIER;
|
||||||
});
|
const tmMoveId = isTmModifier
|
||||||
} else
|
? (modifierType as TmModifierType).moveId
|
||||||
this.scene.ui.setMode(Mode.MODIFIER_SELECT, this.isPlayer(), typeOptions, modifierSelectCallback, );
|
: undefined;
|
||||||
}, pokemonModifierType.selectFilter, modifierType instanceof PokemonMoveModifierType ? (modifierType as PokemonMoveModifierType).moveSelectFilter : undefined, tmMoveId);
|
this.scene.ui.setModeWithoutClear(Mode.PARTY, partyUiMode, -1, (slotIndex: integer, option: PartyOption) => {
|
||||||
|
if (slotIndex < 6) {
|
||||||
|
this.scene.ui.setMode(Mode.MODIFIER_SELECT, this.isPlayer()).then(() => {
|
||||||
|
const modifierType = typeOptions[cursor].type;
|
||||||
|
const modifier = !isMoveModifier
|
||||||
|
? modifierType.newModifier(party[slotIndex])
|
||||||
|
: modifierType.newModifier(party[slotIndex], option - PartyOption.MOVE_1);
|
||||||
|
this.scene.ui.clearText();
|
||||||
|
this.scene.ui.setMode(Mode.MESSAGE);
|
||||||
|
this.scene.addModifier(modifier, false, true).then(() => super.end());
|
||||||
|
});
|
||||||
|
} else
|
||||||
|
this.scene.ui.setMode(Mode.MODIFIER_SELECT, this.isPlayer(), typeOptions, modifierSelectCallback, );
|
||||||
|
}, pokemonModifierType.selectFilter, modifierType instanceof PokemonMoveModifierType ? (modifierType as PokemonMoveModifierType).moveSelectFilter : undefined, tmMoveId);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
this.addModifier(typeOptions[cursor].type.newModifier()).then(() => super.end());
|
this.addModifier(typeOptions[cursor].type.newModifier()).then(() => super.end());
|
||||||
this.scene.ui.clearText();
|
this.scene.ui.clearText();
|
||||||
|
|
|
@ -5,7 +5,7 @@ import { EncounterPhase, SummonPhase, NextEncounterPhase, NewBiomeEncounterPhase
|
||||||
import Pokemon, { PlayerPokemon, EnemyPokemon } from './pokemon';
|
import Pokemon, { PlayerPokemon, EnemyPokemon } from './pokemon';
|
||||||
import PokemonSpecies, { PokemonSpeciesFilter, allSpecies, getPokemonSpecies, initSpecies } from './data/pokemon-species';
|
import PokemonSpecies, { PokemonSpeciesFilter, allSpecies, getPokemonSpecies, initSpecies } from './data/pokemon-species';
|
||||||
import * as Utils from './utils';
|
import * as Utils from './utils';
|
||||||
import { Modifier, ModifierBar, ConsumablePokemonModifier, ConsumableModifier, PokemonHpRestoreModifier, HealingBoosterModifier, PersistentModifier, PokemonHeldItemModifier, ModifierPredicate, DoubleBattleChanceBoosterModifier } from './modifier/modifier';
|
import { Modifier, ModifierBar, ConsumablePokemonModifier, ConsumableModifier, PokemonHpRestoreModifier, HealingBoosterModifier, PersistentModifier, PokemonHeldItemModifier, ModifierPredicate, DoubleBattleChanceBoosterModifier, FusePokemonModifier } from './modifier/modifier';
|
||||||
import { PokeballType } from './data/pokeball';
|
import { PokeballType } from './data/pokeball';
|
||||||
import { initAutoPlay } from './system/auto-play';
|
import { initAutoPlay } from './system/auto-play';
|
||||||
import { initCommonAnims, initMoveAnim, loadCommonAnimAssets, loadMoveAnimAssets, populateAnims } from './data/battle-anims';
|
import { initCommonAnims, initMoveAnim, loadCommonAnimAssets, loadMoveAnimAssets, populateAnims } from './data/battle-anims';
|
||||||
|
@ -352,7 +352,7 @@ export default class BattleScene extends Phaser.Scene {
|
||||||
|
|
||||||
update() {
|
update() {
|
||||||
this.checkInput();
|
this.checkInput();
|
||||||
this.ui.update();
|
this.ui?.update();
|
||||||
}
|
}
|
||||||
|
|
||||||
launchBattle() {
|
launchBattle() {
|
||||||
|
@ -1007,7 +1007,7 @@ export default class BattleScene extends Phaser.Scene {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
playSound(soundName: string, config?: object): AnySound {
|
playSound(sound: string | AnySound, config?: object): AnySound {
|
||||||
if (config) {
|
if (config) {
|
||||||
if (config.hasOwnProperty('volume'))
|
if (config.hasOwnProperty('volume'))
|
||||||
config['volume'] *= this.masterVolume * this.seVolume;
|
config['volume'] *= this.masterVolume * this.seVolume;
|
||||||
|
@ -1015,8 +1015,13 @@ export default class BattleScene extends Phaser.Scene {
|
||||||
config['volume'] = this.masterVolume * this.seVolume;
|
config['volume'] = this.masterVolume * this.seVolume;
|
||||||
} else
|
} else
|
||||||
config = { volume: this.masterVolume * this.seVolume };
|
config = { volume: this.masterVolume * this.seVolume };
|
||||||
this.sound.play(soundName, config);
|
if (typeof sound === 'string') {
|
||||||
return this.sound.get(soundName) as AnySound;
|
this.sound.play(sound, config);
|
||||||
|
return this.sound.get(sound) as AnySound;
|
||||||
|
} else {
|
||||||
|
sound.play(config);
|
||||||
|
return sound;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
playSoundWithoutBgm(soundName: string, pauseDuration?: integer): AnySound {
|
playSoundWithoutBgm(soundName: string, pauseDuration?: integer): AnySound {
|
||||||
|
@ -1149,7 +1154,8 @@ export default class BattleScene extends Phaser.Scene {
|
||||||
args.push(hpRestoreMultiplier.value);
|
args.push(hpRestoreMultiplier.value);
|
||||||
} else
|
} else
|
||||||
args.push(1);
|
args.push(1);
|
||||||
}
|
} else if (modifier instanceof FusePokemonModifier)
|
||||||
|
args.push(this.getPokemonById(modifier.fusePokemonId) as PlayerPokemon);
|
||||||
|
|
||||||
if (modifier.shouldApply(args))
|
if (modifier.shouldApply(args))
|
||||||
modifier.apply(args);
|
modifier.apply(args);
|
||||||
|
|
|
@ -242,7 +242,7 @@ class AnimTimedSoundEvent extends AnimTimedEvent {
|
||||||
}
|
}
|
||||||
return Math.ceil((scene.sound.get(this.resourceName).totalDuration * 1000) / 33.33);
|
return Math.ceil((scene.sound.get(this.resourceName).totalDuration * 1000) / 33.33);
|
||||||
} else
|
} else
|
||||||
return Math.ceil(battleAnim.user.cry(soundConfig) / 33.33);
|
return Math.ceil((battleAnim.user.cry(soundConfig).totalDuration * 1000) / 33.33);
|
||||||
}
|
}
|
||||||
|
|
||||||
getEventType(): string {
|
getEventType(): string {
|
||||||
|
|
|
@ -2023,6 +2023,7 @@ export class ForceSwitchOutAttr extends MoveEffectAttr {
|
||||||
} else {
|
} else {
|
||||||
switchOutTarget.hideInfo().then(() => switchOutTarget.destroy());
|
switchOutTarget.hideInfo().then(() => switchOutTarget.destroy());
|
||||||
switchOutTarget.hp = 0;
|
switchOutTarget.hp = 0;
|
||||||
|
switchOutTarget.trySetStatus(StatusEffect.FAINT);
|
||||||
|
|
||||||
user.scene.queueMessage(getPokemonMessage(switchOutTarget, ' fled!'), null, true, 500);
|
user.scene.queueMessage(getPokemonMessage(switchOutTarget, ' fled!'), null, true, 500);
|
||||||
|
|
||||||
|
|
|
@ -1,11 +1,21 @@
|
||||||
import { Moves } from "./move";
|
import { Moves } from "./move";
|
||||||
import { Species } from "./species";
|
import { Species } from "./species";
|
||||||
|
|
||||||
interface PokemonLevelMoves {
|
export type LevelMoves = (integer | Moves)[][];
|
||||||
[key: string]: Array<Array<integer | Moves>>
|
|
||||||
|
interface PokemonSpeciesLevelMoves {
|
||||||
|
[key: string]: LevelMoves
|
||||||
}
|
}
|
||||||
|
|
||||||
export const pokemonLevelMoves: PokemonLevelMoves = {
|
interface PokemonFormLevelMoves {
|
||||||
|
[key: integer]: LevelMoves
|
||||||
|
}
|
||||||
|
|
||||||
|
interface PokemonSpeciesFormLevelMoves {
|
||||||
|
[key: string]: PokemonFormLevelMoves
|
||||||
|
}
|
||||||
|
|
||||||
|
export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = {
|
||||||
[Species.BULBASAUR]: [
|
[Species.BULBASAUR]: [
|
||||||
[ 1, Moves.TACKLE ],
|
[ 1, Moves.TACKLE ],
|
||||||
[ 3, Moves.GROWL ],
|
[ 3, Moves.GROWL ],
|
||||||
|
@ -10965,4 +10975,43 @@ export const pokemonLevelMoves: PokemonLevelMoves = {
|
||||||
[ 80, Moves.HYPER_BEAM ],
|
[ 80, Moves.HYPER_BEAM ],
|
||||||
[ 88, Moves.OUTRAGE ]
|
[ 88, Moves.OUTRAGE ]
|
||||||
]
|
]
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const pokemonFormLevelMoves: PokemonSpeciesFormLevelMoves = {
|
||||||
|
[Species.KYUREM]: {
|
||||||
|
1: [
|
||||||
|
[ 1, Moves.DRAGON_RAGE ],
|
||||||
|
[ 1, Moves.ICY_WIND ],
|
||||||
|
[ 8, Moves.IMPRISON ],
|
||||||
|
[ 15, Moves.ANCIENT_POWER ],
|
||||||
|
[ 22, Moves.ICE_BEAM ],
|
||||||
|
[ 29, Moves.DRAGON_BREATH ],
|
||||||
|
[ 36, Moves.SLASH ],
|
||||||
|
[ 43, Moves.SCARY_FACE ],
|
||||||
|
[ 50, Moves.ICE_BURN ],
|
||||||
|
[ 57, Moves.DRAGON_PULSE ],
|
||||||
|
[ 64, Moves.IMPRISON ],
|
||||||
|
[ 71, Moves.ENDEAVOR ],
|
||||||
|
[ 78, Moves.BLIZZARD ],
|
||||||
|
[ 85, Moves.OUTRAGE ],
|
||||||
|
[ 92, Moves.HYPER_VOICE ]
|
||||||
|
],
|
||||||
|
2: [
|
||||||
|
[ 1, Moves.DRAGON_RAGE ],
|
||||||
|
[ 1, Moves.ICY_WIND ],
|
||||||
|
[ 8, Moves.IMPRISON ],
|
||||||
|
[ 15, Moves.ANCIENT_POWER ],
|
||||||
|
[ 22, Moves.ICE_BEAM ],
|
||||||
|
[ 29, Moves.DRAGON_BREATH ],
|
||||||
|
[ 36, Moves.SLASH ],
|
||||||
|
[ 43, Moves.SCARY_FACE ],
|
||||||
|
[ 50, Moves.FREEZE_SHOCK ],
|
||||||
|
[ 57, Moves.DRAGON_PULSE ],
|
||||||
|
[ 64, Moves.IMPRISON ],
|
||||||
|
[ 71, Moves.ENDEAVOR ],
|
||||||
|
[ 78, Moves.BLIZZARD ],
|
||||||
|
[ 85, Moves.OUTRAGE ],
|
||||||
|
[ 92, Moves.HYPER_VOICE ]
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,11 +1,12 @@
|
||||||
import { Abilities } from './ability';
|
import { Abilities } from './ability';
|
||||||
import BattleScene from '../battle-scene';
|
import BattleScene, { AnySound } from '../battle-scene';
|
||||||
import { GrowthRate } from './exp';
|
import { GrowthRate } from './exp';
|
||||||
import { SpeciesWildEvolutionDelay, pokemonEvolutions, pokemonPrevolutions } from './pokemon-evolutions';
|
import { SpeciesWildEvolutionDelay, pokemonEvolutions, pokemonPrevolutions } from './pokemon-evolutions';
|
||||||
import { Species } from './species';
|
import { Species } from './species';
|
||||||
import { Type } from './type';
|
import { Type } from './type';
|
||||||
import * as Utils from '../utils';
|
import * as Utils from '../utils';
|
||||||
import { TrainerType, trainerConfigs } from './trainer-type';
|
import { TrainerType, trainerConfigs } from './trainer-type';
|
||||||
|
import { LevelMoves, pokemonFormLevelMoves as pokemonSpeciesFormLevelMoves, pokemonSpeciesLevelMoves } from './pokemon-level-moves';
|
||||||
|
|
||||||
export function getPokemonSpecies(species: Species): PokemonSpecies {
|
export function getPokemonSpecies(species: Species): PokemonSpecies {
|
||||||
if (species >= Species.XERNEAS)
|
if (species >= Species.XERNEAS)
|
||||||
|
@ -74,6 +75,12 @@ export abstract class PokemonSpeciesForm {
|
||||||
return !abilityIndex ? this.ability1 : abilityIndex === 1 && this.ability2 ? this.ability2 : this.abilityHidden
|
return !abilityIndex ? this.ability1 : abilityIndex === 1 && this.ability2 ? this.ability2 : this.abilityHidden
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getLevelMoves(): LevelMoves {
|
||||||
|
if (pokemonSpeciesFormLevelMoves.hasOwnProperty(this.speciesId) && pokemonSpeciesFormLevelMoves[this.speciesId].hasOwnProperty(this.formIndex))
|
||||||
|
return pokemonSpeciesFormLevelMoves[this.speciesId][this.formIndex];
|
||||||
|
return pokemonSpeciesLevelMoves[this.speciesId];
|
||||||
|
}
|
||||||
|
|
||||||
isObtainable() {
|
isObtainable() {
|
||||||
return this.generation <= 5 && this.getFormSpriteKey(this.formIndex) !== 'mega';
|
return this.generation <= 5 && this.getFormSpriteKey(this.formIndex) !== 'mega';
|
||||||
}
|
}
|
||||||
|
@ -147,15 +154,21 @@ export abstract class PokemonSpeciesForm {
|
||||||
const forms = getPokemonSpecies(this.speciesId).forms;
|
const forms = getPokemonSpecies(this.speciesId).forms;
|
||||||
if (forms.length) {
|
if (forms.length) {
|
||||||
const formKey = forms[formIndex || 0].formKey;
|
const formKey = forms[formIndex || 0].formKey;
|
||||||
if (formKey === 'mega' || formKey === 'eternamax')
|
switch (formKey) {
|
||||||
ret += `-${formKey}`;
|
case 'mega':
|
||||||
|
case 'white':
|
||||||
|
case 'black':
|
||||||
|
case 'eternamax':
|
||||||
|
ret += `-${formKey}`;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
loadAssets(scene: BattleScene, female: boolean, formIndex?: integer, shiny?: boolean, startLoad?: boolean): Promise<void> {
|
loadAssets(scene: BattleScene, female: boolean, formIndex?: integer, shiny?: boolean, startLoad?: boolean): Promise<void> {
|
||||||
return new Promise(resolve => {
|
return new Promise(resolve => {
|
||||||
scene.load.audio(this.speciesId.toString(), `audio/cry/${this.getCryKey(formIndex)}.mp3`);
|
scene.load.audio(this.getCryKey(formIndex), `audio/cry/${this.getCryKey(formIndex)}.mp3`);
|
||||||
scene.loadAtlas(this.getSpriteKey(female, formIndex, shiny), 'pokemon', this.getSpriteAtlasPath(female, formIndex, shiny));
|
scene.loadAtlas(this.getSpriteKey(female, formIndex, shiny), 'pokemon', this.getSpriteAtlasPath(female, formIndex, shiny));
|
||||||
scene.load.once(Phaser.Loader.Events.COMPLETE, () => {
|
scene.load.once(Phaser.Loader.Events.COMPLETE, () => {
|
||||||
const originalWarn = console.warn;
|
const originalWarn = console.warn;
|
||||||
|
@ -192,9 +205,13 @@ export abstract class PokemonSpeciesForm {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
cry(scene: BattleScene, soundConfig?: Phaser.Types.Sound.SoundConfig): integer {
|
cry(scene: BattleScene, soundConfig?: Phaser.Types.Sound.SoundConfig, ignorePlay?: boolean): AnySound {
|
||||||
scene.playSound(this.speciesId.toString(), soundConfig);
|
const cryKey = this.getCryKey(this.formIndex);
|
||||||
return scene.sound.get(this.speciesId.toString()).totalDuration * 1000;
|
let cry = scene.sound.get(cryKey) as AnySound;
|
||||||
|
cry = scene.playSound(cry || cryKey, soundConfig);
|
||||||
|
if (ignorePlay)
|
||||||
|
cry.stop();
|
||||||
|
return cry;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1132,8 +1149,8 @@ export function initSpecies() {
|
||||||
),
|
),
|
||||||
new PokemonSpecies(Species.KYUREM, "Kyurem", 5, false, true, false, "Boundary Pokémon", Type.DRAGON, Type.ICE, 3, 325, Abilities.PRESSURE, Abilities.NONE, Abilities.NONE, 660, 125, 130, 90, 130, 90, 95, 3, 0, 297, GrowthRate.SLOW, "Undiscovered", null, null, 120, false, true,
|
new PokemonSpecies(Species.KYUREM, "Kyurem", 5, false, true, false, "Boundary Pokémon", Type.DRAGON, Type.ICE, 3, 325, Abilities.PRESSURE, Abilities.NONE, Abilities.NONE, 660, 125, 130, 90, 130, 90, 95, 3, 0, 297, GrowthRate.SLOW, "Undiscovered", null, null, 120, false, true,
|
||||||
new PokemonForm("Normal", "", Type.DRAGON, Type.ICE, 3, 325, Abilities.PRESSURE, Abilities.NONE, Abilities.NONE, 660, 125, 130, 90, 130, 90, 95, 3, 0, 297, GrowthRate.SLOW, "Undiscovered", null, null, 120, false),
|
new PokemonForm("Normal", "", Type.DRAGON, Type.ICE, 3, 325, Abilities.PRESSURE, Abilities.NONE, Abilities.NONE, 660, 125, 130, 90, 130, 90, 95, 3, 0, 297, GrowthRate.SLOW, "Undiscovered", null, null, 120, false),
|
||||||
new PokemonForm("Black", "black", Type.DRAGON, Type.ICE, 3.3, 325, Abilities.TERAVOLT, Abilities.NONE, Abilities.NONE, 700, 125, 170, 100, 120, 90, 95, 3, 0, 315, GrowthRate.SLOW, "Undiscovered", null, null, 120, false),
|
new PokemonForm("White", "white", Type.DRAGON, Type.ICE, 3.6, 325, Abilities.TURBOBLAZE, Abilities.NONE, Abilities.NONE, 700, 125, 120, 90, 170, 100, 95, 3, 0, 315, GrowthRate.SLOW, "Undiscovered", null, null, 120, false),
|
||||||
new PokemonForm("White", "white", Type.DRAGON, Type.ICE, 3.6, 325, Abilities.TURBOBLAZE, Abilities.NONE, Abilities.NONE, 700, 125, 120, 90, 170, 100, 95, 3, 0, 315, GrowthRate.SLOW, "Undiscovered", null, null, 120, false)
|
new PokemonForm("Black", "black", Type.DRAGON, Type.ICE, 3.3, 325, Abilities.TERAVOLT, Abilities.NONE, Abilities.NONE, 700, 125, 170, 100, 120, 90, 95, 3, 0, 315, GrowthRate.SLOW, "Undiscovered", null, null, 120, false)
|
||||||
),
|
),
|
||||||
new PokemonSpecies(Species.KELDEO, "Keldeo", 5, false, false, true, "Colt Pokémon", Type.WATER, Type.FIGHTING, 1.4, 48.5, Abilities.JUSTIFIED, Abilities.NONE, Abilities.NONE, 580, 91, 72, 90, 129, 90, 108, 3, 35, 261, GrowthRate.SLOW, "Undiscovered", null, null, 80, false, true,
|
new PokemonSpecies(Species.KELDEO, "Keldeo", 5, false, false, true, "Colt Pokémon", Type.WATER, Type.FIGHTING, 1.4, 48.5, Abilities.JUSTIFIED, Abilities.NONE, Abilities.NONE, 580, 91, 72, 90, 129, 90, 108, 3, 35, 261, GrowthRate.SLOW, "Undiscovered", null, null, 80, false, true,
|
||||||
new PokemonForm("Ordinary Forme", "ordinary", Type.WATER, Type.FIGHTING, 1.4, 48.5, Abilities.JUSTIFIED, Abilities.NONE, Abilities.NONE, 580, 91, 72, 90, 129, 90, 108, 3, 35, 261, GrowthRate.SLOW, "Undiscovered", null, null, 80, false),
|
new PokemonForm("Ordinary Forme", "ordinary", Type.WATER, Type.FIGHTING, 1.4, 48.5, Abilities.JUSTIFIED, Abilities.NONE, Abilities.NONE, 580, 91, 72, 90, 129, 90, 108, 3, 35, 261, GrowthRate.SLOW, "Undiscovered", null, null, 80, false),
|
||||||
|
|
|
@ -4,7 +4,6 @@ import { EnemyPokemon } from "../pokemon";
|
||||||
import * as Utils from "../utils";
|
import * as Utils from "../utils";
|
||||||
import { Moves } from "./move";
|
import { Moves } from "./move";
|
||||||
import { pokemonEvolutions, pokemonPrevolutions } from "./pokemon-evolutions";
|
import { pokemonEvolutions, pokemonPrevolutions } from "./pokemon-evolutions";
|
||||||
import { pokemonLevelMoves } from "./pokemon-level-moves";
|
|
||||||
import PokemonSpecies, { PokemonSpeciesFilter, getPokemonSpecies } from "./pokemon-species";
|
import PokemonSpecies, { PokemonSpeciesFilter, getPokemonSpecies } from "./pokemon-species";
|
||||||
import { Species } from "./species";
|
import { Species } from "./species";
|
||||||
import { tmSpecies } from "./tms";
|
import { tmSpecies } from "./tms";
|
||||||
|
@ -552,7 +551,7 @@ export const trainerConfigs: TrainerConfigs = {
|
||||||
[TrainerType.BREEDER]: new TrainerConfig(++t).setEncounterBgm(TrainerType.POKEFAN).setHasGenders().setDouble()
|
[TrainerType.BREEDER]: new TrainerConfig(++t).setEncounterBgm(TrainerType.POKEFAN).setHasGenders().setDouble()
|
||||||
.setPartyTemplateFunc(scene => getWavePartyTemplate(scene, trainerPartyTemplates.FOUR_WEAKER, trainerPartyTemplates.FIVE_WEAKER, trainerPartyTemplates.SIX_WEAKER)),
|
.setPartyTemplateFunc(scene => getWavePartyTemplate(scene, trainerPartyTemplates.FOUR_WEAKER, trainerPartyTemplates.FIVE_WEAKER, trainerPartyTemplates.SIX_WEAKER)),
|
||||||
[TrainerType.CLERK]: new TrainerConfig(++t).setHasGenders().setEncounterBgm(TrainerType.CLERK),
|
[TrainerType.CLERK]: new TrainerConfig(++t).setHasGenders().setEncounterBgm(TrainerType.CLERK),
|
||||||
[TrainerType.CYCLIST]: new TrainerConfig(++t).setHasGenders().setEncounterBgm(TrainerType.CYCLIST).setSpeciesFilter(s => !!pokemonLevelMoves[s.speciesId].find(plm => plm[1] === Moves.QUICK_ATTACK)),
|
[TrainerType.CYCLIST]: new TrainerConfig(++t).setHasGenders().setEncounterBgm(TrainerType.CYCLIST).setSpeciesFilter(s => !!s.getLevelMoves().find(plm => plm[1] === Moves.QUICK_ATTACK)),
|
||||||
[TrainerType.DANCER]: new TrainerConfig(++t).setEncounterBgm(TrainerType.CYCLIST),
|
[TrainerType.DANCER]: new TrainerConfig(++t).setEncounterBgm(TrainerType.CYCLIST),
|
||||||
[TrainerType.DEPOT_AGENT]: new TrainerConfig(++t).setEncounterBgm(TrainerType.CLERK),
|
[TrainerType.DEPOT_AGENT]: new TrainerConfig(++t).setEncounterBgm(TrainerType.CLERK),
|
||||||
[TrainerType.DOCTOR]: new TrainerConfig(++t).setEncounterBgm(TrainerType.CLERK),
|
[TrainerType.DOCTOR]: new TrainerConfig(++t).setEncounterBgm(TrainerType.CLERK),
|
||||||
|
@ -575,8 +574,8 @@ export const trainerConfigs: TrainerConfigs = {
|
||||||
[TrainerType.JANITOR]: new TrainerConfig(++t).setEncounterBgm(TrainerType.CLERK),
|
[TrainerType.JANITOR]: new TrainerConfig(++t).setEncounterBgm(TrainerType.CLERK),
|
||||||
[TrainerType.LINEBACKER]: new TrainerConfig(++t).setEncounterBgm(TrainerType.CYCLIST),
|
[TrainerType.LINEBACKER]: new TrainerConfig(++t).setEncounterBgm(TrainerType.CYCLIST),
|
||||||
[TrainerType.MAID]: new TrainerConfig(++t).setEncounterBgm(TrainerType.RICH).setSpeciesFilter(s => s.eggType1 === 'Field' || s.eggType2 === 'Field'),
|
[TrainerType.MAID]: new TrainerConfig(++t).setEncounterBgm(TrainerType.RICH).setSpeciesFilter(s => s.eggType1 === 'Field' || s.eggType2 === 'Field'),
|
||||||
[TrainerType.MUSICIAN]: new TrainerConfig(++t).setEncounterBgm(TrainerType.ROUGHNECK).setSpeciesFilter(s => !!pokemonLevelMoves[s.speciesId].find(plm => plm[1] === Moves.SING)),
|
[TrainerType.MUSICIAN]: new TrainerConfig(++t).setEncounterBgm(TrainerType.ROUGHNECK).setSpeciesFilter(s => !!s.getLevelMoves().find(plm => plm[1] === Moves.SING)),
|
||||||
[TrainerType.NURSE]: new TrainerConfig(++t).setEncounterBgm('lass').setSpeciesFilter(s => !!pokemonLevelMoves[s.speciesId].find(plm => plm[1] === Moves.CHARM) || !!pokemonLevelMoves[s.speciesId].find(plm => plm[1] === Moves.HEAL_PULSE)),
|
[TrainerType.NURSE]: new TrainerConfig(++t).setEncounterBgm('lass').setSpeciesFilter(s => !!s.getLevelMoves().find(plm => plm[1] === Moves.CHARM) || !!s.getLevelMoves().find(plm => plm[1] === Moves.HEAL_PULSE)),
|
||||||
[TrainerType.NURSERY_AIDE]: new TrainerConfig(++t).setEncounterBgm('lass'),
|
[TrainerType.NURSERY_AIDE]: new TrainerConfig(++t).setEncounterBgm('lass'),
|
||||||
[TrainerType.OFFICER]: new TrainerConfig(++t).setEncounterBgm(TrainerType.CLERK).setSpeciesPools([ Species.VULPIX, Species.GROWLITHE, Species.SNUBBULL, Species.HOUNDOUR, Species.POOCHYENA, Species.ELECTRIKE, Species.LILLIPUP ]),
|
[TrainerType.OFFICER]: new TrainerConfig(++t).setEncounterBgm(TrainerType.CLERK).setSpeciesPools([ Species.VULPIX, Species.GROWLITHE, Species.SNUBBULL, Species.HOUNDOUR, Species.POOCHYENA, Species.ELECTRIKE, Species.LILLIPUP ]),
|
||||||
[TrainerType.PARASOL_LADY]: new TrainerConfig(++t).setEncounterBgm(TrainerType.PARASOL_LADY).setSpeciesFilter(s => s.isOfType(Type.WATER)),
|
[TrainerType.PARASOL_LADY]: new TrainerConfig(++t).setEncounterBgm(TrainerType.PARASOL_LADY).setSpeciesFilter(s => s.isOfType(Type.WATER)),
|
||||||
|
|
|
@ -440,6 +440,28 @@ export class EvolutionItemModifierType extends PokemonModifierType implements Ge
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export class FusePokemonModifierType extends PokemonModifierType {
|
||||||
|
constructor(name: string, iconImage?: string) {
|
||||||
|
super(name, 'Combines two Pokémon, giving the first Pokémon the ability of the second', (_type, args) => new Modifiers.FusePokemonModifier(this, (args[0] as PlayerPokemon).id, (args[1] as PlayerPokemon).id),
|
||||||
|
(pokemon: PlayerPokemon) => {
|
||||||
|
if (pokemon.isFusion())
|
||||||
|
return PartyUiHandler.NoEffectMessage;
|
||||||
|
return null;
|
||||||
|
}, iconImage);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class UnfusePokemonModifierType extends PokemonModifierType {
|
||||||
|
constructor(name: string, iconImage?: string) {
|
||||||
|
super(name, 'Removes the fusion aspects of a spliced Pokémon, but the second Pokémon is lost', (_type, args) => new Modifiers.UnfusePokemonModifier(this, (args[0] as PlayerPokemon).id),
|
||||||
|
(pokemon: PlayerPokemon) => {
|
||||||
|
if (!pokemon.isFusion())
|
||||||
|
return PartyUiHandler.NoEffectMessage;
|
||||||
|
return null;
|
||||||
|
}, iconImage);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
class AttackTypeBoosterModifierTypeGenerator extends ModifierTypeGenerator {
|
class AttackTypeBoosterModifierTypeGenerator extends ModifierTypeGenerator {
|
||||||
constructor() {
|
constructor() {
|
||||||
super((party: Pokemon[], pregenArgs?: any[]) => {
|
super((party: Pokemon[], pregenArgs?: any[]) => {
|
||||||
|
@ -671,6 +693,9 @@ export const modifierTypes = {
|
||||||
SHINY_CHARM: () => new ModifierType('Shiny Charm', 'Dramatically increases the chance of a wild Pokémon being shiny', (type, _args) => new Modifiers.ShinyRateBoosterModifier(type)),
|
SHINY_CHARM: () => new ModifierType('Shiny Charm', 'Dramatically increases the chance of a wild Pokémon being shiny', (type, _args) => new Modifiers.ShinyRateBoosterModifier(type)),
|
||||||
ABILITY_CHARM: () => new ModifierType('Ability Charm', 'Dramatically increases the chance of a wild Pokémon having a hidden ability', (type, _args) => new Modifiers.HiddenAbilityRateBoosterModifier(type)),
|
ABILITY_CHARM: () => new ModifierType('Ability Charm', 'Dramatically increases the chance of a wild Pokémon having a hidden ability', (type, _args) => new Modifiers.HiddenAbilityRateBoosterModifier(type)),
|
||||||
|
|
||||||
|
DNA_SPLICERS: () => new FusePokemonModifierType('DNA Splicers'),
|
||||||
|
REVERSE_DNA_SPLICERS: () => new UnfusePokemonModifierType('Reverse DNA Splicers', 'dna_splicers'),
|
||||||
|
|
||||||
MINI_BLACK_HOLE: () => new TurnHeldItemTransferModifierType('Mini Black Hole'),
|
MINI_BLACK_HOLE: () => new TurnHeldItemTransferModifierType('Mini Black Hole'),
|
||||||
|
|
||||||
GOLDEN_POKEBALL: () => new ModifierType(`Golden ${getPokeballName(PokeballType.POKEBALL)}`, 'Adds 1 extra item option at the end of every battle',
|
GOLDEN_POKEBALL: () => new ModifierType(`Golden ${getPokeballName(PokeballType.POKEBALL)}`, 'Adds 1 extra item option at the end of every battle',
|
||||||
|
@ -713,7 +738,7 @@ const modifierPool = {
|
||||||
new WeightedModifierType(modifierTypes.LURE, 2),
|
new WeightedModifierType(modifierTypes.LURE, 2),
|
||||||
new WeightedModifierType(modifierTypes.TEMP_STAT_BOOSTER, 4),
|
new WeightedModifierType(modifierTypes.TEMP_STAT_BOOSTER, 4),
|
||||||
new WeightedModifierType(modifierTypes.BERRY, 2),
|
new WeightedModifierType(modifierTypes.BERRY, 2),
|
||||||
new WeightedModifierType(modifierTypes.TM_COMMON, 1)
|
new WeightedModifierType(modifierTypes.TM_COMMON, 1),
|
||||||
].map(m => { m.setTier(ModifierTier.COMMON); return m; }),
|
].map(m => { m.setTier(ModifierTier.COMMON); return m; }),
|
||||||
[ModifierTier.GREAT]: [
|
[ModifierTier.GREAT]: [
|
||||||
new WeightedModifierType(modifierTypes.GREAT_BALL, 6),
|
new WeightedModifierType(modifierTypes.GREAT_BALL, 6),
|
||||||
|
@ -774,11 +799,13 @@ const modifierPool = {
|
||||||
new WeightedModifierType(modifierTypes.OVAL_CHARM, 2),
|
new WeightedModifierType(modifierTypes.OVAL_CHARM, 2),
|
||||||
new WeightedModifierType(modifierTypes.ABILITY_CHARM, 2),
|
new WeightedModifierType(modifierTypes.ABILITY_CHARM, 2),
|
||||||
new WeightedModifierType(modifierTypes.EXP_BALANCE, 1),
|
new WeightedModifierType(modifierTypes.EXP_BALANCE, 1),
|
||||||
|
new WeightedModifierType(modifierTypes.REVERSE_DNA_SPLICERS, (party: Pokemon[]) => party.filter(p => p.fusionSpecies).length > 1 ? 3 : 0),
|
||||||
].map(m => { m.setTier(ModifierTier.ULTRA); return m; }),
|
].map(m => { m.setTier(ModifierTier.ULTRA); return m; }),
|
||||||
[ModifierTier.MASTER]: [
|
[ModifierTier.MASTER]: [
|
||||||
new WeightedModifierType(modifierTypes.MASTER_BALL, 3),
|
new WeightedModifierType(modifierTypes.MASTER_BALL, 3),
|
||||||
new WeightedModifierType(modifierTypes.SHINY_CHARM, 2),
|
new WeightedModifierType(modifierTypes.SHINY_CHARM, 2),
|
||||||
new WeightedModifierType(modifierTypes.MINI_BLACK_HOLE, (party: Pokemon[]) => party[0].scene.gameData.unlocks[Unlockables.MINI_BLACK_HOLE] ? 1 : 0)
|
new WeightedModifierType(modifierTypes.DNA_SPLICERS, (party: Pokemon[]) => party.filter(p => !p.fusionSpecies).length > 1 ? 1 : 0),
|
||||||
|
new WeightedModifierType(modifierTypes.MINI_BLACK_HOLE, (party: Pokemon[]) => party[0].scene.gameData.unlocks[Unlockables.MINI_BLACK_HOLE] ? 1 : 0),
|
||||||
].map(m => { m.setTier(ModifierTier.MASTER); return m; }),
|
].map(m => { m.setTier(ModifierTier.MASTER); return m; }),
|
||||||
[ModifierTier.LUXURY]: [
|
[ModifierTier.LUXURY]: [
|
||||||
new WeightedModifierType(modifierTypes.GOLDEN_EXP_CHARM, 1),
|
new WeightedModifierType(modifierTypes.GOLDEN_EXP_CHARM, 1),
|
||||||
|
|
|
@ -908,6 +908,38 @@ export class EvolutionItemModifier extends ConsumablePokemonModifier {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export class FusePokemonModifier extends ConsumablePokemonModifier {
|
||||||
|
public fusePokemonId: integer;
|
||||||
|
|
||||||
|
constructor(type: ModifierType, pokemonId: integer, fusePokemonId: integer) {
|
||||||
|
super(type, pokemonId);
|
||||||
|
|
||||||
|
this.fusePokemonId = fusePokemonId;
|
||||||
|
}
|
||||||
|
|
||||||
|
shouldApply(args: any[]): boolean {
|
||||||
|
return super.shouldApply(args) && args[1] instanceof PlayerPokemon && this.fusePokemonId === (args[1] as PlayerPokemon).id;
|
||||||
|
}
|
||||||
|
|
||||||
|
apply(args: any[]): boolean {
|
||||||
|
(args[0] as PlayerPokemon).fuse(args[1] as PlayerPokemon);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class UnfusePokemonModifier extends ConsumablePokemonModifier {
|
||||||
|
constructor(type: ModifierType, pokemonId: integer) {
|
||||||
|
super(type, pokemonId);
|
||||||
|
}
|
||||||
|
|
||||||
|
apply(args: any[]): boolean {
|
||||||
|
(args[0] as PlayerPokemon).unfuse();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export class MultipleParticipantExpBonusModifier extends PersistentModifier {
|
export class MultipleParticipantExpBonusModifier extends PersistentModifier {
|
||||||
constructor(type: ModifierType, stackCount?: integer) {
|
constructor(type: ModifierType, stackCount?: integer) {
|
||||||
super(type, stackCount);
|
super(type, stackCount);
|
||||||
|
|
209
src/pokemon.ts
209
src/pokemon.ts
|
@ -1,8 +1,7 @@
|
||||||
import Phaser from 'phaser';
|
import Phaser from 'phaser';
|
||||||
import BattleScene, { AnySound } from './battle-scene';
|
import BattleScene, { AnySound } from './battle-scene';
|
||||||
import BattleInfo, { PlayerBattleInfo, EnemyBattleInfo } from './ui/battle-info';
|
import BattleInfo, { PlayerBattleInfo, EnemyBattleInfo } from './ui/battle-info';
|
||||||
import Move, { StatChangeAttr, HighCritAttr, HitsTagAttr, applyMoveAttrs, FixedDamageAttr, VariablePowerAttr, Moves, allMoves, MoveCategory, TypelessAttr, CritOnlyAttr, getMoveTargets, AttackMove, AddBattlerTagAttr } from "./data/move";
|
import Move, { HighCritAttr, HitsTagAttr, applyMoveAttrs, FixedDamageAttr, VariablePowerAttr, Moves, allMoves, MoveCategory, TypelessAttr, CritOnlyAttr, getMoveTargets, AttackMove, AddBattlerTagAttr } from "./data/move";
|
||||||
import { pokemonLevelMoves } from './data/pokemon-level-moves';
|
|
||||||
import { default as PokemonSpecies, PokemonSpeciesForm, getPokemonSpecies } from './data/pokemon-species';
|
import { default as PokemonSpecies, PokemonSpeciesForm, getPokemonSpecies } from './data/pokemon-species';
|
||||||
import * as Utils from './utils';
|
import * as Utils from './utils';
|
||||||
import { Type, TypeDamageMultiplier, getTypeDamageMultiplier } from './data/type';
|
import { Type, TypeDamageMultiplier, getTypeDamageMultiplier } from './data/type';
|
||||||
|
@ -28,6 +27,7 @@ import PokemonData from './system/pokemon-data';
|
||||||
import { BattlerIndex } from './battle';
|
import { BattlerIndex } from './battle';
|
||||||
import { Mode } from './ui/ui';
|
import { Mode } from './ui/ui';
|
||||||
import PartyUiHandler, { PartyOption, PartyUiMode } from './ui/party-ui-handler';
|
import PartyUiHandler, { PartyOption, PartyUiMode } from './ui/party-ui-handler';
|
||||||
|
import SoundFade from 'phaser3-rex-plugins/plugins/soundfade';
|
||||||
|
|
||||||
export enum FieldPosition {
|
export enum FieldPosition {
|
||||||
CENTER,
|
CENTER,
|
||||||
|
@ -59,6 +59,12 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
||||||
public winCount: integer;
|
public winCount: integer;
|
||||||
public pokerus: boolean;
|
public pokerus: boolean;
|
||||||
|
|
||||||
|
public fusionSpecies: PokemonSpecies;
|
||||||
|
public fusionFormIndex: integer;
|
||||||
|
public fusionAbilityIndex: integer;
|
||||||
|
public fusionShiny: boolean;
|
||||||
|
public fusionGender: Gender;
|
||||||
|
|
||||||
public summonData: PokemonSummonData;
|
public summonData: PokemonSummonData;
|
||||||
public battleSummonData: PokemonBattleSummonData;
|
public battleSummonData: PokemonBattleSummonData;
|
||||||
public turnData: PokemonTurnData;
|
public turnData: PokemonTurnData;
|
||||||
|
@ -107,6 +113,11 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
||||||
this.status = dataSource.status;
|
this.status = dataSource.status;
|
||||||
this.winCount = dataSource.winCount;
|
this.winCount = dataSource.winCount;
|
||||||
this.pokerus = !!dataSource.pokerus;
|
this.pokerus = !!dataSource.pokerus;
|
||||||
|
this.fusionSpecies = dataSource.fusionSpecies instanceof PokemonSpecies ? dataSource.fusionSpecies : getPokemonSpecies(dataSource.fusionSpecies);
|
||||||
|
this.fusionFormIndex = dataSource.fusionFormIndex;
|
||||||
|
this.fusionAbilityIndex = dataSource.fusionAbilityIndex;
|
||||||
|
this.fusionShiny = dataSource.fusionShiny;
|
||||||
|
this.fusionGender = dataSource.fusionGender;
|
||||||
} else {
|
} else {
|
||||||
this.generateAndPopulateMoveset();
|
this.generateAndPopulateMoveset();
|
||||||
|
|
||||||
|
@ -216,6 +227,8 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
||||||
.then(() => {
|
.then(() => {
|
||||||
loadMoveAnimAssets(this.scene, moveIds);
|
loadMoveAnimAssets(this.scene, moveIds);
|
||||||
this.getSpeciesForm().loadAssets(this.scene, this.getGender() === Gender.FEMALE, this.formIndex, this.shiny);
|
this.getSpeciesForm().loadAssets(this.scene, this.getGender() === Gender.FEMALE, this.formIndex, this.shiny);
|
||||||
|
if (this.fusionSpecies)
|
||||||
|
this.getFusionSpeciesForm().loadAssets(this.scene, this.getGender() === Gender.FEMALE, this.fusionFormIndex, this.shiny);
|
||||||
if (this.isPlayer())
|
if (this.isPlayer())
|
||||||
this.scene.loadAtlas(this.getBattleSpriteKey(), 'pokemon', this.getBattleSpriteAtlasPath());
|
this.scene.loadAtlas(this.getBattleSpriteKey(), 'pokemon', this.getBattleSpriteAtlasPath());
|
||||||
this.scene.load.once(Phaser.Loader.Events.COMPLETE, () => {
|
this.scene.load.once(Phaser.Loader.Events.COMPLETE, () => {
|
||||||
|
@ -287,6 +300,12 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
||||||
return this.species.forms[this.formIndex];
|
return this.species.forms[this.formIndex];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getFusionSpeciesForm(): PokemonSpeciesForm {
|
||||||
|
if (!this.fusionSpecies.forms?.length || this.fusionFormIndex >= this.fusionSpecies.forms.length)
|
||||||
|
return this.fusionSpecies;
|
||||||
|
return this.fusionSpecies.forms[this.fusionFormIndex];
|
||||||
|
}
|
||||||
|
|
||||||
getSprite(): Phaser.GameObjects.Sprite {
|
getSprite(): Phaser.GameObjects.Sprite {
|
||||||
return this.getAt(0) as Phaser.GameObjects.Sprite;
|
return this.getAt(0) as Phaser.GameObjects.Sprite;
|
||||||
}
|
}
|
||||||
|
@ -373,6 +392,11 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
||||||
if (!this.stats)
|
if (!this.stats)
|
||||||
this.stats = [ 0, 0, 0, 0, 0, 0 ];
|
this.stats = [ 0, 0, 0, 0, 0, 0 ];
|
||||||
const baseStats = this.getSpeciesForm().baseStats.slice(0);
|
const baseStats = this.getSpeciesForm().baseStats.slice(0);
|
||||||
|
if (this.fusionSpecies) {
|
||||||
|
const fusionBaseStats = this.getFusionSpeciesForm().baseStats;
|
||||||
|
for (let s = 0; s < this.stats.length; s++)
|
||||||
|
baseStats[s] = Math.ceil((baseStats[s] + fusionBaseStats[s]) / 2);
|
||||||
|
}
|
||||||
this.scene.applyModifiers(PokemonBaseStatModifier, this.isPlayer(), this, baseStats);
|
this.scene.applyModifiers(PokemonBaseStatModifier, this.isPlayer(), this, baseStats);
|
||||||
const stats = Utils.getEnumValues(Stat);
|
const stats = Utils.getEnumValues(Stat);
|
||||||
for (let s of stats) {
|
for (let s of stats) {
|
||||||
|
@ -452,6 +476,8 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
||||||
getAbility(): Ability {
|
getAbility(): Ability {
|
||||||
if (ABILITY_OVERRIDE && this.isPlayer())
|
if (ABILITY_OVERRIDE && this.isPlayer())
|
||||||
return abilities[ABILITY_OVERRIDE];
|
return abilities[ABILITY_OVERRIDE];
|
||||||
|
if (this.fusionSpecies)
|
||||||
|
return abilities[this.getFusionSpeciesForm().getAbility(this.fusionAbilityIndex)];
|
||||||
return abilities[this.getSpeciesForm().getAbility(this.abilityIndex)];
|
return abilities[this.getSpeciesForm().getAbility(this.abilityIndex)];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -493,7 +519,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
||||||
|
|
||||||
getLevelMoves(startingLevel?: integer): Moves[] {
|
getLevelMoves(startingLevel?: integer): Moves[] {
|
||||||
const ret: Moves[] = [];
|
const ret: Moves[] = [];
|
||||||
const levelMoves = pokemonLevelMoves[this.species.speciesId];
|
const levelMoves = this.getSpeciesForm().getLevelMoves();;
|
||||||
if (levelMoves) {
|
if (levelMoves) {
|
||||||
if (!startingLevel)
|
if (!startingLevel)
|
||||||
startingLevel = this.level;
|
startingLevel = this.level;
|
||||||
|
@ -540,7 +566,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
||||||
generateAndPopulateMoveset(): void {
|
generateAndPopulateMoveset(): void {
|
||||||
this.moveset = [];
|
this.moveset = [];
|
||||||
const movePool = [];
|
const movePool = [];
|
||||||
const allLevelMoves = pokemonLevelMoves[this.species.speciesId];
|
const allLevelMoves = this.getSpeciesForm().getLevelMoves();
|
||||||
if (!allLevelMoves) {
|
if (!allLevelMoves) {
|
||||||
console.log(this.species.speciesId, 'ERROR')
|
console.log(this.species.speciesId, 'ERROR')
|
||||||
return;
|
return;
|
||||||
|
@ -917,22 +943,46 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
||||||
return this.summonData.moveQueue;
|
return this.summonData.moveQueue;
|
||||||
}
|
}
|
||||||
|
|
||||||
cry(soundConfig?: Phaser.Types.Sound.SoundConfig): integer {
|
cry(soundConfig?: Phaser.Types.Sound.SoundConfig): AnySound {
|
||||||
return this.getSpeciesForm().cry(this.scene, soundConfig);
|
const cry = this.getSpeciesForm().cry(this.scene, soundConfig);
|
||||||
|
let duration = cry.totalDuration * 1000;
|
||||||
|
if (this.fusionSpecies) {
|
||||||
|
let fusionCry = this.getFusionSpeciesForm().cry(this.scene, soundConfig, true);
|
||||||
|
duration = Math.min(duration, fusionCry.totalDuration * 1000);
|
||||||
|
fusionCry.destroy();
|
||||||
|
this.scene.time.delayedCall(Utils.fixedInt(Math.ceil(duration * 0.4)), () => {
|
||||||
|
try {
|
||||||
|
SoundFade.fadeOut(this.scene, cry, Utils.fixedInt(Math.ceil(duration * 0.2)));
|
||||||
|
fusionCry = this.getFusionSpeciesForm().cry(this.scene, Object.assign({ seek: Math.max(fusionCry.totalDuration * 0.4, 0) }, soundConfig));
|
||||||
|
SoundFade.fadeIn(this.scene, fusionCry, Utils.fixedInt(Math.ceil(duration * 0.2)), this.scene.masterVolume * this.scene.seVolume, 0);
|
||||||
|
} catch (err) {
|
||||||
|
console.error(err);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return cry;
|
||||||
}
|
}
|
||||||
|
|
||||||
faintCry(callback: Function) {
|
faintCry(callback: Function): void {
|
||||||
const key = this.species.speciesId.toString();
|
if (this.fusionSpecies)
|
||||||
|
return this.fusionFaintCry(callback);
|
||||||
|
|
||||||
|
const key = this.getSpeciesForm().getCryKey();
|
||||||
let i = 0;
|
let i = 0;
|
||||||
let rate = 0.85;
|
let rate = 0.85;
|
||||||
const crySound = this.scene.playSound(key, { rate: rate }) as AnySound;
|
const cry = this.scene.playSound(key, { rate: rate }) as AnySound;
|
||||||
const sprite = this.getSprite();
|
const sprite = this.getSprite();
|
||||||
const tintSprite = this.getTintSprite();
|
const tintSprite = this.getTintSprite();
|
||||||
|
|
||||||
const delay = Math.max(this.scene.sound.get(key).totalDuration * 50, 25);
|
const delay = Math.max(this.scene.sound.get(key).totalDuration * 50, 25);
|
||||||
|
|
||||||
let frameProgress = 0;
|
let frameProgress = 0;
|
||||||
let frameThreshold: number;
|
let frameThreshold: number;
|
||||||
|
|
||||||
sprite.anims.pause();
|
sprite.anims.pause();
|
||||||
tintSprite.anims.pause();
|
tintSprite.anims.pause();
|
||||||
|
|
||||||
let faintCryTimer = this.scene.time.addEvent({
|
let faintCryTimer = this.scene.time.addEvent({
|
||||||
delay: Utils.fixedInt(delay),
|
delay: Utils.fixedInt(delay),
|
||||||
repeat: -1,
|
repeat: -1,
|
||||||
|
@ -947,9 +997,9 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
||||||
}
|
}
|
||||||
frameProgress -= frameThreshold;
|
frameProgress -= frameThreshold;
|
||||||
}
|
}
|
||||||
if (crySound && !crySound.pendingRemove) {
|
if (cry && !cry.pendingRemove) {
|
||||||
rate *= 0.99;
|
rate *= 0.99;
|
||||||
crySound.setRate(rate);
|
cry.setRate(rate);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
faintCryTimer.destroy();
|
faintCryTimer.destroy();
|
||||||
|
@ -959,12 +1009,98 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// Failsafe
|
// Failsafe
|
||||||
this.scene.time.delayedCall(Utils.fixedInt(3000), () => {
|
this.scene.time.delayedCall(Utils.fixedInt(3000), () => {
|
||||||
if (!faintCryTimer || !this.scene)
|
if (!faintCryTimer || !this.scene)
|
||||||
return;
|
return;
|
||||||
if (crySound?.isPlaying)
|
if (cry?.isPlaying)
|
||||||
crySound.stop();
|
cry.stop();
|
||||||
|
faintCryTimer.destroy();
|
||||||
|
if (callback)
|
||||||
|
callback();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private fusionFaintCry(callback: Function): void {
|
||||||
|
const key = this.getSpeciesForm().getCryKey();
|
||||||
|
let i = 0;
|
||||||
|
let rate = 0.85;
|
||||||
|
let cry = this.scene.playSound(key, { rate: rate }) as AnySound;
|
||||||
|
const sprite = this.getSprite();
|
||||||
|
const tintSprite = this.getTintSprite();
|
||||||
|
let duration = cry.totalDuration * 1000;
|
||||||
|
|
||||||
|
let fusionCry = this.scene.playSound(this.getFusionSpeciesForm().getCryKey(this.fusionFormIndex), { rate: rate }) as AnySound;
|
||||||
|
fusionCry.stop();
|
||||||
|
duration = Math.min(duration, fusionCry.totalDuration * 1000);
|
||||||
|
fusionCry.destroy();
|
||||||
|
|
||||||
|
const delay = Math.max(duration * 0.05, 25);
|
||||||
|
|
||||||
|
let transitionIndex = 0;
|
||||||
|
let durationProgress = 0;
|
||||||
|
|
||||||
|
const transitionThreshold = Math.ceil(duration * 0.4);
|
||||||
|
while (durationProgress < transitionThreshold) {
|
||||||
|
++i;
|
||||||
|
durationProgress += delay * rate;
|
||||||
|
rate *= 0.99;
|
||||||
|
}
|
||||||
|
|
||||||
|
transitionIndex = i;
|
||||||
|
|
||||||
|
i = 0;
|
||||||
|
rate = 0.85;
|
||||||
|
|
||||||
|
let frameProgress = 0;
|
||||||
|
let frameThreshold: number;
|
||||||
|
|
||||||
|
sprite.anims.pause();
|
||||||
|
tintSprite.anims.pause();
|
||||||
|
|
||||||
|
let faintCryTimer = this.scene.time.addEvent({
|
||||||
|
delay: Utils.fixedInt(delay),
|
||||||
|
repeat: -1,
|
||||||
|
callback: () => {
|
||||||
|
++i;
|
||||||
|
frameThreshold = sprite.anims.msPerFrame / rate;
|
||||||
|
frameProgress += delay;
|
||||||
|
while (frameProgress > frameThreshold) {
|
||||||
|
if (sprite.anims.duration) {
|
||||||
|
sprite.anims.nextFrame();
|
||||||
|
tintSprite.anims.nextFrame();
|
||||||
|
}
|
||||||
|
frameProgress -= frameThreshold;
|
||||||
|
}
|
||||||
|
if (i === transitionIndex) {
|
||||||
|
SoundFade.fadeOut(this.scene, cry, Utils.fixedInt(Math.ceil((duration / rate) * 0.2)));
|
||||||
|
fusionCry = this.scene.playSound(this.getFusionSpeciesForm().getCryKey(this.fusionFormIndex), Object.assign({ seek: Math.max(fusionCry.totalDuration * 0.4, 0), rate: rate }));
|
||||||
|
SoundFade.fadeIn(this.scene, fusionCry, Utils.fixedInt(Math.ceil((duration / rate) * 0.2)), this.scene.masterVolume * this.scene.seVolume, 0);
|
||||||
|
}
|
||||||
|
rate *= 0.99;
|
||||||
|
if (cry && !cry.pendingRemove)
|
||||||
|
cry.setRate(rate);
|
||||||
|
if (fusionCry && !fusionCry.pendingRemove)
|
||||||
|
fusionCry.setRate(rate);
|
||||||
|
if ((!cry || cry.pendingRemove) && (!fusionCry || fusionCry.pendingRemove)) {
|
||||||
|
faintCryTimer.destroy();
|
||||||
|
faintCryTimer = null;
|
||||||
|
if (callback)
|
||||||
|
callback();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Failsafe
|
||||||
|
this.scene.time.delayedCall(Utils.fixedInt(3000), () => {
|
||||||
|
console.log(faintCryTimer)
|
||||||
|
if (!faintCryTimer || !this.scene)
|
||||||
|
return;
|
||||||
|
if (cry?.isPlaying)
|
||||||
|
cry.stop();
|
||||||
|
if (fusionCry?.isPlaying)
|
||||||
|
fusionCry.stop();
|
||||||
faintCryTimer.destroy();
|
faintCryTimer.destroy();
|
||||||
if (callback)
|
if (callback)
|
||||||
callback();
|
callback();
|
||||||
|
@ -1220,6 +1356,53 @@ export class PlayerPokemon extends Pokemon {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
isFusion(): boolean {
|
||||||
|
return !!(this.fusionSpecies || (this.species.speciesId === Species.KYUREM && this.formIndex));
|
||||||
|
}
|
||||||
|
|
||||||
|
fuse(pokemon: PlayerPokemon): Promise<void> {
|
||||||
|
return new Promise(resolve => {
|
||||||
|
if (this.species.speciesId === Species.KYUREM && (pokemon.species.speciesId === Species.RESHIRAM || pokemon.species.speciesId === Species.ZEKROM))
|
||||||
|
this.formIndex = pokemon.species.speciesId === Species.RESHIRAM ? 1 : 2;
|
||||||
|
else {
|
||||||
|
this.fusionSpecies = pokemon.species;
|
||||||
|
this.fusionFormIndex = pokemon.formIndex;
|
||||||
|
this.fusionAbilityIndex = pokemon.abilityIndex;
|
||||||
|
this.fusionShiny = pokemon.shiny;
|
||||||
|
this.fusionGender = pokemon.gender;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.calculateStats();
|
||||||
|
this.updateInfo(true).then(() => {
|
||||||
|
const fusedPartyMemberIndex = this.scene.getParty().indexOf(pokemon);
|
||||||
|
const fusedPartyMemberHeldModifiers = this.scene.findModifiers(m => m instanceof PokemonHeldItemModifier
|
||||||
|
&& (m as PokemonHeldItemModifier).pokemonId === pokemon.id, true) as PokemonHeldItemModifier[];
|
||||||
|
const transferModifiers: Promise<boolean>[] = [];
|
||||||
|
for (let modifier of fusedPartyMemberHeldModifiers)
|
||||||
|
transferModifiers.push(this.scene.tryTransferHeldItemModifier(modifier, this, true, false));
|
||||||
|
Promise.allSettled(transferModifiers).then(() => {
|
||||||
|
this.scene.removePartyMemberModifiers(fusedPartyMemberIndex);
|
||||||
|
this.scene.getParty().splice(fusedPartyMemberIndex, 1)[0];
|
||||||
|
pokemon.destroy();
|
||||||
|
resolve();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
unfuse(): Promise<void> {
|
||||||
|
return new Promise(resolve => {
|
||||||
|
this.fusionSpecies = undefined;
|
||||||
|
this.fusionFormIndex = 0;
|
||||||
|
this.fusionAbilityIndex = 0;
|
||||||
|
this.fusionShiny = false;
|
||||||
|
this.fusionGender = 0;
|
||||||
|
|
||||||
|
this.calculateStats();
|
||||||
|
this.updateInfo(true).then(() => resolve());
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export class EnemyPokemon extends Pokemon {
|
export class EnemyPokemon extends Pokemon {
|
||||||
|
|
|
@ -45,7 +45,7 @@ export function initGameSpeed() {
|
||||||
sound: Phaser.Sound.BaseSound,
|
sound: Phaser.Sound.BaseSound,
|
||||||
duration: number,
|
duration: number,
|
||||||
destroy?: boolean
|
destroy?: boolean
|
||||||
) => originalFadeOut(scene, sound, thisArg.gameSpeed === 1 ? duration : Math.ceil(duration /= thisArg.gameSpeed), destroy)) as FadeOut;
|
) => originalFadeOut(scene, sound, transformValue(duration), destroy)) as FadeOut;
|
||||||
|
|
||||||
const originalFadeIn = SoundFade.fadeIn;
|
const originalFadeIn = SoundFade.fadeIn;
|
||||||
SoundFade.fadeIn = ((
|
SoundFade.fadeIn = ((
|
||||||
|
@ -54,5 +54,5 @@ export function initGameSpeed() {
|
||||||
duration: number,
|
duration: number,
|
||||||
endVolume?: number,
|
endVolume?: number,
|
||||||
startVolume?: number
|
startVolume?: number
|
||||||
) => originalFadeIn(scene, sound, thisArg.gameSpeed === 1 ? duration : Math.ceil(duration /= thisArg.gameSpeed), endVolume, startVolume)) as FadeIn;
|
) => originalFadeIn(scene, sound, transformValue(duration), endVolume, startVolume)) as FadeIn;
|
||||||
}
|
}
|
|
@ -27,6 +27,12 @@ export default class PokemonData {
|
||||||
public winCount: integer;
|
public winCount: integer;
|
||||||
public pokerus: boolean;
|
public pokerus: boolean;
|
||||||
|
|
||||||
|
public fusionSpecies: Species;
|
||||||
|
public fusionFormIndex: integer;
|
||||||
|
public fusionAbilityIndex: integer;
|
||||||
|
public fusionShiny: boolean;
|
||||||
|
public fusionGender: Gender;
|
||||||
|
|
||||||
public summonData: PokemonSummonData;
|
public summonData: PokemonSummonData;
|
||||||
|
|
||||||
constructor(source: Pokemon | any) {
|
constructor(source: Pokemon | any) {
|
||||||
|
@ -48,6 +54,12 @@ export default class PokemonData {
|
||||||
this.winCount = source.winCount;
|
this.winCount = source.winCount;
|
||||||
this.pokerus = !!source.pokerus;
|
this.pokerus = !!source.pokerus;
|
||||||
|
|
||||||
|
this.fusionSpecies = sourcePokemon ? sourcePokemon.fusionSpecies?.speciesId : source.fusionSpecies;
|
||||||
|
this.fusionFormIndex = source.fusionFormIndex;
|
||||||
|
this.fusionAbilityIndex = source.fusionAbilityIndex;
|
||||||
|
this.fusionShiny = source.fusionShiny;
|
||||||
|
this.fusionGender = source.fusionGender;
|
||||||
|
|
||||||
if (sourcePokemon) {
|
if (sourcePokemon) {
|
||||||
this.moveset = sourcePokemon.moveset;
|
this.moveset = sourcePokemon.moveset;
|
||||||
this.status = sourcePokemon.status;
|
this.status = sourcePokemon.status;
|
||||||
|
|
|
@ -271,7 +271,8 @@ export default class BattleInfo extends Phaser.GameObjects.Container {
|
||||||
ratio = 0;
|
ratio = 0;
|
||||||
instant = true;
|
instant = true;
|
||||||
}
|
}
|
||||||
let duration = this.visible && !instant ? ((levelExp - this.lastLevelExp) / relLevelExp) * 1650 : 0;
|
const durationMultiplier = Phaser.Tweens.Builders.GetEaseFunction('Sine.easeIn')(1 - (Math.max(this.lastLevel - 100, 0) / 150));
|
||||||
|
let duration = this.visible && !instant ? (((levelExp - this.lastLevelExp) / relLevelExp) * 1650) * durationMultiplier : 0;
|
||||||
if (duration)
|
if (duration)
|
||||||
(this.scene as BattleScene).playSound('exp');
|
(this.scene as BattleScene).playSound('exp');
|
||||||
this.scene.tweens.add({
|
this.scene.tweens.add({
|
||||||
|
|
|
@ -21,6 +21,7 @@ export enum PartyUiMode {
|
||||||
MOVE_MODIFIER,
|
MOVE_MODIFIER,
|
||||||
TM_MODIFIER,
|
TM_MODIFIER,
|
||||||
MODIFIER_TRANSFER,
|
MODIFIER_TRANSFER,
|
||||||
|
SPLICE,
|
||||||
RELEASE
|
RELEASE
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -31,6 +32,7 @@ export enum PartyOption {
|
||||||
APPLY,
|
APPLY,
|
||||||
TEACH,
|
TEACH,
|
||||||
TRANSFER,
|
TRANSFER,
|
||||||
|
SPLICE,
|
||||||
SUMMARY,
|
SUMMARY,
|
||||||
RELEASE,
|
RELEASE,
|
||||||
MOVE_1,
|
MOVE_1,
|
||||||
|
@ -41,6 +43,7 @@ export enum PartyOption {
|
||||||
|
|
||||||
export type PartySelectCallback = (cursor: integer, option: PartyOption) => void;
|
export type PartySelectCallback = (cursor: integer, option: PartyOption) => void;
|
||||||
export type PartyModifierTransferSelectCallback = (fromCursor: integer, index: integer, toCursor?: integer) => void;
|
export type PartyModifierTransferSelectCallback = (fromCursor: integer, index: integer, toCursor?: integer) => void;
|
||||||
|
export type PartyModifierSpliceSelectCallback = (fromCursor: integer, toCursor?: integer) => void;
|
||||||
export type PokemonSelectFilter = (pokemon: PlayerPokemon) => string;
|
export type PokemonSelectFilter = (pokemon: PlayerPokemon) => string;
|
||||||
export type PokemonModifierTransferSelectFilter = (pokemon: PlayerPokemon, modifier: PokemonHeldItemModifier) => string;
|
export type PokemonModifierTransferSelectFilter = (pokemon: PlayerPokemon, modifier: PokemonHeldItemModifier) => string;
|
||||||
export type PokemonMoveSelectFilter = (pokemonMove: PokemonMove) => string;
|
export type PokemonMoveSelectFilter = (pokemonMove: PokemonMove) => string;
|
||||||
|
@ -200,9 +203,9 @@ export default class PartyUiHandler extends MessageUiHandler {
|
||||||
} else if ((option !== PartyOption.SUMMARY && option !== PartyOption.RELEASE && option !== PartyOption.CANCEL)
|
} else if ((option !== PartyOption.SUMMARY && option !== PartyOption.RELEASE && option !== PartyOption.CANCEL)
|
||||||
|| (option === PartyOption.RELEASE && this.partyUiMode === PartyUiMode.RELEASE)) {
|
|| (option === PartyOption.RELEASE && this.partyUiMode === PartyUiMode.RELEASE)) {
|
||||||
let filterResult: string;
|
let filterResult: string;
|
||||||
if (option !== PartyOption.TRANSFER) {
|
if (option !== PartyOption.TRANSFER && option !== PartyOption.SPLICE) {
|
||||||
filterResult = (this.selectFilter as PokemonSelectFilter)(pokemon);
|
filterResult = (this.selectFilter as PokemonSelectFilter)(pokemon);
|
||||||
if (filterResult === null && this.partyUiMode === PartyUiMode.MOVE_MODIFIER)
|
if (option === PartyOption.TRANSFER && filterResult === null && this.partyUiMode === PartyUiMode.MOVE_MODIFIER)
|
||||||
filterResult = this.moveSelectFilter(pokemon.moveset[this.optionsCursor]);
|
filterResult = this.moveSelectFilter(pokemon.moveset[this.optionsCursor]);
|
||||||
} else {
|
} else {
|
||||||
const itemModifiers = this.scene.findModifiers(m => m instanceof PokemonHeldItemModifier
|
const itemModifiers = this.scene.findModifiers(m => m instanceof PokemonHeldItemModifier
|
||||||
|
@ -210,11 +213,19 @@ export default class PartyUiHandler extends MessageUiHandler {
|
||||||
filterResult = (this.selectFilter as PokemonModifierTransferSelectFilter)(pokemon, itemModifiers[this.transferOptionCursor]);
|
filterResult = (this.selectFilter as PokemonModifierTransferSelectFilter)(pokemon, itemModifiers[this.transferOptionCursor]);
|
||||||
}
|
}
|
||||||
if (filterResult === null) {
|
if (filterResult === null) {
|
||||||
this.clearOptions();
|
if (this.partyUiMode !== PartyUiMode.SPLICE)
|
||||||
|
this.clearOptions();
|
||||||
if (this.selectCallback) {
|
if (this.selectCallback) {
|
||||||
if (option === PartyOption.TRANSFER) {
|
if (option === PartyOption.TRANSFER) {
|
||||||
(this.selectCallback as PartyModifierTransferSelectCallback)(this.transferCursor, this.transferOptionCursor, this.cursor);
|
(this.selectCallback as PartyModifierTransferSelectCallback)(this.transferCursor, this.transferOptionCursor, this.cursor);
|
||||||
this.clearTransfer();
|
this.clearTransfer();
|
||||||
|
} else if (this.partyUiMode === PartyUiMode.SPLICE) {
|
||||||
|
if (option === PartyOption.SPLICE) {
|
||||||
|
(this.selectCallback as PartyModifierSpliceSelectCallback)(this.transferCursor, this.cursor);
|
||||||
|
this.clearTransfer();
|
||||||
|
} else
|
||||||
|
this.startTransfer();
|
||||||
|
this.clearOptions();
|
||||||
} else if (option === PartyOption.RELEASE)
|
} else if (option === PartyOption.RELEASE)
|
||||||
this.doRelease(this.cursor);
|
this.doRelease(this.cursor);
|
||||||
else {
|
else {
|
||||||
|
@ -276,7 +287,7 @@ export default class PartyUiHandler extends MessageUiHandler {
|
||||||
this.processInput(Button.CANCEL);
|
this.processInput(Button.CANCEL);
|
||||||
return;
|
return;
|
||||||
} else if (button === Button.CANCEL) {
|
} else if (button === Button.CANCEL) {
|
||||||
if (this.partyUiMode === PartyUiMode.MODIFIER_TRANSFER && this.transferMode) {
|
if ((this.partyUiMode === PartyUiMode.MODIFIER_TRANSFER || this.partyUiMode === PartyUiMode.SPLICE) && this.transferMode) {
|
||||||
this.clearTransfer();
|
this.clearTransfer();
|
||||||
ui.playSelect();
|
ui.playSelect();
|
||||||
} else if (this.partyUiMode !== PartyUiMode.FAINT_SWITCH) {
|
} else if (this.partyUiMode !== PartyUiMode.FAINT_SWITCH) {
|
||||||
|
@ -404,6 +415,10 @@ export default class PartyUiHandler extends MessageUiHandler {
|
||||||
if (!this.transferMode)
|
if (!this.transferMode)
|
||||||
optionsMessage = 'Select a held item to transfer.';
|
optionsMessage = 'Select a held item to transfer.';
|
||||||
break;
|
break;
|
||||||
|
case PartyUiMode.SPLICE:
|
||||||
|
if (!this.transferMode)
|
||||||
|
optionsMessage = 'Select another Pokémon to splice.';
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.showText(optionsMessage, 0);
|
this.showText(optionsMessage, 0);
|
||||||
|
@ -441,6 +456,13 @@ export default class PartyUiHandler extends MessageUiHandler {
|
||||||
case PartyUiMode.MODIFIER_TRANSFER:
|
case PartyUiMode.MODIFIER_TRANSFER:
|
||||||
this.options.push(PartyOption.TRANSFER);
|
this.options.push(PartyOption.TRANSFER);
|
||||||
break;
|
break;
|
||||||
|
case PartyUiMode.SPLICE:
|
||||||
|
if (this.transferMode) {
|
||||||
|
if (this.cursor !== this.transferCursor)
|
||||||
|
this.options.push(PartyOption.SPLICE);
|
||||||
|
} else
|
||||||
|
this.options.push(PartyOption.APPLY);
|
||||||
|
break;
|
||||||
case PartyUiMode.RELEASE:
|
case PartyUiMode.RELEASE:
|
||||||
this.options.push(PartyOption.RELEASE);
|
this.options.push(PartyOption.RELEASE);
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -100,19 +100,19 @@ export default class SummaryUiHandler extends UiHandler {
|
||||||
this.pokemonSprite = this.scene.add.sprite(56, -106, `pkmn__sub`);
|
this.pokemonSprite = this.scene.add.sprite(56, -106, `pkmn__sub`);
|
||||||
this.summaryContainer.add(this.pokemonSprite);
|
this.summaryContainer.add(this.pokemonSprite);
|
||||||
|
|
||||||
this.nameText = addTextObject(this.scene, 6, -39, '', TextStyle.SUMMARY);
|
this.nameText = addTextObject(this.scene, 6, -54, '', TextStyle.SUMMARY);
|
||||||
this.nameText.setOrigin(0, 1);
|
this.nameText.setOrigin(0, 0);
|
||||||
this.summaryContainer.add(this.nameText);
|
this.summaryContainer.add(this.nameText);
|
||||||
|
|
||||||
this.pokeball = this.scene.add.sprite(6, -23, 'pb');
|
this.pokeball = this.scene.add.sprite(6, -19, 'pb');
|
||||||
this.pokeball.setOrigin(0, 1);
|
this.pokeball.setOrigin(0, 1);
|
||||||
this.summaryContainer.add(this.pokeball);
|
this.summaryContainer.add(this.pokeball);
|
||||||
|
|
||||||
this.levelText = addTextObject(this.scene, 36, -22, '', TextStyle.SUMMARY);
|
this.levelText = addTextObject(this.scene, 36, -18, '', TextStyle.SUMMARY);
|
||||||
this.levelText.setOrigin(0, 1);
|
this.levelText.setOrigin(0, 1);
|
||||||
this.summaryContainer.add(this.levelText);
|
this.summaryContainer.add(this.levelText);
|
||||||
|
|
||||||
this.genderText = addTextObject(this.scene, 96, -22, '', TextStyle.SUMMARY);
|
this.genderText = addTextObject(this.scene, 96, -18, '', TextStyle.SUMMARY);
|
||||||
this.genderText.setOrigin(0, 1);
|
this.genderText.setOrigin(0, 1);
|
||||||
this.summaryContainer.add(this.genderText);
|
this.summaryContainer.add(this.genderText);
|
||||||
|
|
||||||
|
@ -199,7 +199,17 @@ export default class SummaryUiHandler extends UiHandler {
|
||||||
this.pokemonSprite.play(this.pokemon.getSpriteKey(true));
|
this.pokemonSprite.play(this.pokemon.getSpriteKey(true));
|
||||||
this.pokemon.cry();
|
this.pokemon.cry();
|
||||||
|
|
||||||
this.nameText.setText(this.pokemon.name);
|
let nameLabel = this.pokemon.name;
|
||||||
|
if (this.pokemon.fusionSpecies)
|
||||||
|
nameLabel += `/\n ${this.pokemon.fusionSpecies.name}`;
|
||||||
|
|
||||||
|
this.nameText.setText(nameLabel);
|
||||||
|
|
||||||
|
this.nameText.setFontSize(`${!this.pokemon.fusionSpecies ? '96px' : '72px'}`);
|
||||||
|
const nameShadowSize = !this.pokemon.fusionSpecies ? 6 : 4.5;
|
||||||
|
this.nameText.setShadowOffset(nameShadowSize, nameShadowSize);
|
||||||
|
this.nameText.setLineSpacing(!this.pokemon.fusionSpecies ? 5 : 0);
|
||||||
|
|
||||||
this.pokeball.setFrame(getPokeballAtlasKey(this.pokemon.pokeball));
|
this.pokeball.setFrame(getPokeballAtlasKey(this.pokemon.pokeball));
|
||||||
this.levelText.setText(this.pokemon.level.toString());
|
this.levelText.setText(this.pokemon.level.toString());
|
||||||
this.genderText.setText(getGenderSymbol(this.pokemon.getGender(true)));
|
this.genderText.setText(getGenderSymbol(this.pokemon.getGender(true)));
|
||||||
|
@ -478,7 +488,7 @@ export default class SummaryUiHandler extends UiHandler {
|
||||||
if (this.pokemon.species.type2)
|
if (this.pokemon.species.type2)
|
||||||
profileContainer.add(getTypeIcon(1, this.pokemon.species.type2));
|
profileContainer.add(getTypeIcon(1, this.pokemon.species.type2));
|
||||||
|
|
||||||
const ability = abilities[this.pokemon.species.getAbility(this.pokemon.abilityIndex)];
|
const ability = this.pokemon.getAbility();
|
||||||
|
|
||||||
const abilityNameText = addTextObject(this.scene, 7, 66, ability.name, TextStyle.SUMMARY);
|
const abilityNameText = addTextObject(this.scene, 7, 66, ability.name, TextStyle.SUMMARY);
|
||||||
abilityNameText.setOrigin(0, 1);
|
abilityNameText.setOrigin(0, 1);
|
||||||
|
|
|
@ -101,7 +101,6 @@ export function getTextColor(textStyle: TextStyle, shadow?: boolean) {
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getModifierTierTextTint(tier: integer): integer {
|
export function getModifierTierTextTint(tier: integer): integer {
|
||||||
console.log(tier);
|
|
||||||
switch (tier) {
|
switch (tier) {
|
||||||
case 0: // ModifierTier.COMMON:
|
case 0: // ModifierTier.COMMON:
|
||||||
return 0xffffff;
|
return 0xffffff;
|
||||||
|
|
Loading…
Reference in New Issue