From 8c12cb54832d26f0c5d34bd9d23b7003b45e8400 Mon Sep 17 00:00:00 2001 From: RedstonewolfX <108761527+RedstonewolfX@users.noreply.github.com> Date: Thu, 11 Jul 2024 23:14:13 -0400 Subject: [PATCH] Logger updates Log trainers Log Pokemon correctly Log moves / actions --- src/logger.ts | 107 +++++++++++++++++++++++++++++++----------------- src/phases.ts | 110 ++++++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 175 insertions(+), 42 deletions(-) diff --git a/src/logger.ts b/src/logger.ts index c93bc31cf20..d72dd36cb36 100644 --- a/src/logger.ts +++ b/src/logger.ts @@ -105,6 +105,8 @@ export interface ItemData { quantity: integer, } +export const Actions = [] + export function newDocument(name: string = "Untitled Run", authorName: string | string[] = "Write your name here"): DRPD { return { version: DRPD_Version, @@ -191,6 +193,20 @@ export function exportWave(scene: BattleScene): Wave { return ret; } export function exportTrainer(trainer: Trainer): TrainerData { + if (trainer.config.getTitle(0, trainer.variant) == "Finn") { + return { + id: trainer.config.trainerType, + name: "Finn", + type: "Rival" + } + } + if (trainer.config.getTitle(0, trainer.variant) == "Ivy") { + return { + id: trainer.config.trainerType, + name: "Ivy", + type: "Rival" + } + } return { id: trainer.config.trainerType, name: trainer.name, @@ -213,7 +229,7 @@ export function getSize(str: string) { export function generateOption(i: integer): OptionSelectItem { var filename: string = (JSON.parse(localStorage.getItem(logs[i][1])) as DRPD).title var op: OptionSelectItem = { - label: ` Export ${filename} (${getSize(localStorage.getItem(logs[i][1]))})`, + label: ` Export ${filename} (${getSize(printDRPD("", "", JSON.parse(localStorage.getItem(logs[i][1])) as DRPD))})`, handler: () => { downloadLogByID(i) return false; @@ -266,7 +282,7 @@ export function clearLog(keyword: string) { */ export function downloadLog(keyword: string) { var d = JSON.parse(localStorage.getItem(logs[logKeys.indexOf(keyword)][1])) - const blob = new Blob([ JSON.stringify(d) ], {type: "text/json"}); + const blob = new Blob([ printDRPD("", "", d as DRPD) ], {type: "text/json"}); const link = document.createElement("a"); link.href = window.URL.createObjectURL(blob); var date: string = (d as DRPD).date @@ -303,6 +319,14 @@ export function logTeam(scene: BattleScene, floor: integer = undefined) { } } } +export function logActions(scene: BattleScene, floor: integer, action: string) { + if (localStorage.getItem("drpd") == null) localStorage.setItem("drpd", JSON.stringify(newDocument())) + var drpd: DRPD = JSON.parse(localStorage.getItem("drpd")) as DRPD; + var wv: Wave = getWave(drpd, floor, scene) + wv.actions.push(action) + console.log(drpd) + localStorage.setItem("drpd", JSON.stringify(drpd)) +} export function getWave(drpd: DRPD, floor: integer, scene: BattleScene) { var wv: Wave; var insertPos: integer; @@ -335,6 +359,18 @@ export function getWave(drpd: DRPD, floor: integer, scene: BattleScene) { if (b == undefined) return -1; // empty values move to the bottom return a.id - b.id }) + for (var i = 0; i < drpd.waves.length - 1; i++) { + if (drpd.waves[i] != undefined && drpd.waves[i+1] != undefined) { + if (drpd.waves[i].id == drpd.waves[i+1].id) { + drpd.waves[i] = undefined + drpd.waves.sort((a, b) => { + if (a == undefined) return 1; // empty values move to the bottom + if (b == undefined) return -1; // empty values move to the bottom + return a.id - b.id + }) + } + } + } if (wv == undefined) { console.error("Out of wave slots??") scene.ui.showText("Out of wave slots!\nClearing duplicates...", null, () => { @@ -394,26 +430,6 @@ export function getWave(drpd: DRPD, floor: integer, scene: BattleScene) { } return wv; } -/* -const entry = tierPool[Utils.randSeedInt(tierPool.length)]; -let species: Species; -if (typeof entry === "number") { - species = entry as Species; -} else { - const levelThresholds = Object.keys(entry); - for (let l = levelThresholds.length - 1; l >= 0; l--) { - const levelThreshold = parseInt(levelThresholds[l]); - if (level >= levelThreshold) { - const speciesIds = entry[levelThreshold]; - if (speciesIds.length > 1) { - species = speciesIds[Utils.randSeedInt(speciesIds.length)]; - } else { - species = speciesIds[0]; - } - break; - } - } -}*/ function checkForPokeInBiome(species: Species, pool: (Species | SpeciesTree)[]): boolean { //console.log(species, pool) for (var i = 0; i < pool.length; i++) { @@ -512,16 +528,25 @@ export function logPokemon(scene: BattleScene, floor: integer = undefined, slot: "Ultra Rare", ] for (var i = 0; i < tiernames.length; i++) { + if (wv.pokemon[slot] != undefined) if (checkForPokeInBiome(wv.pokemon[slot].id, scene.arena.pokemonPool[i]) == true) { console.log("Autofilled rarity for " + pk.name + " as " + tiernames[i]) pk.rarity = tiernames[i] } } } + if (pk.rarity == undefined) pk.rarity = "[Unknown]" wv.pokemon[slot] = pk; console.log(drpd) localStorage.setItem("drpd", JSON.stringify(drpd)) } +export function resetWave(scene: BattleScene, floor: integer = undefined) { + if (localStorage.getItem("drpd") == null) localStorage.setItem("drpd", JSON.stringify(newDocument())) + var drpd: DRPD = JSON.parse(localStorage.getItem("drpd")) as DRPD; + drpd.waves[floor] = exportWave(scene) + console.log(drpd) + localStorage.setItem("drpd", JSON.stringify(drpd)) +} export function logTrainer(scene: BattleScene, floor: integer = undefined) { if (localStorage.getItem("drpd") == null) localStorage.setItem("drpd", JSON.stringify(newDocument())) var drpd: DRPD = JSON.parse(localStorage.getItem("drpd")) as DRPD; @@ -650,25 +675,31 @@ function printWave(inData: string, indent: string, wave: Wave): string { inData += ",\n" + indent + " \"reload\": " + wave.reload + "" inData += ",\n" + indent + " \"type\": \"" + wave.type + "\"" inData += ",\n" + indent + " \"double\": " + wave.double + "" - inData += ",\n" + indent + " \"actions\": [\n" var isFirst = true - for (var i = 0; i < wave.actions.length; i++) { - if (wave.actions[i] != undefined) { - if (isFirst) { - isFirst = false; - } else { - inData += "," + if (wave.actions.length > 0) { + inData += ",\n" + indent + " \"actions\": [" + for (var i = 0; i < wave.actions.length; i++) { + if (wave.actions[i] != undefined) { + if (isFirst) { + isFirst = false; + } else { + inData += "," + } + inData += "\n " + indent + "\"" + wave.actions[i] + "\"" } - inData += "\n " + indent + "\"" + wave.actions[i] + "\"" } + if (!isFirst) inData += "\n" + inData += indent + " ]" + } else { + inData += ",\n" + indent + " \"actions\": []" } - if (!isFirst) inData += "\n" - inData += indent + " ]" inData += ",\n " + indent + "\"shop\": \"" + wave.shop + "\"" inData += ",\n " + indent + "\"biome\": \"" + wave.biome + "\"" - if (wave.trainer) - inData += ",\n " + indent + "\"trainer\": " + wave.trainer - if (wave.pokemon) { + if (wave.trainer) { + inData += ",\n " + indent + "\"trainer\": " + inData = printTrainer(inData, indent + " ", wave.trainer) + } + if (wave.pokemon.length > 0) { inData += ",\n " + indent + "\"pokemon\": [\n" isFirst = true for (var i = 0; i < wave.pokemon.length; i++) { @@ -681,12 +712,12 @@ function printWave(inData: string, indent: string, wave: Wave): string { inData = printPoke(inData, indent + " ", wave.pokemon[i]) } } + inData += "\n" + indent + " ]" } - inData += "\n" + indent + " ]\n" + indent + "}" + inData += "\n" + indent + "}" return inData; } function printPoke(inData: string, indent: string, pokemon: PokeData) { - var itemdata: string = "" inData += indent + "{" inData += "\n" + indent + " \"id\": " + pokemon.id inData += ",\n" + indent + " \"name\": \"" + pokemon.name + "\"" @@ -743,7 +774,7 @@ function printIV(inData: string, indent: string, iv: IVData) { return inData; } function printTrainer(inData: string, indent: string, trainer: TrainerData) { - inData += indent + "{" + inData += "{" inData += "\n" + indent + " \"id\": \"" + trainer.id + "\"" inData += ",\n" + indent + " \"name\": \"" + trainer.name + "\"" inData += ",\n" + indent + " \"type\": \"" + trainer.type + "\"" diff --git a/src/phases.ts b/src/phases.ts index f81791ccef8..5e17e68c6a3 100644 --- a/src/phases.ts +++ b/src/phases.ts @@ -26,7 +26,7 @@ import { Gender } from "./data/gender"; import { Weather, WeatherType, getRandomWeatherType, getTerrainBlockMessage, getWeatherDamageMessage, getWeatherLapseMessage } from "./data/weather"; import { TempBattleStat } from "./data/temp-battle-stat"; import { ArenaTagSide, ArenaTrapTag, MistTag, TrickRoomTag } from "./data/arena-tag"; -import { CheckTrappedAbAttr, IgnoreOpponentStatChangesAbAttr, IgnoreOpponentEvasionAbAttr, PostAttackAbAttr, PostBattleAbAttr, PostDefendAbAttr, PostSummonAbAttr, PostTurnAbAttr, PostWeatherLapseAbAttr, PreSwitchOutAbAttr, PreWeatherDamageAbAttr, ProtectStatAbAttr, RedirectMoveAbAttr, BlockRedirectAbAttr, RunSuccessAbAttr, StatChangeMultiplierAbAttr, SuppressWeatherEffectAbAttr, SyncEncounterNatureAbAttr, applyAbAttrs, applyCheckTrappedAbAttrs, applyPostAttackAbAttrs, applyPostBattleAbAttrs, applyPostDefendAbAttrs, applyPostSummonAbAttrs, applyPostTurnAbAttrs, applyPostWeatherLapseAbAttrs, applyPreStatChangeAbAttrs, applyPreSwitchOutAbAttrs, applyPreWeatherEffectAbAttrs, BattleStatMultiplierAbAttr, applyBattleStatMultiplierAbAttrs, IncrementMovePriorityAbAttr, applyPostVictoryAbAttrs, PostVictoryAbAttr, BlockNonDirectDamageAbAttr as BlockNonDirectDamageAbAttr, applyPostKnockOutAbAttrs, PostKnockOutAbAttr, PostBiomeChangeAbAttr, applyPostFaintAbAttrs, PostFaintAbAttr, IncreasePpAbAttr, PostStatChangeAbAttr, applyPostStatChangeAbAttrs, AlwaysHitAbAttr, PreventBerryUseAbAttr, StatChangeCopyAbAttr, PokemonTypeChangeAbAttr, applyPreAttackAbAttrs, applyPostMoveUsedAbAttrs, PostMoveUsedAbAttr, MaxMultiHitAbAttr, HealFromBerryUseAbAttr, WonderSkinAbAttr, applyPreDefendAbAttrs, IgnoreMoveEffectsAbAttr, BlockStatusDamageAbAttr, BypassSpeedChanceAbAttr, AddSecondStrikeAbAttr } from "./data/ability"; +import { CheckTrappedAbAttr, IgnoreOpponentStatChangesAbAttr, IgnoreOpponentEvasionAbAttr, PostAttackAbAttr, PostBattleAbAttr, PostDefendAbAttr, PostSummonAbAttr, PostTurnAbAttr, PostWeatherLapseAbAttr, PreSwitchOutAbAttr, PreWeatherDamageAbAttr, ProtectStatAbAttr, RedirectMoveAbAttr, BlockRedirectAbAttr, RunSuccessAbAttr, StatChangeMultiplierAbAttr, SuppressWeatherEffectAbAttr, SyncEncounterNatureAbAttr, applyAbAttrs, applyCheckTrappedAbAttrs, applyPostAttackAbAttrs, applyPostBattleAbAttrs, applyPostDefendAbAttrs, applyPostSummonAbAttrs, applyPostTurnAbAttrs, applyPostWeatherLapseAbAttrs, applyPreStatChangeAbAttrs, applyPreSwitchOutAbAttrs, applyPreWeatherEffectAbAttrs, BattleStatMultiplierAbAttr, applyBattleStatMultiplierAbAttrs, IncrementMovePriorityAbAttr, applyPostVictoryAbAttrs, PostVictoryAbAttr, BlockNonDirectDamageAbAttr as BlockNonDirectDamageAbAttr, applyPostKnockOutAbAttrs, PostKnockOutAbAttr, PostBiomeChangeAbAttr, applyPostFaintAbAttrs, PostFaintAbAttr, IncreasePpAbAttr, PostStatChangeAbAttr, applyPostStatChangeAbAttrs, AlwaysHitAbAttr, PreventBerryUseAbAttr, StatChangeCopyAbAttr, PokemonTypeChangeAbAttr, applyPreAttackAbAttrs, applyPostMoveUsedAbAttrs, PostMoveUsedAbAttr, MaxMultiHitAbAttr, HealFromBerryUseAbAttr, WonderSkinAbAttr, applyPreDefendAbAttrs, IgnoreMoveEffectsAbAttr, BlockStatusDamageAbAttr, BypassSpeedChanceAbAttr, AddSecondStrikeAbAttr, BattlerTagImmunityAbAttr } from "./data/ability"; import { Unlockables, getUnlockableName } from "./system/unlockables"; import { getBiomeKey } from "./field/arena"; import { BattleType, BattlerIndex, TurnCommand } from "./battle"; @@ -465,7 +465,7 @@ export class TitlePhase extends Phase { // If there are no daily runs, it instead shows the most recently saved run // If this fails too, there are no saves, and the option does not appear var lastsaves = this.getSaves(false, true); - if (lastsaves != undefined) { + if (lastsaves != undefined && lastsaves.length > 0) { lastsaves.forEach(lastsave => { options.push({ label: (lastsave.description ? lastsave.description : "[???]"), @@ -1324,6 +1324,7 @@ export class EncounterPhase extends BattlePhase { doEncounterCommon(showEncounterMessage: boolean = true) { const enemyField = this.scene.getEnemyField(); + LoggerTools.resetWave(this.scene, this.scene.currentBattle.waveIndex) LoggerTools.logTeam(this.scene, this.scene.currentBattle.waveIndex) if (this.scene.getEnemyParty()[0].hasTrainer()) { LoggerTools.logTrainer(this.scene, this.scene.currentBattle.waveIndex) @@ -2683,6 +2684,34 @@ export class TurnStartPhase extends FieldPhase { super(scene); } + generateTargString(t: BattlerIndex[]) { + var targets = ['Self'] + for (var i = 0; i < this.scene.getField().length; i++) { + if (this.scene.getField()[i] != null) + targets[this.scene.getField()[i].getBattlerIndex() + 1] = this.scene.getField()[i].name + } + for (var i = 0; i < this.scene.getEnemyField().length; i++) { + if (this.scene.getEnemyField()[i] != null) + targets[this.scene.getEnemyField()[i].getBattlerIndex() + 1] = this.scene.getEnemyField()[i].name + } + var targetFull = [] + for (var i = 0; i < t.length; i++) { + targetFull.push(targets[t[i] + 1]) + } + if (targetFull.join(", ") == targets.join(", ")) return "" + return " → " + targetFull.join(", ") + } + + getBattlers(user: Pokemon): Pokemon[] { + var battlers = [] + battlers[0] = this.scene.getField()[0] + battlers[1] = this.scene.getField()[1] + battlers[2] = this.scene.getEnemyField()[0] + battlers[3] = this.scene.getEnemyField()[1] + battlers.unshift(user) + return battlers; + } + start() { super.start(); @@ -2691,6 +2720,70 @@ export class TurnStartPhase extends FieldPhase { const battlerBypassSpeed = {}; + const playerActions = [] + + const moveOrder = order.slice(0); + + while (LoggerTools.Actions.length > 0) { + LoggerTools.Actions.pop() + } + + for (const o of moveOrder) { + + const pokemon = field[o]; + const turnCommand = this.scene.currentBattle.turnCommands[o]; + + if (turnCommand.skip || !pokemon.isPlayer()) { + continue; + } + + switch (turnCommand.command) { + case Command.FIGHT: + const queuedMove = turnCommand.move; + if (!queuedMove) { + continue; + } + const move = pokemon.getMoveset().find(m => m.moveId === queuedMove.move) || new PokemonMove(queuedMove.move); + if (!this.scene.currentBattle.double) { + playerActions.push(move.getName()) + } else { + var T = this.getBattlers(pokemon) + for (var i = 0; i < T.length; i++) { + if (T[i] == undefined) { + T.splice(i, 1) + i-- + } + } + console.log(queuedMove.targets, T, queuedMove.targets.map(p => T[p+1].name)) + playerActions.push(move.getName() + " → " + queuedMove.targets.map(p => T[p+1].name).join(", ")) + } + break; + case Command.BALL: + var ballNames = [ + "Poké Ball", + "Great Ball", + "Ultra Ball", + "Rogue Ball", + "Master Ball", + "Luxury Ball" + ] + LoggerTools.Actions[pokemon.getBattlerIndex()] = ballNames[turnCommand.cursor] + playerActions.push(ballNames[turnCommand.cursor]) + //this.scene.unshiftPhase(new AttemptCapturePhase(this.scene, turnCommand.targets[0] % 2, turnCommand.cursor)); + break; + case Command.POKEMON: + LoggerTools.Actions[pokemon.getBattlerIndex()] = "Switch " + this.scene.getParty()[pokemon.getFieldIndex()].name + " to " + this.scene.getParty()[turnCommand.cursor].name + //playerActions.push("Switch " + this.scene.getParty()[pokemon.getFieldIndex()].name + " to " + this.scene.getParty()[turnCommand.cursor].name) + //this.scene.unshiftPhase(new SwitchSummonPhase(this.scene, pokemon.getFieldIndex(), turnCommand.cursor, true, turnCommand.args[0] as boolean, pokemon.isPlayer())); + break; + case Command.RUN: + LoggerTools.Actions[pokemon.getBattlerIndex()] = "Run" + playerActions.push("Run") + break; + } + } + //LoggerTools.logActions(this.scene, this.scene.currentBattle.waveIndex, playerActions.join(" | ")) + this.scene.getField(true).filter(p => p.summonData).map(p => { const bypassSpeed = new Utils.BooleanHolder(false); applyAbAttrs(BypassSpeedChanceAbAttr, p, null, bypassSpeed); @@ -2698,8 +2791,6 @@ export class TurnStartPhase extends FieldPhase { battlerBypassSpeed[p.getBattlerIndex()] = bypassSpeed; }); - const moveOrder = order.slice(0); - moveOrder.sort((a, b) => { const aCommand = this.scene.currentBattle.turnCommands[a]; const bCommand = this.scene.currentBattle.turnCommands[b]; @@ -2906,6 +2997,8 @@ export class TurnEndPhase extends FieldPhase { this.scene.arena.trySetTerrain(TerrainType.NONE, false); } + LoggerTools.logActions(this.scene, this.scene.currentBattle.waveIndex, LoggerTools.Actions.join(" | ")) + this.end(); } } @@ -3163,6 +3256,15 @@ export class MovePhase extends BattlePhase { if (!allMoves[this.move.moveId].hasAttr(CopyMoveAttr)) { this.scene.currentBattle.lastMove = this.move.moveId; } + if (this.pokemon.isPlayer()) { + LoggerTools.Actions[this.pokemon.getBattlerIndex()] = this.move.getName() + if (this.scene.currentBattle.double) { + var targIDs = ["Counter", "Self", "Ally", "L", "R"] + if (this.pokemon.getBattlerIndex() == 1) targIDs = ["Counter", "Ally", "Self", "L", "R"] + LoggerTools.Actions[this.pokemon.getBattlerIndex()] += " → " + this.targets.map(v => targIDs[v+1]) + } + console.log(this.move.getName(), this.targets) + } // Assume conditions affecting targets only apply to moves with a single target let success = this.move.getMove().applyConditions(this.pokemon, targets[0], this.move.getMove());