import * as exp from "constants"; import { QualitySet } from "./BoxSet"; export enum ItemType{ NORMAL=0,//普通 SPECIAL=1,//特殊 可双击打开 EQUIP=2,//装备 } // 掉落物品接口 export interface DropItem { item_uuid: number; // 物品ID probability: number; // 掉落概率 (0-1之间) minCount: number; // 最小掉落数量 maxCount: number; // 最大掉落数量 baseCount: number; // 基础掉落数量 growthRate: number; // 增长参数 } // 怪物掉落配置接口 export interface MonsterDropConfig { monsterId: number; // 怪物ID quality: QualitySet; // 怪物品质 drops: DropItem[]; // 掉落物品列表 } export const Items={ 1001:{uuid: 1001,path: "1001",type:1,quality:QualitySet.GREEN,name: "绿色英雄石",info:"稀有英雄升星必须材料", }, 1002:{uuid: 1002,path: "1002",type:1,quality:QualitySet.BLUE,name: "蓝色英雄石",info:"史诗英雄升星必须材料", }, 1003:{uuid: 1003,path: "1003",type:1,quality:QualitySet.PURPLE,name: "紫色英雄石",info:"传说英雄升星必须材料", }, 1004:{uuid: 1004,path: "1004",type:1,quality:QualitySet.ORANGE,name: "红色英雄石",info:"传说英雄升星必须材料", }, 1005:{uuid: 1005,path: "1005",type:1,quality:QualitySet.ORANGE,name: "招募劵",info:"可以在英雄酒馆招募英雄", }, 1006:{uuid: 1006,path: "1006",type:1,quality:QualitySet.BLUE,name: "铜钥匙",info:"解锁稀有英雄 也可以直接兑换金币", }, 1007:{uuid: 1007,path: "1007",type:1,quality:QualitySet.PURPLE,name: "银钥匙",info:"解锁史诗英雄 也可以直接兑换金币", }, 1008:{uuid: 1008,path: "1008",type:1,quality:QualitySet.ORANGE,name: "金钥匙",info:"解锁传说英雄 也可以直接兑换金币", }, 9001:{uuid: 9001,path: "9001",type:1,quality:QualitySet.GREEN,name: "金币",info:"少许金币", }, 9002:{uuid: 9002,path: "9002",type:1,quality:QualitySet.BLUE,name: "小袋金币",info:"一小袋金币", }, 9003:{uuid: 9003,path: "9003",type:1,quality:QualitySet.PURPLE,name: "大袋金币",info:"一大袋金币", }, 9004:{uuid: 9004,path: "9004",type:1,quality:QualitySet.GREEN,name: "钻石",info:"少许钻石", }, 9005:{uuid: 9005,path: "9005",type:1,quality:QualitySet.GREEN,name: "钻石",info:"少许钻石", }, 9006:{uuid: 9006,path: "9006",type:1,quality:QualitySet.BLUE,name: "小袋钻石",info:"一小袋钻石", }, 9007:{uuid: 9007,path: "9007",type:1,quality:QualitySet.BLUE,name: "大袋钻石",info:"一大袋钻石", }, 9008:{uuid: 9008,path: "9008",type:1,quality:QualitySet.PURPLE,name: "小箱钻石",info:"一小箱钻石", }, 9009:{uuid: 9009,path: "9009",type:1,quality:QualitySet.PURPLE,name: "大箱钻石",info:"一大箱钻石", }, } export enum DropKey{ ItemUUId=0, // 物品ID Pro=1, // 概率 Diff=2, // 上下限差值 Base=3, // 基础数量 GrowthRate=4, // 增长参数 } // 怪物掉落配置表 - 按照DropKey顺序配置 export const MonsterDropTable: { [monsterId: number]: [number, number, number, number, number][] } = { // 普通怪物 - 绿色品质 5201: [ // 兽人战士 [Items[1001].uuid, 1.0, 0, 1, 0.2], // [item_uuid, probability, diff, baseCount, growthRate] - 100%掉落1个绿色英雄石 [Items[1006].uuid, 0.3, 0, 1, 0.1] // [item_uuid, probability, diff, baseCount, growthRate] - 30%概率掉落铜钥匙 ], 5202: [ // 兽人刺客 [Items[1001].uuid, 1.0, 0, 1, 0.2], // [item_uuid, probability, diff, baseCount, growthRate] - 100%掉落1个绿色英雄石 [Items[1006].uuid, 0.4, 0, 1, 0.1] // [item_uuid, probability, diff, baseCount, growthRate] - 40%概率掉落铜钥匙 ], 5203: [ // 兽人护卫 [Items[1001].uuid, 1.0, 0, 1, 0.2], // [item_uuid, probability, diff, baseCount, growthRate] - 100%掉落1个绿色英雄石 [Items[1006].uuid, 0.3, 0, 1, 0.1] // [item_uuid, probability, diff, baseCount, growthRate] - 30%概率掉落铜钥匙 ], 5204: [ // 石卫 [Items[1001].uuid, 1.0, 0, 1, 0.2], // [item_uuid, probability, diff, baseCount, growthRate] - 100%掉落1个绿色英雄石 [Items[1006].uuid, 0.35, 0, 1, 0.1] // [item_uuid, probability, diff, baseCount, growthRate] - 35%概率掉落铜钥匙 ], 5205: [ // 土卫 [Items[1001].uuid, 1.0, 0, 1, 0.2], // [item_uuid, probability, diff, baseCount, growthRate] - 100%掉落1个绿色英雄石 [Items[1006].uuid, 0.35, 0, 1, 0.1] // [item_uuid, probability, diff, baseCount, growthRate] - 35%概率掉落铜钥匙 ], 5206: [ // 树卫 [Items[1001].uuid, 1.0, 0, 1, 0.2], // [item_uuid, probability, diff, baseCount, growthRate] - 100%掉落1个绿色英雄石 [Items[1006].uuid, 0.35, 0, 1, 0.1] // [item_uuid, probability, diff, baseCount, growthRate] - 35%概率掉落铜钥匙 ], 5219: [ // 牛头战士 [Items[1001].uuid, 1.0, 1, 1, 0.25], // [item_uuid, probability, diff, baseCount, growthRate] - 100%掉落1-2个绿色英雄石 [Items[1006].uuid, 0.4, 0, 1, 0.15] // [item_uuid, probability, diff, baseCount, growthRate] - 40%概率掉落铜钥匙 ], 5220: [ // 牛头战士 [Items[1001].uuid, 1.0, 0, 1, 0.2], // [item_uuid, probability, diff, baseCount, growthRate] - 100%掉落1个绿色英雄石 [Items[1006].uuid, 0.3, 0, 1, 0.1] // [item_uuid, probability, diff, baseCount, growthRate] - 30%概率掉落铜钥匙 ], 5221: [ // 牛头战士 [Items[1001].uuid, 1.0, 0, 1, 0.2], // [item_uuid, probability, diff, baseCount, growthRate] - 100%掉落1个绿色英雄石 [Items[1006].uuid, 0.4, 0, 1, 0.1] // [item_uuid, probability, diff, baseCount, growthRate] - 40%概率掉落铜钥匙 ], 5222: [ // 独眼巨人 [Items[1001].uuid, 1.0, 0, 1, 0.2], // [item_uuid, probability, diff, baseCount, growthRate] - 100%掉落1个绿色英雄石 [Items[1006].uuid, 0.3, 0, 1, 0.1] // [item_uuid, probability, diff, baseCount, growthRate] - 30%概率掉落铜钥匙 ], 5223: [ // 独眼巨人 [Items[1001].uuid, 1.0, 0, 1, 0.2], // [item_uuid, probability, diff, baseCount, growthRate] - 100%掉落1个绿色英雄石 [Items[1006].uuid, 0.3, 0, 1, 0.1] // [item_uuid, probability, diff, baseCount, growthRate] - 30%概率掉落铜钥匙 ], 5224: [ // 独眼巨人 [Items[1001].uuid, 1.0, 0, 1, 0.2], // [item_uuid, probability, diff, baseCount, growthRate] - 100%掉落1个绿色英雄石 [Items[1006].uuid, 0.4, 0, 1, 0.1] // [item_uuid, probability, diff, baseCount, growthRate] - 40%概率掉落铜钥匙 ], // 精英怪物 - 蓝色品质 5225: [ // 精英独眼 [Items[1001].uuid, 1.0, 1, 2, 0.3], // [item_uuid, probability, diff, baseCount, growthRate] - 100%掉落2-3个绿色英雄石 [Items[1002].uuid, 1.0, 0, 1, 0.25], // [item_uuid, probability, diff, baseCount, growthRate] - 100%掉落1个蓝色英雄石 [Items[1006].uuid, 0.6, 1, 1, 0.2], // [item_uuid, probability, diff, baseCount, growthRate] - 60%概率掉落铜钥匙 [Items[1007].uuid, 0.2, 0, 1, 0.15] // [item_uuid, probability, diff, baseCount, growthRate] - 20%概率掉落银钥匙 ], 5226: [ // 精英牛头 [Items[1001].uuid, 1.0, 1, 2, 0.3], // [item_uuid, probability, diff, baseCount, growthRate] - 100%掉落2-3个绿色英雄石 [Items[1002].uuid, 1.0, 0, 1, 0.25], // [item_uuid, probability, diff, baseCount, growthRate] - 100%掉落1个蓝色英雄石 [Items[1006].uuid, 0.6, 1, 1, 0.2], // [item_uuid, probability, diff, baseCount, growthRate] - 60%概率掉落铜钥匙 [Items[1007].uuid, 0.2, 0, 1, 0.15] // [item_uuid, probability, diff, baseCount, growthRate] - 20%概率掉落银钥匙 ], 5227: [ // 精英兽人 [Items[1001].uuid, 1.0, 1, 2, 0.3], // [item_uuid, probability, diff, baseCount, growthRate] - 100%掉落2-3个绿色英雄石 [Items[1002].uuid, 1.0, 0, 1, 0.25], // [item_uuid, probability, diff, baseCount, growthRate] - 100%掉落1个蓝色英雄石 [Items[1006].uuid, 0.6, 1, 1, 0.2], // [item_uuid, probability, diff, baseCount, growthRate] - 60%概率掉落铜钥匙 [Items[1007].uuid, 0.2, 0, 1, 0.15] // [item_uuid, probability, diff, baseCount, growthRate] - 20%概率掉落银钥匙 ] }; // 基础资源掉落配置表 - 以普通怪为基础值 export const BaseResourceDropConfig = { // 经验值配置 exp: { baseValue: 100, // 普通怪基础经验值 stageMultiplier: 1.15, // 关卡倍数 (降低增长) randomRange: 0.2, // 随机范围 (±20%) baseProbability: 1.0 // 基础掉落概率 (100%) }, // 金币配置 gold: { baseValue: 50, // 普通怪基础金币值 stageMultiplier: 1.12, // 关卡倍数 (降低增长) randomRange: 0.25, // 随机范围 (±25%) baseProbability: 0.7 // 基础掉落概率 (70%) }, // 钻石配置 diamond: { baseValue: 2, // 基础钻石值 stageMultiplier: 1.05, // 关卡倍数 (大幅降低增长) randomRange: 0.2, // 随机范围 (±20%) baseProbability: 0.0 // 基础掉落概率 (0%,需要品质加成) } }; // 怪物品质加成配置表 - 使用加法权重 export const QualityBonusConfig = { [QualitySet.GREEN]: { // 绿色品质:基础值 + 加成 expBonus: 0, // 经验值加成 goldBonus: 0, // 金币加成 diamondBonus: 0, // 钻石加成 expProbabilityBonus: 0, // 经验掉落概率加成 goldProbabilityBonus: 0, // 金币掉落概率加成 diamondProbabilityBonus: 0 // 钻石掉落概率加成 }, [QualitySet.BLUE]: { // 蓝色品质:基础值 + 加成 expBonus: 50, // 经验值 +50 goldBonus: 25, // 金币 +25 diamondBonus: 0, // 钻石加成 0 expProbabilityBonus: 0, // 经验掉落概率加成 goldProbabilityBonus: 0.1, // 金币掉落概率 +10% diamondProbabilityBonus: 0.2 // 钻石掉落概率 +20% }, [QualitySet.PURPLE]: { // 紫色品质:基础值 + 加成 expBonus: 100, // 经验值 +100 goldBonus: 50, // 金币 +50 diamondBonus: 1, // 钻石 +1 expProbabilityBonus: 0, // 经验掉落概率加成 goldProbabilityBonus: 0.2, // 金币掉落概率 +20% diamondProbabilityBonus: 0.1 // 钻石掉落概率 +10%(精英10%) }, [QualitySet.ORANGE]: { // 橙色品质:基础值 + 加成 expBonus: 200, // 经验值 +200 goldBonus: 100, // 金币 +100 diamondBonus: 3, // 钻石 +3 expProbabilityBonus: 0, // 经验掉落概率加成 goldProbabilityBonus: 0.3, // 金币掉落概率 +30% diamondProbabilityBonus: 1.0 // 钻石掉落概率 +100%(BOSS必掉) } }; // 关卡和buff加成配置表 - 使用加法权重 export const StageBuffBonusConfig = { // 关卡加成配置 stage: { expBonusPerStage: 5, // 每关经验值加成 goldBonusPerStage: 2, // 每关金币加成 diamondBonusPerStage: 0.1, // 每关钻石加成 expProbabilityBonusPerStage: 0, // 每关经验掉落概率加成 goldProbabilityBonusPerStage: 0, // 每关金币掉落概率加成 diamondProbabilityBonusPerStage: 0 // 每关钻石掉落概率加成 }, // buff数量加成配置 buff: { expBonusPerBuff: 10, // 每个buff经验值加成 goldBonusPerBuff: 5, // 每个buff金币加成 diamondBonusPerBuff: 0.5, // 每个buff钻石加成 expProbabilityBonusPerBuff: 0, // 每个buff经验掉落概率加成 goldProbabilityBonusPerBuff: 0.01, // 每个buff金币掉落概率加成 diamondProbabilityBonusPerBuff: 0.005 // 每个buff钻石掉落概率加成 } }; // 怪物掉落管理器 export class MonsterDropManager { /** * 根据怪物ID获取掉落配置 * @param monsterId 怪物ID * @returns 掉落配置 */ static getDropConfig(monsterId: number): [number, number, number, number, number][] | null { return MonsterDropTable[monsterId] || null; } /** * 计算指定关卡数的掉落数量 * @param baseCount 基础数量 * @param growthRate 增长参数 * @param stageNumber 关卡数 * @param diff 上下限差值 * @returns 计算后的掉落数量 */ static calculateDropCount(baseCount: number, growthRate: number, stageNumber: number, diff: number): number { // 公式:基础数量 * 增长参数 * 关卡数 + (0-差值的随机数) const calculatedCount = baseCount * growthRate * stageNumber; const randomBonus = Math.floor(Math.random() * (diff + 1)); // 0到diff的随机数 const finalCount = calculatedCount + randomBonus; // 允许掉落数量为0 return Math.max(0, Math.floor(finalCount)); } /** * 计算怪物掉落物品 * @param monsterId 怪物ID * @param stageNumber 关卡数 * @param playerLuck 玩家幸运值加成 * @returns 掉落物品数组 */ static calculateMonsterDrops(monsterId: number, stageNumber: number, playerLuck: number = 0): Array<{item_uuid: number, count: number}> { const dropArray = this.getDropConfig(monsterId); if (!dropArray) { console.warn(`[MonsterDropManager]: No drop config found for monster ${monsterId}`); return []; } const result: Array<{item_uuid: number, count: number}> = []; const luckBonus = 1 + (playerLuck * 0.01); // 幸运值加成 // 处理所有掉落物品(统一按概率处理) dropArray.forEach(dropData => { const [item_uuid, probability, diff, baseCount, growthRate] = dropData; if (Math.random() < probability) { // 使用新的计算公式:基础值*关卡数*增长参数+(0-差值的随机数) const finalCount = this.calculateDropCount(baseCount, growthRate, stageNumber, diff); const countWithLuck = Math.floor(finalCount * luckBonus); result.push({ item_uuid: item_uuid, count: Math.max(1, countWithLuck) // 确保至少掉落1个 }); } }); return result; } /** * 预览指定关卡数的掉落数量(不包含随机因素) * @param monsterId 怪物ID * @param stageNumber 关卡数 * @returns 掉落物品预览数组 */ static previewMonsterDrops(monsterId: number, stageNumber: number): Array<{item_uuid: number, baseCount: number, calculatedCount: number, maxCount: number}> { const dropArray = this.getDropConfig(monsterId); if (!dropArray) { console.warn(`[MonsterDropManager]: No drop config found for monster ${monsterId}`); return []; } const result: Array<{item_uuid: number, baseCount: number, calculatedCount: number, maxCount: number}> = []; // 处理所有掉落物品 dropArray.forEach(dropData => { const [item_uuid, probability, diff, baseCount, growthRate] = dropData; const calculatedCount = baseCount * growthRate * stageNumber; const maxCount = calculatedCount + diff; result.push({ item_uuid: item_uuid, baseCount: baseCount, calculatedCount: Math.floor(calculatedCount), maxCount: Math.floor(maxCount) }); }); return result; } /** * 计算怪物基础资源掉落(经验、金币、钻石) * @param monsterQuality 怪物品质 * @param stageNumber 关卡数 * @param buffCount buff数量 * @returns 基础资源掉落结果 */ static calculateBaseResourceDrops(monsterQuality: QualitySet, stageNumber: number, buffCount: number = 0): {exp: number, gold: number, diamond: number} { // 初始化结果对象,确保所有字段都存在 const result: {exp: number, gold: number, diamond: number} = { exp: 0, gold: 0, diamond: 0 }; // 获取品质加成 const qualityBonus = QualityBonusConfig[monsterQuality]; // 计算经验值(必出) const expConfig = BaseResourceDropConfig.exp; const expValue = (expConfig.baseValue + qualityBonus.expBonus + StageBuffBonusConfig.stage.expBonusPerStage * stageNumber + StageBuffBonusConfig.buff.expBonusPerBuff * buffCount) * Math.pow(expConfig.stageMultiplier, stageNumber - 1); // 添加随机范围 const expRandomFactor = 1 + (Math.random() - 0.5) * 2 * expConfig.randomRange; result.exp = Math.floor(expValue * expRandomFactor); // 金币与钻石独立判定,可同时掉落: // 使用加法权重系统:基础值 + 品质加成 + 关卡加成 + buff加成 + 关卡增长 // 金币判定 const goldProbability = BaseResourceDropConfig.gold.baseProbability + qualityBonus.goldProbabilityBonus + StageBuffBonusConfig.stage.goldProbabilityBonusPerStage * stageNumber + StageBuffBonusConfig.buff.goldProbabilityBonusPerBuff * buffCount; if (Math.random() < goldProbability) { const goldConfig = BaseResourceDropConfig.gold; const goldValue = (goldConfig.baseValue + qualityBonus.goldBonus + StageBuffBonusConfig.stage.goldBonusPerStage * stageNumber + StageBuffBonusConfig.buff.goldBonusPerBuff * buffCount) * Math.pow(goldConfig.stageMultiplier, stageNumber - 1); const goldRandomFactor = 1 + (Math.random() - 0.5) * 2 * goldConfig.randomRange; result.gold = Math.floor(goldValue * goldRandomFactor); } // 钻石判定 const diamondProbability = BaseResourceDropConfig.diamond.baseProbability + qualityBonus.diamondProbabilityBonus + StageBuffBonusConfig.stage.diamondProbabilityBonusPerStage * stageNumber + StageBuffBonusConfig.buff.diamondProbabilityBonusPerBuff * buffCount; if (Math.random() < diamondProbability) { const diamondConfig = BaseResourceDropConfig.diamond; const diamondValue = (diamondConfig.baseValue + qualityBonus.diamondBonus + StageBuffBonusConfig.stage.diamondBonusPerStage * stageNumber + StageBuffBonusConfig.buff.diamondBonusPerBuff * buffCount) * Math.pow(diamondConfig.stageMultiplier, stageNumber - 1); const diamondRandomFactor = 1 + (Math.random() - 0.5) * 2 * diamondConfig.randomRange; result.diamond = Math.floor(diamondValue * diamondRandomFactor); } return result; } }