Viewing old revision of Module:Game
You are viewing an old revision of this page from 3/21/2026, 5:31:06 PM.
View latest versionconst VENDOR_SELL_MODIFIER = 0.38;
const Utils = require("Utils");
function getSellPrice(buyPrice) {
return buyPrice ? Math.floor(Math.max(buyPrice * VENDOR_SELL_MODIFIER, 1)) : "N/A";
}
async function calculateItemDropFromList(dropList, itemGuid, options = {}) {
if (!Array.isArray(dropList) || !itemGuid) {
return null;
}
const entry = dropList.find(e => e?.guid === itemGuid);
if (!entry) return null;
const dropChance = Number(entry.dropChance) || 0;
// 🔹 Creep-style quantity (Unity Random.Range)
if (entry.dropQuantity !== undefined) {
const dropQuantity = Number(entry.dropQuantity) || 1;
// Unity Random.Range(1, dropQuantity)
const maxActual = Math.max(1, dropQuantity - 1);
const averageQuantity =
maxActual > 1 ? (1 + maxActual) / 2 : 1;
return {
dropChance,
quantityMin: 1,
quantityMax: maxActual,
averageQuantity,
effectiveDrop: dropChance * averageQuantity
};
}
// 🔹 Loot-table fixed quantity
const quantity = Number(entry.quantity) || 1;
return {
dropChance,
quantityMin: quantity,
quantityMax: quantity,
averageQuantity: quantity,
effectiveDrop: dropChance * quantity
};
}
async function calculateCreepDrops(creep, itemGuid, options = {}) {
if (!creep?.loot?.items) return null;
return calculateItemDropFromList(
creep.loot.items,
itemGuid,
options
);
}
async function calculateLootTableDrops(table, itemGuid, options = {}) {
if (!table?.drops) return null;
return calculateItemDropFromList(
table.drops,
itemGuid,
options
);
}
function dyeToRGB(dye) {
let { _hue, _saturation, _brightness, _contrast } = dye;
// 1. Start with neutral gray (important!)
let r = 128, g = 128, b = 128;
// 2. Convert to HSL
let h = _hue / 360;
let s = Math.max(0, Math.min(1, 0.5 + _saturation));
let l = Math.max(0, Math.min(1, 0.5 + _brightness));
// 3. HSL → RGB
function hslToRgb(h, s, l) {
let r, g, b;
if (s === 0) {
r = g = b = l;
} else {
const hue2rgb = (p, q, t) => {
if (t < 0) t += 1;
if (t > 1) t -= 1;
if (t < 1/6) return p + (q - p) * 6 * t;
if (t < 1/2) return q;
if (t < 2/3) return p + (q - p) * (2/3 - t) * 6;
return p;
};
const q = l < 0.5 ? l * (1 + s) : l + s - l * s;
const p = 2 * l - q;
r = hue2rgb(p, q, h + 1/3);
g = hue2rgb(p, q, h);
b = hue2rgb(p, q, h - 1/3);
}
return [r * 255, g * 255, b * 255];
}
[r, g, b] = hslToRgb(h, s, l);
// 4. Apply contrast
r = ((r - 128) * _contrast) + 128;
g = ((g - 128) * _contrast) + 128;
b = ((b - 128) * _contrast) + 128;
// Clamp
r = Math.max(0, Math.min(255, r));
g = Math.max(0, Math.min(255, g));
b = Math.max(0, Math.min(255, b));
return `rgb(${r|0}, ${g|0}, ${b|0})`;
}
exports = {
getSellPrice,
calculateCreepDrops,
calculateLootTableDrops,
dyeToRGB
}