// 掉落物品接口 export interface DropItem { uuid: number; // 物品ID num: number; // 数量 type: number; // 类型 quality?: number; // 品质 } // 怪物类型 export enum MonsterType { Normal = 1, // 普通怪 Elite = 2, // 精英怪 Boss = 3, // Boss怪 } // 掉落倍率配置 export const DropRateConfig = { [MonsterType.Normal]: 1, [MonsterType.Elite]: 2, [MonsterType.Boss]: 10, } // Boss掉落示例(最多5个不同英雄的碎片) // const bossDrops = getMonsterDrops(50, MonsterType.Boss, 1.2); // 精英怪掉落示例(最多2个不同英雄的碎片) // const eliteDrops = getMonsterDrops(50, MonsterType.Elite, 1.2); // 普通怪掉落示例(最多1个英雄的碎片) // const normalDrops = getMonsterDrops(50, MonsterType.Normal, 1.2); /** * 获取怪物掉落 * @param monsterLevel 怪物等级 * @param monsterType 怪物类型 * @param extraRate 额外倍率(比如玩家的幸运值加成) * @returns 掉落物品数组 */ export function getMonsterDrops( monsterLevel: number, monsterType: MonsterType = MonsterType.Normal, extraRate: number = 1 ): DropItem[] { const drops: DropItem[] = []; const baseMultiplier = getDropMultiplier(monsterLevel); const monsterMultiplier = DropRateConfig[monsterType]; const totalMultiplier = baseMultiplier * monsterMultiplier * extraRate; // 分离英雄碎片和道具配置 const heroChipConfigs = DropConfigList.filter(config => config.type === dorptype.hero_chip); const itemConfigs = DropConfigList.filter(config => config.type === dorptype.items); // 获取当前怪物类型可以掉落的英雄碎片数量 const maxHeroChips = HeroChipDropCount[monsterType]; // 随机选择指定数量的英雄碎片 const selectedHeroChips = shuffleArray(heroChipConfigs).slice(0, maxHeroChips); // 处理英雄碎片掉落 for (const config of selectedHeroChips) { if (monsterType === MonsterType.Normal) { // 普通怪按概率掉落 if (shouldDrop(config.dropRate * totalMultiplier)) { const dropItem = calculateDrop(config, monsterLevel, monsterType); if (dropItem) { drops.push(dropItem); } } } else { // 精英怪和Boss必定掉落 const dropItem = calculateDrop(config, monsterLevel, monsterType); if (dropItem) { drops.push(dropItem); } } } // 处理道具掉落 for (const config of itemConfigs) { if (config.uuid === 9001) { // 金币必定掉落 const dropItem = calculateDrop(config, monsterLevel, monsterType); if (dropItem) { drops.push(dropItem); } } else { // 其他道具按概率掉落 if (shouldDrop(config.dropRate * totalMultiplier)) { const dropItem = calculateDrop(config, monsterLevel, monsterType); if (dropItem) { drops.push(dropItem); } } } } return drops; } /** * 计算是否掉落 * @param rate 掉落概率 */ function shouldDrop(rate: number): boolean { return Math.random() * 100 <= Math.min(rate, 100); } /** * 计算单个物品掉落 */ function calculateDrop( config: typeof DropConfigList[0], monsterLevel: number, monsterType: MonsterType ): DropItem | null { // 计算掉落数量 let num = Math.floor(Math.random() * config.num_max) + 1; // Boss额外保底 if (monsterType === MonsterType.Boss && num < config.num_max * 0.3) { num = Math.floor(config.num_max * 0.3); } // 根据类型应用不同规则 if (config.type === dorptype.hero_chip) { // 英雄碎片特殊处理 return { uuid: config.uuid, num: Math.min(num, 10), // 英雄碎片单次最多10个 type: config.type, quality: getHeroQuality(config.uuid) }; } else if (config.type === dorptype.items) { // 普通道具处理 return { uuid: config.uuid, num: num, type: config.type }; } return null; } /** * 获取英雄品质(需要和heroSet配置关联) */ function getHeroQuality(heroId: number): number { // 这里可以从heroSet中获取英雄品质 return 1; // 默认品质 } /** * 获取掉落倍率 * @param monsterLevel 怪物等级 */ export function getDropMultiplier(monsterLevel: number): number { // 基础倍率 let multiplier = Math.max(1, Math.floor(monsterLevel / 10)); // 等级档位加成 if (monsterLevel >= 50) multiplier *= 1.5; if (monsterLevel >= 100) multiplier *= 2; return multiplier; } /** * 批量生成掉落 * @param times 掉落次数 * @param params 掉落参数 */ export function batchGenerateDrops( times: number, monsterLevel: number, monsterType: MonsterType = MonsterType.Normal, extraRate: number = 1 ): DropItem[] { const allDrops: DropItem[] = []; for (let i = 0; i < times; i++) { const drops = getMonsterDrops(monsterLevel, monsterType, extraRate); allDrops.push(...drops); } // 合并相同物品 return mergeDrops(allDrops); } /** * 合并相同物品的掉落 */ function mergeDrops(drops: DropItem[]): DropItem[] { const mergedMap = new Map(); drops.forEach(drop => { const key = `${drop.uuid}-${drop.type}`; if (mergedMap.has(key)) { const existing = mergedMap.get(key)!; existing.num += drop.num; } else { mergedMap.set(key, {...drop}); } }); return Array.from(mergedMap.values()); } /** * 随机打乱数组 */ function shuffleArray(array: T[]): T[] { const newArray = [...array]; for (let i = newArray.length - 1; i > 0; i--) { const j = Math.floor(Math.random() * (i + 1)); [newArray[i], newArray[j]] = [newArray[j], newArray[i]]; } return newArray; } export const BoxDrop={ 1:[ {uuid: 9001,dropRate: 10,num_max: 500000,type:0}, {uuid: 9003,dropRate: 10,num_max: 500,type:0}, ], 2:[ {uuid: 5001,dropRate: 5,num_max: 5,type:1}, // 圣盾战 quality 3 {uuid: 5002,dropRate: 30,num_max: 5,type:1}, // 火女 quality 1 {uuid: 5003,dropRate: 30,num_max: 5,type:1}, // 牧师 quality 1 {uuid: 5004,dropRate: 15,num_max: 5,type:1}, // 自愈骑 quality 2 {uuid: 5005,dropRate: 30,num_max: 5,type:1}, // quality 1 {uuid: 5006,dropRate: 15,num_max: 5,type:1}, // quality 2 {uuid: 5007,dropRate: 5,num_max: 5,type:1}, // 召唤师 quality 3 {uuid: 5008,dropRate: 30,num_max: 5,type:1}, // quality 1 {uuid: 5009,dropRate: 15,num_max: 5,type:1}, // quality 2 {uuid: 5010,dropRate: 5,num_max: 5,type:1}, // quality 3 {uuid: 5011,dropRate: 30,num_max: 5,type:1}, // quality 1 ], 3:[ {uuid: 5001,dropRate: 5,num_max: 5,type:1}, // 圣盾战 quality 3 {uuid: 5002,dropRate: 30,num_max: 5,type:1}, // 火女 quality 1 {uuid: 5003,dropRate: 30,num_max: 5,type:1}, // 牧师 quality 1 {uuid: 5004,dropRate: 15,num_max: 5,type:1}, // 自愈骑 quality 2 {uuid: 5005,dropRate: 30,num_max: 5,type:1}, // quality 1 {uuid: 5006,dropRate: 15,num_max: 5,type:1}, // quality 2 {uuid: 5007,dropRate: 5,num_max: 5,type:1}, // 召唤师 quality 3 {uuid: 5008,dropRate: 30,num_max: 5,type:1}, // quality 1 {uuid: 5009,dropRate: 15,num_max: 5,type:1}, // quality 2 {uuid: 5010,dropRate: 5,num_max: 5,type:1}, // quality 3 {uuid: 5011,dropRate: 30,num_max: 5,type:1}, // quality 1 ], } export const BoxDropCount={ 1:3, 2:3, 3:3, } export const dorptype={ hero_chip:1, items:2, } export const HeroChipDropCount={ 1:1, 2:2, 3:5, } //HeroChipList = [5001,5002,5003,5004,5005,5006,5007,5008,5009,5010,5011,5012,5013,5014,5015,5016,5017,5018,5019,5020,5021,5022,5023,5024,5025,5026,5027] //ItemsList=[9001,1003] //根据HeroChipList,ItemsList设置掉落概率 //参考 heroSet.ts 中 HeroInfo对象数据的quality值来修改,DropConfigList中的dropRaten和um_max值,quality值越大,掉落概率越小,数量越少 export const DropConfigList=[ {uuid: 5001,dropRate: 5,num_max: 5,type:1}, // 圣盾战 quality 3 {uuid: 5002,dropRate: 30,num_max: 5,type:1}, // 火女 quality 1 {uuid: 5003,dropRate: 30,num_max: 5,type:1}, // 牧师 quality 1 {uuid: 5004,dropRate: 15,num_max: 5,type:1}, // 自愈骑 quality 2 {uuid: 5005,dropRate: 30,num_max: 5,type:1}, // quality 1 {uuid: 5006,dropRate: 15,num_max: 5,type:1}, // quality 2 {uuid: 5007,dropRate: 5,num_max: 5,type:1}, // 召唤师 quality 3 {uuid: 5008,dropRate: 30,num_max: 5,type:1}, // quality 1 {uuid: 5009,dropRate: 15,num_max: 5,type:1}, // quality 2 {uuid: 5010,dropRate: 5,num_max: 5,type:1}, // quality 3 {uuid: 5011,dropRate: 30,num_max: 5,type:1}, // quality 1 {uuid: 9001,dropRate: 100,num_max: 5000,type:2}, {uuid: 1003,dropRate: 20,num_max: 5,type:2}, ] // 使用示例: /* // 单次掉落 const drops = getMonsterDrops(50, MonsterType.Boss, 1.2); // 批量掉落(比如连续击杀多个怪物) const batchDrops = batchGenerateDrops(5, 50, MonsterType.Elite, 1.2); // 处理掉落物品 drops.forEach(item => { if (item.type === dorptype.hero_chip) { // 处理英雄碎片 console.log(`获得英雄碎片: ${item.uuid} x${item.num}`); } else if (item.type === dorptype.items) { // 处理道具 console.log(`获得道具: ${item.uuid} x${item.num}`); } }); */