Add quicker party member EXP display and fix some minor bugs

pull/2/head
Flashfyre 2023-10-04 17:24:28 -04:00
parent 46c31f9595
commit 798f6cc53f
11 changed files with 179 additions and 14 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 287 B

View File

@ -1893,7 +1893,7 @@ export class VictoryPhase extends PokemonPhase {
if (exp) { if (exp) {
const partyMemberIndex = party.indexOf(expPartyMembers[pm]); const partyMemberIndex = party.indexOf(expPartyMembers[pm]);
this.scene.unshiftPhase(new ExpPhase(this.scene, partyMemberIndex, exp)); this.scene.unshiftPhase(expPartyMembers[pm].isOnField() ? new ExpPhase(this.scene, partyMemberIndex, exp) : new ShowPartyExpBarPhase(this.scene, partyMemberIndex, exp));
} }
} }
@ -2025,8 +2025,53 @@ export class ExpPhase extends PartyMemberPokemonPhase {
pokemon.updateInfo().then(() => this.end()); pokemon.updateInfo().then(() => this.end());
}, null, true); }, null, true);
} }
}
export class ShowPartyExpBarPhase extends PartyMemberPokemonPhase {
private expValue: number;
constructor(scene: BattleScene, partyMemberIndex: integer, expValue: number) {
super(scene, partyMemberIndex);
this.expValue = expValue;
}
start() {
super.start();
const pokemon = this.getPokemon();
let exp = new Utils.NumberHolder(this.expValue);
this.scene.applyModifiers(ExpBoosterModifier, true, exp);
exp.value = Math.floor(exp.value);
const lastLevel = pokemon.level;
let newLevel: integer;
pokemon.addExp(exp.value);
newLevel = pokemon.level;
if (newLevel > lastLevel)
this.scene.unshiftPhase(new LevelUpPhase(this.scene, this.partyMemberIndex, lastLevel, newLevel));
this.scene.unshiftPhase(new HidePartyExpBarPhase(this.scene));
pokemon.updateInfo();
this.scene.partyExpBar.showPokemonExp(pokemon, exp.value).then(() => {
if (newLevel > lastLevel)
this.end();
else
setTimeout(() => this.end(), 500);
});
}
}
export class HidePartyExpBarPhase extends BattlePhase {
constructor(scene: BattleScene) {
super(scene);
}
start() {
super.start();
this.scene.partyExpBar.hide().then(() => this.end());
}
} }
export class LevelUpPhase extends PartyMemberPokemonPhase { export class LevelUpPhase extends PartyMemberPokemonPhase {

View File

@ -22,6 +22,7 @@ import { BlockItemTheftAbAttr, DoubleBattleChanceAbAttr, applyAbAttrs, initAbili
import Battle from './battle'; import Battle from './battle';
import { GameMode } from './game-mode'; import { GameMode } from './game-mode';
import SpritePipeline from './pipelines/sprite'; import SpritePipeline from './pipelines/sprite';
import PartyExpBar from './ui/party-exp-bar';
const enableAuto = true; const enableAuto = true;
const quickStart = false; const quickStart = false;
@ -65,6 +66,7 @@ export default class BattleScene extends Phaser.Scene {
public field: Phaser.GameObjects.Container; public field: Phaser.GameObjects.Container;
public fieldUI: Phaser.GameObjects.Container; public fieldUI: Phaser.GameObjects.Container;
public abilityBar: AbilityBar; public abilityBar: AbilityBar;
public partyExpBar: PartyExpBar;
public arenaBg: Phaser.GameObjects.Sprite; public arenaBg: Phaser.GameObjects.Sprite;
public arenaBgTransition: Phaser.GameObjects.Sprite; public arenaBgTransition: Phaser.GameObjects.Sprite;
public arenaPlayer: ArenaBase; public arenaPlayer: ArenaBase;
@ -166,6 +168,7 @@ export default class BattleScene extends Phaser.Scene {
this.loadImage('overlay_exp', 'ui'); this.loadImage('overlay_exp', 'ui');
this.loadImage('icon_owned', 'ui'); this.loadImage('icon_owned', 'ui');
this.loadImage('ability_bar', 'ui'); this.loadImage('ability_bar', 'ui');
this.loadImage('party_exp_bar', 'ui');
this.loadImage('shiny_star', 'ui', 'shiny.png'); this.loadImage('shiny_star', 'ui', 'shiny.png');
this.loadImage('party_bg', 'ui'); this.loadImage('party_bg', 'ui');
@ -333,9 +336,13 @@ export default class BattleScene extends Phaser.Scene {
this.abilityBar.setup(); this.abilityBar.setup();
this.fieldUI.add(this.abilityBar); this.fieldUI.add(this.abilityBar);
this.partyExpBar = new PartyExpBar(this);
this.partyExpBar.setup();
this.fieldUI.add(this.partyExpBar);
this.waveCountText = addTextObject(this, (this.game.canvas.width / 6) - 2, 0, startingWave.toString(), TextStyle.BATTLE_INFO); this.waveCountText = addTextObject(this, (this.game.canvas.width / 6) - 2, 0, startingWave.toString(), TextStyle.BATTLE_INFO);
this.waveCountText.setOrigin(1, 0); this.waveCountText.setOrigin(1, 0);
this.updateWaveCountPosition(); this.updateUIPositions();
this.fieldUI.add(this.waveCountText); this.fieldUI.add(this.waveCountText);
this.party = []; this.party = [];
@ -601,8 +608,9 @@ export default class BattleScene extends Phaser.Scene {
this.waveCountText.setVisible(true); this.waveCountText.setVisible(true);
} }
updateWaveCountPosition(): void { updateUIPositions(): void {
this.waveCountText.setY(-(this.game.canvas.height / 6) + (this.enemyModifiers.length ? 15 : 0)); this.waveCountText.setY(-(this.game.canvas.height / 6) + (this.enemyModifiers.length ? 15 : 0));
this.partyExpBar.setY(this.waveCountText.y + 15);
} }
getMaxExpLevel(): integer { getMaxExpLevel(): integer {
@ -901,7 +909,7 @@ export default class BattleScene extends Phaser.Scene {
clearEnemyModifiers(): void { clearEnemyModifiers(): void {
this.enemyModifiers.splice(0, this.enemyModifiers.length); this.enemyModifiers.splice(0, this.enemyModifiers.length);
this.updateModifiers(false).then(() => this.updateWaveCountPosition()); this.updateModifiers(false).then(() => this.updateUIPositions());
} }
updateModifiers(player?: boolean): Promise<void> { updateModifiers(player?: boolean): Promise<void> {
@ -928,7 +936,7 @@ export default class BattleScene extends Phaser.Scene {
this.updatePartyForModifiers(player ? this.getParty() : this.getEnemyField().filter(p => p.isActive())).then(() => { this.updatePartyForModifiers(player ? this.getParty() : this.getEnemyField().filter(p => p.isActive())).then(() => {
(player ? this.modifierBar : this.enemyModifierBar).updateModifiers(modifiers); (player ? this.modifierBar : this.enemyModifierBar).updateModifiers(modifiers);
if (!player) if (!player)
this.updateWaveCountPosition(); this.updateUIPositions();
resolve(); resolve();
}); });
}); });

View File

@ -203,7 +203,7 @@ export class ConfusedTag extends BattlerTag {
if (Utils.randInt(2)) { if (Utils.randInt(2)) {
const atk = pokemon.getBattleStat(Stat.ATK); const atk = pokemon.getBattleStat(Stat.ATK);
const def = pokemon.getBattleStat(Stat.DEF); const def = pokemon.getBattleStat(Stat.DEF);
const damage = Math.ceil(((((2 * pokemon.level / 5 + 2) * 40 * atk / def) / 50) + 2) * ((Utils.randInt(15) + 85) / 100)); const damage = Math.ceil(((((2 * pokemon.level / 5 + 2) * 40 * atk / def) / 50) + 2) * (Utils.randInt(15, 85) / 100));
pokemon.scene.queueMessage('It hurt itself in its\nconfusion!'); pokemon.scene.queueMessage('It hurt itself in its\nconfusion!');
pokemon.scene.unshiftPhase(new DamagePhase(pokemon.scene, pokemon.getBattlerIndex())); pokemon.scene.unshiftPhase(new DamagePhase(pokemon.scene, pokemon.getBattlerIndex()));
pokemon.damage(damage); pokemon.damage(damage);

View File

@ -956,7 +956,7 @@ export class RandomLevelDamageAttr extends FixedDamageAttr {
} }
getDamage(user: Pokemon, target: Pokemon, move: Move): number { getDamage(user: Pokemon, target: Pokemon, move: Move): number {
return user.level * (Utils.randInt(100, 50) * 0.01); return user.level * (Utils.randIntRange(50, 150) * 0.01);
} }
} }
@ -1672,7 +1672,7 @@ export class FrenzyAttr extends MoveEffectAttr {
if (!user.getMoveQueue().length) { if (!user.getMoveQueue().length) {
if (!user.getTag(BattlerTagType.FRENZY)) { if (!user.getTag(BattlerTagType.FRENZY)) {
const turnCount = Utils.randInt(2) + 1; const turnCount = Utils.randIntRange(3, 4);
new Array(turnCount).fill(null).map(() => user.getMoveQueue().push({ move: move.id, targets: [ target.getBattlerIndex() ], ignorePP: true })); new Array(turnCount).fill(null).map(() => user.getMoveQueue().push({ move: move.id, targets: [ target.getBattlerIndex() ], ignorePP: true }));
user.addTag(BattlerTagType.FRENZY, 1, move.id, user.id); user.addTag(BattlerTagType.FRENZY, 1, move.id, user.id);
} else { } else {
@ -1801,13 +1801,13 @@ export class FlinchAttr extends AddBattlerTagAttr {
export class ConfuseAttr extends AddBattlerTagAttr { export class ConfuseAttr extends AddBattlerTagAttr {
constructor(selfTarget?: boolean) { constructor(selfTarget?: boolean) {
super(BattlerTagType.CONFUSED, selfTarget, Utils.randInt(4, 1)); super(BattlerTagType.CONFUSED, selfTarget, Utils.randIntRange(1, 4));
} }
} }
export class TrapAttr extends AddBattlerTagAttr { export class TrapAttr extends AddBattlerTagAttr {
constructor(tagType: BattlerTagType) { constructor(tagType: BattlerTagType) {
super(tagType, false, Utils.randInt(2, 5)); super(tagType, false, Utils.randIntRange(2, 5) + 1);
} }
} }

View File

@ -21,7 +21,7 @@ export class Status {
this.turnCount = turnCount === undefined ? 0 : turnCount; this.turnCount = turnCount === undefined ? 0 : turnCount;
if (cureTurn === undefined) { if (cureTurn === undefined) {
if (effect === StatusEffect.SLEEP) if (effect === StatusEffect.SLEEP)
this.cureTurn = Utils.randInt(3, 1); this.cureTurn = Utils.randInt(3, 2);
} else } else
this.cureTurn = cureTurn; this.cureTurn = cureTurn;
} }

View File

@ -683,6 +683,7 @@ const modifierPool = {
].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),
new WeightedModifierType(modifierTypes.EVOLUTION_ITEM, 1),
new WeightedModifierType(modifierTypes.FULL_HEAL, (party: Pokemon[]) => { new WeightedModifierType(modifierTypes.FULL_HEAL, (party: Pokemon[]) => {
const statusEffectPartyMemberCount = Math.min(party.filter(p => p.hp && !!p.status).length, 3); const statusEffectPartyMemberCount = Math.min(party.filter(p => p.hp && !!p.status).length, 3);
return statusEffectPartyMemberCount * 6; return statusEffectPartyMemberCount * 6;
@ -722,7 +723,6 @@ const modifierPool = {
].map(m => { m.setTier(ModifierTier.GREAT); return m; }), ].map(m => { m.setTier(ModifierTier.GREAT); return m; }),
[ModifierTier.ULTRA]: [ [ModifierTier.ULTRA]: [
new WeightedModifierType(modifierTypes.ULTRA_BALL, 8), new WeightedModifierType(modifierTypes.ULTRA_BALL, 8),
new WeightedModifierType(modifierTypes.EVOLUTION_ITEM, 12),
new WeightedModifierType(modifierTypes.MAX_LURE, 4), new WeightedModifierType(modifierTypes.MAX_LURE, 4),
new WeightedModifierType(modifierTypes.ATTACK_TYPE_BOOSTER, 4), new WeightedModifierType(modifierTypes.ATTACK_TYPE_BOOSTER, 4),
new WeightedModifierType(modifierTypes.TM_ULTRA, 5), new WeightedModifierType(modifierTypes.TM_ULTRA, 5),

View File

@ -769,22 +769,30 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
} }
getTag(tagType: BattlerTagType | { new(...args: any[]): BattlerTag }): BattlerTag { getTag(tagType: BattlerTagType | { new(...args: any[]): BattlerTag }): BattlerTag {
if (!this.summonData)
return null;
return typeof(tagType) === 'number' return typeof(tagType) === 'number'
? this.summonData.tags.find(t => t.tagType === tagType) ? this.summonData.tags.find(t => t.tagType === tagType)
: this.summonData.tags.find(t => t instanceof tagType); : this.summonData.tags.find(t => t instanceof tagType);
} }
findTag(tagFilter: ((tag: BattlerTag) => boolean)) { findTag(tagFilter: ((tag: BattlerTag) => boolean)) {
if (!this.summonData)
return null;
return this.summonData.tags.find(t => tagFilter(t)); return this.summonData.tags.find(t => tagFilter(t));
} }
getTags(tagType: BattlerTagType | { new(...args: any[]): BattlerTag }): BattlerTag[] { getTags(tagType: BattlerTagType | { new(...args: any[]): BattlerTag }): BattlerTag[] {
if (!this.summonData)
return [];
return typeof(tagType) === 'number' return typeof(tagType) === 'number'
? this.summonData.tags.filter(t => t.tagType === tagType) ? this.summonData.tags.filter(t => t.tagType === tagType)
: this.summonData.tags.filter(t => t instanceof tagType); : this.summonData.tags.filter(t => t instanceof tagType);
} }
findTags(tagFilter: ((tag: BattlerTag) => boolean)) { findTags(tagFilter: ((tag: BattlerTag) => boolean)): BattlerTag[] {
if (!this.summonData)
return [];
return this.summonData.tags.filter(t => tagFilter(t)); return this.summonData.tags.filter(t => tagFilter(t));
} }
@ -935,6 +943,9 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
if (cancelled.value) if (cancelled.value)
return false; return false;
if (effect === StatusEffect.SLEEP)
this.setFrameRate(4);
this.status = new Status(effect); this.status = new Status(effect);
return true; return true;
} }
@ -943,6 +954,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
const lastStatus = this.status.effect; const lastStatus = this.status.effect;
this.status = undefined; this.status = undefined;
if (lastStatus === StatusEffect.SLEEP) { if (lastStatus === StatusEffect.SLEEP) {
this.setFrameRate(12);
if (this.getTag(BattlerTagType.NIGHTMARE)) if (this.getTag(BattlerTagType.NIGHTMARE))
this.lapseTag(BattlerTagType.NIGHTMARE); this.lapseTag(BattlerTagType.NIGHTMARE);
} }
@ -968,6 +980,12 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
return (this.getSpeciesForm().baseExp * this.level) / 5 + 1; return (this.getSpeciesForm().baseExp * this.level) / 5 + 1;
} }
setFrameRate(frameRate: integer) {
this.scene.anims.get(this.getBattleSpriteKey()).frameRate = frameRate;
this.getSprite().play(this.getBattleSpriteKey());
this.getTintSprite().play(this.getBattleSpriteKey());
}
tint(color: number, alpha?: number, duration?: integer, ease?: string) { tint(color: number, alpha?: number, duration?: integer, ease?: string) {
const tintSprite = this.getTintSprite(); const tintSprite = this.getTintSprite();
tintSprite.setTintFill(color); tintSprite.setTintFill(color);

View File

@ -271,7 +271,6 @@ export default class BattleInfo extends Phaser.GameObjects.Container {
ratio = 0; ratio = 0;
instant = true; instant = true;
} }
console.log(ratio);
let duration = this.visible && !instant ? ((levelExp - this.lastLevelExp) / relLevelExp) * 1650 : 0; let duration = this.visible && !instant ? ((levelExp - this.lastLevelExp) / relLevelExp) * 1650 : 0;
if (duration) if (duration)
this.scene.sound.play('exp'); this.scene.sound.play('exp');

91
src/ui/party-exp-bar.ts Normal file
View File

@ -0,0 +1,91 @@
import BattleScene from "../battle-scene";
import Pokemon from "../pokemon";
import { TextStyle, addTextObject } from "./text";
export default class PartyExpBar extends Phaser.GameObjects.Container {
private bg: Phaser.GameObjects.NineSlice;
private pokemonIcon: Phaser.GameObjects.Sprite;
private expText: Phaser.GameObjects.Text;
private tween: Phaser.Tweens.Tween;
public shown: boolean;
constructor(scene: BattleScene) {
super(scene, (scene.game.canvas.width / 6), -((scene.game.canvas.height) / 6) + 15);
}
setup(): void {
this.bg = this.scene.add.nineslice(0, 0, 'party_exp_bar', null, 8, 18, 21, 5, 6, 4);
this.bg.setOrigin(0, 0);
this.add(this.bg);
this.pokemonIcon = this.scene.add.sprite(3, 7, 'pokemon_icons_0');
this.pokemonIcon.setOrigin(0, 0.5);
this.pokemonIcon.setScale(0.5);
this.add(this.pokemonIcon);
this.expText = addTextObject(this.scene, 22, 4, '', TextStyle.BATTLE_INFO);
this.expText.setOrigin(0, 0);
this.add(this.expText);
this.setVisible(false);
this.shown = false;
}
showPokemonExp(pokemon: Pokemon, expValue: integer): Promise<void> {
return new Promise<void>(resolve => {
if (this.shown)
return resolve();
this.pokemonIcon.setTexture(pokemon.species.getIconAtlasKey());
this.pokemonIcon.play(pokemon.getIconKey()).stop();
this.expText.setText(`+${expValue.toString()}`);
this.bg.width = this.expText.displayWidth + 28;
(this.scene as BattleScene).fieldUI.bringToTop(this);
if (this.tween)
this.tween.stop();
this.tween = this.scene.tweens.add({
targets: this,
x: (this.scene.game.canvas.width / 6) - (this.bg.width - 5),
duration: 500,
ease: 'Sine.easeOut',
onComplete: () => {
this.tween = null;
resolve();
}
});
this.setVisible(true);
this.shown = true;
});
}
hide(): Promise<void> {
return new Promise<void>(resolve => {
if (!this.shown)
return resolve();
if (this.tween)
this.tween.stop();
this.tween = this.scene.tweens.add({
targets: this,
x: (this.scene.game.canvas.width / 6),
duration: 500,
ease: 'Sine.easeIn',
onComplete: () => {
this.tween = null;
this.shown = false;
this.setVisible(false);
resolve();
}
});
});
}
}

View File

@ -30,6 +30,10 @@ export function randInt(range: integer, min?: integer): integer {
return Math.floor(Math.random() * range) + min; return Math.floor(Math.random() * range) + min;
} }
export function randIntRange(min: integer, max: integer): integer {
return randInt(max - min, min);
}
export function getFrameMs(frameCount: integer): integer { export function getFrameMs(frameCount: integer): integer {
return Math.floor((1 / 60) * 1000 * frameCount); return Math.floor((1 / 60) * 1000 * frameCount);
} }