Revamp Gen 9 Free-For-All Random Battle (#11406)

* WIP free-for-all revamp

* bonus touches

* Create ffa-sets.json

* Most stuff besides items

* Fix plate distribution logic

* The Palafin thing

* Update teams.ts

* Update index.ts

* Update server/chat-plugins/randombattles/index.ts

Co-authored-by: pyuk-bot <21160928+pyuk-bot@users.noreply.github.com>

---------

Co-authored-by: MacChaeger <21160928+pyuk-bot@users.noreply.github.com>
Co-authored-by: Kris Johnson <11083252+KrisXV@users.noreply.github.com>
This commit is contained in:
ACakeWearingAHat 2025-09-01 00:58:46 -05:00 committed by GitHub
parent 8797d4628c
commit c3e0bbd61d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 8902 additions and 17 deletions

View File

@ -44,7 +44,7 @@ export const Formats: import('../sim/dex-formats').FormatList = [
{
name: "[Gen 9] Free-For-All Random Battle",
mod: 'gen9',
team: 'random',
team: 'randomFFA',
gameType: 'freeforall',
tournamentShow: false,
rated: false,

View File

@ -53,10 +53,12 @@ interface BSSFactorySet {
}
export class MoveCounter extends Utils.Multiset<string> {
damagingMoves: Set<Move>;
basePowerMoves: Set<Move>;
constructor() {
super();
this.damagingMoves = new Set();
this.basePowerMoves = new Set();
}
}
@ -413,6 +415,7 @@ export class RandomTeams {
if (move.drain) counter.add('drain');
// Moves which have a base power:
if (move.basePower || move.basePowerCallback) {
counter.basePowerMoves.add(move);
if (!this.noStab.includes(moveid) || PRIORITY_POKEMON.includes(species.id) && move.priority > 0) {
counter.add(moveType);
if (types.includes(moveType)) counter.add('stab');
@ -1096,19 +1099,6 @@ export class RandomTeams {
teraType: string,
role: RandomTeamsTypes.Role,
): string {
// ffa abilities that differ from doubles
if (this.format.gameType === 'freeforall') {
if (species.id === 'bellossom') return 'Chlorophyll';
if (species.id === 'sinistcha') return 'Heatproof';
if (abilities.length === 1 && abilities[0] === 'Telepathy') {
return species.id === 'oranguru' ? 'Inner Focus' : 'Pressure';
}
if (species.id === 'duraludon') return 'Light Metal';
if (species.id === 'clefairy') return 'Magic Guard';
if (species.id === 'blissey') return 'Natural Cure';
if (species.id === 'barraskewda') return 'Swift Swim';
}
if (abilities.length <= 1) return abilities[0];
// Hard-code abilities here

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -161,6 +161,7 @@ function getSets(species: string | Species, format: string | Format = 'gen9rando
let folderName = format.mod;
if (format.team === 'randomBaby') folderName += 'baby';
if (species.isNonstandard === 'CAP') folderName += 'cap';
if (format.team === 'randomFFA') folderName += 'ffa';
const setsFile = JSON.parse(
FS(`data/random-battles/${folderName}/${isDoubles ? 'doubles-' : ''}sets.json`)
.readIfExistsSync() || '{}'
@ -470,6 +471,10 @@ export const commands: Chat.ChatCommands = {
randdubs: 'randombattles',
babyrandombattle: 'randombattles',
babyrands: 'randombattles',
freeforallrandombattle: 'randombattles',
ffarands: 'randombattles',
randffats: 'randombattles',
randffa: 'randombattles',
// randombattlenodmax: 'randombattles',
// randsnodmax: 'randombattles',
randombattles(target, room, user, connection, cmd) {
@ -477,11 +482,13 @@ export const commands: Chat.ChatCommands = {
const battle = room?.battle;
let isDoubles = cmd === 'randomdoublesbattle' || cmd === 'randdubs';
let isBaby = cmd === 'babyrandombattle' || cmd === 'babyrands';
let isFFA = cmd === 'freeforallrandombattle' || cmd === 'ffarands' || cmd === 'randffats' || cmd === 'randffa';
let isNoDMax = cmd.includes('nodmax');
if (battle) {
if (battle.format.includes('nodmax')) isNoDMax = true;
if (battle.format.includes('doubles') || battle.gameType === 'freeforall') isDoubles = true;
if (battle.gameType === 'doubles') isDoubles = true;
if (battle.format.includes('baby')) isBaby = true;
if (battle.gameType === 'freeforall') isFFA = true;
}
const args = target.split(',');
@ -504,8 +511,9 @@ export const commands: Chat.ChatCommands = {
const extraFormatModifier = isLetsGo ? 'letsgo' : (dex.currentMod === 'gen8bdsp' ? 'bdsp' : '');
const babyModifier = isBaby ? 'baby' : '';
const doublesModifier = isDoubles ? 'doubles' : '';
const freeForAllModifier = isFFA ? (dex.gen !== 9 ? 'doubles' : 'freeforall') : '';
const noDMaxModifier = isNoDMax ? 'nodmax' : '';
const formatName = `gen${dex.gen}${extraFormatModifier}${babyModifier}random${doublesModifier}battle${noDMaxModifier}`;
const formatName = `gen${dex.gen}${extraFormatModifier}${freeForAllModifier}${babyModifier}random${doublesModifier}battle${noDMaxModifier}`;
const format = dex.formats.get(formatName);
const movesets = [];

View File

@ -476,6 +476,7 @@ declare namespace RandomTeamsTypes {
illusion?: number;
statusCure?: number;
teraBlast?: number;
imprison?: number;
}
export interface FactoryTeamDetails {
megaCount?: number;
@ -561,5 +562,5 @@ declare namespace RandomTeamsTypes {
'Bulky Attacker' | 'Bulky Setup' | 'Fast Bulky Setup' | 'Bulky Support' | 'Fast Support' | 'AV Pivot' |
'Doubles Fast Attacker' | 'Doubles Setup Sweeper' | 'Doubles Wallbreaker' | 'Doubles Bulky Attacker' |
'Doubles Bulky Setup' | 'Offensive Protect' | 'Bulky Protect' | 'Doubles Support' | 'Choice Item user' |
'Z-Move user' | 'Staller' | 'Spinner' | 'Generalist' | 'Berry Sweeper' | 'Thief user';
'Z-Move user' | 'Staller' | 'Spinner' | 'Generalist' | 'Berry Sweeper' | 'Thief user' | 'Imprisoner';
}

View File

@ -638,6 +638,8 @@ export const Teams = new class Teams {
TeamGenerator = require(`../data/random-battles/gen9baby/teams`).default;
} else if (formatID.includes('gen9randombattle') && format.ruleTable?.has('+pokemontag:cap')) {
TeamGenerator = require(`../data/random-battles/gen9cap/teams`).default;
} else if (formatID.includes('gen9freeforallrandombattle')) {
TeamGenerator = require(`../data/random-battles/gen9ffa/teams`).default;
} else {
TeamGenerator = require(`../data/random-battles/${mod}/teams`).default;
}