Simpler Shop

Hides shop items that you can't use, or would be a waste of money to buy over something else

Attempted to make damage prediction adjust for boss shields

Guaranteed KOs will now be shown even with damage predictions off

Removed 50 wave limit in waves array

Added a secret randomizer mode
This commit is contained in:
RedstonewolfX 2024-07-23 18:31:15 -04:00
parent 7f5166d75a
commit f5d3128a42
9 changed files with 161 additions and 38 deletions

View File

@ -129,6 +129,7 @@ export default class BattleScene extends SceneBase {
public doBiomePanels: boolean = false; public doBiomePanels: boolean = false;
public disableDailyShinies: boolean = true; // Disables shiny luck in Daily Runs to prevent affecting RNG public disableDailyShinies: boolean = true; // Disables shiny luck in Daily Runs to prevent affecting RNG
public quickloadDisplayMode: string = "Dailies"; public quickloadDisplayMode: string = "Dailies";
public chaosmode: boolean = false;
/** /**
* Determines the condition for a notification should be shown for Candy Upgrades * Determines the condition for a notification should be shown for Candy Upgrades
* - 0 = 'Off' * - 0 = 'Off'

View File

@ -28,7 +28,7 @@ export enum Region {
PALDEA PALDEA
} }
export function getPokemonSpecies(species: Species): PokemonSpecies { export function getPokemonSpecies(species: any): PokemonSpecies {
// If a special pool (named trainers) is used here it CAN happen that they have a array as species (which means choose one of those two). So we catch that with this code block // If a special pool (named trainers) is used here it CAN happen that they have a array as species (which means choose one of those two). So we catch that with this code block
if (Array.isArray(species)) { if (Array.isArray(species)) {
// Pick a random species from the list // Pick a random species from the list

View File

@ -134,6 +134,8 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
: (species.abilityHidden && hasHiddenAbility ? species.ability2 ? 2 : 1 : species.ability2 ? randAbilityIndex : 0); : (species.abilityHidden && hasHiddenAbility ? species.ability2 ? 2 : 1 : species.ability2 ? randAbilityIndex : 0);
if (formIndex !== undefined) { if (formIndex !== undefined) {
this.formIndex = formIndex; this.formIndex = formIndex;
} else if (species.formIndex != undefined) {
this.formIndex = species.formIndex
} }
if (gender !== undefined) { if (gender !== undefined) {
this.gender = gender; this.gender = gender;

View File

@ -759,7 +759,10 @@ export function getWave(drpd: DRPD, floor: integer, scene: BattleScene): Wave {
} }
} }
if (wv == undefined) { if (wv == undefined) {
if (scene.gameMode.modeId != GameModes.DAILY) { if (scene.gameMode.modeId != GameModes.DAILY || true) {
if (scene.gameMode.modeId == GameModes.DAILY) {
console.log(";-;")
}
drpd.waves.push({ drpd.waves.push({
id: floor, id: floor,
reload: false, reload: false,

View File

@ -11,7 +11,7 @@ import * as Utils from "../utils";
import { TempBattleStat, getTempBattleStatBoosterItemName, getTempBattleStatName } from "../data/temp-battle-stat"; import { TempBattleStat, getTempBattleStatBoosterItemName, getTempBattleStatName } from "../data/temp-battle-stat";
import { getBerryEffectDescription, getBerryName } from "../data/berry"; import { getBerryEffectDescription, getBerryName } from "../data/berry";
import { Unlockables } from "../system/unlockables"; import { Unlockables } from "../system/unlockables";
import { StatusEffect, getStatusEffectDescriptor } from "../data/status-effect"; import { Status, StatusEffect, getStatusEffectDescriptor } from "../data/status-effect";
import { SpeciesFormKey } from "../data/pokemon-species"; import { SpeciesFormKey } from "../data/pokemon-species";
import BattleScene from "../battle-scene"; import BattleScene from "../battle-scene";
import { VoucherType, getVoucherTypeIcon, getVoucherTypeName } from "../system/voucher"; import { VoucherType, getVoucherTypeIcon, getVoucherTypeName } from "../system/voucher";
@ -1978,40 +1978,115 @@ export function getPlayerModifierTypeOptions(count: integer, party: PlayerPokemo
return options; return options;
} }
export function getPlayerShopModifierTypeOptionsForWave(waveIndex: integer, baseCost: integer): ModifierTypeOption[] { export function getPlayerShopModifierTypeOptionsForWave(scene: BattleScene, waveIndex: integer, baseCost: integer): ModifierTypeOption[] {
if (!(waveIndex % 10)) { if (!(waveIndex % 10)) {
return []; return [];
} }
var maxdmg = 0
var maxdmg_percent = 0
var hasStatus = false // A member of the party has a status condition (Full Heal, Full Restore)
var hasFainted = false // A member of the party has zero health (Revive, Max Revive)
var multiFainted = false // At least two Pokemon have zero health (Sacred Ash)
var hasPPUsed = false // At least one Pokemon has used at least 1 PP (Ether)
var hasPPUsedOver10 = false // At least one Pokemon has used more than 10 PP on a single move (Max Ether, Max Elexir)
var hasPPUsedMulti = false // At least one Pokemon has used at least 1 PP on multiple moves (Elexir, Max Elexir)
var party = scene.getParty()
party.forEach(p => {
maxdmg = Math.max(maxdmg, p.getMaxHp() - p.hp)
maxdmg_percent = Math.max(maxdmg_percent, 1 - (p.hp/p.getMaxHp()))
if (p.status)
switch (p.status.effect) {
case StatusEffect.NONE:
break; // No status effect
case StatusEffect.POISON:
case StatusEffect.TOXIC:
case StatusEffect.PARALYSIS:
case StatusEffect.SLEEP:
case StatusEffect.FREEZE:
case StatusEffect.BURN:
hasStatus = true;
break;
case StatusEffect.FAINT:
if (hasFainted)
multiFainted = true;
hasFainted = true;
break;
}
p.moveset.forEach(m => {
if (m.ppUsed > 0 && hasPPUsed)
hasPPUsedMulti = true
if (m.ppUsed > 0)
hasPPUsed = true
if (m.ppUsed >= 10)
hasPPUsedOver10 = true
})
})
const options = [ const options = [
[ [ // 0
new ModifierTypeOption(modifierTypes.POTION(), 0, baseCost * 0.2), //new ModifierTypeOption(modifierTypes.POTION(), 0, baseCost * 0.2),
new ModifierTypeOption(modifierTypes.ETHER(), 0, baseCost * 0.4), //new ModifierTypeOption(modifierTypes.ETHER(), 0, baseCost * 0.4),
new ModifierTypeOption(modifierTypes.REVIVE(), 0, baseCost * 2) //new ModifierTypeOption(modifierTypes.REVIVE(), 0, baseCost * 2)
], ],
[ [ // 1
new ModifierTypeOption(modifierTypes.SUPER_POTION(), 0, baseCost * 0.45), //new ModifierTypeOption(modifierTypes.SUPER_POTION(), 0, baseCost * 0.45),
new ModifierTypeOption(modifierTypes.FULL_HEAL(), 0, baseCost), //new ModifierTypeOption(modifierTypes.FULL_HEAL(), 0, baseCost),
], ],
[ [ // 2
new ModifierTypeOption(modifierTypes.ELIXIR(), 0, baseCost), //new ModifierTypeOption(modifierTypes.ELIXIR(), 0, baseCost),
new ModifierTypeOption(modifierTypes.MAX_ETHER(), 0, baseCost) //new ModifierTypeOption(modifierTypes.MAX_ETHER(), 0, baseCost)
], ],
[ [ // 3
new ModifierTypeOption(modifierTypes.HYPER_POTION(), 0, baseCost * 0.8), //new ModifierTypeOption(modifierTypes.HYPER_POTION(), 0, baseCost * 0.8),
new ModifierTypeOption(modifierTypes.MAX_REVIVE(), 0, baseCost * 2.75) //new ModifierTypeOption(modifierTypes.MAX_REVIVE(), 0, baseCost * 2.75)
], ],
[ [ // 4
new ModifierTypeOption(modifierTypes.MAX_POTION(), 0, baseCost * 1.5), //new ModifierTypeOption(modifierTypes.MAX_POTION(), 0, baseCost * 1.5),
new ModifierTypeOption(modifierTypes.MAX_ELIXIR(), 0, baseCost * 2.5) //new ModifierTypeOption(modifierTypes.MAX_ELIXIR(), 0, baseCost * 2.5)
], ],
[ [ // 5
new ModifierTypeOption(modifierTypes.FULL_RESTORE(), 0, baseCost * 2.25) //new ModifierTypeOption(modifierTypes.FULL_RESTORE(), 0, baseCost * 2.25)
], ],
[ [ // 6
new ModifierTypeOption(modifierTypes.SACRED_ASH(), 0, baseCost * 10) //new ModifierTypeOption(modifierTypes.SACRED_ASH(), 0, baseCost * 10)
] ]
]; ];
// Assemble the shop by removing items that would just be a waste of money
// HP Restore
if (maxdmg > 0) // If any Pokemon has taken any damage, add Potion
options[0].push(new ModifierTypeOption(modifierTypes.POTION(), 0, baseCost * 0.2))
if (maxdmg >= 20 || maxdmg_percent >= 0.1) // If Potion isn't enough, add Super Potion
options[1].push(new ModifierTypeOption(modifierTypes.SUPER_POTION(), 0, baseCost * 0.45))
if (maxdmg >= 50 || maxdmg_percent >= 0.2) // If Super Potion isn't enough, add Hyper Potion
options[3].push(new ModifierTypeOption(modifierTypes.HYPER_POTION(), 0, baseCost * 0.8))
if (maxdmg >= 200 || maxdmg_percent >= 0.5) // If Hyper Potion isn't enough, add Max Potion
options[4].push(new ModifierTypeOption(modifierTypes.MAX_POTION(), 0, baseCost * 1.5))
// Status Restore
if ((maxdmg >= 200 || maxdmg_percent >= 0.5) && hasStatus) // If Hyper Potion isn't enough, and you have a status condition, add Full Restore
options[5].push(new ModifierTypeOption(modifierTypes.FULL_RESTORE(), 0, baseCost * 2.25))
if (hasStatus) // If you have a status condition, add Full Heal
options[1].push(new ModifierTypeOption(modifierTypes.FULL_HEAL(), 0, baseCost))
// PP Restore
if (hasPPUsed) // If you have used any PP (you probably have), add Ether
options[0].push(new ModifierTypeOption(modifierTypes.ETHER(), 0, baseCost * 0.4))
if (hasPPUsedOver10) // If you used at least 10 PP, add Max Ether
options[2].push(new ModifierTypeOption(modifierTypes.MAX_ETHER(), 0, baseCost))
if (hasPPUsedMulti) // If you have used PP from multiple moves, add Elexir
options[2].push(new ModifierTypeOption(modifierTypes.ELIXIR(), 0, baseCost))
if (hasPPUsedOver10 && hasPPUsedMulti) // If you have used multiple moves' PP, and have used more than 10 in at least one, add Max Elexir
options[4].push(new ModifierTypeOption(modifierTypes.MAX_ELIXIR(), 0, baseCost * 2.5))
// Revives
if (hasFainted) { // If a Pokemon has fainted, add Revive and Max Revive
options[0].push(new ModifierTypeOption(modifierTypes.REVIVE(), 0, baseCost * 2))
options[3].push(new ModifierTypeOption(modifierTypes.MAX_REVIVE(), 0, baseCost * 2.75))
}
if (multiFainted) // If multiple Pokemon are fainted, add Sacred Ash
options[6].push(new ModifierTypeOption(modifierTypes.SACRED_ASH(), 0, baseCost * 10))
return options.slice(0, Math.ceil(Math.max(waveIndex + 10, 0) / 30)).flat(); return options.slice(0, Math.ceil(Math.max(waveIndex + 10, 0) / 30)).flat();
} }

View File

@ -49,7 +49,7 @@ import { OptionSelectConfig, OptionSelectItem } from "./ui/abstact-option-select
import { SaveSlotUiMode } from "./ui/save-slot-select-ui-handler"; import { SaveSlotUiMode } from "./ui/save-slot-select-ui-handler";
import { fetchDailyRunSeed, getDailyRunStarters } from "./data/daily-run"; import { fetchDailyRunSeed, getDailyRunStarters } from "./data/daily-run";
import { GameMode, GameModes, getGameMode } from "./game-mode"; import { GameMode, GameModes, getGameMode } from "./game-mode";
import PokemonSpecies, { getPokemonSpecies, speciesStarters } from "./data/pokemon-species"; import PokemonSpecies, { allSpecies, getPokemonSpecies, getPokemonSpeciesForm, speciesStarters } from "./data/pokemon-species";
import i18next from "./plugins/i18n"; import i18next from "./plugins/i18n";
import * as Overrides from "./overrides"; import * as Overrides from "./overrides";
import { TextStyle, addTextObject } from "./ui/text"; import { TextStyle, addTextObject } from "./ui/text";
@ -613,7 +613,7 @@ export class TitlePhase extends Phase {
} }
}) })
break; break;
case this.scene.quickloadDisplayMode == "Both" && ls2 != undefined: case (this.scene.quickloadDisplayMode == "Both" || this.scene.quickloadDisplayMode == "On") && ls2 != undefined:
ls2.forEach(lastsave2 => { ls2.forEach(lastsave2 => {
options.push({ options.push({
label: (lastsave2.description ? lastsave2.description : "[???]"), label: (lastsave2.description ? lastsave2.description : "[???]"),
@ -703,7 +703,6 @@ export class TitlePhase extends Phase {
handler: () => { handler: () => {
this.scene.biomeChangeMode = false this.scene.biomeChangeMode = false
//return this.logRenameMenu() //return this.logRenameMenu()
//
this.scene.ui.setOverlayMode(Mode.LOG_HANDLER, this.scene.ui.setOverlayMode(Mode.LOG_HANDLER,
(k: string) => { (k: string) => {
if (k === undefined) { if (k === undefined) {
@ -715,7 +714,6 @@ export class TitlePhase extends Phase {
this.showOptions(); this.showOptions();
}); });
return true; return true;
//
} }
}) })
options.push({ options.push({
@ -1398,11 +1396,40 @@ export class EncounterPhase extends BattlePhase {
battle.enemyParty[e] = battle.trainer.genPartyMember(e); battle.enemyParty[e] = battle.trainer.genPartyMember(e);
} else { } else {
LoggerTools.rarityslot[0] = e LoggerTools.rarityslot[0] = e
const enemySpecies = this.scene.randomSpecies(battle.waveIndex, level, true); var enemySpecies = this.scene.randomSpecies(battle.waveIndex, level, true);
if (this.scene.chaosmode) {
enemySpecies = getPokemonSpecies(allSpecies.map(p => p.speciesId))
if (enemySpecies.forms.length > 0) {
enemySpecies.formIndex = Math.max(0, Math.floor(Math.random() * (enemySpecies.forms.length + 0)) - 0)
}
switch (this.scene.gameMode.modeId) {
case GameModes.CLASSIC:
case GameModes.CHALLENGE:
if (this.scene.currentBattle.waveIndex == 200) {
enemySpecies = getPokemonSpecies(Species.ETERNATUS)
enemySpecies.formIndex = 0
}
break;
case GameModes.ENDLESS:
case GameModes.SPLICED_ENDLESS:
if (this.scene.currentBattle.waveIndex % 250 == 0) {
enemySpecies = getPokemonSpecies(Species.ETERNATUS)
enemySpecies.formIndex = 0
if (this.scene.currentBattle.waveIndex % 1000 == 0) {
enemySpecies.formIndex = 1
}
}
break;
case GameModes.DAILY:
// idk
break;
}
}
battle.enemyParty[e] = this.scene.addEnemyPokemon(enemySpecies, level, TrainerSlot.NONE, !!this.scene.getEncounterBossSegments(battle.waveIndex, level, enemySpecies)); battle.enemyParty[e] = this.scene.addEnemyPokemon(enemySpecies, level, TrainerSlot.NONE, !!this.scene.getEncounterBossSegments(battle.waveIndex, level, enemySpecies));
if (this.scene.currentBattle.battleSpec === BattleSpec.FINAL_BOSS) { if (this.scene.currentBattle.battleSpec === BattleSpec.FINAL_BOSS) {
battle.enemyParty[e].ivs = new Array(6).fill(31); battle.enemyParty[e].ivs = new Array(6).fill(31);
} }
//battle.enemyParty[e].formIndex = enemySpecies.formIndex
this.scene.getParty().slice(0, !battle.double ? 1 : 2).reverse().forEach(playerPokemon => { this.scene.getParty().slice(0, !battle.double ? 1 : 2).reverse().forEach(playerPokemon => {
applyAbAttrs(SyncEncounterNatureAbAttr, playerPokemon, null, battle.enemyParty[e]); applyAbAttrs(SyncEncounterNatureAbAttr, playerPokemon, null, battle.enemyParty[e]);
}); });
@ -6487,7 +6514,7 @@ export class SelectModifierPhase extends BattlePhase {
modifierType = typeOptions[cursor].type; modifierType = typeOptions[cursor].type;
break; break;
default: default:
const shopOptions = getPlayerShopModifierTypeOptionsForWave(this.scene.currentBattle.waveIndex, this.scene.getWaveMoneyAmount(1)); const shopOptions = getPlayerShopModifierTypeOptionsForWave(this.scene, this.scene.currentBattle.waveIndex, this.scene.getWaveMoneyAmount(1));
const shopOption = shopOptions[rowCursor > 2 || shopOptions.length <= SHOP_OPTIONS_ROW_LIMIT ? cursor : cursor + SHOP_OPTIONS_ROW_LIMIT]; const shopOption = shopOptions[rowCursor > 2 || shopOptions.length <= SHOP_OPTIONS_ROW_LIMIT ? cursor : cursor + SHOP_OPTIONS_ROW_LIMIT];
modifierType = shopOption.type; modifierType = shopOption.type;
cost = shopOption.cost; cost = shopOption.cost;

View File

@ -671,6 +671,15 @@ export default class FightUiHandler extends UiHandler {
} }
dmgLow = out[0] * minHits dmgLow = out[0] * minHits
dmgHigh = out[1] * maxHits dmgHigh = out[1] * maxHits
var qSuffix = ""
if (target.isBoss()) {
var bossSegs = (target as EnemyPokemon).bossSegments
//dmgLow /= bossSegs
//dmgHigh /= bossSegs
//qSuffix = "?"
}
var dmgLowP = Math.round((dmgLow)/target.getBattleStat(Stat.HP)*100)
var dmgHighP = Math.round((dmgHigh)/target.getBattleStat(Stat.HP)*100)
/* /*
if (user.hasAbility(Abilities.PARENTAL_BOND)) { if (user.hasAbility(Abilities.PARENTAL_BOND)) {
// Second hit deals 0.25x damage // Second hit deals 0.25x damage
@ -689,13 +698,11 @@ export default class FightUiHandler extends UiHandler {
return "---" return "---"
} }
if (scene.damageDisplay == "Value") 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 return target.getMoveEffectiveness(user, move) + "x - " + (Math.round(dmgLow) == Math.round(dmgHigh) ? Math.round(dmgLow).toString() + qSuffix : Math.round(dmgLow) + "-" + Math.round(dmgHigh) + qSuffix) + koText
dmgLow = Math.round((dmgLow)/target.getBattleStat(Stat.HP)*100)
dmgHigh = Math.round((dmgHigh)/target.getBattleStat(Stat.HP)*100)
if (scene.damageDisplay == "Percent") if (scene.damageDisplay == "Percent")
return target.getMoveEffectiveness(user, move) + "x - " + (dmgLow == dmgHigh ? dmgLow + "%" : dmgLow + "%-" + dmgHigh + "%") + koText return target.getMoveEffectiveness(user, move) + "x - " + (dmgLowP == dmgHighP ? dmgLowP + "%" + qSuffix : dmgLowP + "%-" + dmgHighP + "%" + qSuffix) + koText
if (scene.damageDisplay == "Off") if (scene.damageDisplay == "Off")
return target.getMoveEffectiveness(user, move) + "x" return target.getMoveEffectiveness(user, move) + "x" + ((Math.floor(dmgLow) >= target.hp) ? " (KO)" : "")
} }
setCursor(cursor: integer): boolean { setCursor(cursor: integer): boolean {

View File

@ -121,6 +121,11 @@ export default class LogSelectUiHandler extends MessageUiHandler {
} }
} else if (button === Button.CANCEL) { } else if (button === Button.CANCEL) {
this.quitCallback(undefined); this.quitCallback(undefined);
} else if (button === Button.LEFT) {
this.scene.chaosmode = !this.scene.chaosmode
console.log("Toggled Chaos Mode " + (this.scene.chaosmode ? "ON" : "OFF"))
this.showText("Toggled Chaos Mode " + (this.scene.chaosmode ? "ON" : "OFF") + "\n(press LEFT to toggle)", undefined, () => {this.saveSlotSelectMessageBoxContainer.setVisible(false)}, 6000)
success = true
} else { } else {
switch (button) { switch (button) {
case Button.UP: case Button.UP:
@ -310,7 +315,7 @@ class SessionSlot extends Phaser.GameObjects.Container {
return; return;
const iconContainer = this.scene.add.container(26 * i, 0); const iconContainer = this.scene.add.container(26 * i, 0);
iconContainer.setScale(0.75); iconContainer.setScale(0.75);
console.log(p.id, Utils.getEnumKeys(Species)[Utils.getEnumValues(Species).indexOf(p.id)]) //console.log(p.id, Utils.getEnumKeys(Species)[Utils.getEnumValues(Species).indexOf(p.id)], Utils.getEnumKeys(Species)[allSpecies[Utils.getEnumValues(Species).indexOf(p.id)].speciesId])
//if (Utils.getEnumValues(Species)[p.id] == undefined) //if (Utils.getEnumValues(Species)[p.id] == undefined)
//return; //return;
@ -318,7 +323,7 @@ class SessionSlot extends Phaser.GameObjects.Container {
//if (getPokemonSpecies(Utils.getEnumValues(Species)[p.id]) == undefined) //if (getPokemonSpecies(Utils.getEnumValues(Species)[p.id]) == undefined)
//return; //return;
const icon = this.scene.addPkIcon(allSpecies[Utils.getEnumValues(Species).indexOf(p.id)], 0, 0, 0, 0, 0); const icon = this.scene.addPkIcon(getPokemonSpecies(Utils.getEnumValues(Species)[allSpecies[Utils.getEnumValues(Species).indexOf(p.id)].speciesId]), 0, 0, 0, 0, 0);
const text = addTextObject(this.scene, 32, 20, ``, TextStyle.PARTY, { fontSize: "54px", color: "#f8f8f8" }); const text = addTextObject(this.scene, 32, 20, ``, TextStyle.PARTY, { fontSize: "54px", color: "#f8f8f8" });
text.setShadow(0, 0, null); text.setShadow(0, 0, null);

View File

@ -36,6 +36,8 @@ export default class ModifierSelectUiHandler extends AwaitableUiHandler {
private cursorObj: Phaser.GameObjects.Image; private cursorObj: Phaser.GameObjects.Image;
private tO: ModifierTypeOption[];
constructor(scene: BattleScene) { constructor(scene: BattleScene) {
super(scene, Mode.CONFIRM); super(scene, Mode.CONFIRM);
@ -158,8 +160,9 @@ export default class ModifierSelectUiHandler extends AwaitableUiHandler {
this.updateRerollCostText(); this.updateRerollCostText();
const typeOptions = args[1] as ModifierTypeOption[]; const typeOptions = args[1] as ModifierTypeOption[];
this.tO = typeOptions
const shopTypeOptions = !this.scene.gameMode.hasNoShop const shopTypeOptions = !this.scene.gameMode.hasNoShop
? getPlayerShopModifierTypeOptionsForWave(this.scene.currentBattle.waveIndex, this.scene.getWaveMoneyAmount(1)) ? getPlayerShopModifierTypeOptionsForWave(this.scene, this.scene.currentBattle.waveIndex, this.scene.getWaveMoneyAmount(1))
: []; : [];
const optionsYOffset = shopTypeOptions.length >= SHOP_OPTIONS_ROW_LIMIT ? -8 : -24; const optionsYOffset = shopTypeOptions.length >= SHOP_OPTIONS_ROW_LIMIT ? -8 : -24;