Merge branch 'main' of https://github.com/pagefaultgames/pokerogue into aftermath
BIN
public/fonts/item-count.png
Normal file
After Width: | Height: | Size: 607 B |
1
public/fonts/item-count.xml
Normal file
@ -0,0 +1 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?><font><info face="item-count" size="11" bold="0" italic="0" charset="" unicode="1" stretchH="100" smooth="1" aa="1" padding="0,0,0,0" spacing="0,0"/><common lineHeight="11" base="8" scaleW="23" scaleH="27" pages="1" packed="0"/><pages><page id="0" file="item-count.png"/></pages><chars count="11"><char id="32" x="0" y="0" width="0" height="0" xoffset="0" yoffset="0" xadvance="3" page="0" chnl="15"/><!-- --><char id="48" x="0" y="0" width="6" height="9" xoffset="-1" yoffset="0" xadvance="5" page="0" chnl="15"/><!-- 0 --><char id="49" x="6" y="0" width="5" height="9" xoffset="-1" yoffset="0" xadvance="5" page="0" chnl="15"/><!-- 1 --><char id="50" x="11" y="0" width="6" height="9" xoffset="-1" yoffset="0" xadvance="5" page="0" chnl="15"/><!-- 2 --><char id="51" x="17" y="0" width="6" height="9" xoffset="-1" yoffset="0" xadvance="5" page="0" chnl="15"/><!-- 3 --><char id="52" x="0" y="9" width="6" height="9" xoffset="-1" yoffset="0" xadvance="5" page="0" chnl="15"/><!-- 4 --><char id="53" x="0" y="18" width="6" height="9" xoffset="-1" yoffset="0" xadvance="5" page="0" chnl="15"/><!-- 5 --><char id="54" x="6" y="9" width="6" height="9" xoffset="-1" yoffset="0" xadvance="5" page="0" chnl="15"/><!-- 6 --><char id="55" x="6" y="18" width="6" height="9" xoffset="-1" yoffset="0" xadvance="5" page="0" chnl="15"/><!-- 7 --><char id="56" x="12" y="9" width="6" height="9" xoffset="-1" yoffset="0" xadvance="5" page="0" chnl="15"/><!-- 8 --><char id="57" x="12" y="18" width="6" height="9" xoffset="-1" yoffset="0" xadvance="5" page="0" chnl="15"/><!-- 9 --></chars></font>
|
41
public/images/pokemon/172-spiky.json
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
{
|
||||||
|
"textures": [
|
||||||
|
{
|
||||||
|
"image": "172-spiky.png",
|
||||||
|
"format": "RGBA8888",
|
||||||
|
"size": {
|
||||||
|
"w": 37,
|
||||||
|
"h": 37
|
||||||
|
},
|
||||||
|
"scale": 1,
|
||||||
|
"frames": [
|
||||||
|
{
|
||||||
|
"filename": "0001.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 37,
|
||||||
|
"h": 37
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 0,
|
||||||
|
"y": 0,
|
||||||
|
"w": 32,
|
||||||
|
"h": 37
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 0,
|
||||||
|
"y": 0,
|
||||||
|
"w": 32,
|
||||||
|
"h": 37
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"meta": {
|
||||||
|
"app": "https://www.codeandweb.com/texturepacker",
|
||||||
|
"version": "3.0",
|
||||||
|
"smartupdate": "$TexturePacker:SmartUpdate:a54544be532be719321d616d8c7aced5:a2bb30b1b8b6f639fce8842f57cfa1b1:9ae51c05debb17f5b4855b9604caf349$"
|
||||||
|
}
|
||||||
|
}
|
BIN
public/images/pokemon/172-spiky.png
Normal file
After Width: | Height: | Size: 419 B |
41
public/images/pokemon/back/172-spiky.json
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
{
|
||||||
|
"textures": [
|
||||||
|
{
|
||||||
|
"image": "172-spiky.png",
|
||||||
|
"format": "RGBA8888",
|
||||||
|
"size": {
|
||||||
|
"w": 37,
|
||||||
|
"h": 37
|
||||||
|
},
|
||||||
|
"scale": 1,
|
||||||
|
"frames": [
|
||||||
|
{
|
||||||
|
"filename": "0001.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 37,
|
||||||
|
"h": 37
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 0,
|
||||||
|
"y": 0,
|
||||||
|
"w": 28,
|
||||||
|
"h": 37
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 0,
|
||||||
|
"y": 0,
|
||||||
|
"w": 28,
|
||||||
|
"h": 37
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"meta": {
|
||||||
|
"app": "https://www.codeandweb.com/texturepacker",
|
||||||
|
"version": "3.0",
|
||||||
|
"smartupdate": "$TexturePacker:SmartUpdate:0d1cec69240ba50d6a304f627a54acaf:827b2992c2d340b0dc5f851caeb6463e:9ae51c05debb17f5b4855b9604caf349$"
|
||||||
|
}
|
||||||
|
}
|
BIN
public/images/pokemon/back/172-spiky.png
Normal file
After Width: | Height: | Size: 383 B |
41
public/images/pokemon/back/shiny/172-spiky.json
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
{
|
||||||
|
"textures": [
|
||||||
|
{
|
||||||
|
"image": "172-spiky.png",
|
||||||
|
"format": "RGBA8888",
|
||||||
|
"size": {
|
||||||
|
"w": 37,
|
||||||
|
"h": 37
|
||||||
|
},
|
||||||
|
"scale": 1,
|
||||||
|
"frames": [
|
||||||
|
{
|
||||||
|
"filename": "0001.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 37,
|
||||||
|
"h": 37
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 0,
|
||||||
|
"y": 0,
|
||||||
|
"w": 28,
|
||||||
|
"h": 37
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 0,
|
||||||
|
"y": 0,
|
||||||
|
"w": 28,
|
||||||
|
"h": 37
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"meta": {
|
||||||
|
"app": "https://www.codeandweb.com/texturepacker",
|
||||||
|
"version": "3.0",
|
||||||
|
"smartupdate": "$TexturePacker:SmartUpdate:d29f82d65f41d6a2345d138505688bcf:878f83394f1d74e94db8f5e999befc35:9ae51c05debb17f5b4855b9604caf349$"
|
||||||
|
}
|
||||||
|
}
|
BIN
public/images/pokemon/back/shiny/172-spiky.png
Normal file
After Width: | Height: | Size: 388 B |
BIN
public/images/pokemon/icons/172-spiky.png
Normal file
After Width: | Height: | Size: 338 B |
BIN
public/images/pokemon/icons/172s-spiky.png
Normal file
After Width: | Height: | Size: 338 B |
41
public/images/pokemon/shiny/172-spiky.json
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
{
|
||||||
|
"textures": [
|
||||||
|
{
|
||||||
|
"image": "172-spiky.png",
|
||||||
|
"format": "RGBA8888",
|
||||||
|
"size": {
|
||||||
|
"w": 37,
|
||||||
|
"h": 37
|
||||||
|
},
|
||||||
|
"scale": 1,
|
||||||
|
"frames": [
|
||||||
|
{
|
||||||
|
"filename": "0001.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 37,
|
||||||
|
"h": 37
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 0,
|
||||||
|
"y": 0,
|
||||||
|
"w": 32,
|
||||||
|
"h": 37
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 0,
|
||||||
|
"y": 0,
|
||||||
|
"w": 32,
|
||||||
|
"h": 37
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"meta": {
|
||||||
|
"app": "https://www.codeandweb.com/texturepacker",
|
||||||
|
"version": "3.0",
|
||||||
|
"smartupdate": "$TexturePacker:SmartUpdate:49a07db3effcc103cbb05f5e4fcb1155:fe0e8884b0d24f136e2bc354b3a1bb1b:9ae51c05debb17f5b4855b9604caf349$"
|
||||||
|
}
|
||||||
|
}
|
BIN
public/images/pokemon/shiny/172-spiky.png
Normal file
After Width: | Height: | Size: 419 B |
Before Width: | Height: | Size: 41 KiB After Width: | Height: | Size: 41 KiB |
@ -1,4 +1,4 @@
|
|||||||
import Phaser from 'phaser';
|
import Phaser, { Time } from 'phaser';
|
||||||
import UI, { Mode } from './ui/ui';
|
import UI, { Mode } from './ui/ui';
|
||||||
import { NextEncounterPhase, NewBiomeEncounterPhase, SelectBiomePhase, MessagePhase, TurnInitPhase, ReturnPhase, LevelCapPhase, ShowTrainerPhase, LoginPhase, MovePhase, TitlePhase, SwitchPhase } from './phases';
|
import { NextEncounterPhase, NewBiomeEncounterPhase, SelectBiomePhase, MessagePhase, TurnInitPhase, ReturnPhase, LevelCapPhase, ShowTrainerPhase, LoginPhase, MovePhase, TitlePhase, SwitchPhase } from './phases';
|
||||||
import Pokemon, { PlayerPokemon, EnemyPokemon } from './field/pokemon';
|
import Pokemon, { PlayerPokemon, EnemyPokemon } from './field/pokemon';
|
||||||
@ -78,6 +78,7 @@ const DEBUG_RNG = false;
|
|||||||
export const startingWave = STARTING_WAVE_OVERRIDE || 1;
|
export const startingWave = STARTING_WAVE_OVERRIDE || 1;
|
||||||
|
|
||||||
const expSpriteKeys: string[] = [];
|
const expSpriteKeys: string[] = [];
|
||||||
|
const repeatInputDelayMillis = 250;
|
||||||
|
|
||||||
export enum Button {
|
export enum Button {
|
||||||
UP,
|
UP,
|
||||||
@ -118,6 +119,8 @@ export default class BattleScene extends SceneBase {
|
|||||||
public uiTheme: UiTheme = UiTheme.DEFAULT;
|
public uiTheme: UiTheme = UiTheme.DEFAULT;
|
||||||
public windowType: integer = 0;
|
public windowType: integer = 0;
|
||||||
public experimentalSprites: boolean = false;
|
public experimentalSprites: boolean = false;
|
||||||
|
public moveAnimations: boolean = true;
|
||||||
|
public hpBarSpeed: integer = 0;
|
||||||
public fusionPaletteSwaps: boolean = true;
|
public fusionPaletteSwaps: boolean = true;
|
||||||
public enableTouchControls: boolean = false;
|
public enableTouchControls: boolean = false;
|
||||||
public enableVibration: boolean = false;
|
public enableVibration: boolean = false;
|
||||||
@ -183,8 +186,10 @@ export default class BattleScene extends SceneBase {
|
|||||||
private playTimeTimer: Phaser.Time.TimerEvent;
|
private playTimeTimer: Phaser.Time.TimerEvent;
|
||||||
|
|
||||||
private buttonKeys: Phaser.Input.Keyboard.Key[][];
|
private buttonKeys: Phaser.Input.Keyboard.Key[][];
|
||||||
|
private lastProcessedButtonPressTimes: Map<Button, number> = new Map();
|
||||||
private blockInput: boolean;
|
// movementButtonLock ensures only a single movement key is firing repeated inputs
|
||||||
|
// (i.e. by holding down a button) at a time
|
||||||
|
private movementButtonLock: Button;
|
||||||
|
|
||||||
public rngCounter: integer = 0;
|
public rngCounter: integer = 0;
|
||||||
public rngSeedOverride: string = '';
|
public rngSeedOverride: string = '';
|
||||||
@ -1062,29 +1067,34 @@ export default class BattleScene extends SceneBase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
checkInput(): boolean {
|
checkInput(): boolean {
|
||||||
if (this.blockInput)
|
|
||||||
return;
|
|
||||||
let inputSuccess = false;
|
let inputSuccess = false;
|
||||||
let vibrationLength = 0;
|
let vibrationLength = 0;
|
||||||
if (this.isButtonPressed(Button.UP)) {
|
if (this.buttonJustPressed(Button.UP) || this.repeatInputDurationJustPassed(Button.UP)) {
|
||||||
inputSuccess = this.ui.processInput(Button.UP);
|
inputSuccess = this.ui.processInput(Button.UP);
|
||||||
vibrationLength = 5;
|
vibrationLength = 5;
|
||||||
} else if (this.isButtonPressed(Button.DOWN)) {
|
this.setLastProcessedMovementTime(Button.UP)
|
||||||
|
} else if (this.buttonJustPressed(Button.DOWN) || this.repeatInputDurationJustPassed(Button.DOWN)) {
|
||||||
inputSuccess = this.ui.processInput(Button.DOWN);
|
inputSuccess = this.ui.processInput(Button.DOWN);
|
||||||
vibrationLength = 5;
|
vibrationLength = 5;
|
||||||
} else if (this.isButtonPressed(Button.LEFT)) {
|
this.setLastProcessedMovementTime(Button.DOWN)
|
||||||
|
} else if (this.buttonJustPressed(Button.LEFT) || this.repeatInputDurationJustPassed(Button.LEFT)) {
|
||||||
inputSuccess = this.ui.processInput(Button.LEFT);
|
inputSuccess = this.ui.processInput(Button.LEFT);
|
||||||
vibrationLength = 5;
|
vibrationLength = 5;
|
||||||
} else if (this.isButtonPressed(Button.RIGHT)) {
|
this.setLastProcessedMovementTime(Button.LEFT)
|
||||||
|
} else if (this.buttonJustPressed(Button.RIGHT) || this.repeatInputDurationJustPassed(Button.RIGHT)) {
|
||||||
inputSuccess = this.ui.processInput(Button.RIGHT);
|
inputSuccess = this.ui.processInput(Button.RIGHT);
|
||||||
vibrationLength = 5;
|
vibrationLength = 5;
|
||||||
} else if (this.isButtonPressed(Button.SUBMIT)) {
|
this.setLastProcessedMovementTime(Button.RIGHT)
|
||||||
|
} else if (this.buttonJustPressed(Button.SUBMIT) || this.repeatInputDurationJustPassed(Button.SUBMIT)) {
|
||||||
inputSuccess = this.ui.processInput(Button.SUBMIT) || this.ui.processInput(Button.ACTION);
|
inputSuccess = this.ui.processInput(Button.SUBMIT) || this.ui.processInput(Button.ACTION);
|
||||||
} else if (this.isButtonPressed(Button.ACTION))
|
this.setLastProcessedMovementTime(Button.SUBMIT);
|
||||||
|
} else if (this.buttonJustPressed(Button.ACTION) || this.repeatInputDurationJustPassed(Button.ACTION)) {
|
||||||
inputSuccess = this.ui.processInput(Button.ACTION);
|
inputSuccess = this.ui.processInput(Button.ACTION);
|
||||||
else if (this.isButtonPressed(Button.CANCEL)) {
|
this.setLastProcessedMovementTime(Button.ACTION);
|
||||||
|
} else if (this.buttonJustPressed(Button.CANCEL)|| this.repeatInputDurationJustPassed(Button.CANCEL)) {
|
||||||
inputSuccess = this.ui.processInput(Button.CANCEL);
|
inputSuccess = this.ui.processInput(Button.CANCEL);
|
||||||
} else if (this.isButtonPressed(Button.MENU)) {
|
this.setLastProcessedMovementTime(Button.CANCEL);
|
||||||
|
} else if (this.buttonJustPressed(Button.MENU)) {
|
||||||
switch (this.ui?.getMode()) {
|
switch (this.ui?.getMode()) {
|
||||||
case Mode.MESSAGE:
|
case Mode.MESSAGE:
|
||||||
if (!(this.ui.getHandler() as MessageUiHandler).pendingPrompt)
|
if (!(this.ui.getHandler() as MessageUiHandler).pendingPrompt)
|
||||||
@ -1115,25 +1125,25 @@ export default class BattleScene extends SceneBase {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} else if (this.ui?.getHandler() instanceof StarterSelectUiHandler) {
|
} else if (this.ui?.getHandler() instanceof StarterSelectUiHandler) {
|
||||||
if (this.isButtonPressed(Button.CYCLE_SHINY))
|
if (this.buttonJustPressed(Button.CYCLE_SHINY)) {
|
||||||
inputSuccess = this.ui.processInput(Button.CYCLE_SHINY);
|
inputSuccess = this.ui.processInput(Button.CYCLE_SHINY);
|
||||||
else if (this.isButtonPressed(Button.CYCLE_FORM))
|
} else if (this.buttonJustPressed(Button.CYCLE_FORM)) {
|
||||||
inputSuccess = this.ui.processInput(Button.CYCLE_FORM);
|
inputSuccess = this.ui.processInput(Button.CYCLE_FORM);
|
||||||
else if (this.isButtonPressed(Button.CYCLE_GENDER))
|
} else if (this.buttonJustPressed(Button.CYCLE_GENDER)) {
|
||||||
inputSuccess = this.ui.processInput(Button.CYCLE_GENDER);
|
inputSuccess = this.ui.processInput(Button.CYCLE_GENDER);
|
||||||
else if (this.isButtonPressed(Button.CYCLE_ABILITY))
|
} else if (this.buttonJustPressed(Button.CYCLE_ABILITY)) {
|
||||||
inputSuccess = this.ui.processInput(Button.CYCLE_ABILITY);
|
inputSuccess = this.ui.processInput(Button.CYCLE_ABILITY);
|
||||||
else if (this.isButtonPressed(Button.CYCLE_NATURE))
|
} else if (this.buttonJustPressed(Button.CYCLE_NATURE)) {
|
||||||
inputSuccess = this.ui.processInput(Button.CYCLE_NATURE);
|
inputSuccess = this.ui.processInput(Button.CYCLE_NATURE);
|
||||||
else
|
} else
|
||||||
return;
|
return;
|
||||||
} else if (this.isButtonPressed(Button.SPEED_UP)) {
|
} else if (this.buttonJustPressed(Button.SPEED_UP)) {
|
||||||
if (this.gameSpeed < 5) {
|
if (this.gameSpeed < 5) {
|
||||||
this.gameData.saveSetting(Setting.Game_Speed, settingOptions[Setting.Game_Speed].indexOf(`${this.gameSpeed}x`) + 1);
|
this.gameData.saveSetting(Setting.Game_Speed, settingOptions[Setting.Game_Speed].indexOf(`${this.gameSpeed}x`) + 1);
|
||||||
if (this.ui?.getMode() === Mode.SETTINGS)
|
if (this.ui?.getMode() === Mode.SETTINGS)
|
||||||
(this.ui.getHandler() as SettingsUiHandler).show([]);
|
(this.ui.getHandler() as SettingsUiHandler).show([]);
|
||||||
}
|
}
|
||||||
} else if (this.isButtonPressed(Button.SLOW_DOWN)) {
|
} else if (this.buttonJustPressed(Button.SLOW_DOWN)) {
|
||||||
if (this.gameSpeed > 1) {
|
if (this.gameSpeed > 1) {
|
||||||
this.gameData.saveSetting(Setting.Game_Speed, Math.max(settingOptions[Setting.Game_Speed].indexOf(`${this.gameSpeed}x`) - 1, 0));
|
this.gameData.saveSetting(Setting.Game_Speed, Math.max(settingOptions[Setting.Game_Speed].indexOf(`${this.gameSpeed}x`) - 1, 0));
|
||||||
if (this.ui?.getMode() === Mode.SETTINGS)
|
if (this.ui?.getMode() === Mode.SETTINGS)
|
||||||
@ -1143,12 +1153,33 @@ export default class BattleScene extends SceneBase {
|
|||||||
return;
|
return;
|
||||||
if (inputSuccess && this.enableVibration && typeof navigator.vibrate !== 'undefined')
|
if (inputSuccess && this.enableVibration && typeof navigator.vibrate !== 'undefined')
|
||||||
navigator.vibrate(vibrationLength || 10);
|
navigator.vibrate(vibrationLength || 10);
|
||||||
this.blockInput = true;
|
|
||||||
this.time.delayedCall(Utils.fixedInt(250), () => this.blockInput = false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
isButtonPressed(button: Button): boolean {
|
buttonJustPressed(button: Button): boolean {
|
||||||
return this.buttonKeys[button].filter(k => k.isDown).length >= 1;
|
return this.buttonKeys[button].some(k => Phaser.Input.Keyboard.JustDown(k));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* repeatInputDurationJustPassed returns true if @param button has been held down long
|
||||||
|
* enough to fire a repeated input. A button must claim the movementButtonLock before
|
||||||
|
* firing a repeated input - this is to prevent multiple buttons from firing repeatedly.
|
||||||
|
*/
|
||||||
|
repeatInputDurationJustPassed(button: Button): boolean {
|
||||||
|
if (this.movementButtonLock !== null && this.movementButtonLock !== button) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (this.buttonKeys[button].every(k => k.isUp)) {
|
||||||
|
this.movementButtonLock = null;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (this.time.now - this.lastProcessedButtonPressTimes.get(button) >= repeatInputDelayMillis) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
setLastProcessedMovementTime(button: Button) {
|
||||||
|
this.lastProcessedButtonPressTimes.set(button, this.time.now);
|
||||||
|
this.movementButtonLock = button;
|
||||||
}
|
}
|
||||||
|
|
||||||
isBgmPlaying(): boolean {
|
isBgmPlaying(): boolean {
|
||||||
|
@ -2764,7 +2764,7 @@ export function initAbilities() {
|
|||||||
new Ability(Abilities.DAUNTLESS_SHIELD, "Dauntless Shield", "Boosts the Pokémon's Defense stat when the Pokémon enters a battle.", 8)
|
new Ability(Abilities.DAUNTLESS_SHIELD, "Dauntless Shield", "Boosts the Pokémon's Defense stat when the Pokémon enters a battle.", 8)
|
||||||
.attr(PostSummonStatChangeAbAttr, BattleStat.DEF, 1, true),
|
.attr(PostSummonStatChangeAbAttr, BattleStat.DEF, 1, true),
|
||||||
new Ability(Abilities.LIBERO, "Libero (N)", "Changes the Pokémon's type to the type of the move it's about to use.", 8),
|
new Ability(Abilities.LIBERO, "Libero (N)", "Changes the Pokémon's type to the type of the move it's about to use.", 8),
|
||||||
new Ability(Abilities.BALL_FETCH, "Ball Fetch (N)", "If the Pokémon is not holding an item, it will fetch the Poké Ball from the first failed throw of the battle.", 8),
|
new Ability(Abilities.BALL_FETCH, "Ball Fetch (N)", "The Pokémon will fetch the Poké Ball from the first failed throw of the battle.", 8),
|
||||||
new Ability(Abilities.COTTON_DOWN, "Cotton Down (N)", "When the Pokémon is hit by an attack, it scatters cotton fluff around and lowers the Speed stat of all Pokémon except itself.", 8),
|
new Ability(Abilities.COTTON_DOWN, "Cotton Down (N)", "When the Pokémon is hit by an attack, it scatters cotton fluff around and lowers the Speed stat of all Pokémon except itself.", 8),
|
||||||
new Ability(Abilities.PROPELLER_TAIL, "Propeller Tail (N)", "Ignores the effects of opposing Pokémon's Abilities and moves that draw in moves.", 8),
|
new Ability(Abilities.PROPELLER_TAIL, "Propeller Tail (N)", "Ignores the effects of opposing Pokémon's Abilities and moves that draw in moves.", 8),
|
||||||
new Ability(Abilities.MIRROR_ARMOR, "Mirror Armor (N)", "Bounces back only the stat-lowering effects that the Pokémon receives.", 8)
|
new Ability(Abilities.MIRROR_ARMOR, "Mirror Armor (N)", "Bounces back only the stat-lowering effects that the Pokémon receives.", 8)
|
||||||
|
@ -722,6 +722,41 @@ export abstract class BattleAnim {
|
|||||||
const userSprite = user.getSprite();
|
const userSprite = user.getSprite();
|
||||||
const targetSprite = target.getSprite();
|
const targetSprite = target.getSprite();
|
||||||
|
|
||||||
|
const spriteCache: SpriteCache = {
|
||||||
|
[AnimFrameTarget.GRAPHIC]: [],
|
||||||
|
[AnimFrameTarget.USER]: [],
|
||||||
|
[AnimFrameTarget.TARGET]: []
|
||||||
|
};
|
||||||
|
const spritePriorities: integer[] = [];
|
||||||
|
|
||||||
|
const cleanUpAndComplete = () => {
|
||||||
|
userSprite.setPosition(0, 0);
|
||||||
|
userSprite.setScale(1);
|
||||||
|
userSprite.setAlpha(1);
|
||||||
|
userSprite.pipelineData['tone'] = [ 0.0, 0.0, 0.0, 0.0 ];
|
||||||
|
userSprite.setAngle(0);
|
||||||
|
targetSprite.setPosition(0, 0);
|
||||||
|
targetSprite.setScale(1);
|
||||||
|
targetSprite.setAlpha(1);
|
||||||
|
targetSprite.pipelineData['tone'] = [ 0.0, 0.0, 0.0, 0.0 ];
|
||||||
|
targetSprite.setAngle(0);
|
||||||
|
if (!this.isHideUser())
|
||||||
|
userSprite.setVisible(true);
|
||||||
|
if (!this.isHideTarget() && (targetSprite !== userSprite || !this.isHideUser()))
|
||||||
|
targetSprite.setVisible(true);
|
||||||
|
for (let ms of Object.values(spriteCache).flat()) {
|
||||||
|
if (ms)
|
||||||
|
ms.destroy();
|
||||||
|
}
|
||||||
|
if (this.bgSprite)
|
||||||
|
this.bgSprite.destroy();
|
||||||
|
if (callback)
|
||||||
|
callback();
|
||||||
|
};
|
||||||
|
|
||||||
|
if (!scene.moveAnimations)
|
||||||
|
return cleanUpAndComplete();
|
||||||
|
|
||||||
const anim = this.getAnim();
|
const anim = this.getAnim();
|
||||||
|
|
||||||
const userInitialX = user.x;
|
const userInitialX = user.x;
|
||||||
@ -735,13 +770,6 @@ export abstract class BattleAnim {
|
|||||||
let r = anim.frames.length;
|
let r = anim.frames.length;
|
||||||
let f = 0;
|
let f = 0;
|
||||||
|
|
||||||
const spriteCache: SpriteCache = {
|
|
||||||
[AnimFrameTarget.GRAPHIC]: [],
|
|
||||||
[AnimFrameTarget.USER]: [],
|
|
||||||
[AnimFrameTarget.TARGET]: []
|
|
||||||
};
|
|
||||||
const spritePriorities: integer[] = [];
|
|
||||||
|
|
||||||
scene.tweens.addCounter({
|
scene.tweens.addCounter({
|
||||||
duration: Utils.getFrameMs(3),
|
duration: Utils.getFrameMs(3),
|
||||||
repeat: anim.frames.length,
|
repeat: anim.frames.length,
|
||||||
@ -880,30 +908,6 @@ export abstract class BattleAnim {
|
|||||||
r--;
|
r--;
|
||||||
},
|
},
|
||||||
onComplete: () => {
|
onComplete: () => {
|
||||||
const cleanUpAndComplete = () => {
|
|
||||||
userSprite.setPosition(0, 0);
|
|
||||||
userSprite.setScale(1);
|
|
||||||
userSprite.setAlpha(1);
|
|
||||||
userSprite.pipelineData['tone'] = [ 0.0, 0.0, 0.0, 0.0 ];
|
|
||||||
userSprite.setAngle(0);
|
|
||||||
targetSprite.setPosition(0, 0);
|
|
||||||
targetSprite.setScale(1);
|
|
||||||
targetSprite.setAlpha(1);
|
|
||||||
targetSprite.pipelineData['tone'] = [ 0.0, 0.0, 0.0, 0.0 ];
|
|
||||||
targetSprite.setAngle(0);
|
|
||||||
if (!this.isHideUser())
|
|
||||||
userSprite.setVisible(true);
|
|
||||||
if (!this.isHideTarget() && (targetSprite !== userSprite || !this.isHideUser()))
|
|
||||||
targetSprite.setVisible(true);
|
|
||||||
for (let ms of Object.values(spriteCache).flat()) {
|
|
||||||
if (ms)
|
|
||||||
ms.destroy();
|
|
||||||
}
|
|
||||||
if (this.bgSprite)
|
|
||||||
this.bgSprite.destroy();
|
|
||||||
if (callback)
|
|
||||||
callback();
|
|
||||||
};
|
|
||||||
for (let ms of Object.values(spriteCache).flat()) {
|
for (let ms of Object.values(spriteCache).flat()) {
|
||||||
if (ms && !ms.getData('locked'))
|
if (ms && !ms.getData('locked'))
|
||||||
ms.destroy();
|
ms.destroy();
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { CommonAnim, CommonBattleAnim } from "./battle-anims";
|
import { CommonAnim, CommonBattleAnim } from "./battle-anims";
|
||||||
import { CommonAnimPhase, MoveEffectPhase, MovePhase, PokemonHealPhase, ShowAbilityPhase, StatChangePhase } from "../phases";
|
import { CommonAnimPhase, MoveEffectPhase, MovePhase, PokemonHealPhase, ShowAbilityPhase, StatChangePhase } from "../phases";
|
||||||
import { getPokemonMessage } from "../messages";
|
import { getPokemonMessage, getPokemonPrefix } from "../messages";
|
||||||
import Pokemon, { MoveResult, HitResult } from "../field/pokemon";
|
import Pokemon, { MoveResult, HitResult } from "../field/pokemon";
|
||||||
import { Stat, getStatName } from "./pokemon-stat";
|
import { Stat, getStatName } from "./pokemon-stat";
|
||||||
import { StatusEffect } from "./status-effect";
|
import { StatusEffect } from "./status-effect";
|
||||||
@ -587,7 +587,7 @@ export class SandTombTag extends DamagingTrapTag {
|
|||||||
}
|
}
|
||||||
|
|
||||||
getTrapMessage(pokemon: Pokemon): string {
|
getTrapMessage(pokemon: Pokemon): string {
|
||||||
return getPokemonMessage(pokemon.scene.getPokemonById(this.sourceId), ` became trapped\nby ${this.getMoveName()}!`);
|
return getPokemonMessage(pokemon, ` became trapped\nby ${this.getMoveName()}!`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -607,7 +607,7 @@ export class ThunderCageTag extends DamagingTrapTag {
|
|||||||
}
|
}
|
||||||
|
|
||||||
getTrapMessage(pokemon: Pokemon): string {
|
getTrapMessage(pokemon: Pokemon): string {
|
||||||
return getPokemonMessage(pokemon.scene.getPokemonById(this.sourceId), ` trapped the ${pokemon.name}!`);
|
return getPokemonMessage(pokemon.scene.getPokemonById(this.sourceId), ` trapped\n${getPokemonPrefix(pokemon).toLowerCase()}${pokemon.name}!`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -18,6 +18,7 @@ import { BattlerIndex } from "../battle";
|
|||||||
import { Stat } from "./pokemon-stat";
|
import { Stat } from "./pokemon-stat";
|
||||||
import { TerrainType } from "./terrain";
|
import { TerrainType } from "./terrain";
|
||||||
import { SpeciesFormChangeActiveTrigger } from "./pokemon-forms";
|
import { SpeciesFormChangeActiveTrigger } from "./pokemon-forms";
|
||||||
|
import { Species } from "./enums/species";
|
||||||
|
|
||||||
export enum MoveCategory {
|
export enum MoveCategory {
|
||||||
PHYSICAL,
|
PHYSICAL,
|
||||||
@ -521,6 +522,10 @@ export class TargetHalfHpDamageAttr extends FixedDamageAttr {
|
|||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getTargetBenefitScore(user: Pokemon, target: Pokemon, move: Move): number {
|
||||||
|
return target.getHpRatio() > 0.5 ? Math.floor(((target.getHpRatio() - 0.5) * -24) + 4) : -20;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export class MatchHpAttr extends FixedDamageAttr {
|
export class MatchHpAttr extends FixedDamageAttr {
|
||||||
@ -1828,6 +1833,18 @@ export class ThunderAccuracyAttr extends VariableAccuracyAttr {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export class ToxicAccuracyAttr extends VariableAccuracyAttr {
|
||||||
|
apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean {
|
||||||
|
if (user.isOfType(Type.POISON)) {
|
||||||
|
const accuracy = args[0] as Utils.NumberHolder;
|
||||||
|
accuracy.value = -1;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export class BlizzardAccuracyAttr extends VariableAccuracyAttr {
|
export class BlizzardAccuracyAttr extends VariableAccuracyAttr {
|
||||||
apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean {
|
apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean {
|
||||||
if (!user.scene.arena.weather?.isEffectSuppressed(user.scene)) {
|
if (!user.scene.arena.weather?.isEffectSuppressed(user.scene)) {
|
||||||
@ -1843,6 +1860,57 @@ export class BlizzardAccuracyAttr extends VariableAccuracyAttr {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export class VariableMoveTypeAttr extends MoveAttr {
|
||||||
|
apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class AuraWheelTypeAttr extends VariableMoveTypeAttr {
|
||||||
|
apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean {
|
||||||
|
if ([user.species.speciesId, user.fusionSpecies?.speciesId].includes(Species.MORPEKO)) {
|
||||||
|
const form = user.species.speciesId === Species.MORPEKO ? user.formIndex : user.fusionSpecies.formIndex;
|
||||||
|
const type = (args[0] as Utils.IntegerHolder);
|
||||||
|
|
||||||
|
switch (form) {
|
||||||
|
case 1: // Hangry Mode
|
||||||
|
type.value = Type.DARK;
|
||||||
|
break;
|
||||||
|
default: // Full Belly Mode
|
||||||
|
type.value = Type.ELECTRIC;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class RagingBullTypeAttr extends VariableMoveTypeAttr {
|
||||||
|
apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean {
|
||||||
|
if ([user.species.speciesId, user.fusionSpecies?.speciesId].includes(Species.PALDEA_TAUROS)) {
|
||||||
|
const form = user.species.speciesId === Species.PALDEA_TAUROS ? user.formIndex : user.fusionSpecies.formIndex;
|
||||||
|
const type = (args[0] as Utils.IntegerHolder);
|
||||||
|
|
||||||
|
switch (form) {
|
||||||
|
case 1: // Blaze breed
|
||||||
|
type.value = Type.FIRE;
|
||||||
|
break;
|
||||||
|
case 2: // Aqua breed
|
||||||
|
type.value = Type.WATER;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
type.value = Type.FIGHTING;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export class VariableMoveTypeMultiplierAttr extends MoveAttr {
|
export class VariableMoveTypeMultiplierAttr extends MoveAttr {
|
||||||
apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean {
|
apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean {
|
||||||
return false;
|
return false;
|
||||||
@ -1867,8 +1935,11 @@ export class NeutralDamageAgainstFlyingTypeMultiplierAttr extends VariableMoveTy
|
|||||||
export class WaterSuperEffectTypeMultiplierAttr extends VariableMoveTypeMultiplierAttr {
|
export class WaterSuperEffectTypeMultiplierAttr extends VariableMoveTypeMultiplierAttr {
|
||||||
apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean {
|
apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean {
|
||||||
const multiplier = args[0] as Utils.NumberHolder;
|
const multiplier = args[0] as Utils.NumberHolder;
|
||||||
if (target.isOfType(Type.WATER))
|
if (target.isOfType(Type.WATER)) {
|
||||||
multiplier.value *= 4; // Increased twice because initial reduction against water
|
multiplier.value *= 4; // Increased twice because initial reduction against water
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -3056,7 +3127,8 @@ export function initMoves() {
|
|||||||
.attr(ChargeAttr, ChargeAnim.DIG_CHARGING, 'dug a hole!', BattlerTagType.UNDERGROUND)
|
.attr(ChargeAttr, ChargeAnim.DIG_CHARGING, 'dug a hole!', BattlerTagType.UNDERGROUND)
|
||||||
.ignoresVirtual(),
|
.ignoresVirtual(),
|
||||||
new StatusMove(Moves.TOXIC, "Toxic", Type.POISON, 90, 10, "A move that leaves the target badly poisoned. Its poison damage worsens every turn.", -1, 0, 1)
|
new StatusMove(Moves.TOXIC, "Toxic", Type.POISON, 90, 10, "A move that leaves the target badly poisoned. Its poison damage worsens every turn.", -1, 0, 1)
|
||||||
.attr(StatusEffectAttr, StatusEffect.TOXIC),
|
.attr(StatusEffectAttr, StatusEffect.TOXIC)
|
||||||
|
.attr(ToxicAccuracyAttr),
|
||||||
new AttackMove(Moves.CONFUSION, "Confusion", Type.PSYCHIC, MoveCategory.SPECIAL, 50, 100, 25, "The target is hit by a weak telekinetic force. This may also confuse the target.", 10, 0, 1)
|
new AttackMove(Moves.CONFUSION, "Confusion", Type.PSYCHIC, MoveCategory.SPECIAL, 50, 100, 25, "The target is hit by a weak telekinetic force. This may also confuse the target.", 10, 0, 1)
|
||||||
.attr(ConfuseAttr),
|
.attr(ConfuseAttr),
|
||||||
new AttackMove(Moves.PSYCHIC, "Psychic", Type.PSYCHIC, MoveCategory.SPECIAL, 90, 100, 10, "The target is hit by a strong telekinetic force. This may also lower the target's Sp. Def stat.", 10, 0, 1)
|
new AttackMove(Moves.PSYCHIC, "Psychic", Type.PSYCHIC, MoveCategory.SPECIAL, 90, 100, 10, "The target is hit by a strong telekinetic force. This may also lower the target's Sp. Def stat.", 10, 0, 1)
|
||||||
@ -4337,7 +4409,7 @@ export function initMoves() {
|
|||||||
.makesContact(false)
|
.makesContact(false)
|
||||||
.target(MoveTarget.ALL_NEAR_ENEMIES),
|
.target(MoveTarget.ALL_NEAR_ENEMIES),
|
||||||
new AttackMove(Moves.THOUSAND_WAVES, "Thousand Waves", Type.GROUND, MoveCategory.PHYSICAL, 90, 100, 10, "The user attacks with a wave that crawls along the ground. Those it hits can't flee from battle.", -1, 0, 6)
|
new AttackMove(Moves.THOUSAND_WAVES, "Thousand Waves", Type.GROUND, MoveCategory.PHYSICAL, 90, 100, 10, "The user attacks with a wave that crawls along the ground. Those it hits can't flee from battle.", -1, 0, 6)
|
||||||
.attr(AddBattlerTagAttr, BattlerTagType.TRAPPED, false, true, 1)
|
.attr(AddBattlerTagAttr, BattlerTagType.TRAPPED, false, false, 1)
|
||||||
.makesContact(false)
|
.makesContact(false)
|
||||||
.target(MoveTarget.ALL_NEAR_ENEMIES),
|
.target(MoveTarget.ALL_NEAR_ENEMIES),
|
||||||
new AttackMove(Moves.LANDS_WRATH, "Land's Wrath", Type.GROUND, MoveCategory.PHYSICAL, 90, 100, 10, "The user gathers the energy of the land and focuses that power on opposing Pokémon to damage them.", -1, 0, 6)
|
new AttackMove(Moves.LANDS_WRATH, "Land's Wrath", Type.GROUND, MoveCategory.PHYSICAL, 90, 100, 10, "The user gathers the energy of the land and focuses that power on opposing Pokémon to damage them.", -1, 0, 6)
|
||||||
@ -4660,9 +4732,11 @@ export function initMoves() {
|
|||||||
new AttackMove(Moves.BEHEMOTH_BLADE, "Behemoth Blade", Type.STEEL, MoveCategory.PHYSICAL, 100, 100, 5, "The user wields a large, powerful sword using its whole body and cuts the target in a vigorous attack.", -1, 0, 8)
|
new AttackMove(Moves.BEHEMOTH_BLADE, "Behemoth Blade", Type.STEEL, MoveCategory.PHYSICAL, 100, 100, 5, "The user wields a large, powerful sword using its whole body and cuts the target in a vigorous attack.", -1, 0, 8)
|
||||||
.slicingMove(),
|
.slicingMove(),
|
||||||
new AttackMove(Moves.BEHEMOTH_BASH, "Behemoth Bash", Type.STEEL, MoveCategory.PHYSICAL, 100, 100, 5, "The user's body becomes a firm shield and slams into the target fiercely.", -1, 0, 8),
|
new AttackMove(Moves.BEHEMOTH_BASH, "Behemoth Bash", Type.STEEL, MoveCategory.PHYSICAL, 100, 100, 5, "The user's body becomes a firm shield and slams into the target fiercely.", -1, 0, 8),
|
||||||
new AttackMove(Moves.AURA_WHEEL, "Aura Wheel (P)", Type.ELECTRIC, MoveCategory.PHYSICAL, 110, 100, 10, "Morpeko attacks and raises its Speed with the energy stored in its cheeks. This move's type changes depending on the user's form.", 100, 0, 8)
|
new AttackMove(Moves.AURA_WHEEL, "Aura Wheel", Type.ELECTRIC, MoveCategory.PHYSICAL, 110, 100, 10, "Morpeko attacks and raises its Speed with the energy stored in its cheeks. This move's type changes depending on the user's form.", 100, 0, 8)
|
||||||
.attr(StatChangeAttr, BattleStat.SPD, 1, true)
|
.attr(StatChangeAttr, BattleStat.SPD, 1, true)
|
||||||
.makesContact(false),
|
.makesContact(false)
|
||||||
|
.attr(AuraWheelTypeAttr)
|
||||||
|
.condition((user, target, move) => [user.species.speciesId, user.fusionSpecies?.speciesId].includes(Species.MORPEKO)), // Missing custom fail message
|
||||||
new AttackMove(Moves.BREAKING_SWIPE, "Breaking Swipe", Type.DRAGON, MoveCategory.PHYSICAL, 60, 100, 15, "The user swings its tough tail wildly and attacks opposing Pokémon. This also lowers their Attack stats.", 100, 0, 8)
|
new AttackMove(Moves.BREAKING_SWIPE, "Breaking Swipe", Type.DRAGON, MoveCategory.PHYSICAL, 60, 100, 15, "The user swings its tough tail wildly and attacks opposing Pokémon. This also lowers their Attack stats.", 100, 0, 8)
|
||||||
.target(MoveTarget.ALL_NEAR_ENEMIES)
|
.target(MoveTarget.ALL_NEAR_ENEMIES)
|
||||||
.attr(StatChangeAttr, BattleStat.ATK, -1),
|
.attr(StatChangeAttr, BattleStat.ATK, -1),
|
||||||
@ -4955,7 +5029,8 @@ export function initMoves() {
|
|||||||
new AttackMove(Moves.AQUA_STEP, "Aqua Step", Type.WATER, MoveCategory.PHYSICAL, 80, 100, 10, "The user toys with the target and attacks it using light and fluid dance steps. This also boosts the user's Speed stat.", 100, 0, 9)
|
new AttackMove(Moves.AQUA_STEP, "Aqua Step", Type.WATER, MoveCategory.PHYSICAL, 80, 100, 10, "The user toys with the target and attacks it using light and fluid dance steps. This also boosts the user's Speed stat.", 100, 0, 9)
|
||||||
.attr(StatChangeAttr, BattleStat.SPD, 1, true)
|
.attr(StatChangeAttr, BattleStat.SPD, 1, true)
|
||||||
.danceMove(),
|
.danceMove(),
|
||||||
new AttackMove(Moves.RAGING_BULL, "Raging Bull (P)", Type.NORMAL, MoveCategory.PHYSICAL, 90, 100, 10, "The user performs a tackle like a raging bull. This move's type depends on the user's form. It can also break barriers, such as Light Screen and Reflect.", -1, 0, 9),
|
new AttackMove(Moves.RAGING_BULL, "Raging Bull (P)", Type.NORMAL, MoveCategory.PHYSICAL, 90, 100, 10, "The user performs a tackle like a raging bull. This move's type depends on the user's form. It can also break barriers, such as Light Screen and Reflect.", -1, 0, 9)
|
||||||
|
.attr(RagingBullTypeAttr),
|
||||||
new AttackMove(Moves.MAKE_IT_RAIN, "Make It Rain", Type.STEEL, MoveCategory.SPECIAL, 120, 100, 5, "The user attacks by throwing out a mass of coins. This also lowers the user's Sp. Atk stat. Money is earned after the battle.", -1, 0, 9)
|
new AttackMove(Moves.MAKE_IT_RAIN, "Make It Rain", Type.STEEL, MoveCategory.SPECIAL, 120, 100, 5, "The user attacks by throwing out a mass of coins. This also lowers the user's Sp. Atk stat. Money is earned after the battle.", -1, 0, 9)
|
||||||
.attr(MoneyAttr)
|
.attr(MoneyAttr)
|
||||||
.attr(StatChangeAttr, BattleStat.SPATK, -1, true, null, true, true)
|
.attr(StatChangeAttr, BattleStat.SPATK, -1, true, null, true, true)
|
||||||
|
@ -1553,7 +1553,7 @@ export const pokemonEvolutions: PokemonEvolutions = {
|
|||||||
new SpeciesEvolution(Species.BLISSEY, 1, null, new SpeciesFriendshipEvolutionCondition(200), SpeciesWildEvolutionDelay.LONG)
|
new SpeciesEvolution(Species.BLISSEY, 1, null, new SpeciesFriendshipEvolutionCondition(200), SpeciesWildEvolutionDelay.LONG)
|
||||||
],
|
],
|
||||||
[Species.PICHU]: [
|
[Species.PICHU]: [
|
||||||
new SpeciesEvolution(Species.PIKACHU, 1, null, new SpeciesFriendshipEvolutionCondition(70), SpeciesWildEvolutionDelay.SHORT)
|
new SpeciesEvolution(Species.PIKACHU, 1, null, new SpeciesFriendshipEvolutionCondition(90), SpeciesWildEvolutionDelay.SHORT)
|
||||||
],
|
],
|
||||||
[Species.CLEFFA]: [
|
[Species.CLEFFA]: [
|
||||||
new SpeciesEvolution(Species.CLEFAIRY, 1, null, new SpeciesFriendshipEvolutionCondition(160), SpeciesWildEvolutionDelay.SHORT)
|
new SpeciesEvolution(Species.CLEFAIRY, 1, null, new SpeciesFriendshipEvolutionCondition(160), SpeciesWildEvolutionDelay.SHORT)
|
||||||
|
@ -922,7 +922,10 @@ export function initSpecies() {
|
|||||||
new PokemonSpecies(Species.CROBAT, "Crobat", 2, false, false, false, "Bat Pokémon", Type.POISON, Type.FLYING, 1.8, 75, Abilities.INNER_FOCUS, Abilities.NONE, Abilities.INFILTRATOR, 535, 85, 90, 80, 70, 80, 130, 90, 50, 268, GrowthRate.MEDIUM_FAST, 50, false),
|
new PokemonSpecies(Species.CROBAT, "Crobat", 2, false, false, false, "Bat Pokémon", Type.POISON, Type.FLYING, 1.8, 75, Abilities.INNER_FOCUS, Abilities.NONE, Abilities.INFILTRATOR, 535, 85, 90, 80, 70, 80, 130, 90, 50, 268, GrowthRate.MEDIUM_FAST, 50, false),
|
||||||
new PokemonSpecies(Species.CHINCHOU, "Chinchou", 2, false, false, false, "Angler Pokémon", Type.WATER, Type.ELECTRIC, 0.5, 12, Abilities.VOLT_ABSORB, Abilities.ILLUMINATE, Abilities.WATER_ABSORB, 330, 75, 38, 38, 56, 56, 67, 190, 50, 66, GrowthRate.SLOW, 50, false),
|
new PokemonSpecies(Species.CHINCHOU, "Chinchou", 2, false, false, false, "Angler Pokémon", Type.WATER, Type.ELECTRIC, 0.5, 12, Abilities.VOLT_ABSORB, Abilities.ILLUMINATE, Abilities.WATER_ABSORB, 330, 75, 38, 38, 56, 56, 67, 190, 50, 66, GrowthRate.SLOW, 50, false),
|
||||||
new PokemonSpecies(Species.LANTURN, "Lanturn", 2, false, false, false, "Light Pokémon", Type.WATER, Type.ELECTRIC, 1.2, 22.5, Abilities.VOLT_ABSORB, Abilities.ILLUMINATE, Abilities.WATER_ABSORB, 460, 125, 58, 58, 76, 76, 67, 75, 50, 161, GrowthRate.SLOW, 50, false),
|
new PokemonSpecies(Species.LANTURN, "Lanturn", 2, false, false, false, "Light Pokémon", Type.WATER, Type.ELECTRIC, 1.2, 22.5, Abilities.VOLT_ABSORB, Abilities.ILLUMINATE, Abilities.WATER_ABSORB, 460, 125, 58, 58, 76, 76, 67, 75, 50, 161, GrowthRate.SLOW, 50, false),
|
||||||
new PokemonSpecies(Species.PICHU, "Pichu", 2, false, false, false, "Tiny Mouse Pokémon", Type.ELECTRIC, null, 0.3, 2, Abilities.STATIC, Abilities.NONE, Abilities.LIGHTNING_ROD, 205, 20, 40, 15, 35, 35, 60, 190, 50, 41, GrowthRate.MEDIUM_FAST, 50, false),
|
new PokemonSpecies(Species.PICHU, "Pichu", 2, false, false, false, "Tiny Mouse Pokémon", Type.ELECTRIC, null, 0.3, 2, Abilities.STATIC, Abilities.NONE, Abilities.LIGHTNING_ROD, 205, 20, 40, 15, 35, 35, 60, 190, 70, 41, GrowthRate.MEDIUM_FAST, 50, false, false,
|
||||||
|
new PokemonForm("Normal", "", Type.ELECTRIC, null, 1.4, 61.5, Abilities.STATIC, Abilities.NONE, Abilities.LIGHTNING_ROD, 205, 20, 40, 15, 35, 35, 60, 190, 70, 41),
|
||||||
|
new PokemonForm("Spiky-Eared", "spiky", Type.ELECTRIC, null, 1.4, 61.5, Abilities.STATIC, Abilities.NONE, Abilities.LIGHTNING_ROD, 205, 20, 40, 15, 35, 35, 60, 190, 70, 41),
|
||||||
|
),
|
||||||
new PokemonSpecies(Species.CLEFFA, "Cleffa", 2, false, false, false, "Star Shape Pokémon", Type.FAIRY, null, 0.3, 3, Abilities.CUTE_CHARM, Abilities.MAGIC_GUARD, Abilities.FRIEND_GUARD, 218, 50, 25, 28, 45, 55, 15, 150, 140, 44, GrowthRate.FAST, 25, false),
|
new PokemonSpecies(Species.CLEFFA, "Cleffa", 2, false, false, false, "Star Shape Pokémon", Type.FAIRY, null, 0.3, 3, Abilities.CUTE_CHARM, Abilities.MAGIC_GUARD, Abilities.FRIEND_GUARD, 218, 50, 25, 28, 45, 55, 15, 150, 140, 44, GrowthRate.FAST, 25, false),
|
||||||
new PokemonSpecies(Species.IGGLYBUFF, "Igglybuff", 2, false, false, false, "Balloon Pokémon", Type.NORMAL, Type.FAIRY, 0.3, 1, Abilities.CUTE_CHARM, Abilities.COMPETITIVE, Abilities.FRIEND_GUARD, 210, 90, 30, 15, 40, 20, 15, 170, 50, 42, GrowthRate.FAST, 25, false),
|
new PokemonSpecies(Species.IGGLYBUFF, "Igglybuff", 2, false, false, false, "Balloon Pokémon", Type.NORMAL, Type.FAIRY, 0.3, 1, Abilities.CUTE_CHARM, Abilities.COMPETITIVE, Abilities.FRIEND_GUARD, 210, 90, 30, 15, 40, 20, 15, 170, 50, 42, GrowthRate.FAST, 25, false),
|
||||||
new PokemonSpecies(Species.TOGEPI, "Togepi", 2, false, false, false, "Spike Ball Pokémon", Type.FAIRY, null, 0.3, 1.5, Abilities.HUSTLE, Abilities.SERENE_GRACE, Abilities.SUPER_LUCK, 245, 35, 20, 65, 40, 65, 20, 190, 50, 49, GrowthRate.FAST, 87.5, false),
|
new PokemonSpecies(Species.TOGEPI, "Togepi", 2, false, false, false, "Spike Ball Pokémon", Type.FAIRY, null, 0.3, 1.5, Abilities.HUSTLE, Abilities.SERENE_GRACE, Abilities.SUPER_LUCK, 245, 35, 20, 65, 40, 65, 20, 190, 50, 49, GrowthRate.FAST, 87.5, false),
|
||||||
@ -2179,7 +2182,7 @@ export function initSpecies() {
|
|||||||
new PokemonSpecies(Species.REGIDRAGO, "Regidrago", 8, true, false, false, "Dragon Orb Pokémon", Type.DRAGON, null, 2.1, 200, Abilities.DRAGONS_MAW, Abilities.NONE, Abilities.NONE, 580, 200, 100, 50, 100, 50, 80, 3, 35, 290, GrowthRate.SLOW, null, false),
|
new PokemonSpecies(Species.REGIDRAGO, "Regidrago", 8, true, false, false, "Dragon Orb Pokémon", Type.DRAGON, null, 2.1, 200, Abilities.DRAGONS_MAW, Abilities.NONE, Abilities.NONE, 580, 200, 100, 50, 100, 50, 80, 3, 35, 290, GrowthRate.SLOW, null, false),
|
||||||
new PokemonSpecies(Species.GLASTRIER, "Glastrier", 8, true, false, false, "Wild Horse Pokémon", Type.ICE, null, 2.2, 800, Abilities.CHILLING_NEIGH, Abilities.NONE, Abilities.NONE, 580, 100, 145, 130, 65, 110, 30, 3, 35, 290, GrowthRate.SLOW, null, false),
|
new PokemonSpecies(Species.GLASTRIER, "Glastrier", 8, true, false, false, "Wild Horse Pokémon", Type.ICE, null, 2.2, 800, Abilities.CHILLING_NEIGH, Abilities.NONE, Abilities.NONE, 580, 100, 145, 130, 65, 110, 30, 3, 35, 290, GrowthRate.SLOW, null, false),
|
||||||
new PokemonSpecies(Species.SPECTRIER, "Spectrier", 8, true, false, false, "Swift Horse Pokémon", Type.GHOST, null, 2, 44.5, Abilities.GRIM_NEIGH, Abilities.NONE, Abilities.NONE, 580, 100, 65, 60, 145, 80, 130, 3, 35, 290, GrowthRate.SLOW, null, false),
|
new PokemonSpecies(Species.SPECTRIER, "Spectrier", 8, true, false, false, "Swift Horse Pokémon", Type.GHOST, null, 2, 44.5, Abilities.GRIM_NEIGH, Abilities.NONE, Abilities.NONE, 580, 100, 65, 60, 145, 80, 130, 3, 35, 290, GrowthRate.SLOW, null, false),
|
||||||
new PokemonSpecies(Species.CALYREX, "Calyrex", 8, true, false, false, "King Pokémon", Type.PSYCHIC, Type.GRASS, 1.1, 7.7, Abilities.UNNERVE, Abilities.NONE, Abilities.NONE, 500, 100, 80, 80, 80, 80, 80, 3, 100, 250, GrowthRate.SLOW, null, false, false,
|
new PokemonSpecies(Species.CALYREX, "Calyrex", 8, true, false, false, "King Pokémon", Type.PSYCHIC, Type.GRASS, 1.1, 7.7, Abilities.UNNERVE, Abilities.NONE, Abilities.NONE, 500, 100, 80, 80, 80, 80, 80, 3, 100, 250, GrowthRate.SLOW, null, false, true,
|
||||||
new PokemonForm("Normal", "", Type.PSYCHIC, Type.GRASS, 1.1, 7.7, Abilities.UNNERVE, Abilities.NONE, Abilities.NONE, 500, 100, 80, 80, 80, 80, 80, 3, 100, 250),
|
new PokemonForm("Normal", "", Type.PSYCHIC, Type.GRASS, 1.1, 7.7, Abilities.UNNERVE, Abilities.NONE, Abilities.NONE, 500, 100, 80, 80, 80, 80, 80, 3, 100, 250),
|
||||||
new PokemonForm("Ice", "ice", Type.PSYCHIC, Type.ICE, 2.4, 809.1, Abilities.AS_ONE_GLASTRIER, Abilities.NONE, Abilities.NONE, 680, 100, 165, 150, 85, 130, 50, 3, 100, 250),
|
new PokemonForm("Ice", "ice", Type.PSYCHIC, Type.ICE, 2.4, 809.1, Abilities.AS_ONE_GLASTRIER, Abilities.NONE, Abilities.NONE, 680, 100, 165, 150, 85, 130, 50, 3, 100, 250),
|
||||||
new PokemonForm("Shadow", "shadow", Type.PSYCHIC, Type.GHOST, 2.4, 53.6, Abilities.AS_ONE_SPECTRIER, Abilities.NONE, Abilities.NONE, 680, 100, 85, 80, 165, 100, 150, 3, 100, 250),
|
new PokemonForm("Shadow", "shadow", Type.PSYCHIC, Type.GHOST, 2.4, 53.6, Abilities.AS_ONE_SPECTRIER, Abilities.NONE, Abilities.NONE, 680, 100, 85, 80, 165, 100, 150, 3, 100, 250),
|
||||||
|
@ -27,6 +27,7 @@ splashMessages.push(...[
|
|||||||
'Mostly Consistent Seeds!',
|
'Mostly Consistent Seeds!',
|
||||||
'Achievement Points Don\'t Do Anything!',
|
'Achievement Points Don\'t Do Anything!',
|
||||||
'You Do Not Start at Level 2000!',
|
'You Do Not Start at Level 2000!',
|
||||||
|
'Don\'t Talk About the Manaphy Egg Incident!',
|
||||||
'Also Try Pokéngine!',
|
'Also Try Pokéngine!',
|
||||||
'Also Try Emerald Rogue!',
|
'Also Try Emerald Rogue!',
|
||||||
'Also Try Radical Red!',
|
'Also Try Radical Red!',
|
||||||
|
1749
src/data/tms.ts
@ -2,7 +2,7 @@ import Phaser from 'phaser';
|
|||||||
import BattleScene, { ABILITY_OVERRIDE, AnySound, MOVE_OVERRIDE, OPP_ABILITY_OVERRIDE, OPP_MOVE_OVERRIDE } from '../battle-scene';
|
import BattleScene, { ABILITY_OVERRIDE, AnySound, MOVE_OVERRIDE, OPP_ABILITY_OVERRIDE, OPP_MOVE_OVERRIDE } from '../battle-scene';
|
||||||
import BattleInfo, { PlayerBattleInfo, EnemyBattleInfo } from '../ui/battle-info';
|
import BattleInfo, { PlayerBattleInfo, EnemyBattleInfo } from '../ui/battle-info';
|
||||||
import { Moves } from "../data/enums/moves";
|
import { Moves } from "../data/enums/moves";
|
||||||
import Move, { HighCritAttr, HitsTagAttr, applyMoveAttrs, FixedDamageAttr, VariableAtkAttr, VariablePowerAttr, allMoves, MoveCategory, TypelessAttr, CritOnlyAttr, getMoveTargets, OneHitKOAttr, MultiHitAttr, StatusMoveTypeImmunityAttr, MoveTarget, VariableDefAttr, AttackMove, ModifiedDamageAttr, VariableMoveTypeMultiplierAttr, IgnoreOpponentStatChangesAttr, SacrificialAttr } from "../data/move";
|
import Move, { HighCritAttr, HitsTagAttr, applyMoveAttrs, FixedDamageAttr, VariableAtkAttr, VariablePowerAttr, allMoves, MoveCategory, TypelessAttr, CritOnlyAttr, getMoveTargets, OneHitKOAttr, MultiHitAttr, StatusMoveTypeImmunityAttr, MoveTarget, VariableDefAttr, AttackMove, ModifiedDamageAttr, VariableMoveTypeMultiplierAttr, IgnoreOpponentStatChangesAttr, SacrificialAttr, VariableMoveTypeAttr } from "../data/move";
|
||||||
import { default as PokemonSpecies, PokemonSpeciesForm, SpeciesFormKey, getFusedSpeciesName, getPokemonSpecies, getPokemonSpeciesForm } from '../data/pokemon-species';
|
import { default as PokemonSpecies, PokemonSpeciesForm, SpeciesFormKey, getFusedSpeciesName, getPokemonSpecies, getPokemonSpeciesForm } from '../data/pokemon-species';
|
||||||
import * as Utils from '../utils';
|
import * as Utils from '../utils';
|
||||||
import { Type, TypeDamageMultiplier, getTypeDamageMultiplier, getTypeRgb } from '../data/type';
|
import { Type, TypeDamageMultiplier, getTypeDamageMultiplier, getTypeRgb } from '../data/type';
|
||||||
@ -1088,6 +1088,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
|||||||
|
|
||||||
const variableType = new Utils.IntegerHolder(move.type);
|
const variableType = new Utils.IntegerHolder(move.type);
|
||||||
const typeChangeMovePowerMultiplier = new Utils.NumberHolder(1);
|
const typeChangeMovePowerMultiplier = new Utils.NumberHolder(1);
|
||||||
|
applyMoveAttrs(VariableMoveTypeAttr, source, this, move, variableType);
|
||||||
// 2nd argument is for MoveTypeChangePowerMultiplierAbAttr
|
// 2nd argument is for MoveTypeChangePowerMultiplierAbAttr
|
||||||
applyAbAttrs(VariableMoveTypeAbAttr, source, null, variableType, typeChangeMovePowerMultiplier);
|
applyAbAttrs(VariableMoveTypeAbAttr, source, null, variableType, typeChangeMovePowerMultiplier);
|
||||||
const type = variableType.value as Type;
|
const type = variableType.value as Type;
|
||||||
|
@ -129,6 +129,9 @@ export class LoadingScene extends SceneBase {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Load bitmap fonts
|
||||||
|
this.load.bitmapFont('item-count', 'fonts/item-count.png', 'fonts/item-count.xml');
|
||||||
|
|
||||||
// Load trainer images
|
// Load trainer images
|
||||||
this.loadAtlas('trainer_m_back', 'trainer');
|
this.loadAtlas('trainer_m_back', 'trainer');
|
||||||
this.loadAtlas('trainer_m_back_pb', 'trainer');
|
this.loadAtlas('trainer_m_back_pb', 'trainer');
|
||||||
|
@ -2,6 +2,10 @@ import { BattleSpec } from "./enums/battle-spec";
|
|||||||
import Pokemon from "./field/pokemon";
|
import Pokemon from "./field/pokemon";
|
||||||
|
|
||||||
export function getPokemonMessage(pokemon: Pokemon, content: string): string {
|
export function getPokemonMessage(pokemon: Pokemon, content: string): string {
|
||||||
|
return `${getPokemonPrefix(pokemon)}${pokemon.name}${content}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getPokemonPrefix(pokemon: Pokemon): string {
|
||||||
let prefix: string;
|
let prefix: string;
|
||||||
switch (pokemon.scene.currentBattle.battleSpec) {
|
switch (pokemon.scene.currentBattle.battleSpec) {
|
||||||
case BattleSpec.DEFAULT:
|
case BattleSpec.DEFAULT:
|
||||||
@ -11,5 +15,5 @@ export function getPokemonMessage(pokemon: Pokemon, content: string): string {
|
|||||||
prefix = !pokemon.isPlayer() ? 'Foe ' : '';
|
prefix = !pokemon.isPlayer() ? 'Foe ' : '';
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return `${prefix}${pokemon.name}${content}`;
|
return prefix;
|
||||||
}
|
}
|
@ -183,26 +183,14 @@ export abstract class PersistentModifier extends Modifier {
|
|||||||
return container;
|
return container;
|
||||||
}
|
}
|
||||||
|
|
||||||
getIconStackText(scene: BattleScene, virtual?: boolean): Phaser.GameObjects.Text {
|
getIconStackText(scene: BattleScene, virtual?: boolean): Phaser.GameObjects.BitmapText {
|
||||||
if (this.getMaxStackCount(scene) === 1 || (virtual && !this.virtualStackCount))
|
if (this.getMaxStackCount(scene) === 1 || (virtual && !this.virtualStackCount))
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
const isStackMax = this.getStackCount() >= this.getMaxStackCount(scene);
|
const text = scene.add.bitmapText(10, 15, 'item-count', this.stackCount.toString(), 11);
|
||||||
const maxColor = '#f89890';
|
text.letterSpacing = -0.5;
|
||||||
const maxStrokeColor = '#984038';
|
if (this.getStackCount() >= this.getMaxStackCount(scene))
|
||||||
|
text.setTint(0xf89890)
|
||||||
if (virtual) {
|
|
||||||
const virtualText = addTextObject(scene, 27, 12, `+${this.virtualStackCount.toString()}`, TextStyle.PARTY, { fontSize: '66px', color: !isStackMax ? '#40c8f8' : maxColor });
|
|
||||||
virtualText.setShadow(0, 0, null);
|
|
||||||
virtualText.setStroke(!isStackMax ? '#006090' : maxStrokeColor, 16)
|
|
||||||
virtualText.setOrigin(1, 0);
|
|
||||||
|
|
||||||
return virtualText;
|
|
||||||
}
|
|
||||||
|
|
||||||
const text = addTextObject(scene, 8, 12, this.stackCount.toString(), TextStyle.PARTY, { fontSize: '66px', color: !isStackMax ? '#f8f8f8' : maxColor });
|
|
||||||
text.setShadow(0, 0, null);
|
|
||||||
text.setStroke('#424242', 16);
|
|
||||||
text.setOrigin(0, 0);
|
text.setOrigin(0, 0);
|
||||||
|
|
||||||
return text;
|
return text;
|
||||||
@ -1772,7 +1760,7 @@ export abstract class HeldItemTransferModifier extends PokemonHeldItemModifier {
|
|||||||
}
|
}
|
||||||
const randItemIndex = pokemon.randSeedInt(itemModifiers.length);
|
const randItemIndex = pokemon.randSeedInt(itemModifiers.length);
|
||||||
const randItem = itemModifiers[randItemIndex];
|
const randItem = itemModifiers[randItemIndex];
|
||||||
heldItemTransferPromises.push(pokemon.scene.tryTransferHeldItemModifier(randItem, pokemon, false, false, true).then(success => {
|
heldItemTransferPromises.push(pokemon.scene.tryTransferHeldItemModifier(randItem, pokemon, false, false).then(success => {
|
||||||
if (success) {
|
if (success) {
|
||||||
transferredModifierTypes.push(randItem.type);
|
transferredModifierTypes.push(randItem.type);
|
||||||
itemModifiers.splice(randItemIndex, 1);
|
itemModifiers.splice(randItemIndex, 1);
|
||||||
|
@ -9,6 +9,8 @@ export class Phase {
|
|||||||
|
|
||||||
start() {
|
start() {
|
||||||
console.log(`%cStart Phase ${this.constructor.name}`, 'color:green;');
|
console.log(`%cStart Phase ${this.constructor.name}`, 'color:green;');
|
||||||
|
if (this.scene.abilityBar.shown)
|
||||||
|
this.scene.abilityBar.resetAutoHideTimer();
|
||||||
}
|
}
|
||||||
|
|
||||||
end() {
|
end() {
|
||||||
|
@ -2540,7 +2540,7 @@ export class StatChangePhase extends PokemonPhase {
|
|||||||
this.end();
|
this.end();
|
||||||
};
|
};
|
||||||
|
|
||||||
if (relLevels.filter(l => l).length) {
|
if (relLevels.filter(l => l).length && this.scene.moveAnimations) {
|
||||||
pokemon.enableMask();
|
pokemon.enableMask();
|
||||||
const pokemonMaskSprite = pokemon.maskSprite;
|
const pokemonMaskSprite = pokemon.maskSprite;
|
||||||
|
|
||||||
|
@ -14,7 +14,9 @@ export enum Setting {
|
|||||||
Tutorials = "TUTORIALS",
|
Tutorials = "TUTORIALS",
|
||||||
Enable_Retries = "ENABLE_RETRIES",
|
Enable_Retries = "ENABLE_RETRIES",
|
||||||
Sprite_Set = "SPRITE_SET",
|
Sprite_Set = "SPRITE_SET",
|
||||||
|
Move_Animations = "MOVE_ANIMATIONS",
|
||||||
Show_Stats_on_Level_Up = "SHOW_LEVEL_UP_STATS",
|
Show_Stats_on_Level_Up = "SHOW_LEVEL_UP_STATS",
|
||||||
|
HP_Bar_Speed = "HP_BAR_SPEED",
|
||||||
Fusion_Palette_Swaps = "FUSION_PALETTE_SWAPS",
|
Fusion_Palette_Swaps = "FUSION_PALETTE_SWAPS",
|
||||||
Player_Gender = "PLAYER_GENDER",
|
Player_Gender = "PLAYER_GENDER",
|
||||||
Touch_Controls = "TOUCH_CONTROLS",
|
Touch_Controls = "TOUCH_CONTROLS",
|
||||||
@ -40,7 +42,9 @@ export const settingOptions: SettingOptions = {
|
|||||||
[Setting.Tutorials]: [ 'Off', 'On' ],
|
[Setting.Tutorials]: [ 'Off', 'On' ],
|
||||||
[Setting.Enable_Retries]: [ 'Off', 'On' ],
|
[Setting.Enable_Retries]: [ 'Off', 'On' ],
|
||||||
[Setting.Sprite_Set]: [ 'Consistent', 'Prioritize Animation' ],
|
[Setting.Sprite_Set]: [ 'Consistent', 'Prioritize Animation' ],
|
||||||
|
[Setting.Move_Animations]: [ 'Off', 'On' ],
|
||||||
[Setting.Show_Stats_on_Level_Up]: [ 'Off', 'On' ],
|
[Setting.Show_Stats_on_Level_Up]: [ 'Off', 'On' ],
|
||||||
|
[Setting.HP_Bar_Speed]: [ 'Normal', 'Fast', 'Faster', 'Instant' ],
|
||||||
[Setting.Fusion_Palette_Swaps]: [ 'Off', 'On' ],
|
[Setting.Fusion_Palette_Swaps]: [ 'Off', 'On' ],
|
||||||
[Setting.Player_Gender]: [ 'Boy', 'Girl' ],
|
[Setting.Player_Gender]: [ 'Boy', 'Girl' ],
|
||||||
[Setting.Touch_Controls]: [ 'Auto', 'Disabled' ],
|
[Setting.Touch_Controls]: [ 'Auto', 'Disabled' ],
|
||||||
@ -58,7 +62,9 @@ export const settingDefaults: SettingDefaults = {
|
|||||||
[Setting.Tutorials]: 1,
|
[Setting.Tutorials]: 1,
|
||||||
[Setting.Enable_Retries]: 0,
|
[Setting.Enable_Retries]: 0,
|
||||||
[Setting.Sprite_Set]: 0,
|
[Setting.Sprite_Set]: 0,
|
||||||
|
[Setting.Move_Animations]: 1,
|
||||||
[Setting.Show_Stats_on_Level_Up]: 1,
|
[Setting.Show_Stats_on_Level_Up]: 1,
|
||||||
|
[Setting.HP_Bar_Speed]: 0,
|
||||||
[Setting.Fusion_Palette_Swaps]: 1,
|
[Setting.Fusion_Palette_Swaps]: 1,
|
||||||
[Setting.Player_Gender]: 0,
|
[Setting.Player_Gender]: 0,
|
||||||
[Setting.Touch_Controls]: 0,
|
[Setting.Touch_Controls]: 0,
|
||||||
@ -104,9 +110,15 @@ export function setSetting(scene: BattleScene, setting: Setting, value: integer)
|
|||||||
if (value)
|
if (value)
|
||||||
scene.initExpSprites();
|
scene.initExpSprites();
|
||||||
break;
|
break;
|
||||||
|
case Setting.Move_Animations:
|
||||||
|
scene.moveAnimations = settingOptions[setting][value] === 'On';
|
||||||
|
break;
|
||||||
case Setting.Show_Stats_on_Level_Up:
|
case Setting.Show_Stats_on_Level_Up:
|
||||||
scene.showLevelUpStats = settingOptions[setting][value] === 'On';
|
scene.showLevelUpStats = settingOptions[setting][value] === 'On';
|
||||||
break;
|
break;
|
||||||
|
case Setting.HP_Bar_Speed:
|
||||||
|
scene.hpBarSpeed = value;
|
||||||
|
break;
|
||||||
case Setting.Fusion_Palette_Swaps:
|
case Setting.Fusion_Palette_Swaps:
|
||||||
scene.fusionPaletteSwaps = !!value;
|
scene.fusionPaletteSwaps = !!value;
|
||||||
break;
|
break;
|
||||||
|
@ -12,6 +12,7 @@ export default class AbilityBar extends Phaser.GameObjects.Container {
|
|||||||
private abilityNameText: Phaser.GameObjects.Text;
|
private abilityNameText: Phaser.GameObjects.Text;
|
||||||
|
|
||||||
private tween: Phaser.Tweens.Tween;
|
private tween: Phaser.Tweens.Tween;
|
||||||
|
private autoHideTimer: number;
|
||||||
|
|
||||||
public shown: boolean;
|
public shown: boolean;
|
||||||
|
|
||||||
@ -55,7 +56,10 @@ export default class AbilityBar extends Phaser.GameObjects.Container {
|
|||||||
x: shownX,
|
x: shownX,
|
||||||
duration: 500,
|
duration: 500,
|
||||||
ease: 'Sine.easeOut',
|
ease: 'Sine.easeOut',
|
||||||
onComplete: () => this.tween = null
|
onComplete: () => {
|
||||||
|
this.tween = null;
|
||||||
|
this.resetAutoHideTimer();
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
this.setVisible(true);
|
this.setVisible(true);
|
||||||
@ -66,6 +70,9 @@ export default class AbilityBar extends Phaser.GameObjects.Container {
|
|||||||
if (!this.shown)
|
if (!this.shown)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (this.autoHideTimer)
|
||||||
|
clearInterval(this.autoHideTimer);
|
||||||
|
|
||||||
if (this.tween)
|
if (this.tween)
|
||||||
this.tween.stop();
|
this.tween.stop();
|
||||||
|
|
||||||
@ -82,4 +89,13 @@ export default class AbilityBar extends Phaser.GameObjects.Container {
|
|||||||
|
|
||||||
this.shown = false;
|
this.shown = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
resetAutoHideTimer(): void {
|
||||||
|
if (this.autoHideTimer)
|
||||||
|
clearInterval(this.autoHideTimer);
|
||||||
|
this.autoHideTimer = setTimeout(() => {
|
||||||
|
this.hide();
|
||||||
|
this.autoHideTimer = null;
|
||||||
|
}, 2500);
|
||||||
|
}
|
||||||
}
|
}
|
@ -349,7 +349,10 @@ export default class BattleInfo extends Phaser.GameObjects.Container {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const updatePokemonHp = () => {
|
const updatePokemonHp = () => {
|
||||||
const duration = !instant ? Utils.clampInt(Math.abs((this.lastHp) - pokemon.hp) * 5, 250, 5000) : 0;
|
let duration = !instant ? Utils.clampInt(Math.abs((this.lastHp) - pokemon.hp) * 5, 250, 5000) : 0;
|
||||||
|
const speed = (this.scene as BattleScene).hpBarSpeed;
|
||||||
|
if (speed)
|
||||||
|
duration = speed >= 3 ? 0 : duration / Math.pow(2, speed);
|
||||||
this.scene.tweens.add({
|
this.scene.tweens.add({
|
||||||
targets: this.hpBar,
|
targets: this.hpBar,
|
||||||
ease: 'Sine.easeOut',
|
ease: 'Sine.easeOut',
|
||||||
|
@ -638,7 +638,7 @@ export default class StarterSelectUiHandler extends MessageUiHandler {
|
|||||||
return {
|
return {
|
||||||
label: allMoves[sm].name,
|
label: allMoves[sm].name,
|
||||||
handler: () => {
|
handler: () => {
|
||||||
this.swichMoveHandler(i, sm, m)
|
this.switchMoveHandler(i, sm, m)
|
||||||
showSwapOptions(this.starterMoveset);
|
showSwapOptions(this.starterMoveset);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -787,7 +787,7 @@ export default class StarterSelectUiHandler extends MessageUiHandler {
|
|||||||
return success || error;
|
return success || error;
|
||||||
}
|
}
|
||||||
|
|
||||||
swichMoveHandler(i: number, newMove: Moves, move: Moves) {
|
switchMoveHandler(i: number, newMove: Moves, move: Moves) {
|
||||||
const speciesId = this.lastSpecies.speciesId;
|
const speciesId = this.lastSpecies.speciesId;
|
||||||
const existingMoveIndex = this.starterMoveset.indexOf(newMove);
|
const existingMoveIndex = this.starterMoveset.indexOf(newMove);
|
||||||
this.starterMoveset[i] = newMove;
|
this.starterMoveset[i] = newMove;
|
||||||
@ -796,17 +796,17 @@ export default class StarterSelectUiHandler extends MessageUiHandler {
|
|||||||
const props: DexAttrProps = this.scene.gameData.getSpeciesDexAttrProps(this.lastSpecies, this.dexAttrCursor);
|
const props: DexAttrProps = this.scene.gameData.getSpeciesDexAttrProps(this.lastSpecies, this.dexAttrCursor);
|
||||||
// species has different forms
|
// species has different forms
|
||||||
if (pokemonFormLevelMoves.hasOwnProperty(speciesId)) {
|
if (pokemonFormLevelMoves.hasOwnProperty(speciesId)) {
|
||||||
// starterMoveData doesn't have base form moves
|
// starterMoveData doesn't have base form moves or is using the single form format
|
||||||
if (!this.scene.gameData.starterMoveData.hasOwnProperty(speciesId)){
|
if (!this.scene.gameData.starterMoveData.hasOwnProperty(speciesId) || Array.isArray(this.scene.gameData.starterMoveData[speciesId]))
|
||||||
this.scene.gameData.starterMoveData[speciesId] = this.starterMoveset.slice(0) as StarterMoveset;
|
this.scene.gameData.starterMoveData[speciesId] = { [props.formIndex]: this.starterMoveset.slice(0) as StarterMoveset };
|
||||||
}
|
const starterMoveData = this.scene.gameData.starterMoveData[speciesId][props.formIndex];
|
||||||
const starterMoveData = this.scene.gameData.starterMoveData[speciesId]
|
|
||||||
// starterMoveData doesn't have active form moves
|
// starterMoveData doesn't have active form moves
|
||||||
if (!starterMoveData.hasOwnProperty(props.formIndex)) {
|
if (!starterMoveData.hasOwnProperty(props.formIndex))
|
||||||
this.scene.gameData.starterMoveData[speciesId][props.formIndex] = this.starterMoveset.slice(0) as StarterMoveset;
|
this.scene.gameData.starterMoveData[speciesId][props.formIndex] = this.starterMoveset.slice(0) as StarterMoveset;
|
||||||
}
|
|
||||||
// does the species' starter move data have its form's starter moves and has it been updated
|
// does the species' starter move data have its form's starter moves and has it been updated
|
||||||
if (starterMoveData.hasOwnProperty(props.formIndex) && Array.isArray(starterMoveData[props.formIndex])) {
|
if (starterMoveData.hasOwnProperty(props.formIndex)) {
|
||||||
// active form move hasn't been updated
|
// active form move hasn't been updated
|
||||||
if (starterMoveData[props.formIndex][existingMoveIndex] !== newMove)
|
if (starterMoveData[props.formIndex][existingMoveIndex] !== newMove)
|
||||||
this.scene.gameData.starterMoveData[speciesId][props.formIndex] = this.starterMoveset.slice(0) as StarterMoveset;
|
this.scene.gameData.starterMoveData[speciesId][props.formIndex] = this.starterMoveset.slice(0) as StarterMoveset;
|
||||||
@ -889,7 +889,7 @@ export default class StarterSelectUiHandler extends MessageUiHandler {
|
|||||||
const genLimit = this.genSpecies[genCursorWithScroll].length;
|
const genLimit = this.genSpecies[genCursorWithScroll].length;
|
||||||
for (let s = 0; s < 81; s++) {
|
for (let s = 0; s < 81; s++) {
|
||||||
const speciesId = s < genLimit ? this.genSpecies[genCursorWithScroll][s].speciesId : 0 as Species;
|
const speciesId = s < genLimit ? this.genSpecies[genCursorWithScroll][s].speciesId : 0 as Species;
|
||||||
const slotVisible = speciesId && !!(this.scene.gameData.dexData[speciesId].caughtAttr);
|
const slotVisible = !!speciesId;
|
||||||
if (slotVisible) {
|
if (slotVisible) {
|
||||||
const baseStarterValue = speciesStarters[speciesId];
|
const baseStarterValue = speciesStarters[speciesId];
|
||||||
const starterValue = slotVisible ? this.scene.gameData.getSpeciesStarterValue(speciesId) : 0;
|
const starterValue = slotVisible ? this.scene.gameData.getSpeciesStarterValue(speciesId) : 0;
|
||||||
@ -914,7 +914,7 @@ export default class StarterSelectUiHandler extends MessageUiHandler {
|
|||||||
this.starterValueLabels[s].setShadowColor(this.getTextColor(textStyle, true));
|
this.starterValueLabels[s].setShadowColor(this.getTextColor(textStyle, true));
|
||||||
}
|
}
|
||||||
this.starterValueLabels[s].setVisible(slotVisible);
|
this.starterValueLabels[s].setVisible(slotVisible);
|
||||||
this.shinyIcons[s].setVisible(slotVisible && !!(this.scene.gameData.dexData[speciesId].caughtAttr & DexAttr.SHINY));
|
this.shinyIcons[s].setVisible(slotVisible && !!this.scene.gameData.dexData[speciesId].caughtAttr && !!(this.scene.gameData.dexData[speciesId].caughtAttr & DexAttr.SHINY));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
changed = super.setCursor(cursor);
|
changed = super.setCursor(cursor);
|
||||||
@ -1244,17 +1244,22 @@ export default class StarterSelectUiHandler extends MessageUiHandler {
|
|||||||
tryUpdateValue(add?: integer): boolean {
|
tryUpdateValue(add?: integer): boolean {
|
||||||
const value = this.starterGens.reduce((total: integer, gen: integer, i: integer) => total += this.scene.gameData.getSpeciesStarterValue(this.genSpecies[gen][this.starterCursors[i]].speciesId), 0);
|
const value = this.starterGens.reduce((total: integer, gen: integer, i: integer) => total += this.scene.gameData.getSpeciesStarterValue(this.genSpecies[gen][this.starterCursors[i]].speciesId), 0);
|
||||||
const newValue = value + (add || 0);
|
const newValue = value + (add || 0);
|
||||||
const overLimit = newValue > this.getValueLimit();
|
const valueLimit = this.getValueLimit();
|
||||||
|
const overLimit = newValue > valueLimit;
|
||||||
let newValueStr = newValue.toString();
|
let newValueStr = newValue.toString();
|
||||||
if (newValueStr.startsWith('0.'))
|
if (newValueStr.startsWith('0.'))
|
||||||
newValueStr = newValueStr.slice(1);
|
newValueStr = newValueStr.slice(1);
|
||||||
this.valueLimitLabel.setText(`${newValueStr}/${this.getValueLimit()}`);
|
this.valueLimitLabel.setText(`${newValueStr}/${valueLimit}`);
|
||||||
this.valueLimitLabel.setColor(this.getTextColor(!overLimit ? TextStyle.TOOLTIP_CONTENT : TextStyle.SUMMARY_PINK));
|
this.valueLimitLabel.setColor(this.getTextColor(!overLimit ? TextStyle.TOOLTIP_CONTENT : TextStyle.SUMMARY_PINK));
|
||||||
this.valueLimitLabel.setShadowColor(this.getTextColor(!overLimit ? TextStyle.TOOLTIP_CONTENT : TextStyle.SUMMARY_PINK, true));
|
this.valueLimitLabel.setShadowColor(this.getTextColor(!overLimit ? TextStyle.TOOLTIP_CONTENT : TextStyle.SUMMARY_PINK, true));
|
||||||
if (overLimit) {
|
if (overLimit) {
|
||||||
this.scene.time.delayedCall(Utils.fixedInt(500), () => this.tryUpdateValue());
|
this.scene.time.delayedCall(Utils.fixedInt(500), () => this.tryUpdateValue());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
for (let g = 0; g < this.genSpecies.length; g++) {
|
||||||
|
for (let s = 0; s < this.genSpecies[g].length; s++)
|
||||||
|
(this.starterSelectGenIconContainers[g].getAt(s) as Phaser.GameObjects.Sprite).setAlpha((newValue + this.scene.gameData.getSpeciesStarterValue(this.genSpecies[g][s].speciesId)) > valueLimit ? 0.375 : 1);
|
||||||
|
}
|
||||||
this.value = newValue;
|
this.value = newValue;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -13,7 +13,7 @@ export default class TitleUiHandler extends OptionSelectUiHandler {
|
|||||||
private splashMessage: string;
|
private splashMessage: string;
|
||||||
private splashMessageText: Phaser.GameObjects.Text;
|
private splashMessageText: Phaser.GameObjects.Text;
|
||||||
|
|
||||||
private titleStatsTimer;
|
private titleStatsTimer: number;
|
||||||
|
|
||||||
constructor(scene: BattleScene, mode: Mode = Mode.TITLE) {
|
constructor(scene: BattleScene, mode: Mode = Mode.TITLE) {
|
||||||
super(scene, mode);
|
super(scene, mode);
|
||||||
|