This commit is contained in:
iforgetwhyimhere 2026-06-02 12:31:45 -07:00 committed by GitHub
commit 9fc3ee72ea
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 58 additions and 2 deletions

View File

@ -3257,4 +3257,10 @@ export const Rulesets: import('../sim/dex-formats').FormatDataTable = {
if (!speciesMods.length) throw new Error('This format has no rules that modify base stats.');
},
},
editbattle: {
effectType: "Rule",
name: "Edit Battle",
desc: "Allows players to edit battle details using `/editbattle`.",
// Implemented in chat-commands/admin.ts
},
};

View File

@ -1621,12 +1621,18 @@ export const commands: Chat.ChatCommands = {
ebat: 'editbattle',
editbattle(target, room, user) {
room = this.requireRoom();
this.checkCan('forcewin');
if (!target) return this.parse('/help editbattle');
if (!room.battle) {
throw new Chat.ErrorMessage("/editbattle - This is not a battle room.");
}
const battle = room.battle;
const format = Dex.formats.get(battle.format, true);
const ruleTable = Dex.formats.getRuleTable(format);
if (ruleTable.has('editbattle')) {
this.checkCan('editprivacy', null, room);
} else {
this.checkCan('forcewin');
}
void battle.stream.write(`>editbattle user:${user.name}, ${target}`);
},
editbattlehelp: [
@ -1639,9 +1645,11 @@ export const commands: Chat.ChatCommands = {
`/editbattle fieldcondition [fieldcondition]`,
`/editbattle weather [weather]`,
`/editbattle terrain [terrain]`,
`/editbattle basestats [player], [pokemon], [hp], [atk], [def], [spa], [spd], [spe]`,
`/editbattle reseed [optional seed]`,
`Short forms: /ebat h OR s OR pp OR b OR v OR sc OR fc OR w OR t`,
`Short forms: /ebat h OR s OR pp OR b OR v OR sc OR fc OR w OR t OR bs`,
`[player] must be a username or number, [pokemon] must be species name or party slot number (not nickname), [move] must be move name.`,
`Modified base stats must be integers within the stat limit (1-255).`,
],
};

View File

@ -373,6 +373,48 @@ export class BattleStream extends Streams.ObjectReadWriteStream<string> {
if (targets.length) battle.add(`||Reseeded to ${targets.join(',')}`);
break;
}
case 'basestats':
case 'bs': {
if (targets.length !== 8) {
battle.add("||<<< Error: Format should be: basestats PLAYER, POKEMON, HP, ATK, DEF, SPA, SPD, SPE");
return;
}
const [player, pokemon, hpStr, atkStr, defStr, spaStr, spdStr, speStr] = targets.map(t => t.trim());
const p = getPokemon(player, pokemon);
const hp = Number(hpStr);
const atk = Number(atkStr);
const def = Number(defStr);
const spa = Number(spaStr);
const spd = Number(spdStr);
const spe = Number(speStr);
if (![hp, atk, def, spa, spd, spe].every(stat => Number.isInteger(stat))) {
battle.add("||<<< Error: All stats must be integers between 1 and 255.");
return;
}
if ([hp, atk, def, spa, spd, spe].some(stat => stat < 1 || stat > 255)) {
battle.add("||<<< Error: Stats must be integers between 1 and 255.");
return;
}
const newBaseStats: StatsTable = { hp, atk, def, spa, spd, spe };
const oldMaxhp = p.maxhp;
const oldHp = p.hp;
const wasFainted = p.fainted;
const newStats = battle.spreadModify(newBaseStats, p.set);
p.baseStoredStats = newStats;
p.baseMaxhp = newStats.hp;
p.maxhp = newStats.hp;
if (wasFainted) {
p.hp = 0;
} else {
const hpRatio = oldMaxhp ? oldHp / oldMaxhp : 1;
p.hp = Math.max(1, Math.min(p.maxhp, Math.round(hpRatio * p.maxhp)));
}
for (const stat in p.storedStats) {
p.storedStats[stat as StatIDExceptHP] = newStats[stat as StatIDExceptHP];
}
p.speed = p.storedStats.spe;
break;
}
default:
throw new Error(`Unknown editbattle command: ${cmd}`);
}