Add scaling level cap and party switch option after load

Add scaling level cap and party switch option after load; update Phaser to newest beta version
This commit is contained in:
Flashfyre committed 2023-10-03 12:50:31 -04:00
1 parent e633ff1577
commit 46c31f9595
13 files changed
+559 -160

No files matched your search

+23 -2
View File
@@ -1,4 +1,4 @@
import BattleScene, { maxExpLevel, startingLevel, startingWave } from "./battle-scene";
import BattleScene, { startingLevel, startingWave } from "./battle-scene";
import { default as Pokemon, PlayerPokemon, EnemyPokemon, PokemonMove, MoveResult, DamageResult, FieldPosition, HitResult } from "./pokemon";
import * as Utils from './utils';
import { allMoves, applyMoveAttrs, BypassSleepAttr, ChargeAttr, applyFilteredMoveAttrs, HitsTagAttr, MissEffectAttr, MoveAttr, MoveCategory, MoveEffectAttr, MoveFlags, Moves, MultiHitAttr, OverrideMoveEffectAttr, VariableAccuracyAttr, MoveTarget, OneHitKOAttr, getMoveTargets, MoveTargetSet, MoveEffectTrigger } from "./data/move";
@@ -78,6 +78,11 @@ export class CheckLoadPhase extends BattlePhase {
this.scene.pushPhase(new SummonPhase(this.scene, 0));
if (this.scene.currentBattle.double && this.scene.getParty().filter(p => !p.isFainted()).length > 1)
this.scene.pushPhase(new SummonPhase(this.scene, 1));
if (this.scene.currentBattle.waveIndex > 1) {
this.scene.pushPhase(new CheckSwitchPhase(this.scene, 0, this.scene.currentBattle.double));
if (this.scene.currentBattle.double)
this.scene.pushPhase(new CheckSwitchPhase(this.scene, 1, this.scene.currentBattle.double));
}
super.end();
}
@@ -751,6 +756,22 @@ export class SummonMissingPhase extends SummonPhase {
}
}
export class LevelCapPhase extends FieldPhase {
constructor(scene: BattleScene) {
super(scene);
}
start(): void {
super.start();
this.scene.ui.setMode(Mode.MESSAGE).then(() => {
this.scene.playSoundWithoutBgm('level_up_fanfare', 1500);
this.scene.ui.showText(`The level cap\nhas increased to ${this.scene.getMaxExpLevel()}!`, null, () => this.end(), null, true);
this.executeForAll(pokemon => pokemon.updateInfo(true));
});
}
}
export class TurnInitPhase extends FieldPhase {
constructor(scene: BattleScene) {
super(scene);
@@ -1821,7 +1842,7 @@ export class VictoryPhase extends PokemonPhase {
const expBalanceModifier = this.scene.findModifier(m => m instanceof ExpBalanceModifier) as ExpBalanceModifier;
const multipleParticipantExpBonusModifier = this.scene.findModifier(m => m instanceof MultipleParticipantExpBonusModifier) as MultipleParticipantExpBonusModifier;
const expValue = this.getPokemon().getExpValue();
const expPartyMembers = party.filter(p => p.hp && p.level < maxExpLevel);
const expPartyMembers = party.filter(p => p.hp && p.level < this.scene.getMaxExpLevel());
const partyMemberExp = [];
for (let partyMember of expPartyMembers) {
const pId = partyMember.id;
+14 -3
View File
@@ -1,7 +1,7 @@
import Phaser from 'phaser';
import { Biome } from './data/biome';
import UI from './ui/ui';
import { EncounterPhase, SummonPhase, NextEncounterPhase, NewBiomeEncounterPhase, SelectBiomePhase, MessagePhase, CheckLoadPhase, TurnInitPhase, ReturnPhase, ToggleDoublePositionPhase, CheckSwitchPhase, PostSummonPhase } from './battle-phases';
import { EncounterPhase, SummonPhase, NextEncounterPhase, NewBiomeEncounterPhase, SelectBiomePhase, MessagePhase, CheckLoadPhase, TurnInitPhase, ReturnPhase, ToggleDoublePositionPhase, CheckSwitchPhase, PostSummonPhase, LevelCapPhase } from './battle-phases';
import Pokemon, { PlayerPokemon, EnemyPokemon } from './pokemon';
import PokemonSpecies, { allSpecies, getPokemonSpecies, initSpecies } from './data/pokemon-species';
import * as Utils from './utils';
@@ -29,8 +29,6 @@ export const startingLevel = 5;
export const startingWave = 1;
export const startingBiome = Biome.TOWN;
export const maxExpLevel = 10000;
export enum Button {
UP,
DOWN,
@@ -163,6 +161,7 @@ export default class BattleScene extends Phaser.Scene {
this.loadImage('pbinfo_enemy_mini', 'ui');
this.loadImage('overlay_lv', 'ui');
this.loadAtlas('numbers', 'ui');
this.loadAtlas('numbers_red', 'ui');
this.loadAtlas('overlay_hp', 'ui');
this.loadImage('overlay_exp', 'ui');
this.loadImage('icon_owned', 'ui');
@@ -525,6 +524,8 @@ export default class BattleScene extends Phaser.Scene {
const lastBattle = this.currentBattle;
const maxExpLevel = this.getMaxExpLevel();
this.currentBattle = new Battle(newWaveIndex, newDouble);
this.currentBattle.incrementTurn(this);
@@ -536,6 +537,10 @@ export default class BattleScene extends Phaser.Scene {
else {
this.pushPhase(new SelectBiomePhase(this));
this.pushPhase(new NewBiomeEncounterPhase(this));
const newMaxExpLevel = this.getMaxExpLevel();
if (newMaxExpLevel > maxExpLevel)
this.pushPhase(new LevelCapPhase(this));
}
} else {
if (!this.quickStart)
@@ -600,6 +605,12 @@ export default class BattleScene extends Phaser.Scene {
this.waveCountText.setY(-(this.game.canvas.height / 6) + (this.enemyModifiers.length ? 15 : 0));
}
getMaxExpLevel(): integer {
const lastWaveIndex = Math.ceil((this.currentBattle?.waveIndex || 1) / 10) * 10;
const baseLevel = (1 + lastWaveIndex / 2 + Math.pow(lastWaveIndex / 25, 2)) * 1.2;
return Math.min(Math.ceil(baseLevel / 2) * 2 + 2, 10000);
}
randomSpecies(waveIndex: integer, level: integer, fromArenaPool?: boolean): PokemonSpecies {
return fromArenaPool
? this.arena.randomSpecies(waveIndex, level)
+1 -1
View File
@@ -3236,7 +3236,7 @@ export function initMoves() {
.makesContact(false),
new AttackMove(Moves.STORM_THROW, "Storm Throw", Type.FIGHTING, MoveCategory.PHYSICAL, 60, 100, 10, -1, "Always results in a critical hit.", 100, 0, 5)
.attr(CritOnlyAttr),
new AttackMove(Moves.FLAME_BURST, "Flame Burst", Type.FIRE, MoveCategory.SPECIAL, 70, 100, 15, -1, "May also injure nearby Pokémon.", -1, 0, 5), // TODO
new AttackMove(Moves.FLAME_BURST, "Flame Burst (P)", Type.FIRE, MoveCategory.SPECIAL, 70, 100, 15, -1, "May also injure nearby Pokémon.", -1, 0, 5), // TODO
new AttackMove(Moves.SLUDGE_WAVE, "Sludge Wave", Type.POISON, MoveCategory.SPECIAL, 95, 100, 10, -1, "May poison opponent.", 10, 0, 5)
.attr(StatusEffectAttr, StatusEffect.POISON),
new SelfStatusMove(Moves.QUIVER_DANCE, "Quiver Dance", Type.BUG, -1, 20, -1, "Raises user's Special Attack, Special Defense and Speed.", -1, 0, 5)
+2 -2
View File
@@ -1,6 +1,6 @@
import * as ModifierTypes from './modifier-type';
import { LearnMovePhase, LevelUpPhase, PokemonHealPhase } from "../battle-phases";
import BattleScene, { maxExpLevel } from "../battle-scene";
import BattleScene from "../battle-scene";
import { getLevelTotalExp } from "../data/exp";
import { PokeballType } from "../data/pokeball";
import Pokemon, { PlayerPokemon } from "../pokemon";
@@ -814,7 +814,7 @@ export class PokemonLevelIncrementModifier extends ConsumablePokemonModifier {
pokemon.scene.applyModifiers(LevelIncrementBoosterModifier, true, levelCount);
pokemon.level += levelCount.value;
if (pokemon.level <= maxExpLevel) {
if (pokemon.level <= pokemon.scene.getMaxExpLevel()) {
pokemon.exp = getLevelTotalExp(pokemon.level, pokemon.species.growthRate);
pokemon.levelExp = 0;
}
+19 -10
View File
@@ -26,7 +26,6 @@ import { Biome } from './data/biome';
import { Abilities, Ability, BattleStatMultiplierAbAttr, BlockCritAbAttr, NonSuperEffectiveImmunityAbAttr, PreApplyBattlerTagAbAttr, StatusEffectImmunityAbAttr, TypeImmunityAbAttr, VariableMovePowerAbAttr, abilities, applyBattleStatMultiplierAbAttrs, applyPreApplyBattlerTagAbAttrs, applyPreAttackAbAttrs, applyPreDefendAbAttrs, applyPreSetStatusAbAttrs } from './data/ability';
import PokemonData from './system/pokemon-data';
import { BattlerIndex } from './battle';
import SpritePipeline from './pipelines/sprite';
export enum FieldPosition {
CENTER,
@@ -573,9 +572,15 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
}
addExp(exp: integer) {
const maxExpLevel = this.scene.getMaxExpLevel();
const initialExp = this.exp;
this.exp += exp;
while (this.exp >= getLevelTotalExp(this.level + 1, this.getSpeciesForm().growthRate))
while (this.level < maxExpLevel && this.exp >= getLevelTotalExp(this.level + 1, this.getSpeciesForm().growthRate))
this.level++;
if (this.level >= maxExpLevel) {
console.log(initialExp, this.exp, getLevelTotalExp(this.level, this.getSpeciesForm().growthRate));
this.exp = Math.max(getLevelTotalExp(this.level, this.getSpeciesForm().growthRate), initialExp);
}
this.levelExp = this.exp - getLevelTotalExp(this.level, this.getSpeciesForm().growthRate);
}
@@ -654,17 +659,21 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
const targetDef = this.getBattleStat(isPhysical ? Stat.DEF : Stat.SPDEF);
const stabMultiplier = source.species.type1 === move.type || (source.species.type2 !== null && source.species.type2 === move.type) ? 1.5 : 1;
const criticalMultiplier = isCritical ? 2 : 1;
damage = Math.ceil(((((2 * source.level / 5 + 2) * power.value * sourceAtk / targetDef) / 50) + 2) * stabMultiplier * typeMultiplier.value * weatherTypeMultiplier * ((Utils.randInt(15) + 85) / 100)) * criticalMultiplier;
if (isPhysical && source.status && source.status.effect === StatusEffect.BURN)
damage = Math.floor(damage / 2);
move.getAttrs(HitsTagAttr).map(hta => hta as HitsTagAttr).filter(hta => hta.doubleDamage).forEach(hta => {
if (this.getTag(hta.tagType))
damage *= 2;
});
const isTypeImmune = (typeMultiplier.value * weatherTypeMultiplier) === 0;
if (!isTypeImmune) {
damage = Math.ceil(((((2 * source.level / 5 + 2) * power.value * sourceAtk / targetDef) / 50) + 2) * stabMultiplier * typeMultiplier.value * weatherTypeMultiplier * ((Utils.randInt(15) + 85) / 100)) * criticalMultiplier;
if (isPhysical && source.status && source.status.effect === StatusEffect.BURN)
damage = Math.floor(damage / 2);
move.getAttrs(HitsTagAttr).map(hta => hta as HitsTagAttr).filter(hta => hta.doubleDamage).forEach(hta => {
if (this.getTag(hta.tagType))
damage *= 2;
});
}
const fixedDamage = new Utils.IntegerHolder(0);
applyMoveAttrs(FixedDamageAttr, source, this, move, fixedDamage);
if (damage && fixedDamage.value) {
if (!isTypeImmune && fixedDamage.value) {
damage = fixedDamage.value;
isCritical = false;
result = HitResult.EFFECTIVE;
+18 -6
View File
@@ -4,7 +4,7 @@ import * as Utils from '../utils';
import { addTextObject, TextStyle } from './text';
import { getGenderSymbol, getGenderColor } from '../data/gender';
import { StatusEffect } from '../data/status-effect';
import { maxExpLevel } from '../battle-scene';
import BattleScene from '../battle-scene';
export default class BattleInfo extends Phaser.GameObjects.Container {
private player: boolean;
@@ -18,6 +18,7 @@ export default class BattleInfo extends Phaser.GameObjects.Container {
private lastExp: integer;
private lastLevelExp: integer;
private lastLevel: integer;
private lastLevelCapped: boolean;
private box: Phaser.GameObjects.Sprite;
private nameText: Phaser.GameObjects.Text;
@@ -233,9 +234,16 @@ export default class BattleInfo extends Phaser.GameObjects.Container {
this.lastMaxHp = pokemon.getMaxHp();
};
if (this.player && (this.lastExp !== pokemon.exp || this.lastLevel !== pokemon.level)) {
const originalResolve = resolve;
resolve = () => this.updatePokemonExp(pokemon).then(() => originalResolve());
if (this.player) {
const isLevelCapped = pokemon.level >= (this.scene as BattleScene).getMaxExpLevel();
if ((this.lastExp !== pokemon.exp || this.lastLevel !== pokemon.level)) {
const originalResolve = resolve;
resolve = () => this.updatePokemonExp(pokemon).then(() => originalResolve());
} else if (isLevelCapped !== this.lastLevelCapped)
this.setLevel(pokemon.level);
this.lastLevelCapped = isLevelCapped;
}
if (this.lastHp !== pokemon.hp || this.lastMaxHp !== pokemon.getMaxHp()) {
@@ -256,11 +264,14 @@ export default class BattleInfo extends Phaser.GameObjects.Container {
const relLevelExp = getLevelRelExp(this.lastLevel + 1, battler.species.growthRate);
const levelExp = levelUp ? relLevelExp : battler.levelExp;
let ratio = relLevelExp ? levelExp / relLevelExp : 0;
if (this.lastLevel >= maxExpLevel) {
if (this.lastLevel >= (this.scene as BattleScene).getMaxExpLevel()) {
if (levelUp)
ratio = 1;
else
ratio = 0;
instant = true;
}
console.log(ratio);
let duration = this.visible && !instant ? ((levelExp - this.lastLevelExp) / relLevelExp) * 1650 : 0;
if (duration)
this.scene.sound.play('exp');
@@ -297,10 +308,11 @@ export default class BattleInfo extends Phaser.GameObjects.Container {
}
setLevel(level: integer) {
const isCapped = level >= (this.scene as BattleScene).getMaxExpLevel();
this.levelNumbersContainer.removeAll(true);
const levelStr = level.toString();
for (let i = 0; i < levelStr.length; i++)
this.levelNumbersContainer.add(this.scene.add.image(i * 8, 0, 'numbers', levelStr[i]));
this.levelNumbersContainer.add(this.scene.add.image(i * 8, 0, `numbers${isCapped ? '_red' : ''}`, levelStr[i]));
this.levelContainer.setX((this.player ? -41 : -50) - 8 * Math.max(levelStr.length - 3, 0));
}
+1 -1
View File
@@ -635,7 +635,7 @@ class PartySlot extends Phaser.GameObjects.Container {
slotLevelLabel.setPositionRelative(slotName, 8, 12);
slotLevelLabel.setOrigin(0, 0);
const slotLevelText = addTextObject(this.scene, 0, 0, this.pokemon.level.toString(), TextStyle.PARTY);
const slotLevelText = addTextObject(this.scene, 0, 0, this.pokemon.level.toString(), this.pokemon.level < (this.scene as BattleScene).getMaxExpLevel() ? TextStyle.PARTY : TextStyle.PARTY_RED);
slotLevelText.setPositionRelative(slotLevelLabel, 9, 0);
slotLevelText.setOrigin(0, 0.25);
+3 -4
View File
@@ -1,4 +1,4 @@
import BattleScene, { Button, maxExpLevel } from "../battle-scene";
import BattleScene, { Button } from "../battle-scene";
import { Mode } from "./ui";
import UiHandler from "./uiHandler";
import * as Utils from "../utils";
@@ -9,7 +9,6 @@ import Move, { MoveCategory } from "../data/move";
import { getPokeballAtlasKey } from "../data/pokeball";
import { getGenderColor, getGenderSymbol } from "../data/gender";
import { getLevelTotalExp } from "../data/exp";
import { BlendModes } from "phaser";
import { Stat, getStatName } from "../data/pokemon-stat";
import { abilities } from "../data/ability";
import { PokemonHeldItemModifier } from "../modifier/modifier";
@@ -482,7 +481,7 @@ export default class SummaryUiHandler extends UiHandler {
});
const totalLvExp = getLevelTotalExp(this.pokemon.level, this.pokemon.species.growthRate);
const expRatio = this.pokemon.level < maxExpLevel ? this.pokemon.levelExp / totalLvExp : 0;
const expRatio = this.pokemon.level < this.scene.getMaxExpLevel() ? this.pokemon.levelExp / totalLvExp : 0;
const expLabel = addTextObject(this.scene, 6, 112, 'EXP. POINTS', TextStyle.SUMMARY);
expLabel.setOrigin(0, 0);
@@ -496,7 +495,7 @@ export default class SummaryUiHandler extends UiHandler {
expText.setOrigin(1, 0);
statsContainer.add(expText);
const nextLvExp = this.pokemon.level < maxExpLevel
const nextLvExp = this.pokemon.level < this.scene.getMaxExpLevel()
? getLevelTotalExp(this.pokemon.level + 1, this.pokemon.species.growthRate) - this.pokemon.levelExp
: 0;
const nextLvExpText = addTextObject(this.scene, 208, 128, nextLvExp.toString(), TextStyle.WINDOW);
+4
View File
@@ -3,6 +3,7 @@ export enum TextStyle {
WINDOW,
BATTLE_INFO,
PARTY,
PARTY_RED,
SUMMARY,
SUMMARY_RED,
SUMMARY_GOLD
@@ -36,6 +37,7 @@ export function addTextObject(scene: Phaser.Scene, x: number, y: number, content
shadowSize = 4;
break;
case TextStyle.PARTY:
case TextStyle.PARTY_RED:
styleOptions.fontFamily = 'pkmnems';
styleOptions.fontSize = '66px';
break;
@@ -69,6 +71,8 @@ export function getTextColor(textStyle: TextStyle, shadow?: boolean) {
return !shadow ? '#404040' : '#ded6b5';
case TextStyle.PARTY:
return !shadow ? '#f8f8f8' : '#707070';
case TextStyle.PARTY_RED:
return !shadow ? '#f89890' : '#984038';
case TextStyle.SUMMARY:
return !shadow ? '#ffffff' : '#636363';
case TextStyle.SUMMARY_RED: