start clowning around encounter
This commit is contained in:
parent
e3ec09f88b
commit
de8a5b8987
|
@ -1430,7 +1430,7 @@ export default class BattleScene extends SceneBase {
|
|||
const wave = waveIndex || this.currentBattle?.waveIndex || 0;
|
||||
this.waveSeed = Utils.shiftCharCodes(this.seed, wave);
|
||||
Phaser.Math.RND.sow([ this.waveSeed ]);
|
||||
// console.log("Wave Seed:", this.waveSeed, wave);
|
||||
console.log("Wave Seed:", this.waveSeed, wave);
|
||||
this.rngCounter = 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,181 @@
|
|||
import {
|
||||
EnemyPartyConfig,
|
||||
initBattleWithEnemyConfig,
|
||||
setEncounterRewards,
|
||||
} from "#app/data/mystery-encounters/utils/encounter-phase-utils";
|
||||
import {
|
||||
trainerConfigs,
|
||||
TrainerPartyCompoundTemplate,
|
||||
TrainerPartyTemplate,
|
||||
} from "#app/data/trainer-config";
|
||||
import { ModifierTier } from "#app/modifier/modifier-tier";
|
||||
import { modifierTypes } from "#app/modifier/modifier-type";
|
||||
import { MysteryEncounterType } from "#enums/mystery-encounter-type";
|
||||
import { PartyMemberStrength } from "#enums/party-member-strength";
|
||||
import BattleScene from "#app/battle-scene";
|
||||
import IMysteryEncounter, { MysteryEncounterBuilder } from "../mystery-encounter";
|
||||
import { MysteryEncounterTier } from "#enums/mystery-encounter-tier";
|
||||
import { Species } from "#enums/species";
|
||||
import { TrainerType } from "#enums/trainer-type";
|
||||
import { getPokemonSpecies } from "#app/data/pokemon-species";
|
||||
|
||||
/** the i18n namespace for the encounter */
|
||||
const namespace = "mysteryEncounter:clowningAround";
|
||||
|
||||
/**
|
||||
* Clowning Around encounter.
|
||||
* @see {@link https://github.com/AsdarDevelops/PokeRogue-Events/issues/69 | GitHub Issue #69}
|
||||
* @see For biome requirements check {@linkcode mysteryEncountersByBiome}
|
||||
*/
|
||||
export const ClowningAroundEncounter: IMysteryEncounter =
|
||||
MysteryEncounterBuilder.withEncounterType(MysteryEncounterType.CLOWNING_AROUND)
|
||||
.withEncounterTier(MysteryEncounterTier.ULTRA)
|
||||
.withSceneWaveRangeRequirement(10, 180) // waves 10 to 180
|
||||
.withIntroSpriteConfigs([
|
||||
{
|
||||
spriteKey: Species.MR_MIME.toString(),
|
||||
fileRoot: "pokemon",
|
||||
hasShadow: true,
|
||||
repeat: true,
|
||||
x: -25,
|
||||
tint: 0.3,
|
||||
y: -3,
|
||||
yShadow: -3
|
||||
},
|
||||
{
|
||||
spriteKey: Species.BLACEPHALON.toString(),
|
||||
fileRoot: "pokemon/exp",
|
||||
hasShadow: true,
|
||||
repeat: true,
|
||||
x: 25,
|
||||
tint: 0.3,
|
||||
y: -3,
|
||||
yShadow: -3
|
||||
},
|
||||
{
|
||||
spriteKey: "harlequin",
|
||||
fileRoot: "trainer",
|
||||
hasShadow: true,
|
||||
x: 0
|
||||
},
|
||||
])
|
||||
.withIntroDialogue([
|
||||
{
|
||||
text: `${namespace}.intro`,
|
||||
},
|
||||
{
|
||||
text: `${namespace}.intro_dialogue`,
|
||||
speaker: `${namespace}.speaker`
|
||||
},
|
||||
])
|
||||
.withOnInit((scene: BattleScene) => {
|
||||
const encounter = scene.currentBattle.mysteryEncounter;
|
||||
|
||||
// Clown trainer is pulled from pool of boss trainers (gym leaders) for the biome
|
||||
// They are given an E4 template team, so will be stronger than usual boss encounter and always have 6 mons
|
||||
const clownTrainerType = TrainerType.HARLEQUIN;
|
||||
const clownPartyTemplate = new TrainerPartyCompoundTemplate(
|
||||
new TrainerPartyTemplate(1, PartyMemberStrength.STRONG),
|
||||
new TrainerPartyTemplate(1, PartyMemberStrength.STRONGER),
|
||||
new TrainerPartyTemplate(1, PartyMemberStrength.STRONG));
|
||||
const clownConfig = trainerConfigs[clownTrainerType].copy();
|
||||
clownConfig.setPartyTemplates(clownPartyTemplate);
|
||||
clownConfig.partyTemplateFunc = null; // Overrides party template func
|
||||
|
||||
encounter.enemyPartyConfigs.push({
|
||||
trainerConfig: clownConfig,
|
||||
pokemonConfigs: [ // Overrides first 2 pokemon to be Mr. Mime and Blacephalon
|
||||
{
|
||||
species: getPokemonSpecies(Species.MR_MIME),
|
||||
isBoss: false
|
||||
},
|
||||
{
|
||||
species: getPokemonSpecies(Species.BLACEPHALON),
|
||||
isBoss: true
|
||||
},
|
||||
]
|
||||
});
|
||||
|
||||
return true;
|
||||
})
|
||||
.withTitle(`${namespace}.title`)
|
||||
.withDescription(`${namespace}.description`)
|
||||
.withQuery(`${namespace}.query`)
|
||||
.withSimpleOption(
|
||||
{
|
||||
buttonLabel: `${namespace}.option.1.label`,
|
||||
buttonTooltip: `${namespace}.option.1.tooltip`,
|
||||
selected: [
|
||||
{
|
||||
text: `${namespace}.option.selected`,
|
||||
},
|
||||
],
|
||||
},
|
||||
async (scene: BattleScene) => {
|
||||
const encounter = scene.currentBattle.mysteryEncounter;
|
||||
// Spawn battle
|
||||
const config: EnemyPartyConfig = encounter.enemyPartyConfigs[0];
|
||||
|
||||
setEncounterRewards(scene, { guaranteedModifierTypeFuncs: [modifierTypes.TM_COMMON, modifierTypes.TM_GREAT, modifierTypes.MEMORY_MUSHROOM], fillRemaining: true });
|
||||
await initBattleWithEnemyConfig(scene, config);
|
||||
}
|
||||
)
|
||||
.withSimpleOption(
|
||||
{
|
||||
buttonLabel: `${namespace}.option.2.label`,
|
||||
buttonTooltip: `${namespace}.option.2.tooltip`,
|
||||
selected: [
|
||||
{
|
||||
text: `${namespace}.option.selected`,
|
||||
},
|
||||
],
|
||||
},
|
||||
async (scene: BattleScene) => {
|
||||
const encounter = scene.currentBattle.mysteryEncounter;
|
||||
// Spawn hard fight with ULTRA/GREAT reward (can improve with luck)
|
||||
const config: EnemyPartyConfig = encounter.enemyPartyConfigs[1];
|
||||
|
||||
setEncounterRewards(scene, { guaranteedModifierTiers: [ModifierTier.ULTRA, ModifierTier.ULTRA, ModifierTier.GREAT, ModifierTier.GREAT], fillRemaining: true });
|
||||
|
||||
// Seed offsets to remove possibility of different trainers having exact same teams
|
||||
let ret;
|
||||
scene.executeWithSeedOffset(() => {
|
||||
ret = initBattleWithEnemyConfig(scene, config);
|
||||
}, scene.currentBattle.waveIndex * 100);
|
||||
return ret;
|
||||
}
|
||||
)
|
||||
.withSimpleOption(
|
||||
{
|
||||
buttonLabel: `${namespace}.option.3.label`,
|
||||
buttonTooltip: `${namespace}.option.3.tooltip`,
|
||||
selected: [
|
||||
{
|
||||
text: `${namespace}.option.selected`,
|
||||
},
|
||||
],
|
||||
},
|
||||
async (scene: BattleScene) => {
|
||||
const encounter = scene.currentBattle.mysteryEncounter;
|
||||
// Spawn brutal fight with ROGUE/ULTRA/GREAT reward (can improve with luck)
|
||||
const config: EnemyPartyConfig = encounter.enemyPartyConfigs[2];
|
||||
|
||||
// To avoid player level snowballing from picking this option
|
||||
encounter.expMultiplier = 0.9;
|
||||
|
||||
setEncounterRewards(scene, { guaranteedModifierTiers: [ModifierTier.ROGUE, ModifierTier.ROGUE, ModifierTier.ULTRA, ModifierTier.GREAT], fillRemaining: true });
|
||||
|
||||
// Seed offsets to remove possibility of different trainers having exact same teams
|
||||
let ret;
|
||||
scene.executeWithSeedOffset(() => {
|
||||
ret = initBattleWithEnemyConfig(scene, config);
|
||||
}, scene.currentBattle.waveIndex * 1000);
|
||||
return ret;
|
||||
}
|
||||
)
|
||||
.withOutroDialogue([
|
||||
{
|
||||
text: `${namespace}.outro`,
|
||||
},
|
||||
])
|
||||
.build();
|
|
@ -21,6 +21,7 @@ import { AbsoluteAvariceEncounter } from "#app/data/mystery-encounters/encounter
|
|||
import { ATrainersTestEncounter } from "#app/data/mystery-encounters/encounters/a-trainers-test-encounter";
|
||||
import { TrashToTreasureEncounter } from "#app/data/mystery-encounters/encounters/trash-to-treasure-encounter";
|
||||
import { BerriesAboundEncounter } from "#app/data/mystery-encounters/encounters/berries-abound-encounter";
|
||||
import { ClowningAroundEncounter } from "#app/data/mystery-encounters/encounters/clowing-around-encounter";
|
||||
|
||||
// Spawn chance: (BASE_MYSTERY_ENCOUNTER_SPAWN_WEIGHT + WIGHT_INCREMENT_ON_SPAWN_MISS * <number of missed spawns>) / 256
|
||||
export const BASE_MYSTERY_ENCOUNTER_SPAWN_WEIGHT = 1;
|
||||
|
@ -141,7 +142,7 @@ const humanTransitableBiomeEncounters: MysteryEncounterType[] = [
|
|||
MysteryEncounterType.MYSTERIOUS_CHALLENGERS,
|
||||
MysteryEncounterType.SHADY_VITAMIN_DEALER,
|
||||
MysteryEncounterType.THE_POKEMON_SALESMAN,
|
||||
MysteryEncounterType.AN_OFFER_YOU_CANT_REFUSE
|
||||
MysteryEncounterType.AN_OFFER_YOU_CANT_REFUSE,
|
||||
];
|
||||
|
||||
const civilizationBiomeEncounters: MysteryEncounterType[] = [
|
||||
|
@ -159,7 +160,8 @@ const anyBiomeEncounters: MysteryEncounterType[] = [
|
|||
MysteryEncounterType.DELIBIRDY,
|
||||
MysteryEncounterType.A_TRAINERS_TEST,
|
||||
MysteryEncounterType.TRASH_TO_TREASURE,
|
||||
MysteryEncounterType.BERRIES_ABOUND
|
||||
MysteryEncounterType.BERRIES_ABOUND,
|
||||
MysteryEncounterType.CLOWNING_AROUND
|
||||
];
|
||||
|
||||
/**
|
||||
|
@ -249,6 +251,7 @@ export function initMysteryEncounters() {
|
|||
allMysteryEncounters[MysteryEncounterType.A_TRAINERS_TEST] = ATrainersTestEncounter;
|
||||
allMysteryEncounters[MysteryEncounterType.TRASH_TO_TREASURE] = TrashToTreasureEncounter;
|
||||
allMysteryEncounters[MysteryEncounterType.BERRIES_ABOUND] = BerriesAboundEncounter;
|
||||
allMysteryEncounters[MysteryEncounterType.CLOWNING_AROUND] = ClowningAroundEncounter;
|
||||
|
||||
// Add extreme encounters to biome map
|
||||
extremeBiomeEncounters.forEach(encounter => {
|
||||
|
|
|
@ -12,6 +12,7 @@ import PokemonData from "#app/system/pokemon-data";
|
|||
import { OptionSelectConfig, OptionSelectItem } from "#app/ui/abstact-option-select-ui-handler";
|
||||
import { PartyOption, PartyUiMode } from "#app/ui/party-ui-handler";
|
||||
import { Mode } from "#app/ui/ui";
|
||||
import * as Utils from "#app/utils";
|
||||
import { isNullOrUndefined } from "#app/utils";
|
||||
import { BattlerTagType } from "#enums/battler-tag-type";
|
||||
import { Biome } from "#enums/biome";
|
||||
|
@ -19,7 +20,6 @@ import { TrainerType } from "#enums/trainer-type";
|
|||
import i18next from "i18next";
|
||||
import BattleScene from "#app/battle-scene";
|
||||
import Trainer, { TrainerVariant } from "#app/field/trainer";
|
||||
import * as Utils from "#app/utils";
|
||||
import { Gender } from "#app/data/gender";
|
||||
import { Nature } from "#app/data/nature";
|
||||
import { Moves } from "#enums/moves";
|
||||
|
@ -152,7 +152,17 @@ export async function initBattleWithEnemyConfig(scene: BattleScene, partyConfig:
|
|||
let isBoss = false;
|
||||
if (!loaded) {
|
||||
if (trainerType || trainerConfig) {
|
||||
battle.enemyParty[e] = battle.trainer.genPartyMember(e);
|
||||
// Allows overriding a trainer's pokemon to use specific species/data
|
||||
if (e < partyConfig?.pokemonConfigs?.length) {
|
||||
const config = partyConfig?.pokemonConfigs?.[e];
|
||||
level = config.level ? config.level : level;
|
||||
dataSource = config.dataSource;
|
||||
enemySpecies = config.species;
|
||||
isBoss = config.isBoss;
|
||||
battle.enemyParty[e] = scene.addEnemyPokemon(enemySpecies, level, TrainerSlot.TRAINER, isBoss, dataSource);
|
||||
} else {
|
||||
battle.enemyParty[e] = battle.trainer.genPartyMember(e);
|
||||
}
|
||||
} else {
|
||||
if (e < partyConfig?.pokemonConfigs?.length) {
|
||||
const config = partyConfig?.pokemonConfigs?.[e];
|
||||
|
|
|
@ -18,5 +18,6 @@ export enum MysteryEncounterType {
|
|||
ABSOLUTE_AVARICE,
|
||||
A_TRAINERS_TEST,
|
||||
TRASH_TO_TREASURE,
|
||||
BERRIES_ABOUND
|
||||
BERRIES_ABOUND,
|
||||
CLOWNING_AROUND
|
||||
}
|
||||
|
|
|
@ -18,6 +18,7 @@ import { absoluteAvariceDialogue } from "#app/locales/en/mystery-encounters/abso
|
|||
import { aTrainersTestDialogue } from "#app/locales/en/mystery-encounters/a-trainers-test-dialogue";
|
||||
import { trashToTreasureDialogue } from "#app/locales/en/mystery-encounters/trash-to-treasure-dialogue";
|
||||
import { berriesAboundDialogue } from "#app/locales/en/mystery-encounters/berries-abound-dialogue";
|
||||
import { clowningAroundDialogue } from "#app/locales/en/mystery-encounters/clowning-around-dialogue";
|
||||
|
||||
/**
|
||||
* Patterns that can be used:
|
||||
|
@ -60,5 +61,6 @@ export const mysteryEncounter = {
|
|||
absoluteAvarice: absoluteAvariceDialogue,
|
||||
aTrainersTest: aTrainersTestDialogue,
|
||||
trashToTreasure: trashToTreasureDialogue,
|
||||
berriesAbound: berriesAboundDialogue
|
||||
berriesAbound: berriesAboundDialogue,
|
||||
clowningAround: clowningAroundDialogue
|
||||
} as const;
|
||||
|
|
|
@ -0,0 +1,33 @@
|
|||
export const clowningAroundDialogue = {
|
||||
intro: "It's...@d{64} a clown?",
|
||||
speaker: "Clown",
|
||||
intro_dialogue: `Bumbling buffoon,\nbrace for a brilliant battle!
|
||||
$You’ll be beaten by this brawling busker!\nBring it!`,
|
||||
title: "Clowning Around",
|
||||
description: "The clown seems eager to goad you into a battle, but to what end?\n\nSomething is off about this encounter.",
|
||||
query: "What will you do?",
|
||||
option: {
|
||||
1: {
|
||||
label: "Battle the Clown",
|
||||
tooltip: "(-) Strange Battle\n(?) Affects Pokémon Abilities",
|
||||
selected: "Your pitiful Pokémon are poised for a pathetic performance!"
|
||||
},
|
||||
2: {
|
||||
label: "Remain Unprovoked",
|
||||
tooltip: "(-) Upsets the Clown\n(?) Affects Pokémon Items",
|
||||
selected: "Dismal dodger, you deny a delightful duel?\nFeel my fury!",
|
||||
selected_2: `The clown's Blacephalon uses Trick!
|
||||
All of your {{switchPokemon}}'s items were randomly swapped!`,
|
||||
selected_3: "Flustered fool, fall for my flawless deception!",
|
||||
},
|
||||
3: {
|
||||
label: "Return the Insults",
|
||||
tooltip: "(-) Upsets the Clown\n(?) Affects Pokémon Types",
|
||||
selected: "I'm appalled at your absurd antics!\nTaste my temper!",
|
||||
selected_2: `The clown's Blacephalon uses\na move you've never seen before!
|
||||
All of your team's types were randomly swapped!`,
|
||||
selected_3: "Flustered fool, fall for my flawless deception!",
|
||||
},
|
||||
},
|
||||
outro: "The clown and his cohorts\ndisappear in a puff of smoke."
|
||||
};
|
|
@ -127,9 +127,9 @@ class DefaultOverrides {
|
|||
// -------------------------
|
||||
|
||||
// 1 to 256, set to null to ignore
|
||||
readonly MYSTERY_ENCOUNTER_RATE_OVERRIDE: number = null;
|
||||
readonly MYSTERY_ENCOUNTER_RATE_OVERRIDE: number = 256;
|
||||
readonly MYSTERY_ENCOUNTER_TIER_OVERRIDE: MysteryEncounterTier = null;
|
||||
readonly MYSTERY_ENCOUNTER_OVERRIDE: MysteryEncounterType = null;
|
||||
readonly MYSTERY_ENCOUNTER_OVERRIDE: MysteryEncounterType = MysteryEncounterType.CLOWNING_AROUND;
|
||||
|
||||
// -------------------------
|
||||
// MODIFIER / ITEM OVERRIDES
|
||||
|
|
Loading…
Reference in New Issue