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:
1 parent
e633ff1577
commit
46c31f9595
13 files changed
+559
-160
No files matched your search
+23
-2
@@ -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
@@ -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
@@ -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)
|
||||
|
||||
@@ -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
@@ -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
@@ -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));
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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:
|
||||
|
||||
Reference in new issue
Block a user