Fixed phases which award rewards without going through the reward selection screen

This commit is contained in:
Wlowscha 2025-08-08 00:52:00 +02:00
parent 07dad0981d
commit 949467f9f4
No known key found for this signature in database
GPG Key ID: 3C8F1AD330565D04
7 changed files with 39 additions and 78 deletions

View File

@ -44,3 +44,9 @@ export type RewardPool = {
export interface RewardPoolWeights {
[tier: string]: number[];
}
export type SilentReward =
| TrainerItemId
| typeof RewardId.VOUCHER
| typeof RewardId.VOUCHER_PLUS
| typeof RewardId.VOUCHER_PREMIUM;

View File

@ -8,18 +8,17 @@ import { Gender } from "#data/gender";
import type { PokemonSpecies, PokemonSpeciesFilter } from "#data/pokemon-species";
import { AbilityId } from "#enums/ability-id";
import { MoveId } from "#enums/move-id";
import type { PartyMemberStrength } from "#enums/party-member-strength";
import { PartyMemberStrength } from "#enums/party-member-strength";
import { PokeballType } from "#enums/pokeball";
import { PokemonType } from "#enums/pokemon-type";
import { SpeciesId } from "#enums/species-id";
import { TeraAIMode } from "#enums/tera-ai-mode";
import { TrainerItemId } from "#enums/trainer-item-id";
import { TrainerPoolTier } from "#enums/trainer-pool-tier";
import { TrainerSlot } from "#enums/trainer-slot";
import { TrainerType } from "#enums/trainer-type";
import { TrainerVariant } from "#enums/trainer-variant";
import type { EnemyPokemon } from "#field/pokemon";
import { allRewards } from "#items/all-rewards";
import type { Reward, RewardGenerator } from "#items/reward";
import { PokemonMove } from "#moves/pokemon-move";
import { getIsInitialized, initI18n } from "#plugins/i18n";
import type { EvilTeam } from "#trainers/evil-admin-trainer-pools";
@ -29,9 +28,10 @@ import {
getGymLeaderPartyTemplate,
getWavePartyTemplate,
TrainerPartyCompoundTemplate,
type TrainerPartyTemplate,
TrainerPartyTemplate,
trainerPartyTemplates,
} from "#trainers/trainer-party-template";
import type { SilentReward } from "#types/rewards";
import type {
GenAIFunc,
GenTrainerItemsFunc,
@ -109,7 +109,7 @@ export class TrainerConfig {
public victoryBgm: string;
public genTrainerItemsFunc: GenTrainerItemsFunc;
public genAIFuncs: GenAIFunc[] = [];
public rewardFuncs: (Reward | RewardGenerator)[] = [];
public silentRewards: SilentReward[] = [];
public partyTemplates: TrainerPartyTemplate[];
public partyTemplateFunc: PartyTemplateFunc;
public partyMemberFuncs: PartyMemberFuncs = {};
@ -501,12 +501,8 @@ export class TrainerConfig {
return this;
}
setRewardFuncs(...rewardFuncs: (Reward | RewardGenerator)[]): TrainerConfig {
this.rewardFuncs = rewardFuncs.map(func => () => {
const rewardFunc = func();
const reward = rewardFunc();
return reward;
});
setSilentReward(...silentRewards: SilentReward[]): TrainerConfig {
this.silentRewards = silentRewards;
return this;
}
@ -911,9 +907,9 @@ export class TrainerConfig {
clone = this.victoryBgm ? clone.setVictoryBgm(this.victoryBgm) : clone;
clone = this.genTrainerItemsFunc ? clone.setGenTrainerItemsFunc(this.genTrainerItemsFunc) : clone;
if (this.rewardFuncs) {
if (this.silentRewards) {
// Clones array instead of passing ref
clone.rewardFuncs = this.rewardFuncs.slice(0);
clone.silentRewards = this.silentRewards.slice(0);
}
if (this.partyTemplates) {
@ -4471,10 +4467,7 @@ export const trainerConfigs: TrainerConfigs = {
.setBattleBgm("battle_rival")
.setMixedBattleBgm("battle_rival")
.setPartyTemplates(trainerPartyTemplates.RIVAL)
.setRewardFuncs(
() => allRewards.SUPER_EXP_CHARM,
() => allRewards.EXP_SHARE,
)
.setSilentReward(TrainerItemId.SUPER_EXP_CHARM, TrainerItemId.EXP_SHARE)
.setPartyMemberFunc(
0,
getRandomPartyMemberFunc(
@ -4541,7 +4534,7 @@ export const trainerConfigs: TrainerConfigs = {
.setBattleBgm("battle_rival")
.setMixedBattleBgm("battle_rival")
.setPartyTemplates(trainerPartyTemplates.RIVAL_2)
.setRewardFuncs(() => allRewards.EXP_SHARE)
.setSilentReward(TrainerItemId.EXP_SHARE)
.setPartyMemberFunc(
0,
getRandomPartyMemberFunc(
@ -4694,7 +4687,7 @@ export const trainerConfigs: TrainerConfigs = {
.setBattleBgm("battle_rival_2")
.setMixedBattleBgm("battle_rival_2")
.setPartyTemplates(trainerPartyTemplates.RIVAL_4)
.setRewardFuncs(() => allRewards.TERA_ORB)
.setSilentReward(TrainerItemId.TERA_ORB)
.setPartyMemberFunc(
0,
getRandomPartyMemberFunc(

View File

@ -7,15 +7,14 @@ export class GameOverRewardPhase extends RewardPhase {
public readonly phaseName = "GameOverRewardPhase";
doReward(): Promise<void> {
return new Promise<void>(resolve => {
const newModifier = this.reward.newModifier();
globalScene.addModifier(newModifier);
globalScene.applyReward(this.reward, {});
// Sound loaded into game as is
globalScene.playSound("level_up_fanfare");
globalScene.ui.setMode(UiMode.MESSAGE);
globalScene.ui.fadeIn(250).then(() => {
globalScene.ui.showText(
i18next.t("battle:rewardGain", {
modifierName: newModifier?.type.name,
modifierName: this.reward.name,
}),
null,
() => {

View File

@ -1,6 +1,8 @@
import { globalScene } from "#app/global-scene";
import type { Reward, RewardGenerator } from "#items/reward";
import type { Reward } from "#items/reward";
import { generateRewardOptionFromId } from "#items/reward-utils";
import { BattlePhase } from "#phases/battle-phase";
import type { SilentReward } from "#types/rewards";
import i18next from "i18next";
export class RewardPhase extends BattlePhase {
@ -9,10 +11,10 @@ export class RewardPhase extends BattlePhase {
public readonly phaseName: "RewardPhase" | "RibbonRewardPhase" | "GameOverRewardPhase" = "RewardPhase";
protected reward: Reward;
constructor(rewardFunc: Reward | RewardGenerator) {
constructor(rewardId: SilentReward) {
super();
this.reward = rewardFunc();
this.reward = generateRewardOptionFromId(rewardId)?.type;
}
start() {
@ -23,7 +25,7 @@ export class RewardPhase extends BattlePhase {
doReward(): Promise<void> {
return new Promise<void>(resolve => {
globalScene.applyReward(this.reward);
globalScene.applyReward(this.reward, {});
globalScene.playSound("item_fanfare");
globalScene.ui.showText(
i18next.t("battle:rewardGain", {

View File

@ -1,31 +1,30 @@
import { globalScene } from "#app/global-scene";
import type { PokemonSpecies } from "#data/pokemon-species";
import { UiMode } from "#enums/ui-mode";
import type { Reward, RewardGenerator } from "#items/reward";
import { RewardPhase } from "#phases/reward-phase";
import type { SilentReward } from "#types/rewards";
import i18next from "i18next";
export class RibbonRewardPhase extends RewardPhase {
public readonly phaseName = "RibbonRewardPhase";
private species: PokemonSpecies;
constructor(rewardFunc: Reward | RewardGenerator, species: PokemonSpecies) {
super(rewardFunc);
constructor(rewardId: SilentReward, species: PokemonSpecies) {
super(rewardId);
this.species = species;
}
doReward(): Promise<void> {
return new Promise<void>(resolve => {
const newModifier = this.reward.newModifier();
globalScene.addModifier(newModifier);
globalScene.applyReward(this.reward, {});
globalScene.playSound("level_up_fanfare");
globalScene.ui.setMode(UiMode.MESSAGE);
globalScene.ui.showText(
i18next.t("battle:beatModeFirstTime", {
speciesName: this.species.name,
gameMode: globalScene.gameMode.getName(),
newModifier: newModifier?.type.name,
newModifier: this.reward.name,
}),
null,
() => {

View File

@ -1,40 +0,0 @@
import { globalScene } from "#app/global-scene";
import { type Reward, RewardGenerator } from "#items/reward";
import { BattlePhase } from "#phases/battle-phase";
import i18next from "i18next";
export class RewardPhase extends BattlePhase {
// RibbonRewardPhase extends RewardPhase and to make typescript happy
// we need to use a union type here
public readonly phaseName: "RewardPhase" | "RibbonRewardPhase" | "GameOverRewardPhase" = "RewardPhase";
protected reward: Reward;
constructor(rewardFunc: Reward | RewardGenerator) {
super();
const reward = rewardFunc();
this.reward = reward instanceof RewardGenerator ? reward.generateReward() : reward;
}
start() {
super.start();
this.doReward().then(() => this.end());
}
doReward(): Promise<void> {
return new Promise<void>(resolve => {
globalScene.applyReward(this.reward);
globalScene.playSound("item_fanfare");
globalScene.ui.showText(
i18next.t("battle:rewardGain", {
modifierName: this.reward.name,
}),
null,
() => resolve(),
null,
true,
);
});
}
}

View File

@ -1,8 +1,8 @@
import { timedEventManager } from "#app/global-event-manager";
import { globalScene } from "#app/global-scene";
import { allRewards } from "#data/data-lists";
import { getCharVariantFromDialogue } from "#data/dialogue";
import { BiomeId } from "#enums/biome-id";
import { RewardId } from "#enums/reward-id";
import { TrainerSlot } from "#enums/trainer-slot";
import { TrainerType } from "#enums/trainer-type";
import { BattlePhase } from "#phases/battle-phase";
@ -20,9 +20,11 @@ export class TrainerVictoryPhase extends BattlePhase {
globalScene.phaseManager.unshiftNew("MoneyRewardPhase", globalScene.currentBattle.trainer?.config.moneyMultiplier!); // TODO: is this bang correct?
const rewardFuncs = globalScene.currentBattle.trainer?.config.rewardFuncs!; // TODO: is this bang correct?
for (const rewardFunc of rewardFuncs) {
globalScene.phaseManager.unshiftNew("RewardPhase", rewardFunc);
const silentRewards = globalScene.currentBattle.trainer?.config.silentRewards; // TODO: is this bang correct?
if (silentRewards) {
for (const id of silentRewards) {
globalScene.phaseManager.unshiftNew("RewardPhase", id);
}
}
const trainerType = globalScene.currentBattle.trainer?.config.trainerType!; // TODO: is this bang correct?
@ -35,14 +37,14 @@ export class TrainerVictoryPhase extends BattlePhase {
if (timedEventManager.getUpgradeUnlockedVouchers()) {
globalScene.phaseManager.unshiftNew(
"RewardPhase",
[allRewards.VOUCHER_PLUS, allRewards.VOUCHER_PLUS, allRewards.VOUCHER_PLUS, allRewards.VOUCHER_PREMIUM][
[RewardId.VOUCHER_PLUS, RewardId.VOUCHER_PLUS, RewardId.VOUCHER_PLUS, RewardId.VOUCHER_PREMIUM][
vouchers[TrainerType[trainerType]].voucherType
],
);
} else {
globalScene.phaseManager.unshiftNew(
"RewardPhase",
[allRewards.VOUCHER, allRewards.VOUCHER, allRewards.VOUCHER_PLUS, allRewards.VOUCHER_PREMIUM][
[RewardId.VOUCHER, RewardId.VOUCHER, RewardId.VOUCHER_PLUS, RewardId.VOUCHER_PREMIUM][
vouchers[TrainerType[trainerType]].voucherType
],
);