Let's Go: Implement itemless megas (#10212)

This commit is contained in:
Karthik 2024-03-24 19:56:13 -07:00 committed by GitHub
parent e34d184c2b
commit 76c2e598c6
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
9 changed files with 128 additions and 11 deletions

View File

@ -4,8 +4,71 @@ export const Scripts: ModdedBattleScriptsData = {
this.modData('Abilities', 'noability').isNonstandard = null;
for (const i in this.data.Pokedex) {
this.modData('Pokedex', i).abilities = {0: 'No Ability'};
delete this.modData('Pokedex', i).requiredItem;
}
},
actions: {
canMegaEvo(pokemon) {
const species = pokemon.baseSpecies;
const altForme = this.dex.species.get(species.otherFormes?.find(f => f.endsWith('-Mega')));
if (
altForme.exists && !this.battle.ruleTable.check(`pokemon:${altForme.id}`) &&
!this.battle.ruleTable.check('pokemontag:mega')
) {
return altForme.name;
}
return null;
},
canMegaEvoX(pokemon) {
const species = pokemon.baseSpecies;
const altForme = this.dex.species.get(species.otherFormes?.find(f => f.endsWith('-Mega-X')));
if (
altForme.exists && !this.battle.ruleTable.check(`pokemon:${altForme.id}`) &&
!this.battle.ruleTable.check('pokemontag:mega')
) {
return altForme.name;
}
return null;
},
canMegaEvoY(pokemon) {
const species = pokemon.baseSpecies;
const altForme = this.dex.species.get(species.otherFormes?.find(f => f.endsWith('-Mega-Y')));
if (
altForme.exists && !this.battle.ruleTable.check(`pokemon:${altForme.id}`) &&
!this.battle.ruleTable.check('pokemontag:mega')
) {
return altForme.name;
}
return null;
},
runMegaEvo(pokemon) {
const speciesid = pokemon.canMegaEvo || pokemon.canMegaEvoX || pokemon.canMegaEvoY;
if (!speciesid) return false;
pokemon.formeChange(speciesid, null, true);
this.battle.add('-mega', pokemon, this.dex.species.get(speciesid).baseSpecies);
// Limit one mega evolution
for (const ally of pokemon.side.pokemon) {
ally.canMegaEvo = null;
ally.canMegaEvoX = null;
ally.canMegaEvoY = null;
}
this.battle.runEvent('AfterMega', pokemon);
return true;
},
runMegaEvoX(pokemon) {
if (!pokemon.canMegaEvoX) return false;
pokemon.canMegaEvoY = null;
return this.runMegaEvo(pokemon);
},
runMegaEvoY(pokemon) {
if (!pokemon.canMegaEvoY) return false;
pokemon.canMegaEvoX = null;
return this.runMegaEvo(pokemon);
},
},
/**
* Given a table of base stats and a pokemon set, return the actual stats.
*/

View File

@ -1896,6 +1896,12 @@ export class BattleActions {
return true;
}
// Let's Go
canMegaEvoX?: (this: BattleActions, pokemon: Pokemon) => string | null;
canMegaEvoY?: (this: BattleActions, pokemon: Pokemon) => string | null;
runMegaEvoX?: (this: BattleActions, pokemon: Pokemon) => boolean;
runMegaEvoY?: (this: BattleActions, pokemon: Pokemon) => boolean;
canTerastallize(pokemon: Pokemon) {
if (pokemon.getItem().zMove || pokemon.canMegaEvo || this.dex.gen !== 9) {
return null;

View File

@ -92,7 +92,7 @@ export interface FieldAction {
/** A generic action done by a single pokemon */
export interface PokemonAction {
/** action type */
choice: 'megaEvo' | 'shift' | 'runPrimal' | 'runSwitch' | 'event' | 'runUnnerve' | 'runDynamax' | 'terastallize';
choice: 'megaEvo' | 'megaEvoX' | 'megaEvoY' | 'shift' | 'runPrimal' | 'runSwitch' | 'event' | 'runUnnerve' | 'runDynamax' | 'terastallize';
/** priority of the action (lower first) */
priority: number;
/** speed of pokemon doing action (higher first if priority tie) */
@ -179,6 +179,8 @@ export class BattleQueue {
runPrimal: 102,
switch: 103,
megaEvo: 104,
megaEvoX: 104,
megaEvoY: 104,
runDynamax: 105,
terastallize: 106,
priorityChargeMove: 107,
@ -210,6 +212,18 @@ export class BattleQueue {
pokemon: action.pokemon,
}));
}
if (action.megax && !action.pokemon.isSkyDropped()) {
actions.unshift(...this.resolveAction({
choice: 'megaEvoX',
pokemon: action.pokemon,
}));
}
if (action.megay && !action.pokemon.isSkyDropped()) {
actions.unshift(...this.resolveAction({
choice: 'megaEvoY',
pokemon: action.pokemon,
}));
}
if (action.terastallize && !action.pokemon.terastallized) {
actions.unshift(...this.resolveAction({
choice: 'terastallize',

View File

@ -2556,6 +2556,12 @@ export class Battle {
case 'megaEvo':
this.actions.runMegaEvo(action.pokemon);
break;
case 'megaEvoX':
this.actions.runMegaEvoX?.(action.pokemon);
break;
case 'megaEvoY':
this.actions.runMegaEvoY?.(action.pokemon);
break;
case 'runDynamax':
action.pokemon.addVolatile('dynamax');
action.pokemon.side.dynamaxUsed = true;
@ -2686,7 +2692,7 @@ export class Battle {
// in gen 3 or earlier, switching in fainted pokemon is done after
// every move, rather than only at the end of the turn.
this.checkFainted();
} else if (action.choice === 'megaEvo' && this.gen === 7) {
} else if (['megaEvo', 'megaEvoX', 'megaEvoY'].includes(action.choice) && this.gen === 7) {
this.eachEvent('Update');
// In Gen 7, the action order is recalculated for a Pokémon that mega evolves.
for (const [i, queuedAction] of this.queue.list.entries()) {

View File

@ -194,10 +194,6 @@ export class DexItems {
if (item.gen > this.dex.gen) {
(item as any).isNonstandard = 'Future';
}
// hack for allowing mega evolution in LGPE
if (this.dex.currentMod === 'gen7letsgo' && !item.isNonstandard && !item.megaStone) {
(item as any).isNonstandard = 'Past';
}
} else {
item = new Item({name: id, exists: false});
}

View File

@ -219,6 +219,8 @@ interface ModdedBattleActions {
afterMoveSecondaryEvent?: (this: BattleActions, targets: Pokemon[], pokemon: Pokemon, move: ActiveMove) => undefined;
calcRecoilDamage?: (this: BattleActions, damageDealt: number, move: Move, pokemon: Pokemon) => number;
canMegaEvo?: (this: BattleActions, pokemon: Pokemon) => string | undefined | null;
canMegaEvoX?: (this: BattleActions, pokemon: Pokemon) => string | null;
canMegaEvoY?: (this: BattleActions, pokemon: Pokemon) => string | null;
canUltraBurst?: (this: BattleActions, pokemon: Pokemon) => string | null;
canZMove?: (this: BattleActions, pokemon: Pokemon) => ZMoveOptions | void;
canDynamax?: (this: BattleActions, pokemon: Pokemon, skipChecks?: boolean) => DynamaxOptions | void;
@ -250,6 +252,8 @@ interface ModdedBattleActions {
) => number | undefined | false;
runAction?: (this: BattleActions, action: Action) => void;
runMegaEvo?: (this: BattleActions, pokemon: Pokemon) => boolean;
runMegaEvoX?: (this: BattleActions, pokemon: Pokemon) => boolean;
runMegaEvoY?: (this: BattleActions, pokemon: Pokemon) => boolean;
runMove?: (
this: BattleActions, moveOrMoveName: Move | string, pokemon: Pokemon, targetLoc: number, sourceEffect?: Effect | null,
zMove?: string, externalMove?: boolean, maxMove?: string, originalTarget?: Pokemon

View File

@ -253,6 +253,8 @@ export class Pokemon {
abilityOrder: number;
canMegaEvo: string | null | undefined;
canMegaEvoX: string | null | undefined;
canMegaEvoY: string | null | undefined;
canUltraBurst: string | null | undefined;
readonly canGigantamax: string | null;
/**
@ -468,6 +470,8 @@ export class Pokemon {
this.abilityOrder = 0;
this.canMegaEvo = this.battle.actions.canMegaEvo(this);
this.canMegaEvoX = this.battle.actions.canMegaEvoX?.(this);
this.canMegaEvoY = this.battle.actions.canMegaEvoY?.(this);
this.canUltraBurst = this.battle.actions.canUltraBurst(this);
this.canGigantamax = this.baseSpecies.canGigantamax || null;
this.canTerastallize = this.battle.actions.canTerastallize(this);
@ -1043,6 +1047,8 @@ export class Pokemon {
trapped?: boolean,
maybeTrapped?: boolean,
canMegaEvo?: boolean,
canMegaEvoX?: boolean,
canMegaEvoY?: boolean,
canUltraBurst?: boolean,
canZMove?: AnyObject | null,
canDynamax?: boolean,
@ -1070,6 +1076,8 @@ export class Pokemon {
if (!lockedMove) {
if (this.canMegaEvo) data.canMegaEvo = true;
if (this.canMegaEvoX) data.canMegaEvoX = true;
if (this.canMegaEvoY) data.canMegaEvoY = true;
if (this.canUltraBurst) data.canUltraBurst = true;
const canZMove = this.battle.actions.canZMove(this);
if (canZMove) data.canZMove = canZMove;

View File

@ -36,6 +36,8 @@ export interface ChosenAction {
index?: number; // the chosen index in Team Preview
side?: Side; // the action's side
mega?: boolean | null; // true if megaing or ultra bursting
megax?: boolean | null; // true if megaing x
megay?: boolean | null; // true if megaing y
zmove?: string; // if zmoving, the name of the zmove
maxMove?: string; // if dynamaxed, the name of the max move
terastallize?: string; // if terastallizing, tera type
@ -408,7 +410,7 @@ export class Side {
chooseMove(
moveText?: string | number,
targetLoc = 0,
event: 'mega' | 'zmove' | 'ultra' | 'dynamax' | 'terastallize' | '' = ''
event: 'mega' | 'megax' | 'megay' | 'zmove' | 'ultra' | 'dynamax' | 'terastallize' | '' = ''
) {
if (this.requestState !== 'move') {
return this.emitChoiceError(`Can't move: You need a ${this.requestState} response`);
@ -591,10 +593,18 @@ export class Side {
// Mega evolution
const mega = (event === 'mega');
const megax = (event === 'megax');
const megay = (event === 'megay');
if (mega && !pokemon.canMegaEvo) {
return this.emitChoiceError(`Can't move: ${pokemon.name} can't mega evolve`);
}
if (mega && this.choice.mega) {
if (megax && !pokemon.canMegaEvoX) {
return this.emitChoiceError(`Can't move: ${pokemon.name} can't mega evolve X`);
}
if (megay && !pokemon.canMegaEvoY) {
return this.emitChoiceError(`Can't move: ${pokemon.name} can't mega evolve Y`);
}
if ((mega || megax || megay) && this.choice.mega) {
return this.emitChoiceError(`Can't move: You can only mega-evolve once per battle`);
}
const ultra = (event === 'ultra');
@ -639,6 +649,8 @@ export class Side {
targetLoc,
moveid,
mega: mega || ultra,
megax: megax,
megay: megay,
zmove: zMove,
maxMove: maxMove ? maxMove.id : undefined,
terastallize: terastallize ? pokemon.teraType : undefined,
@ -648,7 +660,7 @@ export class Side {
this.choice.cantUndo = this.choice.cantUndo || pokemon.isLastActive();
}
if (mega) this.choice.mega = true;
if (mega || megax || megay) this.choice.mega = true;
if (ultra) this.choice.ultra = true;
if (zMove) this.choice.zMove = true;
if (dynamax) this.choice.dynamax = true;
@ -939,7 +951,7 @@ export class Side {
const original = data;
const error = () => this.emitChoiceError(`Conflicting arguments for "move": ${original}`);
let targetLoc: number | undefined;
let event: 'mega' | 'zmove' | 'ultra' | 'dynamax' | 'terastallize' | '' = '';
let event: 'mega' | 'megax' | 'megay' | 'zmove' | 'ultra' | 'dynamax' | 'terastallize' | '' = '';
while (true) {
// If data ends with a number, treat it as a target location.
// We need to special case 'Conversion 2' so it doesn't get
@ -953,6 +965,14 @@ export class Side {
if (event) return error();
event = 'mega';
data = data.slice(0, -5);
} else if (data.endsWith(' megax')) {
if (event) return error();
event = 'megax';
data = data.slice(0, -6);
} else if (data.endsWith(' megay')) {
if (event) return error();
event = 'megay';
data = data.slice(0, -6);
} else if (data.endsWith(' zmove')) {
if (event) return error();
event = 'zmove';

View File

@ -682,7 +682,7 @@ export class TeamValidator {
if (dex.gen === 4 && item.id === 'griseousorb' && species.num !== 487) {
problems.push(`${set.name} cannot hold the Griseous Orb.`, `(In Gen 4, only Giratina could hold the Griseous Orb).`);
}
if (dex.gen <= 1) {
if (dex.gen <= 1 || dex.currentMod === 'gen7letsgo') {
if (item.id) {
// no items allowed
set.item = '';