Merge branch 'mystery-battle-events' into event/getting-lost-at-the-sea

This commit is contained in:
Felix Staud 2024-07-16 21:40:48 -07:00
commit 7653cffb5f
4 changed files with 80 additions and 22 deletions

View File

@ -9,7 +9,7 @@ body:
attributes:
label: Event Name
description: Name of the event
placeholder: e.g Fight or Flight
placeholder: e.g. "Fight or Flight"
validations:
required: true
- type: markdown # SEPARATOR
@ -20,15 +20,24 @@ body:
id: rarity
attributes:
label: Rarity Tier
description: Check out the [Event Proposal Guide](https://github.com/AsdarDevelops/PokeRogue-Events/blob/mystery-battle-events/MEs_Proposal_Guide.md) if you have not yet!
multiple: false
options:
- Common
- Great
- Ultra
- Rogue
- Part of a "Quest"
- Other or unsure (please specify)
- type: input
id: rarity-other
attributes:
label: Rarity Tier - Other. Please Specify
description: If you chose `Other` on the `Rarity Tier` please specify it here
placeholder: e.g. "I'm unsure of whether this should be Common or Great"
validations:
required: true
required: false
- type: markdown # SEPARATOR
attributes:
value: |
@ -37,8 +46,8 @@ body:
id: waves
attributes:
label: Waves
description: Classic/Challenge is 1 -200. Currently only 11-179 is supported.
placeholder: 1-200
description: Classic/Challenge ranges 1-200. Currently only 11-179 is supported.
placeholder: 11-179
validations:
required: true
- type: markdown # SEPARATOR
@ -49,8 +58,8 @@ body:
id: description
attributes:
label: Description
description: Describe the event you are proposing
placeholder: What is it?
description: Describe the event you are proposing. Explain its theme and how it's different from others. If the Event has any requirements to even trigger, detail them here too.
placeholder: e.g. "Fight or Flight is a common event where the player can fight a boss PKMN of the biome. The PKMN is stronger than usual, but also holds an item that's better than usual."
validations:
required: true
- type: markdown # SEPARATOR
@ -61,11 +70,13 @@ body:
id: biomes
attributes:
label: Biomes
description: Select all biomes where the event can occur
description: Select all biomes where the event can occur. "ANY, NON-EXTREME, CIVILIZATION and HUMAN are groups of biomes. Check the [Biomes part of the guide](https://github.com/AsdarDevelops/PokeRogue-Events/blob/mystery-battle-events/MEs_Proposal_Guide.md#biomes)."
multiple: true
options:
- ANY (no need to select all)
- NON-EXTREME (almost all except Space, Seabed, etc...)
- ANY
- NON-EXTREME
- HUMAN
- CIVILIZATION
- TOWN
- PLAINS
- GRASS
@ -104,6 +115,15 @@ body:
- OTHER (please specify)
validations:
required: true
- type: input
id: biome-other
attributes:
label: Biome - Other. Please Specify
description: If you chose `Other` on the `Biome` please specify it here
placeholder: e.g. "I would like to only trigger at Graveyard at night!"
validations:
required: false
- type: markdown # SEPARATOR
attributes:
value: |
@ -134,13 +154,25 @@ body:
attributes:
label: Explanation/Notes on Design
description: Explain why you think this design is right and what this Event brings to the table
placeholder: Explain why you think this design is right and what this Event brings to the table
placeholder: e.g. "We need more simple Events that mix slightly higher stakes with slightly better rewards"
validations:
required: true
- type: markdown # SEPARATOR
attributes:
value: |
---
- type: textarea
id: artist-notes
attributes:
label: Notes to Artists
description: Does your Event need custom spriting? If so, please detail them here (reference screenshots are helpful)
placeholder: Ie. "We currently don't have a Cynthia sprite while dressed in a Garchomp costume. RAWR! This is highly needed for my Event!"
validations:
required: false
- type: markdown # SEPARATOR
attributes:
value: |
---
- type: textarea
id: dev-notes
attributes:

View File

@ -1071,13 +1071,14 @@ export default class BattleScene extends SceneBase {
this.field.add(newTrainer);
}
// Check for mystery encounter
// Can only occur in place of a standard wild battle, waves 10-180
// TODO: remove this once spawn rates are finalized
// let testStartingWeight = 0;
// while (testStartingWeight < 20) {
// while (testStartingWeight < 3) {
// calculateMEAggregateStats(this, testStartingWeight);
// testStartingWeight += 1;
// }
// Check for mystery encounter
// Can only occur in place of a standard wild battle, waves 10-180
if (this.gameMode.hasMysteryEncounters && newBattleType === BattleType.WILD && !this.gameMode.isBoss(newWaveIndex) && newWaveIndex < 180 && newWaveIndex > 10) {
const roll = Utils.randSeedInt(256);
@ -2651,7 +2652,7 @@ export default class BattleScene extends SceneBase {
}
// Common / Uncommon / Rare / Super Rare
const tierWeights = [61, 40, 21, 6];
const tierWeights = [64, 40, 21, 3];
// Adjust tier weights by previously encountered events to lower odds of only common/uncommons in run
this.mysteryEncounterData.encounteredEvents.forEach(val => {
@ -2681,10 +2682,23 @@ export default class BattleScene extends SceneBase {
// If no valid encounters exist at tier, checks next tier down, continuing until there are some encounters available
while (availableEncounters.length === 0 && tier >= 0) {
availableEncounters = biomeMysteryEncounters
.filter((encounterType) =>
allMysteryEncounters[encounterType]?.meetsRequirements(this) &&
allMysteryEncounters[encounterType].encounterTier === tier &&
(isNullOrUndefined(previousEncounter) || encounterType !== previousEncounter))
.filter((encounterType) => {
if (allMysteryEncounters[encounterType].encounterTier !== tier) { // Encounter is in tier
return false;
}
if (!allMysteryEncounters[encounterType]?.meetsRequirements(this)) { // Meets encounter requirements
return false;
}
if (!isNullOrUndefined(previousEncounter) && encounterType === previousEncounter) { // Previous encounter was not this one
return false;
}
if (this.mysteryEncounterData.encounteredEvents?.length > 0 && // Encounter has not exceeded max allowed encounters
allMysteryEncounters[encounterType].maxAllowedEncounters > 0
&& this.mysteryEncounterData.encounteredEvents.filter(e => e[0] === encounterType).length >= allMysteryEncounters[encounterType].maxAllowedEncounters) {
return false;
}
return true;
})
.map((m) => (allMysteryEncounters[m]));
tier--;
}

View File

@ -50,6 +50,7 @@ export default interface IMysteryEncounter {
hideBattleIntroMessage?: boolean;
hideIntroVisuals?: boolean;
catchAllowed?: boolean;
maxAllowedEncounters?: number;
doEncounterExp?: (scene: BattleScene) => boolean;
doEncounterRewards?: (scene: BattleScene) => boolean;
onInit?: (scene: BattleScene) => boolean;
@ -144,6 +145,8 @@ export default class IMysteryEncounter implements IMysteryEncounter {
}
this.encounterTier = this.encounterTier ? this.encounterTier : MysteryEncounterTier.COMMON;
this.dialogue = this.dialogue ?? {};
// Default max is 1 for ROGUE encounters, 3 for others
this.maxAllowedEncounters = this.maxAllowedEncounters ?? this.encounterTier === MysteryEncounterTier.ROGUE ? 1 : 3;
this.encounterVariant = MysteryEncounterVariant.DEFAULT;
this.requirements = this.requirements ? this.requirements : [];
this.hideBattleIntroMessage = !isNullOrUndefined(this.hideBattleIntroMessage) ? this.hideBattleIntroMessage : false;
@ -440,9 +443,9 @@ export class MysteryEncounterBuilder implements Partial<IMysteryEncounter> {
* If not specified, defaults to COMMON
* Tiers are:
* COMMON 32/64 odds
* UNCOMMON 16/64 odds
* RARE 10/64 odds
* SUPER_RARE 6/64 odds
* GREAT 16/64 odds
* ULTRA 10/64 odds
* ROGUE 6/64 odds
* ULTRA_RARE Not currently used
* @param encounterTier
* @returns
@ -451,6 +454,15 @@ export class MysteryEncounterBuilder implements Partial<IMysteryEncounter> {
return Object.assign(this, { encounterTier: encounterTier });
}
/**
* Sets the maximum number of times that an encounter can spawn in a given Classic run
* @param maxAllowedEncounters
* @returns
*/
withMaxAllowedEncounters(maxAllowedEncounters: number): this & Required<Pick<IMysteryEncounter, "maxAllowedEncounters">> {
return Object.assign(this, { maxAllowedEncounters: maxAllowedEncounters });
}
/**
* Specifies a requirement for an encounter
* For example, passing requirement as "new WaveCountRequirement([2, 180])" would create a requirement that the encounter can only be spawned between waves 2 and 180

View File

@ -634,7 +634,7 @@ export function calculateMEAggregateStats(scene: BattleScene, baseSpawnWeight: n
// Calculate encounter rarity
// Common / Uncommon / Rare / Super Rare (base is out of 128)
const tierWeights = [61, 40, 21, 6];
const tierWeights = [64, 40, 21, 3];
// Adjust tier weights by currently encountered events (pity system that lowers odds of multiple common/uncommons)
tierWeights[0] = tierWeights[0] - 6 * numEncounters[0];