function randomInt(min: number, max: number) { return Math.floor(Math.random() * (max - min + 1)) + min; } function shuffle(items: T[]) { const result = [...items]; for (let i = result.length - 1; i > 0; i--) { const j = Math.floor(Math.random() * (i + 1)); [result[i], result[j]] = [result[j], result[i]]; } return result; } function splitRandom(total: number, parts: number) { if (parts <= 0) return []; if (parts === 1) return [total]; const result = new Array(parts).fill(1); let remaining = total - parts; while (remaining > 0) { result[Math.floor(Math.random() * parts)]++; remaining--; } return result; } import { ResourceType } from "./ResourceType"; export type PropDropPlan = { resource: ResourceType; totalDrop: number; spawnedDrop: number; hitAmounts: number[]; }; export function createDropPlan( maxHealth: number, rule: { resource: ResourceType; minTotal: number; maxTotal: number; minSpawnHits: number; maxSpawnHits: number; }, ): PropDropPlan { const totalDrop = randomInt(rule.minTotal, rule.maxTotal); const spawnEvents = randomInt(rule.minSpawnHits, rule.maxSpawnHits); const hitAmounts = new Array(maxHealth).fill(0); const hitIndexes = shuffle([...Array(maxHealth).keys()]).slice(0, spawnEvents); const amounts = splitRandom(totalDrop, spawnEvents); hitIndexes.forEach((hitIndex, index) => { hitAmounts[hitIndex] = amounts[index]; }); return { resource: rule.resource, totalDrop, spawnedDrop: 0, hitAmounts, }; }