isaacscript-common
Version:
Helper functions and features for IsaacScript mods.
65 lines (64 loc) • 3.01 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.getRandomCustomStageRoom = getRandomCustomStageRoom;
exports.getRandomBossRoomFromPool = getRandomBossRoomFromPool;
const array_1 = require("../../../../functions/array");
const log_1 = require("../../../../functions/log");
const random_1 = require("../../../../functions/random");
/**
* Helper function to get a random custom stage room from an array of custom stage rooms.
*
* Note that this function does not simply choose a random element in the provided array; it will
* properly account for each room weight using the algorithm from:
* https://stackoverflow.com/questions/1761626/weighted-random-numbers
*/
function getRandomCustomStageRoom(roomsMetadata, seedOrRNG, verbose = false) {
const totalWeight = getTotalWeightOfCustomStageRooms(roomsMetadata);
if (verbose) {
(0, log_1.log)(`Total weight of the custom stage rooms provided: ${totalWeight}`);
}
const chosenWeight = (0, random_1.getRandomFloat)(0, totalWeight, seedOrRNG);
if (verbose) {
(0, log_1.log)(`Randomly chose weight for custom stage room: ${chosenWeight}`);
}
return getCustomStageRoomWithChosenWeight(roomsMetadata, chosenWeight);
}
function getTotalWeightOfCustomStageRooms(roomsMetadata) {
const weights = roomsMetadata.map((roomMetadata) => roomMetadata.weight);
return (0, array_1.sumArray)(weights);
}
function getCustomStageRoomWithChosenWeight(roomsMetadata, chosenWeight) {
for (const roomMetadata of roomsMetadata) {
if (chosenWeight < roomMetadata.weight) {
return roomMetadata;
}
chosenWeight -= roomMetadata.weight;
}
error(`Failed to get a custom stage room with chosen weight: ${chosenWeight}`);
}
function getRandomBossRoomFromPool(roomsMetadata, bossPool, seedOrRNG, verbose = false) {
const totalWeight = getTotalWeightOfBossPool(bossPool);
if (verbose) {
(0, log_1.log)(`Total weight of the custom stage boss pool provided: ${totalWeight}`);
}
const chosenWeight = (0, random_1.getRandomFloat)(0, totalWeight, seedOrRNG);
if (verbose) {
(0, log_1.log)(`Randomly chose weight for custom stage boss pool: ${chosenWeight}`);
}
const bossEntry = getBossEntryWithChosenWeight(bossPool, chosenWeight);
const roomsMetadataForBoss = roomsMetadata.filter((roomMetadata) => roomMetadata.subType === bossEntry.subType);
return getRandomCustomStageRoom(roomsMetadataForBoss, seedOrRNG, verbose);
}
function getTotalWeightOfBossPool(bossPool) {
const weights = bossPool.map((bossEntry) => bossEntry.weight);
return (0, array_1.sumArray)(weights);
}
function getBossEntryWithChosenWeight(bossPool, chosenWeight) {
for (const bossEntry of bossPool) {
if (chosenWeight < bossEntry.weight) {
return bossEntry;
}
chosenWeight -= bossEntry.weight;
}
error(`Failed to get a custom stage boss entry with chosen weight: ${chosenWeight}`);
}