[Feature] Stop random trainers from spawning near fixed battles (#2610)
* Stop trainer spawns on evil team and E4 floors * Thanks Xavion * change "floors" to "wave" in coment * at test for not spawning 3 waves within fixed trainer battle * remove out-commented code * apply code formatting * Updated test and make sure isWaveTrainer returns a boolean * Update comment --------- Co-authored-by: Felix Staud <felix.staud@headwire.com>
This commit is contained in:
parent
0d9dd1dfc8
commit
f9327680dd
|
@ -384,6 +384,10 @@ export class Arena {
|
|||
return weatherMultiplier * terrainMultiplier;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the denominator for the chance for a trainer spawn
|
||||
* @returns n where 1/n is the chance of a trainer battle
|
||||
*/
|
||||
getTrainerChance(): integer {
|
||||
switch (this.biomeType) {
|
||||
case Biome.METROPOLIS:
|
||||
|
|
|
@ -107,22 +107,37 @@ export class GameMode implements GameModeConfig {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines whether or not to generate a trainer
|
||||
* @param waveIndex the current floor the player is on (trainer sprites fail to generate on X1 floors)
|
||||
* @param arena the arena that contains the scene and functions
|
||||
* @returns true if a trainer should be generated, false otherwise
|
||||
*/
|
||||
isWaveTrainer(waveIndex: integer, arena: Arena): boolean {
|
||||
/**
|
||||
* Daily spawns trainers on floors 5, 15, 20, 25, 30, 35, 40, and 45
|
||||
*/
|
||||
if (this.isDaily) {
|
||||
return waveIndex % 10 === 5 || (!(waveIndex % 10) && waveIndex > 10 && !this.isWaveFinal(waveIndex));
|
||||
}
|
||||
if ((waveIndex % 30) === (arena.scene.offsetGym ? 0 : 20) && !this.isWaveFinal(waveIndex)) {
|
||||
return true;
|
||||
} else if (waveIndex % 10 !== 1 && waveIndex % 10) {
|
||||
/**
|
||||
* Do not check X1 floors since there's a bug that stops trainer sprites from appearing
|
||||
* after a X0 full party heal
|
||||
*/
|
||||
|
||||
const trainerChance = arena.getTrainerChance();
|
||||
let allowTrainerBattle = true;
|
||||
if (trainerChance) {
|
||||
const waveBase = Math.floor(waveIndex / 10) * 10;
|
||||
// Stop generic trainers from spawning in within 3 waves of a trainer battle
|
||||
for (let w = Math.max(waveIndex - 3, waveBase + 2); w <= Math.min(waveIndex + 3, waveBase + 9); w++) {
|
||||
if (w === waveIndex) {
|
||||
continue;
|
||||
}
|
||||
if ((w % 30) === (arena.scene.offsetGym ? 0 : 20) || this.isFixedBattle(waveIndex)) {
|
||||
if ((w % 30) === (arena.scene.offsetGym ? 0 : 20) || this.isFixedBattle(w)) {
|
||||
allowTrainerBattle = false;
|
||||
break;
|
||||
} else if (w < waveIndex) {
|
||||
|
@ -138,7 +153,7 @@ export class GameMode implements GameModeConfig {
|
|||
}
|
||||
}
|
||||
}
|
||||
return allowTrainerBattle && trainerChance && !Utils.randSeedInt(trainerChance);
|
||||
return Boolean(allowTrainerBattle && trainerChance && !Utils.randSeedInt(trainerChance));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,52 @@
|
|||
import { GameMode, GameModes, getGameMode } from "#app/game-mode.js";
|
||||
import {
|
||||
afterEach,
|
||||
beforeAll,
|
||||
beforeEach,
|
||||
describe,
|
||||
expect,
|
||||
it,
|
||||
vi,
|
||||
} from "vitest";
|
||||
import GameManager from "./utils/gameManager";
|
||||
import * as Utils from "../utils";
|
||||
describe("game-mode", () => {
|
||||
let phaserGame: Phaser.Game;
|
||||
let game: GameManager;
|
||||
beforeAll(() => {
|
||||
phaserGame = new Phaser.Game({
|
||||
type: Phaser.HEADLESS,
|
||||
});
|
||||
});
|
||||
afterEach(() => {
|
||||
game.phaseInterceptor.restoreOg();
|
||||
vi.resetAllMocks();
|
||||
});
|
||||
beforeEach(() => {
|
||||
game = new GameManager(phaserGame);
|
||||
});
|
||||
describe("classic", () => {
|
||||
let classicGameMode: GameMode;
|
||||
beforeEach(() => {
|
||||
classicGameMode = getGameMode(GameModes.CLASSIC);
|
||||
});
|
||||
it("does NOT spawn trainers within 3 waves of fixed battle", () => {
|
||||
const { arena } = game.scene;
|
||||
/** set wave 16 to be a fixed trainer fight meaning wave 13-19 don't allow trainer spawns */
|
||||
vi.spyOn(classicGameMode, "isFixedBattle").mockImplementation(
|
||||
(n: number) => (n === 16 ? true : false)
|
||||
);
|
||||
vi.spyOn(arena, "getTrainerChance").mockReturnValue(1);
|
||||
vi.spyOn(Utils, "randSeedInt").mockReturnValue(0);
|
||||
expect(classicGameMode.isWaveTrainer(11, arena)).toBeFalsy();
|
||||
expect(classicGameMode.isWaveTrainer(12, arena)).toBeTruthy();
|
||||
expect(classicGameMode.isWaveTrainer(13, arena)).toBeFalsy();
|
||||
expect(classicGameMode.isWaveTrainer(14, arena)).toBeFalsy();
|
||||
expect(classicGameMode.isWaveTrainer(15, arena)).toBeFalsy();
|
||||
// Wave 16 is a fixed trainer battle
|
||||
expect(classicGameMode.isWaveTrainer(17, arena)).toBeFalsy();
|
||||
expect(classicGameMode.isWaveTrainer(18, arena)).toBeFalsy();
|
||||
expect(classicGameMode.isWaveTrainer(19, arena)).toBeFalsy();
|
||||
});
|
||||
});
|
||||
});
|
Loading…
Reference in New Issue