/* eslint-disable @typescript-eslint/no-explicit-any */
import java from 'java';
import { AbstractAPIComponent } from './AbstractAPIComponent';
import { PlayableCharacter } from '../MasterLists/PlayableCharacters';
import { Random } from './Random';
import {
ModificationType, Modification, MasterModificationList, ModificationMap,
} from '../MasterLists/Modifications';
/**
* Modifications for the daily climb
* @type DailyModifications
*/
export interface DailyModifications {
starter: Modification | undefined;
generic: Modification | undefined;
difficulty: Modification | undefined;
}
/**
* Helper to handle daily climb modifications
*/
export class ModificationHelper extends AbstractAPIComponent {
private static readonly rotationConstant = 5;
private readonly _seed: number;
private readonly _character: PlayableCharacter;
private _starterMods: any;
private _genericMods: any;
private _difficultyMods: any;
private _legacyMods: any;
/**
*
* @param {string} stsJarPath Path to the `desktop-1.0.jar` Slay the Spire game file
* @param {Random} rng Random number generator
* @param {PlayableCharacter} character Selected character for the daily climb
*
* @example
* const rng: Random = new Random('./path/to/stsJar', 1337);
* const modHelper: ModificationHelper = new ModificationHelper('./path/to/stsJar',
* rng, PlayableCharacter.Ironclad);
*/
constructor(stsJarPath: string, rng: Random, character: PlayableCharacter) {
super(stsJarPath);
this._seed = rng.seed;
this._character = character;
this._starterMods = java.newInstanceSync('java.util.HashMap');
this._genericMods = java.newInstanceSync('java.util.HashMap');
this._difficultyMods = java.newInstanceSync('java.util.HashMap');
this._legacyMods = java.newInstanceSync('java.util.HashMap');
MasterModificationList.forEach((modification) => {
switch (modification.type) {
case ModificationType.STARTER:
this._starterMods.putSync(modification.id, modification.id);
break;
case ModificationType.GENERIC:
this._genericMods.putSync(modification.id, modification.id);
break;
case ModificationType.DIFFICULTY:
this._difficultyMods.putSync(
modification.id,
modification.id,
);
break;
case ModificationType.LEGACY:
this._legacyMods.putSync(modification.id, modification.id);
break;
default:
throw Error(`Unable to add mod: ${modification.id}`);
}
});
}
/**
* The modifications for the daily climb
* @type {DailyModifications}
*
* @example
* const rng: Random = new Random('./path/to/stsJar', 1337);
* const modHelper: ModificationHelper = new ModificationHelper('./path/to/stsJar',
* rng, PlayableCharacter.Ironclad);
*
* const todaysMods: DailyModifications = modHelper.modifications;
*/
get modifications(): DailyModifications {
return {
starter: ModificationMap.get(
this.getModification(this._starterMods),
),
generic: ModificationMap.get(
this.getModification(this._genericMods),
),
difficulty: ModificationMap.get(
this.getModification(this._difficultyMods),
),
};
}
/**
* @private
*
* Choose a random {@link Modification} ID from a list of {@link Modification}s
* @param modificationList list of {@link Modification}s to choose from
* @returns {string}
*/
private getModification(modificationList: any): string {
const shuffledList = java.newInstanceSync('java.util.ArrayList');
const modificationArray: Array<string> = modificationList
.entrySetSync()
.toArraySync()
.map((mod: any) => mod.toStringSync().replace(/=.*/g, ''));
const character: PlayableCharacter = this._character;
modificationArray.forEach((modificationId: string) => {
const modification = ModificationMap.get(modificationId);
if (modification && modification.exclude !== character) {
shuffledList.addSync(modificationId);
}
});
let modSelectionIndex = this._seed % ModificationHelper.rotationConstant;
if (modSelectionIndex < 0) modSelectionIndex += ModificationHelper.rotationConstant;
const shuffleInterval = Math.floor(
this._seed / ModificationHelper.rotationConstant,
);
const shuffleRng = java.newInstanceSync(
'java.util.Random',
shuffleInterval,
);
java.callStaticMethodSync(
'java.util.Collections',
'shuffle',
shuffledList,
shuffleRng,
);
return shuffledList.toArraySync()[modSelectionIndex];
}
}
Source