const BanchoMod = require("../BanchoMod"); const Enum = Object.freeze({ None: new BanchoMod(0, "none", "None"), NoFail: new BanchoMod(1, "nf", "NoFail"), Easy: new BanchoMod(2, "ez", "Easy"), Hidden: new BanchoMod(8, "hd", "Hidden"), HardRock: new BanchoMod(16, "hr", "HardRock"), SuddenDeath: new BanchoMod(32, "sd", "SuddenDeath"), DoubleTime: new BanchoMod(64, "dt", "DoubleTime"), Relax: new BanchoMod(128, "rx", "Relax"), HalfTime: new BanchoMod(256, "ht", "HalfTime"), Nightcore: new BanchoMod(512, "nc", "Nightcore"), Flashlight: new BanchoMod(1024, "fl", "Flashlight"), Autoplay: new BanchoMod(2048, "at", "Auto"), SpunOut: new BanchoMod(4096, "so", "SpunOut"), Relax2: new BanchoMod(8192, "ap", "Relax2"), Perfect: new BanchoMod(16384, "pf", "Perfect"), Key4: new BanchoMod(32768, "k4", "Key4"), Key5: new BanchoMod(65536, "k5", "Key5"), Key6: new BanchoMod(131072, "k6", "Key6"), Key7: new BanchoMod(262144, "k7", "Key7"), Key8: new BanchoMod(524288, "k8", "Key8"), FadeIn: new BanchoMod(1048576, "fi", "FadeIn"), Random: new BanchoMod(2097152, "rn", "Random"), LastMod: new BanchoMod(4194304, "lm", "LastMod"), Key9: new BanchoMod(16777216, "k9", "Key9"), Key10: new BanchoMod(33554432, "k10", "Key10"), Key1: new BanchoMod(67108864, "k1", "Key1"), Key3: new BanchoMod(134217728, "k3", "Key3"), Key2: new BanchoMod(268435456, "k2", "Key2") }); /** * Static class with a property for each mods and methods to manipulate them. * * @class BanchoMods * @prop {BanchoMod} None * @prop {BanchoMod} NoFail * @prop {BanchoMod} Easy * @prop {BanchoMod} Hidden * @prop {BanchoMod} HardRock * @prop {BanchoMod} SuddenDeath * @prop {BanchoMod} DoubleTime * @prop {BanchoMod} Relax * @prop {BanchoMod} HalfTime * @prop {BanchoMod} Nightcore * @prop {BanchoMod} Flashlight * @prop {BanchoMod} Autoplay * @prop {BanchoMod} SpunOut * @prop {BanchoMod} Relax2 * @prop {BanchoMod} Perfect * @prop {BanchoMod} Key4 * @prop {BanchoMod} Key5 * @prop {BanchoMod} Key6 * @prop {BanchoMod} Key7 * @prop {BanchoMod} Key8 * @prop {BanchoMod} FadeIn * @prop {BanchoMod} Random * @prop {BanchoMod} LastMod * @prop {BanchoMod} Key9 * @prop {BanchoMod} Key10 * @prop {BanchoMod} Key1 * @prop {BanchoMod} Key3 * @prop {BanchoMod} Key2 */ class BanchoMods { constructor() { Object.assign(this, Enum); this.enum = Enum; } /** * Parse mods in their bit flags form and returns them in an array of BanchoMods. * * @param {number} bits Mods combination in bit flags form * @param {boolean} [returnNone=true] Returns [BanchoMods.None] if bits is equal to 0 * @returns {BanchoMods[]} */ parseBitFlags(bits, returnNone = true) { if(bits == 0) if(returnNone) return [Enum.None]; else return []; const mods = []; for(const mod of Object.values(Enum)) if(mod != Enum.None && (bits & mod.enumValue) == mod.enumValue) mods.push(mod); return mods; } /** * Returns a bits flag integer representing the passed mods. * * @param {BanchoMods[]} mods * @returns {number} */ returnBitFlags(mods) { let ret = 0; for(const mod of mods) ret += mod.enumValue; return ret; } /** * Parse a mod in its short form (eg. HD). Case insensitive. * * @param {String} string * @returns {BanchoMod} */ parseShortMod(string) { for(const modName in Enum) if(Enum[modName].shortMod.toLowerCase() == string.toLowerCase()) return Enum[modName]; return null; } /** * Parse a short mods combination as a string or array of strings. * Accepted string formats: "HDDT", "HD, DT", "HD DT". The amount of spaces doesn't matter. Allowed seperators are comma and spaces. * @param {string|string[]} input */ parseShortMods(input) { let splits = []; if(Array.isArray(input)) splits = input; else if(typeof input == "string") { if(input.indexOf(",") != -1) splits = input.split(","); else if(input.indexOf(" ") != -1) splits = input.split(" "); else if(input.length % 2 == 0) { splits[0] = ""; for(const char of input) if(splits[splits.length - 1].length < 2) splits[splits.length - 1] += char; else splits[splits.length] = char; } else return [input]; } else return null; const mods = []; for(let i = 0; i < splits.length; i++) { const shortMod = this.parseShortMod(splits[i].trim()); if(shortMod) mods.push(shortMod); } return mods; } /** * Parse a mod in its long form (eg. Hidden). Case insensitive. * * @param {String} string * @returns {BanchoMod} */ parseLongMod(string) { for(const modName in Enum) if(Enum[modName].longMod.toLowerCase() == string.toLowerCase()) return Enum[modName]; return null; } /** * Parse a long mods combination as a string or array of strings. * Accepted string formats: "Hidden, DoubleTime", "Hidden DoubleTime". The amount of spaces doesn't matter. Allowed seperators are comma and spaces. * @param {string|string[]} input */ parseLongMods(input) { let splits = []; if(Array.isArray(input)) splits = input; else if(typeof input == "string") { if(input.indexOf(",") != -1) splits = input.split(","); else if(input.indexOf(" ") != -1) splits = input.split(" "); else splits = [input]; } else return null; const mods = []; for(let i = 0; i < splits.length; i++) { const longMod = this.parseLongMod(splits[i].trim()); if(longMod) mods.push(longMod); } return mods; } } module.exports = new BanchoMods();