mirror of
https://github.com/pagefaultgames/pokerogue.git
synced 2025-08-26 17:29:30 +02:00
Log item transfers
This commit is contained in:
parent
8c12cb5483
commit
06b782cd06
@ -120,6 +120,7 @@ export default class BattleScene extends SceneBase {
|
||||
public enableTutorials: boolean = import.meta.env.VITE_BYPASS_TUTORIAL === "1";
|
||||
public enableMoveInfo: boolean = true;
|
||||
public enableRetries: boolean = false;
|
||||
public damageDisplay: string = "Off";
|
||||
/**
|
||||
* Determines the condition for a notification should be shown for Candy Upgrades
|
||||
* - 0 = 'Off'
|
||||
|
111
src/logger.ts
111
src/logger.ts
@ -16,6 +16,8 @@ import { Item } from "pokenode-ts";
|
||||
import Trainer from "./field/trainer";
|
||||
import { Species } from "./enums/species";
|
||||
import { junit } from "node:test/reporters";
|
||||
import { i } from "vitest/dist/reporters-xEmem8D4.js";
|
||||
import { GameModes } from "./game-mode";
|
||||
|
||||
/**
|
||||
* All logs.
|
||||
@ -38,6 +40,33 @@ export const logKeys: string[] = [
|
||||
"d", // Debug
|
||||
];
|
||||
|
||||
export function getLogID(scene: BattleScene) {
|
||||
return "drpd_log:" + scene.seed
|
||||
}
|
||||
export function getLogs() {
|
||||
while(logs.length > 0)
|
||||
logs.pop()
|
||||
for (var i = 0; i < localStorage.length; i++) {
|
||||
if (localStorage.key(i).substring(0, 9) == "drpd_log:") {
|
||||
logs.push(["drpd.json", localStorage.key(i), localStorage.key(i).substring(9), "", "", ""])
|
||||
}
|
||||
}
|
||||
}
|
||||
export function getMode(scene: BattleScene) {
|
||||
switch (scene.gameMode.modeId) {
|
||||
case GameModes.CLASSIC:
|
||||
return "Classic"
|
||||
case GameModes.ENDLESS:
|
||||
return "Endless"
|
||||
case GameModes.SPLICED_ENDLESS:
|
||||
return "Spliced Endless"
|
||||
case GameModes.DAILY:
|
||||
return "Daily"
|
||||
case GameModes.CHALLENGE:
|
||||
return "Challenge"
|
||||
}
|
||||
}
|
||||
|
||||
export const rarities = []
|
||||
export const rarityslot = [0]
|
||||
|
||||
@ -226,16 +255,23 @@ export function getSize(str: string) {
|
||||
return d.toString() + filesizes[unit]
|
||||
}
|
||||
|
||||
export function generateOption(i: integer): OptionSelectItem {
|
||||
export function generateOption(i: integer, saves: any): OptionSelectItem {
|
||||
var filename: string = (JSON.parse(localStorage.getItem(logs[i][1])) as DRPD).title
|
||||
var op: OptionSelectItem = {
|
||||
label: ` Export ${filename} (${getSize(printDRPD("", "", JSON.parse(localStorage.getItem(logs[i][1])) as DRPD))})`,
|
||||
label: `Export ${filename} (${getSize(printDRPD("", "", JSON.parse(localStorage.getItem(logs[i][1])) as DRPD))})`,
|
||||
handler: () => {
|
||||
downloadLogByID(i)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
for (var j = 0; j < saves.length; j++) {
|
||||
console.log(saves[j].seed, logs[i][2], saves[j].seed == logs[i][2])
|
||||
if (saves[j].seed == logs[i][2]) {
|
||||
op.label = "[Slot " + (j + 1) + "]" + op.label.substring(6)
|
||||
}
|
||||
}
|
||||
if (logs[i][4] != "") {
|
||||
op.label = " " + op.label
|
||||
op.item = logs[i][4]
|
||||
}
|
||||
return op;
|
||||
@ -306,6 +342,7 @@ export function downloadLogByID(i: integer) {
|
||||
export function logTeam(scene: BattleScene, floor: integer = undefined) {
|
||||
if (floor == undefined) floor = scene.currentBattle.waveIndex
|
||||
var team = scene.getEnemyParty()
|
||||
console.log("Log Enemy Team")
|
||||
if (team[0].hasTrainer()) {
|
||||
//var sprite = scene.currentBattle.trainer.config.getSpriteKey()
|
||||
//var trainerCat = Utils.getEnumKeys(TrainerType)[Utils.getEnumValues(TrainerType).indexOf(scene.currentBattle.trainer.config.trainerType)]
|
||||
@ -320,20 +357,47 @@ 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;
|
||||
if (localStorage.getItem(getLogID(scene)) == null) localStorage.setItem(getLogID(scene), JSON.stringify(newDocument(getMode(scene) + " Run")))
|
||||
var drpd: DRPD = JSON.parse(localStorage.getItem(getLogID(scene))) as DRPD;
|
||||
console.log("Log Action", drpd)
|
||||
var wv: Wave = getWave(drpd, floor, scene)
|
||||
wv.actions.push(action)
|
||||
console.log(drpd)
|
||||
localStorage.setItem("drpd", JSON.stringify(drpd))
|
||||
localStorage.setItem(getLogID(scene), JSON.stringify(drpd))
|
||||
}
|
||||
export function logShop(scene: BattleScene, floor: integer, action: string) {
|
||||
if (localStorage.getItem(getLogID(scene)) == null) localStorage.setItem(getLogID(scene), JSON.stringify(newDocument(getMode(scene) + " Run")))
|
||||
var drpd: DRPD = JSON.parse(localStorage.getItem(getLogID(scene))) as DRPD;
|
||||
console.log("Log Shop Item", drpd)
|
||||
var wv: Wave = getWave(drpd, floor, scene)
|
||||
wv.shop = action
|
||||
console.log(drpd)
|
||||
localStorage.setItem(getLogID(scene), JSON.stringify(drpd))
|
||||
}
|
||||
export function getWave(drpd: DRPD, floor: integer, scene: BattleScene) {
|
||||
var wv: Wave;
|
||||
var insertPos: integer;
|
||||
console.log(drpd.waves)
|
||||
if (drpd.waves[floor - 1] != undefined) {
|
||||
return drpd.waves[floor - 1]
|
||||
}
|
||||
drpd.waves[floor - 1] = {
|
||||
id: floor,
|
||||
reload: false,
|
||||
//type: floor % 10 == 0 ? "boss" : (floor % 10 == 5 ? "trainer" : "wild"),
|
||||
type: floor % 10 == 0 ? "boss" : "wild",
|
||||
double: scene.currentBattle.double,
|
||||
actions: [],
|
||||
shop: "",
|
||||
biome: getBiomeName(scene.arena.biomeType),
|
||||
pokemon: []
|
||||
}
|
||||
return drpd.waves[floor - 1]
|
||||
for (var i = 0; i < drpd.waves.length; i++) {
|
||||
if (drpd.waves[i] != undefined) {
|
||||
if (drpd.waves[i] != undefined && drpd.waves[i] != null) {
|
||||
if (drpd.waves[i].id == floor) {
|
||||
wv = drpd.waves[i]
|
||||
console.log("Found wave for floor " + floor + " at index " + i)
|
||||
if (wv.pokemon == undefined) wv.pokemon = []
|
||||
}
|
||||
} else if (insertPos == undefined) {
|
||||
@ -341,6 +405,7 @@ export function getWave(drpd: DRPD, floor: integer, scene: BattleScene) {
|
||||
}
|
||||
}
|
||||
if (wv == undefined && insertPos != undefined) {
|
||||
console.log("Created new wave for floor " + floor + " at index " + insertPos)
|
||||
drpd.waves[insertPos] = {
|
||||
id: floor,
|
||||
reload: false,
|
||||
@ -392,9 +457,10 @@ export function getWave(drpd: DRPD, floor: integer, scene: BattleScene) {
|
||||
console.error("Go yell at @redstonewolf8557 to fix this")
|
||||
} else {
|
||||
for (var i = 0; i < drpd.waves.length; i++) {
|
||||
if (drpd.waves[i] != undefined) {
|
||||
if (drpd.waves[i] != undefined && drpd.waves[i] != null) {
|
||||
if (drpd.waves[i].id == floor) {
|
||||
wv = drpd.waves[i]
|
||||
console.log("Found wave for floor " + floor + " at index " + i)
|
||||
if (wv.pokemon == undefined) wv.pokemon = []
|
||||
}
|
||||
} else if (insertPos == undefined) {
|
||||
@ -402,6 +468,7 @@ export function getWave(drpd: DRPD, floor: integer, scene: BattleScene) {
|
||||
}
|
||||
}
|
||||
if (wv == undefined && insertPos != undefined) {
|
||||
console.log("Created new wave for floor " + floor + " at index " + insertPos)
|
||||
drpd.waves[insertPos] = {
|
||||
id: floor,
|
||||
reload: false,
|
||||
@ -479,8 +546,9 @@ export function logPokemon(scene: BattleScene, floor: integer = undefined, slot:
|
||||
setRow("e", newLine, floor, slot)
|
||||
//console.log(localStorage.getItem(logs[logKeys.indexOf("e")][1]).split("\n"))
|
||||
*/
|
||||
if (localStorage.getItem("drpd") == null) localStorage.setItem("drpd", JSON.stringify(newDocument()))
|
||||
var drpd: DRPD = JSON.parse(localStorage.getItem("drpd")) as DRPD;
|
||||
if (localStorage.getItem(getLogID(scene)) == null) localStorage.setItem(getLogID(scene), JSON.stringify(newDocument(getMode(scene) + " Run")))
|
||||
var drpd: DRPD = JSON.parse(localStorage.getItem(getLogID(scene))) as DRPD;
|
||||
console.log("Log Enemy Pokemon", drpd)
|
||||
var wv: Wave = getWave(drpd, floor, scene)
|
||||
var pk: PokeData = exportPokemon(pokemon, encounterRarity)
|
||||
if (wv.pokemon[slot] != undefined) {
|
||||
@ -537,36 +605,33 @@ export function logPokemon(scene: BattleScene, floor: integer = undefined, slot:
|
||||
}
|
||||
if (pk.rarity == undefined) pk.rarity = "[Unknown]"
|
||||
wv.pokemon[slot] = pk;
|
||||
while (wv.actions.length > 0)
|
||||
wv.actions.pop()
|
||||
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))
|
||||
localStorage.setItem(getLogID(scene), 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;
|
||||
if (localStorage.getItem(getLogID(scene)) == null) localStorage.setItem(getLogID(scene), JSON.stringify(newDocument(getMode(scene) + " Run")))
|
||||
var drpd: DRPD = JSON.parse(localStorage.getItem(getLogID(scene))) as DRPD;
|
||||
console.log("Log Trainer", drpd)
|
||||
var wv: Wave = getWave(drpd, floor, scene)
|
||||
var t: TrainerData = exportTrainer(scene.currentBattle.trainer)
|
||||
wv.trainer = t
|
||||
wv.type = "trainer"
|
||||
console.log(drpd)
|
||||
localStorage.setItem("drpd", JSON.stringify(drpd))
|
||||
localStorage.setItem(getLogID(scene), JSON.stringify(drpd))
|
||||
}
|
||||
export function logPlayerTeam(scene: BattleScene) {
|
||||
if (localStorage.getItem("drpd") == null) localStorage.setItem("drpd", JSON.stringify(newDocument()))
|
||||
var drpd: DRPD = JSON.parse(localStorage.getItem("drpd")) as DRPD;
|
||||
if (localStorage.getItem(getLogID(scene)) == null) localStorage.setItem(getLogID(scene), JSON.stringify(newDocument(getMode(scene) + " Run")))
|
||||
var drpd: DRPD = JSON.parse(localStorage.getItem(getLogID(scene))) as DRPD;
|
||||
//var wv: Wave = getWave(drpd, 1, scene)
|
||||
console.log("Log Player Starters", drpd)
|
||||
var P = scene.getParty()
|
||||
for (var i = 0; i < P.length; i++) {
|
||||
drpd.starters[i] = exportPokemon(P[i])
|
||||
}
|
||||
console.log(drpd)
|
||||
localStorage.setItem("drpd", JSON.stringify(drpd))
|
||||
localStorage.setItem(getLogID(scene), JSON.stringify(drpd))
|
||||
}
|
||||
|
||||
export function dataSorter(a: string, b: string) {
|
||||
|
@ -409,9 +409,10 @@ export class TitlePhase extends Phase {
|
||||
|
||||
logMenu(): boolean {
|
||||
const options: OptionSelectItem[] = [];
|
||||
LoggerTools.getLogs()
|
||||
for (var i = 0; i < LoggerTools.logs.length; i++) {
|
||||
if (localStorage.getItem(LoggerTools.logs[i][1]) != null) {
|
||||
options.push(LoggerTools.generateOption(i) as OptionSelectItem)
|
||||
options.push(LoggerTools.generateOption(i, this.getSaves()) as OptionSelectItem)
|
||||
} else {
|
||||
//options.push(LoggerTools.generateAddOption(i, this.scene, this))
|
||||
}
|
||||
@ -1324,7 +1325,7 @@ export class EncounterPhase extends BattlePhase {
|
||||
doEncounterCommon(showEncounterMessage: boolean = true) {
|
||||
const enemyField = this.scene.getEnemyField();
|
||||
|
||||
LoggerTools.resetWave(this.scene, this.scene.currentBattle.waveIndex)
|
||||
//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)
|
||||
@ -2743,20 +2744,6 @@ export class TurnStartPhase extends FieldPhase {
|
||||
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 = [
|
||||
@ -4502,11 +4489,13 @@ export class VictoryPhase extends PokemonPhase {
|
||||
if (this.scene.currentBattle.waveIndex % 10) {
|
||||
this.scene.pushPhase(new SelectModifierPhase(this.scene));
|
||||
} else if (this.scene.gameMode.isDaily) {
|
||||
LoggerTools.logShop(this.scene, this.scene.currentBattle.waveIndex, "")
|
||||
this.scene.pushPhase(new ModifierRewardPhase(this.scene, modifierTypes.EXP_CHARM));
|
||||
if (this.scene.currentBattle.waveIndex > 10 && !this.scene.gameMode.isWaveFinal(this.scene.currentBattle.waveIndex)) {
|
||||
this.scene.pushPhase(new ModifierRewardPhase(this.scene, modifierTypes.GOLDEN_POKEBALL));
|
||||
}
|
||||
} else {
|
||||
LoggerTools.logShop(this.scene, this.scene.currentBattle.waveIndex, "")
|
||||
const superExpWave = !this.scene.gameMode.isEndless ? (this.scene.offsetGym ? 0 : 20) : 10;
|
||||
if (this.scene.gameMode.isEndless && this.scene.currentBattle.waveIndex === 10) {
|
||||
this.scene.pushPhase(new ModifierRewardPhase(this.scene, modifierTypes.EXP_SHARE));
|
||||
@ -4524,6 +4513,7 @@ export class VictoryPhase extends PokemonPhase {
|
||||
}
|
||||
this.scene.pushPhase(new NewBattlePhase(this.scene));
|
||||
} else {
|
||||
LoggerTools.logShop(this.scene, this.scene.currentBattle.waveIndex, "")
|
||||
this.scene.currentBattle.battleType = BattleType.CLEAR;
|
||||
this.scene.score += this.scene.gameMode.getClearScoreBonus();
|
||||
this.scene.updateScoreText();
|
||||
@ -5612,6 +5602,7 @@ export class AttemptRunPhase extends PokemonPhase {
|
||||
|
||||
if (playerPokemon.randSeedInt(256) < escapeChance.value) {
|
||||
this.scene.playSound("flee");
|
||||
LoggerTools.logShop(this.scene, this.scene.currentBattle.waveIndex, "")
|
||||
this.scene.queueMessage(i18next.t("battle:runAwaySuccess"), null, true, 500);
|
||||
|
||||
this.scene.tweens.add({
|
||||
@ -5672,6 +5663,7 @@ export class SelectModifierPhase extends BattlePhase {
|
||||
if (rowCursor < 0 || cursor < 0) {
|
||||
this.scene.ui.showText(i18next.t("battle:skipItemQuestion"), null, () => {
|
||||
this.scene.ui.setOverlayMode(Mode.CONFIRM, () => {
|
||||
LoggerTools.logShop(this.scene, this.scene.currentBattle.waveIndex, "")
|
||||
this.scene.ui.revertMode();
|
||||
this.scene.ui.setMode(Mode.MESSAGE);
|
||||
super.end();
|
||||
@ -5691,6 +5683,7 @@ export class SelectModifierPhase extends BattlePhase {
|
||||
return false;
|
||||
} else {
|
||||
this.scene.reroll = true;
|
||||
LoggerTools.logActions(this.scene, this.scene.currentBattle.waveIndex, "Reroll" + (this.scene.lockModifierTiers ? " (Locked)" : ""))
|
||||
this.scene.unshiftPhase(new SelectModifierPhase(this.scene, this.rerollCount + 1, typeOptions.map(o => o.type.tier)));
|
||||
this.scene.ui.clearText();
|
||||
this.scene.ui.setMode(Mode.MESSAGE).then(() => super.end());
|
||||
@ -5701,11 +5694,17 @@ export class SelectModifierPhase extends BattlePhase {
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
this.scene.ui.setModeWithoutClear(Mode.PARTY, PartyUiMode.MODIFIER_TRANSFER, -1, (fromSlotIndex: integer, itemIndex: integer, itemQuantity: integer, toSlotIndex: integer) => {
|
||||
this.scene.ui.setModeWithoutClear(Mode.PARTY, PartyUiMode.MODIFIER_TRANSFER, -1, (fromSlotIndex: integer, itemIndex: integer, itemQuantity: integer, toSlotIndex: integer, isAll: boolean, isFirst: boolean) => {
|
||||
if (toSlotIndex !== undefined && fromSlotIndex < 6 && toSlotIndex < 6 && fromSlotIndex !== toSlotIndex && itemIndex > -1) {
|
||||
const itemModifiers = this.scene.findModifiers(m => m instanceof PokemonHeldItemModifier
|
||||
&& (m as PokemonHeldItemModifier).getTransferrable(true) && (m as PokemonHeldItemModifier).pokemonId === party[fromSlotIndex].id) as PokemonHeldItemModifier[];
|
||||
const itemModifier = itemModifiers[itemIndex];
|
||||
if (isAll) {
|
||||
if (isFirst)
|
||||
LoggerTools.logActions(this.scene, this.scene.currentBattle.waveIndex, "Transfer [" + (fromSlotIndex + 1) + "] " + this.scene.getParty()[fromSlotIndex].name + " (All) → [" + (toSlotIndex + 1) + "] " + this.scene.getParty()[toSlotIndex].name)
|
||||
} else {
|
||||
LoggerTools.logActions(this.scene, this.scene.currentBattle.waveIndex, "Transfer [" + (fromSlotIndex + 1) + "] " + this.scene.getParty()[fromSlotIndex].name + " (" + itemModifier.type.name + (itemQuantity == itemModifier.getStackCount() ? "" : " x" + itemQuantity) + ") → [" + (toSlotIndex + 1) + "] " + this.scene.getParty()[toSlotIndex].name)
|
||||
}
|
||||
this.scene.tryTransferHeldItemModifier(itemModifier, party[toSlotIndex], true, itemQuantity);
|
||||
} else {
|
||||
this.scene.ui.setMode(Mode.MODIFIER_SELECT, this.isPlayer(), typeOptions, modifierSelectCallback, this.getRerollCost(typeOptions, this.scene.lockModifierTiers));
|
||||
|
@ -43,7 +43,8 @@ const AUTO_DISABLED: SettingOption[] = [
|
||||
export enum SettingType {
|
||||
GENERAL,
|
||||
DISPLAY,
|
||||
AUDIO
|
||||
AUDIO,
|
||||
MOD
|
||||
}
|
||||
|
||||
type SettingOption = {
|
||||
@ -98,6 +99,7 @@ export const SettingKeys = {
|
||||
SE_Volume: "SE_VOLUME",
|
||||
Music_Preference: "MUSIC_PREFERENCE",
|
||||
Show_BGM_Bar: "SHOW_BGM_BAR",
|
||||
Damage_Display: "DAMAGE_DISPLAY"
|
||||
};
|
||||
|
||||
/**
|
||||
@ -242,6 +244,22 @@ export const Setting: Array<Setting> = [
|
||||
default: 0,
|
||||
type: SettingType.GENERAL
|
||||
},
|
||||
{
|
||||
key: SettingKeys.Damage_Display,
|
||||
label: "Damage Display",
|
||||
options: [{
|
||||
label: "Off",
|
||||
value: "Off"
|
||||
}, {
|
||||
label: "Value",
|
||||
value: "Value"
|
||||
}, {
|
||||
label: "Percent",
|
||||
value: "Percent"
|
||||
}],
|
||||
default: 0,
|
||||
type: SettingType.GENERAL
|
||||
},
|
||||
{
|
||||
key: SettingKeys.Tutorials,
|
||||
label: i18next.t("settings:tutorials"),
|
||||
@ -604,6 +622,8 @@ export function setSetting(scene: BattleScene, setting: string, value: integer):
|
||||
case SettingKeys.Enable_Retries:
|
||||
scene.enableRetries = Setting[index].options[value].value === "On";
|
||||
break;
|
||||
case SettingKeys.Damage_Display:
|
||||
scene.damageDisplay = Setting[index].options[value].value
|
||||
case SettingKeys.Skip_Seen_Dialogues:
|
||||
scene.skipSeenDialogues = Setting[index].options[value].value === "On";
|
||||
break;
|
||||
|
@ -15,15 +15,16 @@ import { Stat } from "#app/data/pokemon-stat.js";
|
||||
import { Abilities } from "#app/enums/abilities.js";
|
||||
import { WeatherType } from "#app/data/weather.js";
|
||||
import { Moves } from "#app/enums/moves.js";
|
||||
import { AddSecondStrikeAbAttr, AllyMoveCategoryPowerBoostAbAttr, applyAbAttrs, applyPreAttackAbAttrs, applyPreDefendAbAttrs, BlockCritAbAttr, BonusCritAbAttr, BypassBurnDamageReductionAbAttr, ConditionalCritAbAttr, DamageBoostAbAttr, FieldMoveTypePowerBoostAbAttr, FieldPriorityMoveImmunityAbAttr, MoveImmunityAbAttr, MoveTypeChangeAttr, MultCritAbAttr, PreDefendFullHpEndureAbAttr, ReceivedMoveDamageMultiplierAbAttr, StabBoostAbAttr, TypeImmunityAbAttr, UserFieldMoveTypePowerBoostAbAttr, VariableMovePowerAbAttr } from "#app/data/ability.js";
|
||||
import { AddSecondStrikeAbAttr, AllyMoveCategoryPowerBoostAbAttr, AlwaysHitAbAttr, applyAbAttrs, applyBattleStatMultiplierAbAttrs, applyPreAttackAbAttrs, applyPreDefendAbAttrs, BattleStatMultiplierAbAttr, BlockCritAbAttr, BonusCritAbAttr, BypassBurnDamageReductionAbAttr, ConditionalCritAbAttr, DamageBoostAbAttr, FieldMoveTypePowerBoostAbAttr, FieldPriorityMoveImmunityAbAttr, IgnoreOpponentEvasionAbAttr, IgnoreOpponentStatChangesAbAttr, MoveImmunityAbAttr, MoveTypeChangeAttr, MultCritAbAttr, PreDefendFullHpEndureAbAttr, ReceivedMoveDamageMultiplierAbAttr, StabBoostAbAttr, TypeImmunityAbAttr, UserFieldMoveTypePowerBoostAbAttr, VariableMovePowerAbAttr, WonderSkinAbAttr } from "#app/data/ability.js";
|
||||
import { ArenaTagType } from "#app/enums/arena-tag-type.js";
|
||||
import { ArenaTagSide, WeakenMoveScreenTag, WeakenMoveTypeTag } from "#app/data/arena-tag.js";
|
||||
import { BattlerTagLapseType, HelpingHandTag, TypeBoostTag } from "#app/data/battler-tags.js";
|
||||
import { BattlerTagLapseType, HelpingHandTag, SemiInvulnerableTag, TypeBoostTag } from "#app/data/battler-tags.js";
|
||||
import { TerrainType } from "#app/data/terrain.js";
|
||||
import { AttackTypeBoosterModifier, EnemyDamageBoosterModifier, EnemyDamageReducerModifier, EnemyEndureChanceModifier, PokemonMultiHitModifier, TempBattleStatBoosterModifier } from "#app/modifier/modifier.js";
|
||||
import { AttackTypeBoosterModifier, EnemyDamageBoosterModifier, EnemyDamageReducerModifier, EnemyEndureChanceModifier, PokemonMoveAccuracyBoosterModifier, PokemonMultiHitModifier, TempBattleStatBoosterModifier } from "#app/modifier/modifier.js";
|
||||
import { BattlerTagType } from "#app/enums/battler-tag-type.js";
|
||||
import { TempBattleStat } from "#app/data/temp-battle-stat.js";
|
||||
import { StatusEffect } from "#app/data/status-effect.js";
|
||||
import { BattleStat } from "#app/data/battle-stat.js";
|
||||
|
||||
export default class FightUiHandler extends UiHandler {
|
||||
private movesContainer: Phaser.GameObjects.Container;
|
||||
@ -439,6 +440,117 @@ export default class FightUiHandler extends UiHandler {
|
||||
return [damage1.value, damage2.value]
|
||||
}
|
||||
|
||||
calculateAccuracy(user: Pokemon, target: Pokemon, move: PokemonMove) {
|
||||
if (this.scene.currentBattle.double && false) {
|
||||
switch (move.getMove().moveTarget) {
|
||||
case MoveData.MoveTarget.USER: // Targets yourself
|
||||
return -1; // Moves targeting yourself always hit
|
||||
case MoveData.MoveTarget.OTHER: // Targets one Pokemon
|
||||
return move.getMove().accuracy
|
||||
case MoveData.MoveTarget.ALL_OTHERS: // Targets all Pokemon
|
||||
return move.getMove().accuracy;
|
||||
case MoveData.MoveTarget.NEAR_OTHER: // Targets a Pokemon adjacent to the user
|
||||
return move.getMove().accuracy;
|
||||
case MoveData.MoveTarget.ALL_NEAR_OTHERS: // Targets all Pokemon adjacent to the user
|
||||
return move.getMove().accuracy;
|
||||
case MoveData.MoveTarget.NEAR_ENEMY: // Targets an opponent adjacent to the user
|
||||
return move.getMove().accuracy;
|
||||
case MoveData.MoveTarget.ALL_NEAR_ENEMIES: // Targets all opponents adjacent to the user
|
||||
return move.getMove().accuracy;
|
||||
case MoveData.MoveTarget.RANDOM_NEAR_ENEMY: // Targets a random opponent adjacent to the user
|
||||
return move.getMove().accuracy;
|
||||
case MoveData.MoveTarget.ALL_ENEMIES: // Targets all opponents
|
||||
return move.getMove().accuracy;
|
||||
case MoveData.MoveTarget.ATTACKER: // Counter move
|
||||
return move.getMove().accuracy;
|
||||
case MoveData.MoveTarget.NEAR_ALLY: // Targets an adjacent ally
|
||||
return move.getMove().accuracy;
|
||||
case MoveData.MoveTarget.ALLY: // Targets an ally
|
||||
return move.getMove().accuracy;
|
||||
case MoveData.MoveTarget.USER_OR_NEAR_ALLY: // Targets an ally or yourself
|
||||
return move.getMove().accuracy;
|
||||
case MoveData.MoveTarget.USER_AND_ALLIES: // Targets all on your side
|
||||
return move.getMove().accuracy;
|
||||
case MoveData.MoveTarget.ALL: // Targets everyone
|
||||
return move.getMove().accuracy;
|
||||
case MoveData.MoveTarget.USER_SIDE: // Targets your field
|
||||
return move.getMove().accuracy;
|
||||
case MoveData.MoveTarget.ENEMY_SIDE: // Targets enemy field
|
||||
return -1; // Moves placing entry hazards always hit
|
||||
case MoveData.MoveTarget.BOTH_SIDES: // Targets the entire field
|
||||
return move.getMove().accuracy;
|
||||
case MoveData.MoveTarget.PARTY: // Targets all of the Player's Pokemon, including ones that aren't active
|
||||
return move.getMove().accuracy;
|
||||
case MoveData.MoveTarget.CURSE:
|
||||
return move.getMove().accuracy;
|
||||
}
|
||||
}
|
||||
// Moves targeting the user and entry hazards can't miss
|
||||
if ([MoveData.MoveTarget.USER, MoveData.MoveTarget.ENEMY_SIDE].includes(move.getMove().moveTarget)) {
|
||||
return -1;
|
||||
}
|
||||
if (target == undefined) return move.getMove().accuracy;
|
||||
// If either Pokemon has No Guard,
|
||||
if (user.hasAbilityWithAttr(AlwaysHitAbAttr) || target.hasAbilityWithAttr(AlwaysHitAbAttr)) {
|
||||
return -1;
|
||||
}
|
||||
// If the user should ignore accuracy on a target, check who the user targeted last turn and see if they match
|
||||
if (user.getTag(BattlerTagType.IGNORE_ACCURACY) && (user.getLastXMoves().slice(1).find(() => true)?.targets || []).indexOf(target.getBattlerIndex()) !== -1) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
const hiddenTag = target.getTag(SemiInvulnerableTag);
|
||||
if (hiddenTag && !move.getMove().getAttrs(MoveData.HitsTagAttr).some(hta => hta.tagType === hiddenTag.tagType)) {
|
||||
return 0;
|
||||
}
|
||||
const moveAccuracy = new Utils.NumberHolder(move.getMove().accuracy);
|
||||
|
||||
MoveData.applyMoveAttrs(MoveData.VariableAccuracyAttr, user, target, move.getMove(), moveAccuracy);
|
||||
applyPreDefendAbAttrs(WonderSkinAbAttr, target, user, move.getMove(), { value: false }, moveAccuracy);
|
||||
|
||||
if (moveAccuracy.value === -1) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
const isOhko = move.getMove().hasAttr(MoveData.OneHitKOAccuracyAttr);
|
||||
|
||||
if (!isOhko) {
|
||||
user.scene.applyModifiers(PokemonMoveAccuracyBoosterModifier, user.isPlayer(), user, moveAccuracy);
|
||||
}
|
||||
|
||||
if (this.scene.arena.weather?.weatherType === WeatherType.FOG) {
|
||||
moveAccuracy.value = Math.floor(moveAccuracy.value * 0.9);
|
||||
}
|
||||
|
||||
if (!isOhko && this.scene.arena.getTag(ArenaTagType.GRAVITY)) {
|
||||
moveAccuracy.value = Math.floor(moveAccuracy.value * 1.67);
|
||||
}
|
||||
|
||||
const userAccuracyLevel = new Utils.IntegerHolder(user.summonData.battleStats[BattleStat.ACC]);
|
||||
const targetEvasionLevel = new Utils.IntegerHolder(target.summonData.battleStats[BattleStat.EVA]);
|
||||
applyAbAttrs(IgnoreOpponentStatChangesAbAttr, target, null, userAccuracyLevel);
|
||||
applyAbAttrs(IgnoreOpponentStatChangesAbAttr, user, null, targetEvasionLevel);
|
||||
applyAbAttrs(IgnoreOpponentEvasionAbAttr, user, null, targetEvasionLevel);
|
||||
MoveData.applyMoveAttrs(MoveData.IgnoreOpponentStatChangesAttr, user, target, move.getMove(), targetEvasionLevel);
|
||||
this.scene.applyModifiers(TempBattleStatBoosterModifier, user.isPlayer(), TempBattleStat.ACC, userAccuracyLevel);
|
||||
|
||||
const accuracyMultiplier = new Utils.NumberHolder(1);
|
||||
if (userAccuracyLevel.value !== targetEvasionLevel.value) {
|
||||
accuracyMultiplier.value = userAccuracyLevel.value > targetEvasionLevel.value
|
||||
? (3 + Math.min(userAccuracyLevel.value - targetEvasionLevel.value, 6)) / 3
|
||||
: 3 / (3 + Math.min(targetEvasionLevel.value - userAccuracyLevel.value, 6));
|
||||
}
|
||||
|
||||
applyBattleStatMultiplierAbAttrs(BattleStatMultiplierAbAttr, user, BattleStat.ACC, accuracyMultiplier, move.getMove());
|
||||
|
||||
const evasionMultiplier = new Utils.NumberHolder(1);
|
||||
applyBattleStatMultiplierAbAttrs(BattleStatMultiplierAbAttr, target, BattleStat.EVA, evasionMultiplier);
|
||||
|
||||
accuracyMultiplier.value /= evasionMultiplier.value;
|
||||
|
||||
return moveAccuracy.value * accuracyMultiplier.value
|
||||
}
|
||||
|
||||
calcDamage(scene: BattleScene, user: PlayerPokemon, target: Pokemon, move: PokemonMove) {
|
||||
/*
|
||||
var power = move.getMove().power
|
||||
@ -535,11 +647,17 @@ export default class FightUiHandler extends UiHandler {
|
||||
var percentChance = (target.hp - dmgLow + 1) / (dmgHigh - dmgLow + 1)
|
||||
koText = " (" + Math.round(percentChance * 100) + "% KO)"
|
||||
}
|
||||
return (Math.round(dmgLow) == Math.round(dmgHigh) ? Math.round(dmgLow).toString() : Math.round(dmgLow) + "-" + Math.round(dmgHigh)) + koText
|
||||
if (target.getMoveEffectiveness(user, move) == undefined) {
|
||||
return "---"
|
||||
}
|
||||
if (scene.damageDisplay == "Value")
|
||||
return target.getMoveEffectiveness(user, move) + "x - " + (Math.round(dmgLow) == Math.round(dmgHigh) ? Math.round(dmgLow).toString() : Math.round(dmgLow) + "-" + Math.round(dmgHigh)) + koText
|
||||
dmgLow = Math.round((dmgLow)/target.getBattleStat(Stat.HP)*100)
|
||||
dmgHigh = Math.round((dmgHigh)/target.getBattleStat(Stat.HP)*100)
|
||||
return (dmgLow == dmgHigh ? dmgLow + "%" : dmgLow + "%-" + dmgHigh + "%") + koText
|
||||
return "???"
|
||||
if (scene.damageDisplay == "Percent")
|
||||
return target.getMoveEffectiveness(user, move) + "x - " + (dmgLow == dmgHigh ? dmgLow + "%" : dmgLow + "%-" + dmgHigh + "%") + koText
|
||||
if (scene.damageDisplay == "Off")
|
||||
return target.getMoveEffectiveness(user, move) + "x"
|
||||
}
|
||||
|
||||
setCursor(cursor: integer): boolean {
|
||||
@ -574,9 +692,15 @@ export default class FightUiHandler extends UiHandler {
|
||||
const maxPP = pokemonMove.getMovePp();
|
||||
const pp = maxPP - pokemonMove.ppUsed;
|
||||
|
||||
const accuracy1 = this.calculateAccuracy(pokemon, this.scene.getEnemyField()[0], pokemonMove)
|
||||
const accuracy2 = this.calculateAccuracy(pokemon, this.scene.getEnemyField()[1], pokemonMove)
|
||||
|
||||
this.ppText.setText(`${Utils.padInt(pp, 2, " ")}/${Utils.padInt(maxPP, 2, " ")}`);
|
||||
this.powerText.setText(`${power >= 0 ? power : "---"}`);
|
||||
this.accuracyText.setText(`${accuracy >= 0 ? accuracy : "---"}`);
|
||||
this.accuracyText.setText(`${accuracy1 >= 0 ? accuracy1 : "---"}`);
|
||||
if (this.scene.getEnemyField()[1] != undefined)
|
||||
this.accuracyText.setText(`${accuracy1 >= 0 ? accuracy1 : "---"}/${accuracy2 >= 0 ? accuracy2 : "---"}`);
|
||||
|
||||
const ppPercentLeft = pp / maxPP;
|
||||
|
||||
@ -939,8 +1063,8 @@ export function simulateAttack(scene: BattleScene, user: Pokemon, target: Pokemo
|
||||
applyPreDefendAbAttrs(ReceivedMoveDamageMultiplierAbAttr, user, target, move, cancelled, damage1);
|
||||
applyPreDefendAbAttrs(ReceivedMoveDamageMultiplierAbAttr, user, target, move, cancelled, damage2);
|
||||
|
||||
console.log("damage (min)", damage1.value, move.name, power.value, sourceAtk, targetDef);
|
||||
console.log("damage (max)", damage2.value, move.name, power.value, sourceAtkCrit, targetDefCrit);
|
||||
//console.log("damage (min)", damage1.value, move.name, power.value, sourceAtk, targetDef);
|
||||
//console.log("damage (max)", damage2.value, move.name, power.value, sourceAtkCrit, targetDefCrit);
|
||||
|
||||
// In case of fatal damage, this tag would have gotten cleared before we could lapse it.
|
||||
const destinyTag = target.getTag(BattlerTagType.DESTINY_BOND);
|
||||
|
@ -63,7 +63,7 @@ export enum PartyOption {
|
||||
}
|
||||
|
||||
export type PartySelectCallback = (cursor: integer, option: PartyOption) => void;
|
||||
export type PartyModifierTransferSelectCallback = (fromCursor: integer, index: integer, itemQuantity?: integer, toCursor?: integer) => void;
|
||||
export type PartyModifierTransferSelectCallback = (fromCursor: integer, index: integer, itemQuantity?: integer, toCursor?: integer, isAll?: boolean, isFirst?: boolean) => void;
|
||||
export type PartyModifierSpliceSelectCallback = (fromCursor: integer, toCursor?: integer) => void;
|
||||
export type PokemonSelectFilter = (pokemon: PlayerPokemon) => string;
|
||||
export type PokemonModifierTransferSelectFilter = (pokemon: PlayerPokemon, modifier: PokemonHeldItemModifier) => string;
|
||||
@ -326,7 +326,7 @@ export default class PartyUiHandler extends MessageUiHandler {
|
||||
if (option === PartyOption.TRANSFER) {
|
||||
if (this.transferCursor !== this.cursor) {
|
||||
if (this.transferAll) {
|
||||
getTransferrableItemsFromPokemon(this.scene.getParty()[this.transferCursor]).forEach((_, i) => (this.selectCallback as PartyModifierTransferSelectCallback)(this.transferCursor, i, this.transferQuantitiesMax[i], this.cursor));
|
||||
getTransferrableItemsFromPokemon(this.scene.getParty()[this.transferCursor]).forEach((_, i) => (this.selectCallback as PartyModifierTransferSelectCallback)(this.transferCursor, i, this.transferQuantitiesMax[i], this.cursor, true, i == 0));
|
||||
} else {
|
||||
(this.selectCallback as PartyModifierTransferSelectCallback)(this.transferCursor, this.transferOptionCursor, this.transferQuantities[this.transferOptionCursor], this.cursor);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user