import { TableNames } from '../../../game/ConfigTableData'; import { aiLog } from '../runtime/AiLog'; import { BattleBuffSlotType } from '../../../manager/battleBuff/BattleBuffTypes'; /** 局内 AI 可抽 functiontype 下限(新表 1~16;排除 type=3 局外即时) */ const AI_BUFF_FT_MIN = 1; /** 局内 AI 可抽 functiontype 上限 */ const AI_BUFF_FT_MAX = 16; /** Battlebuff 加权不重复抽取 */ export class AiBattlebuffPicker { /** * 按 type 与 weight 加权抽取不重复 buff id。 * 仅 `type=1|2` 且 `functiontype∈[1,16]`;**排除 type=3**。 * 新表无主动行时 `buffType=1` 返回 []。 * @param buffType 1=主动,2=被动 * @param count 目标个数 * @param seed 随机种子 */ pick(buffType: 1 | 2, count: number, seed: number): number[] { const need = Math.max(0, Math.floor(Number(count) || 0)); if (need <= 0) return []; const list = gg.data.table.getTableList(TableNames.Battlebuff) ?? []; const ids: number[] = []; const weights: number[] = []; for (let i = 0; i < list.length; i++) { const row = list[i]; const slotType = Math.floor(Number(row.type) || 0); if (slotType === BattleBuffSlotType.Auto) continue; if (slotType !== buffType) continue; const ft = Math.floor(Number(row.functiontype) || 0); if (ft < AI_BUFF_FT_MIN || ft > AI_BUFF_FT_MAX) continue; const w = Math.max(0, Math.floor(Number(row.weight) || 0)); if (w <= 0) continue; const id = Math.floor(Number(row.id) || 0); if (id <= 0) continue; ids.push(id); weights.push(w); } if (ids.length < need) { aiLog(`[AiBattlebuffPicker] candidate shortage buffType=${buffType} need=${need} have=${ids.length}`); return []; } const picked: number[] = []; let rng = (Math.floor(Number(seed) || 0) >>> 0) || 1; for (let n = 0; n < need; n++) { let total = 0; for (let i = 0; i < weights.length; i++) total += weights[i]; if (total <= 0) { aiLog(`[AiBattlebuffPicker] remaining weight 0 buffType=${buffType} picked=${picked.join(',')}`); return []; } rng = (rng * 1664525 + 1013904223) >>> 0; let roll = (rng / 4294967296) * total; let choose = -1; for (let i = 0; i < weights.length; i++) { roll -= weights[i]; if (roll < 0) { choose = i; break; } } if (choose < 0) choose = weights.length - 1; picked.push(ids[choose]); ids.splice(choose, 1); weights.splice(choose, 1); } return picked; } }