Update enemy modifier rates and update trainer modifier display

pull/2/head
Flashfyre 2023-10-23 13:48:56 -04:00
parent 00f7bc595b
commit 2001dd780b
8 changed files with 68 additions and 33 deletions

View File

@ -16,7 +16,7 @@ import { EvolutionPhase } from "./evolution-phase";
import { BattlePhase } from "./battle-phase";
import { BattleStat, getBattleStatLevelChangeDescription, getBattleStatName } from "./data/battle-stat";
import { Biome, biomeLinks } from "./data/biome";
import { ModifierType, ModifierTypeOption, PokemonModifierType, PokemonMoveModifierType, TmModifierType, getPlayerModifierTypeOptionsForWave, regenerateModifierPoolThresholds } from "./modifier/modifier-type";
import { ModifierPoolType, ModifierType, ModifierTypeOption, PokemonModifierType, PokemonMoveModifierType, TmModifierType, getPlayerModifierTypeOptionsForWave, regenerateModifierPoolThresholds } from "./modifier/modifier-type";
import SoundFade from "phaser3-rex-plugins/plugins/soundfade";
import { BattlerTagLapseType, BattlerTagType, HideSpriteTag as HiddenTag, TrappedTag } from "./data/battler-tag";
import { getPokemonMessage } from "./messages";
@ -266,6 +266,7 @@ export class EncounterPhase extends BattlePhase {
if (e < (battle.double ? 2 : 1)) {
if (battle.battleType === BattleType.WILD) {
this.scene.field.add(enemyPokemon);
battle.seenEnemyPartyMemberIds.add(enemyPokemon.id);
const playerPokemon = this.scene.getPlayerPokemon();
if (playerPokemon.visible)
this.scene.field.moveBelow(enemyPokemon as Pokemon, playerPokemon);
@ -280,7 +281,7 @@ export class EncounterPhase extends BattlePhase {
});
if (!this.loaded) {
regenerateModifierPoolThresholds(this.scene.getEnemyField(), false);
regenerateModifierPoolThresholds(this.scene.getEnemyField(), battle.battleType === BattleType.TRAINER ? ModifierPoolType.TRAINER : ModifierPoolType.WILD);
this.scene.generateEnemyModifiers();
}
@ -632,6 +633,8 @@ export class SummonPhase extends PartyMemberPokemonPhase {
const playerPokemon = this.scene.getPlayerPokemon() as Pokemon;
if (playerPokemon.visible)
this.scene.field.moveBelow(pokemon, playerPokemon);
this.scene.currentBattle.seenEnemyPartyMemberIds.add(pokemon.id);
this.scene.updateModifiers(false);
}
pokemon.showInfo();
pokemon.playAnim();
@ -2753,7 +2756,7 @@ export class SelectModifierPhase extends BattlePhase {
this.scene.resetSeed();
const party = this.scene.getParty();
regenerateModifierPoolThresholds(party);
regenerateModifierPoolThresholds(party, ModifierPoolType.PLAYER);
const modifierCount = new Utils.IntegerHolder(3);
this.scene.applyModifiers(ExtraModifierModifier, true, modifierCount);
const typeOptions: Array<ModifierTypeOption> = getPlayerModifierTypeOptionsForWave(this.scene.currentBattle.waveIndex, modifierCount.value, party);

View File

@ -16,7 +16,7 @@ import { GameData } from './system/game-data';
import StarterSelectUiHandler from './ui/starter-select-ui-handler';
import { TextStyle, addTextObject } from './ui/text';
import { Moves, initMoves } from './data/move';
import { getDefaultModifierTypeForTier, getEnemyModifierTypesForWave } from './modifier/modifier-type';
import { ModifierPoolType, getDefaultModifierTypeForTier, getEnemyModifierTypesForWave } from './modifier/modifier-type';
import AbilityBar from './ui/ability-bar';
import { BlockItemTheftAbAttr, DoubleBattleChanceAbAttr, applyAbAttrs, initAbilities } from './data/ability';
import Battle, { BattleType, FixedBattleConfig, fixedBattles } from './battle';
@ -1128,7 +1128,10 @@ export default class BattleScene extends Phaser.Scene {
const isBoss = !(waveIndex % 10);
let count = 0;
for (let c = 0; c < chances; c++) {
if (!Utils.randInt(!isBoss ? 12 : 4))
let modifierChance = !isBoss ? 16 : 6;
if (this.currentBattle.battleType === BattleType.TRAINER)
modifierChance /= 2;
if (!Utils.randSeedInt(modifierChance))
count++;
if (count === 12)
break;
@ -1136,7 +1139,7 @@ export default class BattleScene extends Phaser.Scene {
if (isBoss)
count = Math.max(count, Math.floor(chances / 2));
const enemyField = this.getEnemyField();
getEnemyModifierTypesForWave(waveIndex, count, this.getEnemyField())
getEnemyModifierTypesForWave(waveIndex, count, this.getEnemyField(), this.currentBattle.battleType === BattleType.TRAINER ? ModifierPoolType.TRAINER : ModifierPoolType.WILD)
.map(mt => mt.newModifier(enemyField[Utils.randInt(enemyField.length)]).add(this.enemyModifiers, false));
this.updateModifiers(false).then(() => resolve());

View File

@ -37,6 +37,7 @@ export default class Battle {
public trainer: Trainer;
public enemyLevels: integer[];
public enemyParty: EnemyPokemon[];
public seenEnemyPartyMemberIds: Set<integer>;
public double: boolean;
public started: boolean;
public turn: integer;
@ -54,6 +55,7 @@ export default class Battle {
? new Array(double ? 2 : 1).fill(null).map(() => this.getLevelForWave())
: trainer.getPartyLevels(this.waveIndex);
this.enemyParty = [];
this.seenEnemyPartyMemberIds = new Set<integer>();
this.double = double;
this.turn = 0;
this.started = false;

View File

@ -2177,7 +2177,7 @@ function applyMoveAttrsInternal(attrFilter: MoveAttrFilter, user: Pokemon, targe
const moveAttrs = move.attrs.filter(a => attrFilter(a));
for (let attr of moveAttrs) {
const result = attr.apply(user, target, move, args);
if (result instanceof Promise<boolean>)
if (result instanceof Promise)
attrPromises.push(result);
}
Promise.allSettled(attrPromises).then(() => resolve());

View File

@ -23,6 +23,12 @@ export enum ModifierTier {
LUXURY
};
export enum ModifierPoolType {
PLAYER,
WILD,
TRAINER
}
type NewModifierFunc = (type: ModifierType, args: any[]) => Modifier;
export class ModifierType {
@ -623,7 +629,7 @@ export const modifierTypes = {
GOLDEN_EXP_CHARM: () => new ExpBoosterModifierType('Golden EXP. Charm', 75),
LUCKY_EGG: () => new PokemonExpBoosterModifierType('Lucky Egg', 50),
GOLDEN_EGG: () => new PokemonExpBoosterModifierType('Golden Egg', 200),
GOLDEN_EGG: () => new PokemonExpBoosterModifierType('Golden Egg', 150),
GRIP_CLAW: () => new ContactHeldItemTransferChanceModifierType('Grip Claw', 10),
@ -719,7 +725,7 @@ const modifierPool = {
new WeightedModifierType(modifierTypes.MAP, (party: Pokemon[]) => party[0].scene.gameMode === GameMode.CLASSIC ? 1 : 0),
new WeightedModifierType(modifierTypes.TM_GREAT, 2),
new WeightedModifierType(modifierTypes.EXP_SHARE, 1),
new WeightedModifierType(modifierTypes.BASE_STAT_BOOSTER, 3)
new WeightedModifierType(modifierTypes.BASE_STAT_BOOSTER, 3),
].map(m => { m.setTier(ModifierTier.GREAT); return m; }),
[ModifierTier.ULTRA]: [
new WeightedModifierType(modifierTypes.ULTRA_BALL, 8),
@ -738,7 +744,7 @@ const modifierPool = {
new WeightedModifierType(modifierTypes.BERRY_POUCH, 3),
new WeightedModifierType(modifierTypes.EXP_CHARM, 4),
new WeightedModifierType(modifierTypes.OVAL_CHARM, 2),
new WeightedModifierType(modifierTypes.EXP_BALANCE, 1)
new WeightedModifierType(modifierTypes.EXP_BALANCE, 1),
].map(m => { m.setTier(ModifierTier.ULTRA); return m; }),
[ModifierTier.MASTER]: [
new WeightedModifierType(modifierTypes.MASTER_BALL, 3),
@ -748,11 +754,11 @@ const modifierPool = {
[ModifierTier.LUXURY]: [
new WeightedModifierType(modifierTypes.GOLDEN_EXP_CHARM, 1),
new WeightedModifierType(modifierTypes.GOLDEN_POKEBALL, 1),
new WeightedModifierType(modifierTypes.RARER_CANDY, 1)
new WeightedModifierType(modifierTypes.RARER_CANDY, 1),
].map(m => { m.setTier(ModifierTier.LUXURY); return m; }),
};
const enemyModifierPool = {
const wildModifierPool = {
[ModifierTier.COMMON]: [
new WeightedModifierType(modifierTypes.BERRY, 1)
].map(m => { m.setTier(ModifierTier.COMMON); return m; }),
@ -760,16 +766,34 @@ const enemyModifierPool = {
new WeightedModifierType(modifierTypes.BASE_STAT_BOOSTER, 1)
].map(m => { m.setTier(ModifierTier.GREAT); return m; }),
[ModifierTier.ULTRA]: [
new WeightedModifierType(modifierTypes.REVIVER_SEED, 2),
new WeightedModifierType(modifierTypes.ATTACK_TYPE_BOOSTER, 10),
new WeightedModifierType(modifierTypes.LUCKY_EGG, 4),
].map(m => { m.setTier(ModifierTier.ULTRA); return m; }),
[ModifierTier.MASTER]: [
new WeightedModifierType(modifierTypes.GOLDEN_EGG, 1)
].map(m => { m.setTier(ModifierTier.MASTER); return m; })
};
const trainerModifierPool = {
[ModifierTier.COMMON]: [
new WeightedModifierType(modifierTypes.BERRY, 8),
new WeightedModifierType(modifierTypes.BASE_STAT_BOOSTER, 3)
].map(m => { m.setTier(ModifierTier.COMMON); return m; }),
[ModifierTier.GREAT]: [
new WeightedModifierType(modifierTypes.BASE_STAT_BOOSTER, 3),
new WeightedModifierType(modifierTypes.ATTACK_TYPE_BOOSTER, 1),
].map(m => { m.setTier(ModifierTier.GREAT); return m; }),
[ModifierTier.ULTRA]: [
new WeightedModifierType(modifierTypes.REVIVER_SEED, 2),
new WeightedModifierType(modifierTypes.FOCUS_BAND, 2),
new WeightedModifierType(modifierTypes.LUCKY_EGG, 4),
new WeightedModifierType(modifierTypes.GRIP_CLAW, 1),
new WeightedModifierType(modifierTypes.KINGS_ROCK, 1),
new WeightedModifierType(modifierTypes.LEFTOVERS, 1),
new WeightedModifierType(modifierTypes.SHELL_BELL, 1),
].map(m => { m.setTier(ModifierTier.ULTRA); return m; }),
[ModifierTier.MASTER]: [
new WeightedModifierType(modifierTypes.GOLDEN_EGG, 1)
new WeightedModifierType(modifierTypes.GOLDEN_EGG, 1),
].map(m => { m.setTier(ModifierTier.MASTER); return m; })
};
@ -779,10 +803,9 @@ let ignoredPoolIndexes = {};
let enemyModifierPoolThresholds = {};
let enemyIgnoredPoolIndexes = {};
export function regenerateModifierPoolThresholds(party: Pokemon[], player?: boolean) {
if (player === undefined)
player = true;
const pool = player ? modifierPool : enemyModifierPool;
export function regenerateModifierPoolThresholds(party: Pokemon[], poolType: ModifierPoolType) {
const player = !poolType;
const pool = player ? modifierPool : poolType === ModifierPoolType.WILD ? wildModifierPool : trainerModifierPool;
const ignoredIndexes = {};
const thresholds = Object.fromEntries(new Map(Object.keys(pool).map(t => {
ignoredIndexes[t] = [];
@ -826,25 +849,24 @@ export function getPlayerModifierTypeOptionsForWave(waveIndex: integer, count: i
const options: ModifierTypeOption[] = [];
const retryCount = Math.min(count * 5, 50);
new Array(count).fill(0).map(() => {
let candidate = getNewModifierTypeOption(party);
let candidate = getNewModifierTypeOption(party, ModifierPoolType.PLAYER);
let r = 0;
while (options.length && ++r < retryCount && options.filter(o => o.type.name === candidate.type.name || o.type.group === candidate.type.group).length)
candidate = getNewModifierTypeOption(party, true, candidate.type.tier, candidate.upgraded);
candidate = getNewModifierTypeOption(party, ModifierPoolType.PLAYER, candidate.type.tier, candidate.upgraded);
options.push(candidate);
});
return options;
}
export function getEnemyModifierTypesForWave(waveIndex: integer, count: integer, party: EnemyPokemon[]): PokemonHeldItemModifierType[] {
const ret = new Array(count).fill(0).map(() => getNewModifierTypeOption(party, false).type as PokemonHeldItemModifierType);
export function getEnemyModifierTypesForWave(waveIndex: integer, count: integer, party: EnemyPokemon[], poolType: ModifierPoolType.WILD | ModifierPoolType.TRAINER): PokemonHeldItemModifierType[] {
const ret = new Array(count).fill(0).map(() => getNewModifierTypeOption(party, poolType).type as PokemonHeldItemModifierType);
if (waveIndex === 200)
ret.push(modifierTypes.MINI_BLACK_HOLE());
return ret;
}
function getNewModifierTypeOption(party: Pokemon[], player?: boolean, tier?: ModifierTier, upgrade?: boolean): ModifierTypeOption {
if (player === undefined)
player = true;
function getNewModifierTypeOption(party: Pokemon[], poolType: ModifierPoolType, tier?: ModifierTier, upgrade?: boolean): ModifierTypeOption {
const player = !poolType;
if (tier === undefined) {
const tierValue = Utils.randSeedInt(256);
if (player && tierValue) {
@ -870,13 +892,13 @@ function getNewModifierTypeOption(party: Pokemon[], player?: boolean, tier?: Mod
if (player)
console.log(index, ignoredPoolIndexes[tier].filter(i => i <= index).length, ignoredPoolIndexes[tier])
let modifierType: ModifierType = ((player ? modifierPool : enemyModifierPool)[tier][index]).modifierType;
let modifierType: ModifierType = ((player ? modifierPool : poolType === ModifierPoolType.WILD ? wildModifierPool : trainerModifierPool)[tier][index]).modifierType;
if (modifierType instanceof ModifierTypeGenerator) {
modifierType = (modifierType as ModifierTypeGenerator).generateType(party);
if (modifierType === null) {
if (player)
console.log(ModifierTier[tier], upgrade);
return getNewModifierTypeOption(party, player, tier, upgrade);
return getNewModifierTypeOption(party, poolType, tier, upgrade);
}
}

View File

@ -334,10 +334,13 @@ export abstract class PokemonHeldItemModifier extends PersistentModifier {
if (!forSummary) {
const pokemon = this.getPokemon(scene);
const pokemonIcon = scene.add.sprite(0, 8, pokemon.species.getIconAtlasKey());
if (pokemon.species.isObtainable())
pokemonIcon.play(pokemon.getIconKey()).stop();
else {
const isIconShown = pokemon instanceof PlayerPokemon || scene.currentBattle.seenEnemyPartyMemberIds.has(pokemon.id);
const iconAtlasKey = isIconShown ? pokemon.species.getIconAtlasKey() : 'pokemon_icons_0';
const pokemonIcon = scene.add.sprite(0, 8, iconAtlasKey);
if (pokemon.species.isObtainable()) {
const iconKey = isIconShown ? pokemon.getIconKey() : 'pkmn_icon__000';
pokemonIcon.play(iconKey).stop();
} else {
if (pokemon.species.speciesId === Species.ETERNATUS)
pokemonIcon.setScale(0.5, 0.5);
else
@ -395,7 +398,7 @@ export class PokemonBaseStatModifier extends PokemonHeldItemModifier {
}
shouldApply(args: any[]): boolean {
return super.shouldApply(args) && args.length === 2 && args[1] instanceof Array<integer>;
return super.shouldApply(args) && args.length === 2 && args[1] instanceof Array;
}
apply(args: any[]): boolean {

View File

@ -226,6 +226,8 @@ export class GameData {
sessionData.enemyParty.forEach((enemyData, e) => {
const enemyPokemon = enemyData.toPokemon(scene) as EnemyPokemon;
battle.enemyParty[e] = enemyPokemon;
if (battleType === BattleType.WILD)
battle.seenEnemyPartyMemberIds.add(enemyPokemon.id);
loadPokemonAssets.push(enemyPokemon.loadAssets());
});

View File

@ -47,7 +47,7 @@ export function addTextObject(scene: Phaser.Scene, x: number, y: number, content
if (extraStyleOptions) {
if (extraStyleOptions.fontSize) {
const sizeRatio = parseInt(extraStyleOptions.fontSize.slice(0, -2)) / parseInt(styleOptions.fontSize.slice(0, -2));
const sizeRatio = parseInt(extraStyleOptions.fontSize.toString().slice(0, -2)) / parseInt(styleOptions.fontSize.slice(0, -2));
shadowSize *= sizeRatio;
}
styleOptions = Object.assign(styleOptions, extraStyleOptions);