Files
heros/assets/script/game/common/config/RewardSet.ts

305 lines
9.8 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// 掉落物品接口
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<string, DropItem>();
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<T>(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]
//根据HeroChipListItemsList设置掉落概率
//参考 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}`);
}
});
*/