Skip to content

Commit

Permalink
[Balance] Change IV Scanner to single stack (#5299)
Browse files Browse the repository at this point in the history
* Make IV Scanner max stack 1

* Apply suggestions from code review

Co-authored-by: Sirz Benjie <[email protected]>

---------

Co-authored-by: Sirz Benjie <[email protected]>
Co-authored-by: damocleas <[email protected]>
  • Loading branch information
3 people authored Feb 11, 2025
1 parent 195a393 commit 03011c4
Show file tree
Hide file tree
Showing 6 changed files with 15 additions and 43 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -315,7 +315,7 @@ async function summonSafariPokemon() {

const ivScannerModifier = globalScene.findModifier(m => m instanceof IvScannerModifier);
if (ivScannerModifier) {
globalScene.pushPhase(new ScanIvsPhase(pokemon.getBattlerIndex(), Math.min(ivScannerModifier.getStackCount() * 2, 6)));
globalScene.pushPhase(new ScanIvsPhase(pokemon.getBattlerIndex()));
}
}

Expand Down
12 changes: 6 additions & 6 deletions src/modifier/modifier.ts
Original file line number Diff line number Diff line change
Expand Up @@ -165,9 +165,9 @@ export abstract class PersistentModifier extends Modifier {
public stackCount: number;
public virtualStackCount: number;

constructor(type: ModifierType, stackCount?: number) {
constructor(type: ModifierType, stackCount: number = 1) {
super(type);
this.stackCount = stackCount === undefined ? 1 : stackCount;
this.stackCount = stackCount;
this.virtualStackCount = 0;
}

Expand Down Expand Up @@ -3295,27 +3295,27 @@ export class ContactHeldItemTransferChanceModifier extends HeldItemTransferModif

export class IvScannerModifier extends PersistentModifier {
constructor(type: ModifierType, stackCount?: number) {
super(type, stackCount);
super(type);
}

match(modifier: Modifier): boolean {
return modifier instanceof IvScannerModifier;
}

clone(): IvScannerModifier {
return new IvScannerModifier(this.type, this.stackCount);
return new IvScannerModifier(this.type);
}

/**
* Applies {@linkcode IvScannerModifier}
* @returns always `true`
*/
override apply(): boolean {
return true;
return true; //Dude are you kidding me
}

getMaxStackCount(): number {
return 3;
return 1;
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/phases/encounter-phase.ts
Original file line number Diff line number Diff line change
Expand Up @@ -478,7 +478,7 @@ export class EncounterPhase extends BattlePhase {
}));
const ivScannerModifier = globalScene.findModifier(m => m instanceof IvScannerModifier);
if (ivScannerModifier) {
enemyField.map(p => globalScene.pushPhase(new ScanIvsPhase(p.getBattlerIndex(), Math.min(ivScannerModifier.getStackCount() * 2, 6))));
enemyField.map(p => globalScene.pushPhase(new ScanIvsPhase(p.getBattlerIndex())));
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/phases/mystery-encounter-phases.ts
Original file line number Diff line number Diff line change
Expand Up @@ -396,7 +396,7 @@ export class MysteryEncounterBattlePhase extends Phase {
if (encounterMode !== MysteryEncounterMode.TRAINER_BATTLE) {
const ivScannerModifier = globalScene.findModifier(m => m instanceof IvScannerModifier);
if (ivScannerModifier) {
enemyField.map(p => globalScene.pushPhase(new ScanIvsPhase(p.getBattlerIndex(), Math.min(ivScannerModifier.getStackCount() * 2, 6))));
enemyField.map(p => globalScene.pushPhase(new ScanIvsPhase(p.getBattlerIndex())));
}
}

Expand Down
19 changes: 4 additions & 15 deletions src/phases/scan-ivs-phase.ts
Original file line number Diff line number Diff line change
@@ -1,29 +1,21 @@
import { globalScene } from "#app/global-scene";
import type { BattlerIndex } from "#app/battle";
import { CommonBattleAnim, CommonAnim } from "#app/data/battle-anims";
import { Stat } from "#app/enums/stat";
import { PERMANENT_STATS, Stat } from "#app/enums/stat";
import { getPokemonNameWithAffix } from "#app/messages";
import { getTextColor, TextStyle } from "#app/ui/text";
import { Mode } from "#app/ui/ui";
import i18next from "i18next";
import { PokemonPhase } from "./pokemon-phase";

export class ScanIvsPhase extends PokemonPhase {
private shownIvs: number;

constructor(battlerIndex: BattlerIndex, shownIvs: number) {
constructor(battlerIndex: BattlerIndex) {
super(battlerIndex);

this.shownIvs = shownIvs;
}

start() {
super.start();

if (!this.shownIvs) {
return this.end();
}

const pokemon = this.getPokemon();

let enemyIvs: number[] = [];
Expand All @@ -34,12 +26,11 @@ export class ScanIvsPhase extends PokemonPhase {
for (let e = 0; e < enemyField.length; e++) {
enemyIvs = enemyField[e].ivs;
const currentIvs = globalScene.gameData.dexData[enemyField[e].species.getRootSpeciesId()].ivs; // we are using getRootSpeciesId() here because we want to check against the baby form, not the mid form if it exists
const ivsToShow = globalScene.ui.getMessageHandler().getTopIvs(enemyIvs, this.shownIvs);
statsContainer = enemyField[e].getBattleInfo().getStatsValueContainer().list as Phaser.GameObjects.Sprite[];
statsContainerLabels = statsContainer.filter(m => m.name.indexOf("icon_stat_label") >= 0);
for (let s = 0; s < statsContainerLabels.length; s++) {
const ivStat = Stat[statsContainerLabels[s].frame.name];
if (enemyIvs[ivStat] > currentIvs[ivStat] && ivsToShow.indexOf(Number(ivStat)) >= 0) {
if (enemyIvs[ivStat] > currentIvs[ivStat] && PERMANENT_STATS.indexOf(Number(ivStat)) >= 0) {
const hexColour = enemyIvs[ivStat] === 31 ? getTextColor(TextStyle.PERFECT_IV, false, uiTheme) : getTextColor(TextStyle.SUMMARY_GREEN, false, uiTheme);
const hexTextColour = Phaser.Display.Color.HexStringToColor(hexColour).color;
statsContainerLabels[s].setTint(hexTextColour);
Expand All @@ -53,9 +44,7 @@ export class ScanIvsPhase extends PokemonPhase {
globalScene.ui.setMode(Mode.CONFIRM, () => {
globalScene.ui.setMode(Mode.MESSAGE);
globalScene.ui.clearText();
new CommonBattleAnim(CommonAnim.LOCK_ON, pokemon, pokemon).play(false, () => {
globalScene.ui.getMessageHandler().promptIvs(pokemon.id, pokemon.ivs, this.shownIvs).then(() => this.end());
});
globalScene.ui.getMessageHandler().promptIvs(pokemon.id, pokemon.ivs).then(() => this.end());
}, () => {
globalScene.ui.setMode(Mode.MESSAGE);
globalScene.ui.clearText();
Expand Down
21 changes: 2 additions & 19 deletions src/ui/battle-message-ui-handler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import { addWindow } from "./ui-theme";
import type BBCodeText from "phaser3-rex-plugins/plugins/bbcodetext";
import { Button } from "#enums/buttons";
import i18next from "i18next";
import type { Stat } from "#app/enums/stat";
import { PERMANENT_STATS, getStatKey } from "#app/enums/stat";

export default class BattleMessageUiHandler extends MessageUiHandler {
Expand Down Expand Up @@ -191,13 +190,12 @@ export default class BattleMessageUiHandler extends MessageUiHandler {
});
}

promptIvs(pokemonId: number, ivs: number[], shownIvsCount: number): Promise<void> {
promptIvs(pokemonId: number, ivs: number[]): Promise<void> {
return new Promise(resolve => {
globalScene.executeWithSeedOffset(() => {
let levelUpStatsValuesText = "";
const shownStats = this.getTopIvs(ivs, shownIvsCount);
for (const s of PERMANENT_STATS) {
levelUpStatsValuesText += `${shownStats.includes(s) ? this.getIvDescriptor(ivs[s], s, pokemonId) : "???"}\n`;
levelUpStatsValuesText += `${this.getIvDescriptor(ivs[s], s, pokemonId)}\n`;
}
this.levelUpStatsValuesContent.text = levelUpStatsValuesText;
this.levelUpStatsIncrContent.setVisible(false);
Expand All @@ -211,21 +209,6 @@ export default class BattleMessageUiHandler extends MessageUiHandler {
});
}

getTopIvs(ivs: number[], shownIvsCount: number): Stat[] {
let shownStats: Stat[] = [];
if (shownIvsCount < 6) {
const statsPool = PERMANENT_STATS.slice();
// Sort the stats from highest to lowest iv
statsPool.sort((s1, s2) => ivs[s2] - ivs[s1]);
for (let i = 0; i < shownIvsCount; i++) {
shownStats.push(statsPool[i]);
}
} else {
shownStats = PERMANENT_STATS.slice();
}
return shownStats;
}

getIvDescriptor(value: number, typeIv: number, pokemonId: number): string {
const starterSpecies = globalScene.getPokemonById(pokemonId)!.species.getRootSpeciesId(); // we are using getRootSpeciesId() here because we want to check against the baby form, not the mid form if it exists
const starterIvs: number[] = globalScene.gameData.dexData[starterSpecies].ivs;
Expand Down

0 comments on commit 03011c4

Please sign in to comment.