Something (#4728)
* [Feature] Add event-based friendship multiplier and update TrainerConfig for event modifiers * [UI][Dev] Improve event banner placement (#4726) * [ui] automatically place event banner and timer in the title screen * add new event banner * ugh * [Refactor] Clean up TrainerConfig and remove unused timed event --------- Co-authored-by: Moka <54149968+MokaStitcher@users.noreply.github.com>
After Width: | Height: | Size: 26 KiB |
After Width: | Height: | Size: 15 KiB |
After Width: | Height: | Size: 15 KiB |
After Width: | Height: | Size: 26 KiB |
After Width: | Height: | Size: 15 KiB |
After Width: | Height: | Size: 25 KiB |
After Width: | Height: | Size: 16 KiB |
After Width: | Height: | Size: 25 KiB |
After Width: | Height: | Size: 85 KiB |
|
@ -203,6 +203,7 @@ export class TrainerConfig {
|
||||||
public modifierRewardFuncs: ModifierTypeFunc[] = [];
|
public modifierRewardFuncs: ModifierTypeFunc[] = [];
|
||||||
public partyTemplates: TrainerPartyTemplate[];
|
public partyTemplates: TrainerPartyTemplate[];
|
||||||
public partyTemplateFunc: PartyTemplateFunc;
|
public partyTemplateFunc: PartyTemplateFunc;
|
||||||
|
public eventRewardFuncs: ModifierTypeFunc[] = [];
|
||||||
public partyMemberFuncs: PartyMemberFuncs = {};
|
public partyMemberFuncs: PartyMemberFuncs = {};
|
||||||
public speciesPools: TrainerTierPools;
|
public speciesPools: TrainerTierPools;
|
||||||
public speciesFilter: PokemonSpeciesFilter;
|
public speciesFilter: PokemonSpeciesFilter;
|
||||||
|
@ -546,6 +547,17 @@ export class TrainerConfig {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
setEventModifierRewardFuncs(...modifierTypeFuncs: (() => ModifierTypeFunc)[]): TrainerConfig {
|
||||||
|
this.eventRewardFuncs = modifierTypeFuncs.map(func => () => {
|
||||||
|
const modifierTypeFunc = func();
|
||||||
|
const modifierType = modifierTypeFunc();
|
||||||
|
modifierType.withIdFromFunc(modifierTypeFunc);
|
||||||
|
return modifierType;
|
||||||
|
});
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
setModifierRewardFuncs(...modifierTypeFuncs: (() => ModifierTypeFunc)[]): TrainerConfig {
|
setModifierRewardFuncs(...modifierTypeFuncs: (() => ModifierTypeFunc)[]): TrainerConfig {
|
||||||
this.modifierRewardFuncs = modifierTypeFuncs.map(func => () => {
|
this.modifierRewardFuncs = modifierTypeFuncs.map(func => () => {
|
||||||
const modifierTypeFunc = func();
|
const modifierTypeFunc = func();
|
||||||
|
@ -1828,10 +1840,12 @@ export const trainerConfigs: TrainerConfigs = {
|
||||||
|
|
||||||
[TrainerType.RIVAL]: new TrainerConfig((t = TrainerType.RIVAL)).setName("Finn").setHasGenders("Ivy").setHasCharSprite().setTitle("Rival").setStaticParty().setEncounterBgm(TrainerType.RIVAL).setBattleBgm("battle_rival").setMixedBattleBgm("battle_rival").setPartyTemplates(trainerPartyTemplates.RIVAL)
|
[TrainerType.RIVAL]: new TrainerConfig((t = TrainerType.RIVAL)).setName("Finn").setHasGenders("Ivy").setHasCharSprite().setTitle("Rival").setStaticParty().setEncounterBgm(TrainerType.RIVAL).setBattleBgm("battle_rival").setMixedBattleBgm("battle_rival").setPartyTemplates(trainerPartyTemplates.RIVAL)
|
||||||
.setModifierRewardFuncs(() => modifierTypes.SUPER_EXP_CHARM, () => modifierTypes.EXP_SHARE)
|
.setModifierRewardFuncs(() => modifierTypes.SUPER_EXP_CHARM, () => modifierTypes.EXP_SHARE)
|
||||||
|
.setEventModifierRewardFuncs(() => modifierTypes.SHINY_CHARM, () => modifierTypes.ABILITY_CHARM)
|
||||||
.setPartyMemberFunc(0, getRandomPartyMemberFunc([ Species.BULBASAUR, Species.CHARMANDER, Species.SQUIRTLE, Species.CHIKORITA, Species.CYNDAQUIL, Species.TOTODILE, Species.TREECKO, Species.TORCHIC, Species.MUDKIP, Species.TURTWIG, Species.CHIMCHAR, Species.PIPLUP, Species.SNIVY, Species.TEPIG, Species.OSHAWOTT, Species.CHESPIN, Species.FENNEKIN, Species.FROAKIE, Species.ROWLET, Species.LITTEN, Species.POPPLIO, Species.GROOKEY, Species.SCORBUNNY, Species.SOBBLE, Species.SPRIGATITO, Species.FUECOCO, Species.QUAXLY ], TrainerSlot.TRAINER, true))
|
.setPartyMemberFunc(0, getRandomPartyMemberFunc([ Species.BULBASAUR, Species.CHARMANDER, Species.SQUIRTLE, Species.CHIKORITA, Species.CYNDAQUIL, Species.TOTODILE, Species.TREECKO, Species.TORCHIC, Species.MUDKIP, Species.TURTWIG, Species.CHIMCHAR, Species.PIPLUP, Species.SNIVY, Species.TEPIG, Species.OSHAWOTT, Species.CHESPIN, Species.FENNEKIN, Species.FROAKIE, Species.ROWLET, Species.LITTEN, Species.POPPLIO, Species.GROOKEY, Species.SCORBUNNY, Species.SOBBLE, Species.SPRIGATITO, Species.FUECOCO, Species.QUAXLY ], TrainerSlot.TRAINER, true))
|
||||||
.setPartyMemberFunc(1, getRandomPartyMemberFunc([ Species.PIDGEY, Species.HOOTHOOT, Species.TAILLOW, Species.STARLY, Species.PIDOVE, Species.FLETCHLING, Species.PIKIPEK, Species.ROOKIDEE, Species.WATTREL ], TrainerSlot.TRAINER, true)),
|
.setPartyMemberFunc(1, getRandomPartyMemberFunc([ Species.PIDGEY, Species.HOOTHOOT, Species.TAILLOW, Species.STARLY, Species.PIDOVE, Species.FLETCHLING, Species.PIKIPEK, Species.ROOKIDEE, Species.WATTREL ], TrainerSlot.TRAINER, true)),
|
||||||
[TrainerType.RIVAL_2]: new TrainerConfig(++t).setName("Finn").setHasGenders("Ivy").setHasCharSprite().setTitle("Rival").setStaticParty().setMoneyMultiplier(1.25).setEncounterBgm(TrainerType.RIVAL).setBattleBgm("battle_rival").setMixedBattleBgm("battle_rival").setPartyTemplates(trainerPartyTemplates.RIVAL_2)
|
[TrainerType.RIVAL_2]: new TrainerConfig(++t).setName("Finn").setHasGenders("Ivy").setHasCharSprite().setTitle("Rival").setStaticParty().setMoneyMultiplier(1.25).setEncounterBgm(TrainerType.RIVAL).setBattleBgm("battle_rival").setMixedBattleBgm("battle_rival").setPartyTemplates(trainerPartyTemplates.RIVAL_2)
|
||||||
.setModifierRewardFuncs(() => modifierTypes.EXP_SHARE)
|
.setModifierRewardFuncs(() => modifierTypes.EXP_SHARE)
|
||||||
|
.setEventModifierRewardFuncs(() => modifierTypes.SHINY_CHARM)
|
||||||
.setPartyMemberFunc(0, getRandomPartyMemberFunc([ Species.IVYSAUR, Species.CHARMELEON, Species.WARTORTLE, Species.BAYLEEF, Species.QUILAVA, Species.CROCONAW, Species.GROVYLE, Species.COMBUSKEN, Species.MARSHTOMP, Species.GROTLE, Species.MONFERNO, Species.PRINPLUP, Species.SERVINE, Species.PIGNITE, Species.DEWOTT, Species.QUILLADIN, Species.BRAIXEN, Species.FROGADIER, Species.DARTRIX, Species.TORRACAT, Species.BRIONNE, Species.THWACKEY, Species.RABOOT, Species.DRIZZILE, Species.FLORAGATO, Species.CROCALOR, Species.QUAXWELL ], TrainerSlot.TRAINER, true))
|
.setPartyMemberFunc(0, getRandomPartyMemberFunc([ Species.IVYSAUR, Species.CHARMELEON, Species.WARTORTLE, Species.BAYLEEF, Species.QUILAVA, Species.CROCONAW, Species.GROVYLE, Species.COMBUSKEN, Species.MARSHTOMP, Species.GROTLE, Species.MONFERNO, Species.PRINPLUP, Species.SERVINE, Species.PIGNITE, Species.DEWOTT, Species.QUILLADIN, Species.BRAIXEN, Species.FROGADIER, Species.DARTRIX, Species.TORRACAT, Species.BRIONNE, Species.THWACKEY, Species.RABOOT, Species.DRIZZILE, Species.FLORAGATO, Species.CROCALOR, Species.QUAXWELL ], TrainerSlot.TRAINER, true))
|
||||||
.setPartyMemberFunc(1, getRandomPartyMemberFunc([ Species.PIDGEOTTO, Species.HOOTHOOT, Species.TAILLOW, Species.STARAVIA, Species.TRANQUILL, Species.FLETCHINDER, Species.TRUMBEAK, Species.CORVISQUIRE, Species.WATTREL ], TrainerSlot.TRAINER, true))
|
.setPartyMemberFunc(1, getRandomPartyMemberFunc([ Species.PIDGEOTTO, Species.HOOTHOOT, Species.TAILLOW, Species.STARAVIA, Species.TRANQUILL, Species.FLETCHINDER, Species.TRUMBEAK, Species.CORVISQUIRE, Species.WATTREL ], TrainerSlot.TRAINER, true))
|
||||||
.setPartyMemberFunc(2, getSpeciesFilterRandomPartyMemberFunc((species: PokemonSpecies) => !pokemonEvolutions.hasOwnProperty(species.speciesId) && !pokemonPrevolutions.hasOwnProperty(species.speciesId) && species.baseTotal >= 450)),
|
.setPartyMemberFunc(2, getSpeciesFilterRandomPartyMemberFunc((species: PokemonSpecies) => !pokemonEvolutions.hasOwnProperty(species.speciesId) && !pokemonPrevolutions.hasOwnProperty(species.speciesId) && species.baseTotal >= 450)),
|
||||||
|
|
|
@ -4114,7 +4114,11 @@ export class PlayerPokemon extends Pokemon {
|
||||||
fusionStarterSpeciesId ? this.scene.gameData.starterData[fusionStarterSpeciesId] : null
|
fusionStarterSpeciesId ? this.scene.gameData.starterData[fusionStarterSpeciesId] : null
|
||||||
].filter(d => !!d);
|
].filter(d => !!d);
|
||||||
const amount = new Utils.IntegerHolder(friendship);
|
const amount = new Utils.IntegerHolder(friendship);
|
||||||
const starterAmount = new Utils.IntegerHolder(Math.floor(friendship * (this.scene.gameMode.isClassic && friendship > 0 ? CLASSIC_CANDY_FRIENDSHIP_MULTIPLIER : 1) / (fusionStarterSpeciesId ? 2 : 1)));
|
let candyFriendshipMultiplier = CLASSIC_CANDY_FRIENDSHIP_MULTIPLIER;
|
||||||
|
if (this.scene.eventManager.isEventActive()) {
|
||||||
|
candyFriendshipMultiplier *= this.scene.eventManager.getFriendshipMultiplier();
|
||||||
|
}
|
||||||
|
const starterAmount = new Utils.IntegerHolder(Math.floor(friendship * (this.scene.gameMode.isClassic && friendship > 0 ? candyFriendshipMultiplier : 1) / (fusionStarterSpeciesId ? 2 : 1)));
|
||||||
if (amount.value > 0) {
|
if (amount.value > 0) {
|
||||||
this.scene.applyModifier(PokemonFriendshipBoosterModifier, true, this, amount);
|
this.scene.applyModifier(PokemonFriendshipBoosterModifier, true, this, amount);
|
||||||
this.scene.applyModifier(PokemonFriendshipBoosterModifier, true, this, starterAmount);
|
this.scene.applyModifier(PokemonFriendshipBoosterModifier, true, this, starterAmount);
|
||||||
|
|
|
@ -246,9 +246,9 @@ export class LoadingScene extends SceneBase {
|
||||||
}
|
}
|
||||||
const availableLangs = [ "en", "de", "it", "fr", "ja", "ko", "es", "pt-BR", "zh-CN" ];
|
const availableLangs = [ "en", "de", "it", "fr", "ja", "ko", "es", "pt-BR", "zh-CN" ];
|
||||||
if (lang && availableLangs.includes(lang)) {
|
if (lang && availableLangs.includes(lang)) {
|
||||||
this.loadImage("egg-update_" + lang, "events");
|
this.loadImage("halloween2024-event-" + lang, "events");
|
||||||
} else {
|
} else {
|
||||||
this.loadImage("egg-update_en", "events");
|
this.loadImage("halloween2024-event-en", "events");
|
||||||
}
|
}
|
||||||
|
|
||||||
this.loadAtlas("statuses", "");
|
this.loadAtlas("statuses", "");
|
||||||
|
|
|
@ -1301,13 +1301,12 @@ function lureWeightFunc(maxBattles: number, weight: number): WeightedModifierTyp
|
||||||
return !(party[0].scene.gameMode.isClassic && party[0].scene.currentBattle.waveIndex === 199) && (lures.length === 0 || lures.filter(m => m.getMaxBattles() === maxBattles && m.getBattleCount() >= maxBattles * 0.6).length === 0) ? weight : 0;
|
return !(party[0].scene.gameMode.isClassic && party[0].scene.currentBattle.waveIndex === 199) && (lures.length === 0 || lures.filter(m => m.getMaxBattles() === maxBattles && m.getBattleCount() >= maxBattles * 0.6).length === 0) ? weight : 0;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
class WeightedModifierType {
|
class WeightedModifierType {
|
||||||
public modifierType: ModifierType;
|
public modifierType: ModifierType;
|
||||||
public weight: integer | WeightedModifierTypeWeightFunc;
|
public weight: integer | WeightedModifierTypeWeightFunc;
|
||||||
public maxWeight: integer;
|
public maxWeight: integer | WeightedModifierTypeWeightFunc;
|
||||||
|
|
||||||
constructor(modifierTypeFunc: ModifierTypeFunc, weight: integer | WeightedModifierTypeWeightFunc, maxWeight?: integer) {
|
constructor(modifierTypeFunc: ModifierTypeFunc, weight: integer | WeightedModifierTypeWeightFunc, maxWeight?: integer | WeightedModifierTypeWeightFunc) {
|
||||||
this.modifierType = modifierTypeFunc();
|
this.modifierType = modifierTypeFunc();
|
||||||
this.modifierType.id = Object.keys(modifierTypes).find(k => modifierTypes[k] === modifierTypeFunc)!; // TODO: is this bang correct?
|
this.modifierType.id = Object.keys(modifierTypes).find(k => modifierTypes[k] === modifierTypeFunc)!; // TODO: is this bang correct?
|
||||||
this.weight = weight;
|
this.weight = weight;
|
||||||
|
@ -1694,7 +1693,10 @@ const modifierPool: ModifierPool = {
|
||||||
new WeightedModifierType(modifierTypes.EVOLUTION_ITEM, (party: Pokemon[]) => {
|
new WeightedModifierType(modifierTypes.EVOLUTION_ITEM, (party: Pokemon[]) => {
|
||||||
return Math.min(Math.ceil(party[0].scene.currentBattle.waveIndex / 15), 8);
|
return Math.min(Math.ceil(party[0].scene.currentBattle.waveIndex / 15), 8);
|
||||||
}, 8),
|
}, 8),
|
||||||
new WeightedModifierType(modifierTypes.MAP, (party: Pokemon[]) => party[0].scene.gameMode.isClassic && party[0].scene.currentBattle.waveIndex < 180 ? 1 : 0, 1),
|
new WeightedModifierType(modifierTypes.MAP,
|
||||||
|
(party: Pokemon[]) => party[0].scene.gameMode.isClassic && party[0].scene.currentBattle.waveIndex < 180 ? party[0].scene.eventManager.isEventActive() ? 2 : 1 : 0,
|
||||||
|
(party: Pokemon[]) => party[0].scene.eventManager.isEventActive() ? 2 : 1),
|
||||||
|
new WeightedModifierType(modifierTypes.SOOTHE_BELL, (party: Pokemon[]) => party[0].scene.eventManager.isEventActive() ? 3 : 0),
|
||||||
new WeightedModifierType(modifierTypes.TM_GREAT, 3),
|
new WeightedModifierType(modifierTypes.TM_GREAT, 3),
|
||||||
new WeightedModifierType(modifierTypes.MEMORY_MUSHROOM, (party: Pokemon[]) => {
|
new WeightedModifierType(modifierTypes.MEMORY_MUSHROOM, (party: Pokemon[]) => {
|
||||||
if (!party.find(p => p.getLearnableLevelMoves().length)) {
|
if (!party.find(p => p.getLearnableLevelMoves().length)) {
|
||||||
|
@ -1762,7 +1764,7 @@ const modifierPool: ModifierPool = {
|
||||||
new WeightedModifierType(modifierTypes.CANDY_JAR, skipInLastClassicWaveOrDefault(5)),
|
new WeightedModifierType(modifierTypes.CANDY_JAR, skipInLastClassicWaveOrDefault(5)),
|
||||||
new WeightedModifierType(modifierTypes.ATTACK_TYPE_BOOSTER, 9),
|
new WeightedModifierType(modifierTypes.ATTACK_TYPE_BOOSTER, 9),
|
||||||
new WeightedModifierType(modifierTypes.TM_ULTRA, 11),
|
new WeightedModifierType(modifierTypes.TM_ULTRA, 11),
|
||||||
new WeightedModifierType(modifierTypes.RARER_CANDY, 4),
|
new WeightedModifierType(modifierTypes.RARER_CANDY, (party: Pokemon[]) => party[0].scene.eventManager.isEventActive() ? 6 : 4),
|
||||||
new WeightedModifierType(modifierTypes.GOLDEN_PUNCH, skipInLastClassicWaveOrDefault(2)),
|
new WeightedModifierType(modifierTypes.GOLDEN_PUNCH, skipInLastClassicWaveOrDefault(2)),
|
||||||
new WeightedModifierType(modifierTypes.IV_SCANNER, skipInLastClassicWaveOrDefault(4)),
|
new WeightedModifierType(modifierTypes.IV_SCANNER, skipInLastClassicWaveOrDefault(4)),
|
||||||
new WeightedModifierType(modifierTypes.EXP_CHARM, skipInLastClassicWaveOrDefault(8)),
|
new WeightedModifierType(modifierTypes.EXP_CHARM, skipInLastClassicWaveOrDefault(8)),
|
||||||
|
@ -1785,7 +1787,7 @@ const modifierPool: ModifierPool = {
|
||||||
new WeightedModifierType(modifierTypes.BATON, 2),
|
new WeightedModifierType(modifierTypes.BATON, 2),
|
||||||
new WeightedModifierType(modifierTypes.SOUL_DEW, 7),
|
new WeightedModifierType(modifierTypes.SOUL_DEW, 7),
|
||||||
//new WeightedModifierType(modifierTypes.OVAL_CHARM, 6),
|
//new WeightedModifierType(modifierTypes.OVAL_CHARM, 6),
|
||||||
new WeightedModifierType(modifierTypes.SOOTHE_BELL, 4),
|
new WeightedModifierType(modifierTypes.SOOTHE_BELL, (party: Pokemon[]) => party[0].scene.eventManager.isEventActive() ? 0 : 4),
|
||||||
new WeightedModifierType(modifierTypes.ABILITY_CHARM, skipInClassicAfterWave(189, 6)),
|
new WeightedModifierType(modifierTypes.ABILITY_CHARM, skipInClassicAfterWave(189, 6)),
|
||||||
new WeightedModifierType(modifierTypes.FOCUS_BAND, 5),
|
new WeightedModifierType(modifierTypes.FOCUS_BAND, 5),
|
||||||
new WeightedModifierType(modifierTypes.KINGS_ROCK, 3),
|
new WeightedModifierType(modifierTypes.KINGS_ROCK, 3),
|
||||||
|
|
|
@ -27,6 +27,12 @@ export class TrainerVictoryPhase extends BattlePhase {
|
||||||
this.scene.unshiftPhase(new ModifierRewardPhase(this.scene, modifierRewardFunc));
|
this.scene.unshiftPhase(new ModifierRewardPhase(this.scene, modifierRewardFunc));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (this.scene.eventManager.isEventActive()) {
|
||||||
|
for (const rewardFunc of this.scene.currentBattle.trainer?.config.eventRewardFuncs!) {
|
||||||
|
this.scene.unshiftPhase(new ModifierRewardPhase(this.scene, rewardFunc));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const trainerType = this.scene.currentBattle.trainer?.config.trainerType!; // TODO: is this bang correct?
|
const trainerType = this.scene.currentBattle.trainer?.config.trainerType!; // TODO: is this bang correct?
|
||||||
if (vouchers.hasOwnProperty(TrainerType[trainerType])) {
|
if (vouchers.hasOwnProperty(TrainerType[trainerType])) {
|
||||||
if (!this.scene.validateVoucher(vouchers[TrainerType[trainerType]]) && this.scene.currentBattle.trainer?.config.isBoss) {
|
if (!this.scene.validateVoucher(vouchers[TrainerType[trainerType]]) && this.scene.currentBattle.trainer?.config.isBoss) {
|
||||||
|
|
|
@ -5,13 +5,13 @@ import i18next from "i18next";
|
||||||
|
|
||||||
export enum EventType {
|
export enum EventType {
|
||||||
SHINY,
|
SHINY,
|
||||||
GENERIC
|
NO_TIMER_DISPLAY
|
||||||
}
|
}
|
||||||
|
|
||||||
interface EventBanner {
|
interface EventBanner {
|
||||||
bannerKey?: string;
|
bannerKey?: string;
|
||||||
xPosition?: number;
|
xOffset?: number;
|
||||||
yPosition?: number;
|
yOffset?: number;
|
||||||
scale?: number;
|
scale?: number;
|
||||||
availableLangs?: string[];
|
availableLangs?: string[];
|
||||||
}
|
}
|
||||||
|
@ -20,19 +20,20 @@ interface TimedEvent extends EventBanner {
|
||||||
name: string;
|
name: string;
|
||||||
eventType: EventType;
|
eventType: EventType;
|
||||||
shinyMultiplier?: number;
|
shinyMultiplier?: number;
|
||||||
|
friendshipMultiplier?: number;
|
||||||
startDate: Date;
|
startDate: Date;
|
||||||
endDate: Date;
|
endDate: Date;
|
||||||
}
|
}
|
||||||
|
|
||||||
const timedEvents: TimedEvent[] = [
|
const timedEvents: TimedEvent[] = [
|
||||||
{
|
{
|
||||||
name: "Egg Skip Update",
|
name: "Halloween Update",
|
||||||
eventType: EventType.GENERIC,
|
eventType: EventType.SHINY,
|
||||||
startDate: new Date(Date.UTC(2024, 8, 8, 0)),
|
shinyMultiplier: 2,
|
||||||
endDate: new Date(Date.UTC(2024, 8, 12, 0)),
|
friendshipMultiplier: 2,
|
||||||
bannerKey: "egg-update",
|
startDate: new Date(Date.UTC(2024, 9, 25, 0)),
|
||||||
xPosition: 19,
|
endDate: new Date(Date.UTC(2024, 10, 4, 0)),
|
||||||
yPosition: 120,
|
bannerKey: "halloween2024-event-",
|
||||||
scale: 0.21,
|
scale: 0.21,
|
||||||
availableLangs: [ "en", "de", "it", "fr", "ja", "ko", "es", "pt-BR", "zh-CN" ]
|
availableLangs: [ "en", "de", "it", "fr", "ja", "ko", "es", "pt-BR", "zh-CN" ]
|
||||||
}
|
}
|
||||||
|
@ -61,6 +62,16 @@ export class TimedEventManager {
|
||||||
return activeEvents.length > 0;
|
return activeEvents.length > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getFriendshipMultiplier(): number {
|
||||||
|
let multiplier = 1;
|
||||||
|
const friendshipEvents = timedEvents.filter((te) => this.isActive(te));
|
||||||
|
friendshipEvents.forEach((fe) => {
|
||||||
|
multiplier *= fe.friendshipMultiplier ?? 1;
|
||||||
|
});
|
||||||
|
|
||||||
|
return multiplier;
|
||||||
|
}
|
||||||
|
|
||||||
getShinyMultiplier(): number {
|
getShinyMultiplier(): number {
|
||||||
let multiplier = 1;
|
let multiplier = 1;
|
||||||
const shinyEvents = timedEvents.filter((te) => te.eventType === EventType.SHINY && this.isActive(te));
|
const shinyEvents = timedEvents.filter((te) => te.eventType === EventType.SHINY && this.isActive(te));
|
||||||
|
@ -80,42 +91,63 @@ export class TimedEventDisplay extends Phaser.GameObjects.Container {
|
||||||
private event: TimedEvent | nil;
|
private event: TimedEvent | nil;
|
||||||
private eventTimerText: Phaser.GameObjects.Text;
|
private eventTimerText: Phaser.GameObjects.Text;
|
||||||
private banner: Phaser.GameObjects.Image;
|
private banner: Phaser.GameObjects.Image;
|
||||||
private bannerShadow: Phaser.GameObjects.Rectangle;
|
private availableWidth: number;
|
||||||
private eventTimer: NodeJS.Timeout | null;
|
private eventTimer: NodeJS.Timeout | null;
|
||||||
|
|
||||||
constructor(scene: BattleScene, x: number, y: number, event?: TimedEvent) {
|
constructor(scene: BattleScene, x: number, y: number, event?: TimedEvent) {
|
||||||
super(scene, x, y);
|
super(scene, x, y);
|
||||||
|
this.availableWidth = scene.scaledCanvas.width;
|
||||||
this.event = event;
|
this.event = event;
|
||||||
this.setVisible(false);
|
this.setVisible(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the width that can be used to display the event timer and banner. By default
|
||||||
|
* these elements get centered horizontally in that space, in the bottom left of the screen
|
||||||
|
*/
|
||||||
|
setWidth(width: number) {
|
||||||
|
if (width !== this.availableWidth) {
|
||||||
|
this.availableWidth = width;
|
||||||
|
const xPosition = this.availableWidth / 2 + (this.event?.xOffset ?? 0);
|
||||||
|
if (this.banner) {
|
||||||
|
this.banner.x = xPosition;
|
||||||
|
}
|
||||||
|
if (this.eventTimerText) {
|
||||||
|
this.eventTimerText.x = xPosition;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
setup() {
|
setup() {
|
||||||
const lang = i18next.resolvedLanguage;
|
const lang = i18next.resolvedLanguage;
|
||||||
if (this.event && this.event.bannerKey) {
|
if (this.event && this.event.bannerKey) {
|
||||||
let key = this.event.bannerKey;
|
let key = this.event.bannerKey;
|
||||||
if (lang && this.event.availableLangs && this.event.availableLangs.length > 0) {
|
if (lang && this.event.availableLangs && this.event.availableLangs.length > 0) {
|
||||||
if (this.event.availableLangs.includes(lang)) {
|
if (this.event.availableLangs.includes(lang)) {
|
||||||
key += "_" + lang;
|
key += lang;
|
||||||
} else {
|
} else {
|
||||||
key += "_en";
|
key += "en";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
console.log(this.event.bannerKey);
|
console.log(this.event.bannerKey);
|
||||||
this.banner = new Phaser.GameObjects.Image(this.scene, this.event.xPosition ?? 29, this.event.yPosition ?? 64, key);
|
const padding = 5;
|
||||||
|
const showTimer = this.event.eventType !== EventType.NO_TIMER_DISPLAY;
|
||||||
|
const yPosition = this.scene.game.canvas.height / 6 - padding - (showTimer ? 10 : 0) - (this.event.yOffset ?? 0);
|
||||||
|
this.banner = new Phaser.GameObjects.Image(this.scene, this.availableWidth / 2, yPosition - padding, key);
|
||||||
this.banner.setName("img-event-banner");
|
this.banner.setName("img-event-banner");
|
||||||
this.banner.setOrigin(0.08, -0.35);
|
this.banner.setOrigin(0.5, 1);
|
||||||
this.banner.setScale(this.event.scale ?? 0.18);
|
this.banner.setScale(this.event.scale ?? 0.18);
|
||||||
if (this.event.eventType !== EventType.GENERIC) {
|
if (showTimer) {
|
||||||
this.eventTimerText = addTextObject(
|
this.eventTimerText = addTextObject(
|
||||||
this.scene,
|
this.scene,
|
||||||
this.banner.x + 8,
|
this.banner.x,
|
||||||
this.banner.y + 100,
|
this.banner.y + 2,
|
||||||
this.timeToGo(this.event.endDate),
|
this.timeToGo(this.event.endDate),
|
||||||
TextStyle.WINDOW
|
TextStyle.WINDOW
|
||||||
);
|
);
|
||||||
this.eventTimerText.setName("text-event-timer");
|
this.eventTimerText.setName("text-event-timer");
|
||||||
this.eventTimerText.setScale(0.15);
|
this.eventTimerText.setScale(0.15);
|
||||||
this.eventTimerText.setOrigin(0, 0);
|
this.eventTimerText.setOrigin(0.5, 0);
|
||||||
|
|
||||||
this.add(this.eventTimerText);
|
this.add(this.eventTimerText);
|
||||||
}
|
}
|
||||||
|
@ -161,7 +193,7 @@ export class TimedEventDisplay extends Phaser.GameObjects.Container {
|
||||||
}
|
}
|
||||||
|
|
||||||
updateCountdown() {
|
updateCountdown() {
|
||||||
if (this.event && this.event.eventType !== EventType.GENERIC) {
|
if (this.event && this.event.eventType !== EventType.NO_TIMER_DISPLAY) {
|
||||||
this.eventTimerText.setText(this.timeToGo(this.event.endDate));
|
this.eventTimerText.setText(this.timeToGo(this.event.endDate));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -103,6 +103,7 @@ export default class TitleUiHandler extends OptionSelectUiHandler {
|
||||||
const ui = this.getUi();
|
const ui = this.getUi();
|
||||||
|
|
||||||
if (this.scene.eventManager.isEventActive()) {
|
if (this.scene.eventManager.isEventActive()) {
|
||||||
|
this.eventDisplay.setWidth(this.scene.scaledCanvas.width - this.optionSelectBg.width - this.optionSelectBg.x);
|
||||||
this.eventDisplay.show();
|
this.eventDisplay.show();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|