From 5dd354a86b5e42454dd605b6438300304886c9df Mon Sep 17 00:00:00 2001 From: panfudan Date: Tue, 12 Aug 2025 15:54:56 +0800 Subject: [PATCH] =?UTF-8?q?=E5=88=B7=E6=80=AA=E5=AE=8C=E6=88=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- assets/script/game/common/config/Mission.ts | 18 +- assets/script/game/common/config/heroSet.ts | 262 +----- assets/script/game/hero/Hero.ts | 1 - assets/script/game/hero/HeroViewComp.ts | 5 +- assets/script/game/hero/Mon.ts | 54 +- assets/script/game/map/MissionMonComp.ts | 171 ++-- assets/script/game/map/RogueConfig.ts | 958 +++++++------------- 7 files changed, 465 insertions(+), 1004 deletions(-) diff --git a/assets/script/game/common/config/Mission.ts b/assets/script/game/common/config/Mission.ts index a70303eb..de6138fe 100644 --- a/assets/script/game/common/config/Mission.ts +++ b/assets/script/game/common/config/Mission.ts @@ -90,27 +90,11 @@ export enum FightSet { export const MissionData = { gold:1000,//金币 score:0,//分数 - refrsh_time:5, //刷新时间 - refresh_gold:1,//刷新金币 - call_gold:0,//召唤金币 - add_gold:1,//金币增加 - lucky_gold:1,//幸运金币 - change_gold:0,//金币变化 - back_gold:1,//返还金币 - buff_back_gold:0,//额外返还金币 - buff_add_gold:0,//额外增加金币 - buff_refrsh_time:0,//额外刷新时间 - buff_refresh_gold:0,//额外发现所需的金币 - current_wave:0, + current_wave:1, mon_num:0,//怪物数量 wave_time_num:0,//波次时间 in_fight:false, fight_time:0,//战斗时间 - equip_stone:0,//装备石 - equip_stone_max:10,//装备石最大数量 - skill_stone:0,//技能石 - skill_stone_max:10,//技能石最大数量 - refresh_count:5,//刷新次 } export const HeroUI = { uuid:0, diff --git a/assets/script/game/common/config/heroSet.ts b/assets/script/game/common/config/heroSet.ts index 7a789259..c4aead28 100644 --- a/assets/script/game/common/config/heroSet.ts +++ b/assets/script/game/common/config/heroSet.ts @@ -1,4 +1,5 @@ import { v3 } from "cc" +import { FacSet } from "./BoxSet" /** * kind :1:烈焰 2:寒冰 3:自然 4:暗影 5:神圣 @@ -27,32 +28,23 @@ export enum HType { remote = 1, mage = 2, } - -export const getHeroList = ()=>{ - return Masters - +//fac:FacSet.HERO +export const getHeroList = (quality:number)=>{ + return Object.values(HeroInfo).filter(item=>{ + const facMatch = item.fac === FacSet.HERO; + const qualityMatch = quality === 0 || item.quality === quality; + return facMatch && qualityMatch; + }).map(item=>item.uuid) +} +//fac:FacSet.MON +export const getMonList = (quality:number)=>{ + return Object.values(HeroInfo).filter(item=>{ + const facMatch = item.fac === FacSet.MON; + const qualityMatch = quality === 0 || item.quality === quality; + return facMatch && qualityMatch; + }).map(item=>item.uuid) } -export const getHeroListByCalled = (count:number,called:any[])=>{ - let list=Masters - if(called.length==3){ - list=called.map((item:any)=>item.uuid) - } - // 确保请求数量不超过可用卡牌数量 - count = Math.min(count, list.length); - - // 打乱数组顺序 - const shuffled = [...list].sort(() => Math.random() - 0.5); - - // 返回指定数量的卡牌 - return shuffled.slice(0, count).map(uuid => ({ - uuid - })); -} - -export const HeroList = [5021,5022,5023,5024,5025,5026,5027,5028] -export const MonList = [5201,5202,5203,5204,5205,5206,5219,5220,5221,5222,5223,5224,5225,5226,5227] -export const Masters = [5001,5002,5005,5008,5009,5010,5011] export const HeroPos={ 0:{pos:v3(-290,0,0)}, @@ -73,193 +65,17 @@ export const MonSet = { 3:{pos:v3(340,0,0)}, 4:{pos:v3(400,0,0)}, 5:{pos:v3(460,0,0)}, - 6:{pos:v3(520,0,0)}, - 7:{pos:v3(440,0,0)}, - 8:{pos:v3(480,0,0)}, - 9:{pos:v3(520,0,0)}, - 10:{pos:v3(560,0,0)}, - 11:{pos:v3(830,0,0)}, - 12:{pos:v3(870,0,0)}, - 13:{pos:v3(910,0,0)}, - 14:{pos:v3(950,0,0)}, - 15:{pos:v3(990,0,0)}, - 16:{pos:v3(1030,0,0)}, - 17:{pos:v3(1070,0,0)}, - 18:{pos:v3(1110,0,0)}, - 19:{pos:v3(1150,0,0)}, - 20:{pos:v3(1190,0,0)}, - 21:{pos:v3(1230,0,0)}, - 22:{pos:v3(1270,0,0)}, - 23:{pos:v3(1310,0,0)}, - 24:{pos:v3(1350,0,0)}, - 25:{pos:v3(1390,0,0)}, - 26:{pos:v3(1430,0,0)}, - 27:{pos:v3(1470,0,0)}, - 28:{pos:v3(1510,0,0)}, - 29:{pos:v3(1550,0,0)}, - 30:{pos:v3(1590,0,0)}, - 31:{pos:v3(1630,0,0)}, } -// 经验值计算函数 - 复杂递增规律 -// 基础经验值:100 -// 递增值:每级递增10,且递增值本身也会递增 -// 公式:基础经验值 + 递增值累加 -// 递增值规律:第1级递增值=10,第2级递增值=20,第3级递增值=30... -export const getUpExp = (currentLevel: number): number => { - const baseExp = 100; // 基础经验值 - let totalIncrement = 0; - - // 计算从1级到当前等级的递增值累加 - for (let level = 1; level < currentLevel; level++) { - totalIncrement += level * 10; // 每级的递增值 = 等级 * 10 - } - - return baseExp + totalIncrement; -}; -// 获取从当前等级升级到目标等级所需的总经验值 -export const getTotalUpExp = (currentLevel: number, targetLevel: number): number => { - let totalExp = 0; - for (let level = currentLevel; level < targetLevel; level++) { - totalExp += getUpExp(level); - } - return totalExp; -}; - -// 简化的升级属性增长计算 -// 基于 HType 的攻击力增长配置 -export const ApGrowthByType = { - [HType.warrior]: (baseAp: number) => Math.floor(baseAp * 0.05) + 3, // 战士:+5% + 3 - [HType.remote]: (baseAp: number) => Math.floor(baseAp * 0.10) + 2, // 远程:+10% + 2 - [HType.mage]: (baseAp: number) => Math.floor(baseAp * 0.15) + 1, // 法师:+15% + 1 -}; - -// 基于 HType 的HP增长配置 -export const HpGrowthByType = { - [HType.warrior]: (baseHp: number) => Math.floor(baseHp * 0.08) + 10, // 战士:+8% + 10 - [HType.remote]: (baseHp: number) => Math.floor(baseHp * 0.05) + 5, // 远程:+5% + 5 - [HType.mage]: (baseHp: number) => Math.floor(baseHp * 0.03) + 3, // 法师:+3% + 3 -}; - -// 获取从1级升级到2级增加的攻击力 -export const getUpAp = (heroId: number): number => { - const heroInfo = HeroInfo[heroId]; - if (!heroInfo) { - console.warn(`[getUpAp] 英雄 ${heroId} 不存在`); - return 0; - } - - const baseAp = heroInfo.ap; - const heroType = heroInfo.type; - const growthFunction = ApGrowthByType[heroType] || ApGrowthByType[HType.warrior]; - return growthFunction(baseAp); -}; - -// 获取从1级升级到2级增加的HP -export const getUpHp = (heroId: number): number => { - const heroInfo = HeroInfo[heroId]; - if (!heroInfo) { - console.warn(`[getUpHp] 英雄 ${heroId} 不存在`); - return 0; - } - - const baseHp = heroInfo.hp; - const heroType = heroInfo.type; - const growthFunction = HpGrowthByType[heroType] || HpGrowthByType[HType.warrior]; - return growthFunction(baseHp); -}; - -// 获取英雄在指定等级的总攻击力 -export const getHeroTotalAp = (heroId: number, level: number): number => { - const heroInfo = HeroInfo[heroId]; - if (!heroInfo) { - console.warn(`[getHeroTotalAp] 英雄 ${heroId} 不存在`); - return 0; - } - - const baseAp = heroInfo.ap; - const heroType = heroInfo.type; - const growthFunction = ApGrowthByType[heroType] || ApGrowthByType[HType.warrior]; - const levelUpAp = growthFunction(baseAp); - return baseAp + levelUpAp; -}; - -// 获取英雄在指定等级的总HP -export const getHeroTotalHp = (heroId: number, level: number): number => { - const heroInfo = HeroInfo[heroId]; - if (!heroInfo) { - console.warn(`[getHeroTotalHp] 英雄 ${heroId} 不存在`); - return 0; - } - - const baseHp = heroInfo.hp; - const heroType = heroInfo.type; - const growthFunction = HpGrowthByType[heroType] || HpGrowthByType[HType.warrior]; - const levelUpHp = growthFunction(baseHp); - return baseHp + levelUpHp; -}; - -// 获取从当前等级升级到目标等级增加的攻击力 -export const getApIncrease = (heroId: number, currentLevel: number, targetLevel: number): number => { - const heroInfo = HeroInfo[heroId]; - if (!heroInfo) { - console.warn(`[getApIncrease] 英雄 ${heroId} 不存在`); - return 0; - } - - const baseAp = heroInfo.ap; - const heroType = heroInfo.type; - const growthFunction = ApGrowthByType[heroType] || ApGrowthByType[HType.warrior]; - return growthFunction(baseAp); -}; - -// 获取从当前等级升级到目标等级增加的HP -export const getHpIncrease = (heroId: number, currentLevel: number, targetLevel: number): number => { - const heroInfo = HeroInfo[heroId]; - if (!heroInfo) { - console.warn(`[getHpIncrease] 英雄 ${heroId} 不存在`); - return 0; - } - - const baseHp = heroInfo.hp; - const heroType = heroInfo.type; - const growthFunction = HpGrowthByType[heroType] || HpGrowthByType[HType.warrior]; - return growthFunction(baseHp); -}; - -// 获取升级后的完整属性信息 -export const getLevelUpStats = (heroId: number, currentLevel: number, targetLevel: number) => { - return { - apIncrease: getApIncrease(heroId, currentLevel, targetLevel), - hpIncrease: getHpIncrease(heroId, currentLevel, targetLevel), - newTotalAp: getHeroTotalAp(heroId, targetLevel), - newTotalHp: getHeroTotalHp(heroId, targetLevel) - }; -}; - -// 根据英雄类型获取增长模式描述 -export const getGrowthModeDescription = (heroType: HType): string => { - switch (heroType) { - case HType.warrior: - return "战士型:AP固定增长为主(每级+3,+5%),HP高增长(每级+10,+8%)"; - case HType.remote: - return "远程型:AP平衡增长(每级+2,+10%),HP中等增长(每级+5,+5%)"; - case HType.mage: - return "法师型:AP百分比增长为主(每级+1,+15%),HP低增长(每级+3,+3%)"; - default: - return "未知类型"; - } -}; export const HeroInfo = { - //主将 - 5001:{uuid:5001,name:"火焰骑士",path:"hk1", quality:HQuality.BLUE,lv:1,kind:1, + 5001:{uuid:5001,name:"火焰骑士",path:"hk1", fac:FacSet.HERO, quality:HQuality.BLUE,lv:1,kind:1, type:HType.warrior,hp:100,ap:15,dis:100,cd:1,speed:150,skills:[6011,6020], buff:[],info:"剑类专精,穿刺伤害额外+10%"}, - 5002:{uuid:5002,name:"hk1",path:"hk1", quality:HQuality.BLUE,lv:1,kind:1, + 5002:{uuid:5002,name:"hk1",path:"hk1", fac:FacSet.HERO, quality:HQuality.BLUE,lv:1,kind:1, type:HType.warrior,hp:100,ap:15,dis:100,cd:1,speed:150,skills:[6011,6004], buff:[],info:"斧类专精,风怒概率增加10%"}, @@ -271,93 +87,93 @@ export const HeroInfo = { // type:HType.warrior,hp:100,ap:15,dis:400,cd:1,speed:100,skills:[6010,6021,6001], // buff:[],info:"刀类专精,易伤效果额外持续1次"}, - 5005:{uuid:5005,name:"ha1",path:"ha1", quality:HQuality.BLUE,lv:1,kind:2, + 5005:{uuid:5005,name:"ha1",path:"ha1", fac:FacSet.HERO, quality:HQuality.BLUE,lv:1,kind:2, type:HType.remote,hp:100,ap:15,dis:400,cd:1,speed:100,skills:[6025,6031], buff:[],info:"说明"}, - 5007:{uuid:5007,name:"mh1",path:"hmh1", quality:HQuality.BLUE,lv:1,kind:2, + 5007:{uuid:5007,name:"mh1",path:"hmh1", fac:FacSet.HERO, quality:HQuality.BLUE,lv:1,kind:2, type:HType.mage,hp:100,ap:15,dis:400,cd:1,speed:100,skills:[6002,6002], buff:[],info:"说明"}, - 5008:{uuid:5008,name:"mf1",path:"hmf1", quality:HQuality.BLUE,lv:1,kind:2, + 5008:{uuid:5008,name:"mf1",path:"hmf1", fac:FacSet.HERO, quality:HQuality.BLUE,lv:1,kind:2, type:HType.mage,hp:100,ap:15,dis:400,cd:1.5,speed:100,skills:[6022,6029], buff:[],info:"说明"}, - 5009:{uuid:5009,name:"风暴精灵",path:"hk1", quality:HQuality.BLUE,lv:1,kind:2, + 5009:{uuid:5009,name:"风暴精灵",path:"hk1", fac:FacSet.HERO, quality:HQuality.BLUE,lv:1,kind:2, type:HType.mage,hp:100,ap:15,dis:400,cd:1.5,speed:100,skills:[6002,6002], buff:[],info:"说明"}, - 5010:{uuid:5010,name:"战争祭祀",path:"hk1", quality:HQuality.BLUE,lv:1,kind:2, + 5010:{uuid:5010,name:"战争祭祀",path:"hk1", fac:FacSet.HERO, quality:HQuality.BLUE,lv:1,kind:2, type:HType.mage,hp:100,ap:15,dis:400,cd:1.5,speed:100,skills:[6024,6002], buff:[],info:"说明"}, - 5011:{uuid:5011,name:"ha2",path:"ha2", quality:HQuality.BLUE,lv:1,kind:2, + 5011:{uuid:5011,name:"ha2",path:"ha2", fac:FacSet.HERO, quality:HQuality.BLUE,lv:1,kind:2, type:HType.remote,hp:100,ap:15,dis:400,cd:1,speed:100,skills:[6003,6003], buff:[],info:"说明"}, //怪物 - 5201:{uuid:5201,name:"兽人战士",path:"mo1", quality:HQuality.GREEN,lv:1,kind:1, + 5201:{uuid:5201,name:"兽人战士",path:"mo1", fac:FacSet.MON, quality:HQuality.GREEN,lv:1,kind:1, type:HType.warrior,hp:25,ap:5,dis:90,cd:2,speed:100,skills:[6010], buff:[],info:"普通怪物-战士型"}, - 5202:{uuid:5202,name:"兽人刺客",path:"mo1", quality:HQuality.GREEN,lv:1,kind:1, + 5202:{uuid:5202,name:"兽人刺客",path:"mo1", fac:FacSet.MON, quality:HQuality.GREEN,lv:1,kind:1, type:HType.remote,hp:20,ap:5,dis:350,cd:1,speed:100,skills:[6008], buff:[],info:"普通怪物-战士型"}, - 5203:{uuid:5203,name:"兽人护卫",path:"mo1", quality:HQuality.GREEN,lv:1,kind:1, + 5203:{uuid:5203,name:"兽人护卫",path:"mo1", fac:FacSet.MON, quality:HQuality.GREEN,lv:1,kind:1, type:HType.warrior,hp:25,ap:5,dis:90,cd:2,speed:100,skills:[6010], buff:[],info:"普通怪物-战士型"}, - 5204:{uuid:5204,name:"石卫", path:"mo1",quality:HQuality.GREEN,lv:1,kind:1, + 5204:{uuid:5204,name:"石卫", path:"mo1", fac:FacSet.MON, quality:HQuality.GREEN,lv:1,kind:1, type:HType.mage,hp:18,ap:5,dis:90,cd:2.5,speed:100,skills:[6010], buff:[],info:"法师怪物-高伤害脆弱"}, - 5205:{uuid:5205,name:"土卫", path:"mo1",quality:HQuality.GREEN,lv:1,kind:1, + 5205:{uuid:5205,name:"土卫", path:"mo1", fac:FacSet.MON, quality:HQuality.GREEN,lv:1,kind:1, type:HType.mage,hp:18,ap:5,dis:90,cd:2.5,speed:100,skills:[6010], buff:[],info:"法师怪物-高伤害脆弱"}, - 5206:{uuid:5206,name:"树卫", path:"mo1",quality:HQuality.GREEN,lv:1,kind:1, + 5206:{uuid:5206,name:"树卫", path:"mo1", fac:FacSet.MON, quality:HQuality.GREEN,lv:1,kind:1, type:HType.mage,hp:18,ap:5,dis:90,cd:2.5,speed:100,skills:[6010], buff:[],info:"法师怪物-高伤害脆弱"}, - 5219:{uuid:5219,name:"牛头战士",path:"mo1", quality:HQuality.GREEN,lv:2,kind:1, + 5219:{uuid:5219,name:"牛头战士",path:"mo1", fac:FacSet.MON, quality:HQuality.GREEN,lv:2,kind:1, type:HType.warrior,hp:25,ap:5,dis:90,cd:2,speed:100,skills:[6010], buff:[],info:"普通怪物-战士型"}, - 5220:{uuid:5220,name:"牛头战士",path:"mo1", quality:HQuality.GREEN,lv:1,kind:1, + 5220:{uuid:5220,name:"牛头战士",path:"mo1", fac:FacSet.MON, quality:HQuality.GREEN,lv:1,kind:1, type:HType.warrior,hp:25,ap:5,dis:90,cd:2,speed:100,skills:[6010], buff:[],info:"普通怪物-战士型"}, - 5221:{uuid:5221,name:"牛头战士",path:"mo1", quality:HQuality.GREEN,lv:1,kind:1, + 5221:{uuid:5221,name:"牛头战士",path:"mo1", fac:FacSet.MON, quality:HQuality.GREEN,lv:1,kind:1, type:HType.remote,hp:20,ap:5,dis:350,cd:1.5,speed:100,skills:[6008], buff:[],info:"普通怪物-战士型"}, - 5222:{uuid:5222,name:"独眼巨人",path:"mo1", quality:HQuality.GREEN,lv:1,kind:1, + 5222:{uuid:5222,name:"独眼巨人",path:"mo1", fac:FacSet.MON, quality:HQuality.GREEN,lv:1,kind:1, type:HType.warrior,hp:25,ap:5,dis:90,cd:2,speed:100,skills:[6010], buff:[],info:"普通怪物-战士型"}, - 5223:{uuid:5223,name:"独眼巨人",path:"mo1", quality:HQuality.GREEN,lv:1,kind:1, + 5223:{uuid:5223,name:"独眼巨人",path:"mo1", fac:FacSet.MON, quality:HQuality.GREEN,lv:1,kind:1, type:HType.warrior,hp:25,ap:5,dis:90,cd:2,speed:100,skills:[6010], buff:[],info:"普通怪物-战士型"}, - 5224:{uuid:5224,name:"独眼巨人",path:"mo1", quality:HQuality.GREEN,lv:1,kind:1, + 5224:{uuid:5224,name:"独眼巨人",path:"mo1", fac:FacSet.MON, quality:HQuality.GREEN,lv:1,kind:1, type:HType.remote,hp:20,ap:5,dis:350,cd:1.5,speed:100,skills:[6010], buff:[],info:"普通怪物-战士型"}, - 5225:{uuid:5225,name:"精英独眼",path:"mo1", quality:HQuality.BLUE,lv:1,kind:1, + 5225:{uuid:5225,name:"精英独眼",path:"mo1", fac:FacSet.MON, quality:HQuality.BLUE,lv:1,kind:1, type:HType.warrior,hp:45,ap:12,dis:300,cd:2,speed:100,skills:[6006], buff:[],info:"精英怪物-战士型"}, - 5226:{uuid:5226,name:"精英牛头",path:"mo1", quality:HQuality.BLUE,lv:1,kind:1, + 5226:{uuid:5226,name:"精英牛头",path:"mo1", fac:FacSet.MON, quality:HQuality.BLUE,lv:1,kind:1, type:HType.warrior,hp:45,ap:12,dis:300,cd:2,speed:100,skills:[6007], buff:[],info:"精英怪物-战士型"}, - 5227:{uuid:5227,name:"精英兽人",path:"mo1", quality:HQuality.BLUE,lv:1,kind:1, + 5227:{uuid:5227,name:"精英兽人",path:"mo1", fac:FacSet.MON, quality:HQuality.BLUE,lv:1,kind:1, type:HType.warrior,hp:45,ap:12,dis:300,cd:2,speed:100,skills:[6008], buff:[],info:"精英怪物-战士型"}, diff --git a/assets/script/game/hero/Hero.ts b/assets/script/game/hero/Hero.ts index 1fbb1e32..ea1161c7 100644 --- a/assets/script/game/hero/Hero.ts +++ b/assets/script/game/hero/Hero.ts @@ -86,7 +86,6 @@ export class Hero extends ecs.Entity { hv.Attrs[BuffAttr.ATK_CD]=hv.cd=hero.cd hv.Attrs[BuffAttr.HP_MAX]=hv.hp=hv.hp_max=hero.hp+info.hp hv.Attrs[BuffAttr.AP]=hv.ap=hero.ap+info.ap; - hv.Attrs[BuffAttr.DEF]=hv.def=hero.def+info.def; hero.buff.forEach((buff:any)=>{ hv.apply_buff(buff.type,buff.value) }) diff --git a/assets/script/game/hero/HeroViewComp.ts b/assets/script/game/hero/HeroViewComp.ts index c3da1107..981521ef 100644 --- a/assets/script/game/hero/HeroViewComp.ts +++ b/assets/script/game/hero/HeroViewComp.ts @@ -11,9 +11,6 @@ import { oops } from "db://oops-framework/core/Oops"; import { GameEvent } from "../common/config/GameEvent"; import { EquipSpecialAttr } from "../common/config/Equips"; import { FightSet, getExpDrops, getStoneDrops, TooltipTypes } from "../common/config/Mission"; -import { getApIncrease, getHpIncrease, getUpExp, HeroInfo, HeroPos } from "../common/config/heroSet"; -import { FriendModelComp } from "./FriendModel"; -import { MasterModelComp } from "./MasterModel"; import { RandomManager } from "db://oops-framework/core/common/random/RandomManager"; import { EnhancementType } from "../common/config/LevelUp"; const { ccclass, property } = _decorator; @@ -136,6 +133,7 @@ export class HeroViewComp extends CCComp { start () { this.as.idle() this.BUFFCOMP=this.node.getComponent(BuffComp); + console.log("[HeroViewComp]:heroview"+this.hero_name,this.Attrs) /** 方向 */ this.node.setScale(this.scale,1); this.node.getChildByName("top").setScale(this.scale,1); @@ -420,6 +418,7 @@ export class HeroViewComp extends CCComp { if(is_crit) { damage = Math.floor(damage * (1 + (FightSet.CRIT_DAMAGE+crit_d)/100)) } + console.log(this.hero_name+"[HeroViewComp]:heroview :damage|hp|hp_max",damage,this.hp,this.Attrs[BuffAttr.HP_MAX]) this.hp -= damage; if(this.hp <= 0) { diff --git a/assets/script/game/hero/Mon.ts b/assets/script/game/hero/Mon.ts index 3f094e7c..6350a6f8 100644 --- a/assets/script/game/hero/Mon.ts +++ b/assets/script/game/hero/Mon.ts @@ -30,7 +30,7 @@ export class Monster extends ecs.Entity { } /** 加载角色 */ - load(pos: Vec3 = Vec3.ZERO,scale:number = 1,uuid:number=1001,is_boss:boolean=false,is_call:boolean=false,lv:number=1,rogueBuffData?: any[], rogueHp?: number, rogueAttack?: number) { + load(pos: Vec3 = Vec3.ZERO,scale:number = 1,uuid:number=1001,is_boss:boolean=false,is_call:boolean=false,lv:number=1,enhancement?: any, stageMultipliers?: any) { scale=-1 let box_group=BoxSet.MONSTER console.log("mon load",uuid) @@ -45,7 +45,7 @@ export class Monster extends ecs.Entity { const collider = node.getComponent(BoxCollider2D); if (collider) collider.enabled = false; // 先禁用 // 延迟一帧启用碰撞体 node.setPosition(pos) - this.hero_init(uuid,node,scale,box_group,is_boss,is_call,lv,rogueBuffData,rogueHp,rogueAttack) + this.hero_init(uuid,node,scale,box_group,is_boss,is_call,lv,enhancement,stageMultipliers) oops.message.dispatchEvent("monster_load",this) // 初始化移动参数 @@ -60,7 +60,7 @@ export class Monster extends ecs.Entity { node.parent = scene.entityLayer!.node! node.setPosition(pos) } - hero_init(uuid:number=1001,node:Node,scale:number=1,box_group=BoxSet.HERO,is_boss:boolean=false,is_call:boolean=false,lv:number=1,rogueBuffData?: any[], rogueHp?: number, rogueAttack?: number) { + hero_init(uuid:number=1001,node:Node,scale:number=1,box_group=BoxSet.HERO,is_boss:boolean=false,is_call:boolean=false,lv:number=1,enhancement?: any, stageMultipliers?: any) { var hv = node.getComponent(HeroViewComp)!; hv.hide_info() // console.log("hero_init",buff) @@ -79,30 +79,26 @@ export class Monster extends ecs.Entity { // 初始化Attrs属性系统,参考Hero.ts的实现 hv.Attrs = getBuffNum(); - // 肉鸽模式使用固定数值,否则使用等级计算 - if (rogueHp !== undefined && rogueAttack !== undefined) { - // 肉鸽模式:使用固定数值 - hv.hp = hv.hp_max = rogueHp; - hv.ap = rogueAttack; - hv.ap_base = rogueAttack; - console.log(`[Monster-Rogue]: 怪物${hero.name} - 固定HP:${rogueHp}, 固定AP:${rogueAttack}`); + // 计算基础属性(使用关卡倍数) + const baseHp = hero.hp; + const baseAp = hero.ap; + + // 应用关卡倍数 + let finalHp = baseHp; + let finalAp = baseAp; + + if (stageMultipliers) { + finalHp = Math.floor(baseHp * stageMultipliers.hp); + finalAp = Math.floor(baseAp * stageMultipliers.attack); + console.log(`[Monster]: 怪物${hero.name} 关卡倍数 - HP: ${baseHp} x ${stageMultipliers.hp.toFixed(2)} = ${finalHp}, AP: ${baseAp} x ${stageMultipliers.attack.toFixed(2)} = ${finalAp}`); } else { - // 普通模式:根据Design.md设计文档计算怪物等级属性 - const baseHp = hero.hp; - const baseAp = hero.ap; - - // 怪物属性随等级增长 (根据Design.md中的公式) - // HP增长: Math.floor(baseHp * (1 + (level-1) * 0.3)) - // AP增长: Math.floor(baseAp * (1 + (level-1) * 0.25)) - const levelHp = Math.floor(baseHp * (1 + (lv - 1) * 0.5)); - const levelAp = Math.floor(baseAp * (1 + (lv - 1) * 0.1)); - - hv.hp = hv.hp_max = levelHp; - hv.ap = levelAp; - hv.ap_base = levelAp; - console.log(`[Monster]: 怪物${hero.name}(等级${lv}) - 基础HP:${baseHp}->等级HP:${levelHp}, 基础AP:${baseAp}->等级AP:${levelAp}`); + console.log(`[Monster]: 怪物${hero.name} 使用基础属性 - HP: ${finalHp}, AP: ${finalAp}`); } + hv.hp = hv.hp_max = finalHp; + hv.ap = finalAp; + hv.ap_base = finalAp; + // 设置基础属性到Attrs系统 hv.Attrs[BuffAttr.SPEED] = hv.speed = hv.speed_base = hero.speed; hv.Attrs[BuffAttr.DIS] = hv.dis = hero.dis; @@ -116,11 +112,11 @@ export class Monster extends ecs.Entity { hv.apply_buff(buff.type, buff.value); }) - // 处理肉鸽模式的词条Buff - if (rogueBuffData && rogueBuffData.length > 0) { - console.log(`[Monster]: 怪物${hero.name}应用肉鸽词条:`, rogueBuffData); - rogueBuffData.forEach((buff:any)=>{ - hv.apply_buff(buff.type, buff.value); + // 处理肉鸽模式的增强属性 + if (enhancement && enhancement.buffList && enhancement.buffList.length > 0) { + console.log(`[Monster]: 怪物${hero.name}应用增强属性:`, enhancement.buffList.map((buff: any) => `${buff.name}:+${buff.value}`)); + enhancement.buffList.forEach((buff:any)=>{ + hv.apply_buff(buff.buffType, buff.value); }) } diff --git a/assets/script/game/map/MissionMonComp.ts b/assets/script/game/map/MissionMonComp.ts index 4a930600..d030e18e 100644 --- a/assets/script/game/map/MissionMonComp.ts +++ b/assets/script/game/map/MissionMonComp.ts @@ -10,7 +10,14 @@ import { smc } from "../common/SingletonModuleComp"; import { GameEvent } from "../common/config/GameEvent"; import { oops } from "db://oops-framework/core/Oops"; // 导入肉鸽配置 -import { getRogueWaveConfig, RogueConfig, RogueWaveType, AffixCountConfig, MonsterAffixConfig } from "./RogueConfig"; +import { + generateStageConfig, + getStageMonsterConfigs, + getStageAllMultipliers, + MonsterType, + StageType, + getStageType +} from "./RogueConfig"; import { MonModelComp } from "../hero/MonModelComp"; const { ccclass, property } = _decorator; @@ -18,16 +25,14 @@ const { ccclass, property } = _decorator; /** 视图层对象 */ @ccclass('MissionMonCompComp') @ecs.register('MissionMonComp', false) -export class MissionMonCompComp extends CCComp { // 添加刷怪队列 - 扩展支持词条 +export class MissionMonCompComp extends CCComp { // 添加刷怪队列 - 使用新的RogueConfig格式 private monsterQueue: Array<{ uuid: number, position: number, - isBoss: boolean, + type: MonsterType, level: number, - affixes?: any[], - buffData?: any[], // 使用BuffAttr格式的buff数据 - rogueHp?: number, // 肉鸽固定血量 - rogueAttack?: number // 肉鸽固定攻击力 + enhancement?: any, // 增强属性配置 + stageMultipliers?: any // 关卡倍数配置 }> = []; private isSpawning: boolean = false;// 是否正在生成怪物 private spawnInterval: number = 0.1; // 每个怪物生成间隔时间 @@ -49,7 +54,7 @@ export class MissionMonCompComp extends CCComp { // 添加刷怪队列 - 扩 } fight_ready(){ - console.log("[MissionMonComp]:fight_ready") + // console.log("[MissionMonComp]:fight_ready") this.do_mon_wave() } @@ -68,7 +73,7 @@ export class MissionMonCompComp extends CCComp { // 添加刷怪队列 - 扩 this.isPausing = false; this.spawnCount = 0; this.spawnTimer = 0; - console.log("[MissionMonComp]: 暂停结束,继续召唤怪物"); + // console.log("[MissionMonComp]: 暂停结束,继续召唤怪物"); } return; // 暂停期间不召唤怪物 } @@ -82,7 +87,7 @@ export class MissionMonCompComp extends CCComp { // 添加刷怪队列 - 扩 if (this.spawnCount >= 5) { this.isPausing = true; this.spawnTimer = 0; // 重置计时器用于暂停计时 - console.log("[MissionMonComp]: 已召唤5只怪物,开始暂停5秒"); + // console.log("[MissionMonComp]: 已召唤5只怪物,开始暂停5秒"); } } } @@ -90,125 +95,101 @@ export class MissionMonCompComp extends CCComp { // 添加刷怪队列 - 扩 do_mon_wave(){ - console.log("[MissionMonComp]:怪物登场,当前波次 :",smc.vmdata.mission_data.current_wave) + // console.log("[MissionMonComp]:怪物登场,当前关卡 :",smc.vmdata.mission_data.current_wave) // 重置召唤相关状态 this.spawnCount = 0; this.isPausing = false; this.spawnTimer = 0; - const currentWave = smc.vmdata.mission_data.current_wave; - // 使用肉鸽模式配置 - const rogueWaveConfig = getRogueWaveConfig(currentWave); - console.log(`[MissionMonComp]:肉鸽模式第${currentWave}波配置:`, rogueWaveConfig.description); - this.generateRogueMonstersFromConfig(rogueWaveConfig); + const currentStage = smc.vmdata.mission_data.current_wave; + // 使用新的肉鸽关卡配置 + const stageType = getStageType(currentStage); + const monsterConfigs = getStageMonsterConfigs(currentStage); + console.log(`[MissionMonComp]:第${currentStage}关 - ${stageType}类型,怪物数量: ${monsterConfigs.length}`); + this.generateMonstersFromStageConfig(monsterConfigs); } - // 根据肉鸽配置生成怪物(肉鸽模式) - private generateRogueMonstersFromConfig(rogueWaveConfig: any) { - const { monsters, waveType } = rogueWaveConfig; - const currentWave = smc.vmdata.mission_data.current_wave; - const monsterLevel = RogueConfig.getMonsterLevel(currentWave); - smc.vmdata.mission_data.mon_num=monsters.reduce((total: number, group: any) => total + group.count, 0); - // 固定9波模式,所有波次都是战斗波次 - console.log(`[MissionMonComp]:第${currentWave}波 - ${waveType}战斗波次`); + // 根据新的关卡配置生成怪物 + private generateMonstersFromStageConfig(monsterConfigs: any[]) { + const currentStage = smc.vmdata.mission_data.current_wave; - if (!monsters || monsters.length === 0) { - console.warn(`[MissionMonComp]:肉鸽波次配置中没有怪物信息`); + // 设置怪物总数 + smc.vmdata.mission_data.mon_num = monsterConfigs.length; + + if (!monsterConfigs || monsterConfigs.length === 0) { + console.warn(`[MissionMonComp]:关卡${currentStage}配置中没有怪物信息`); return; } - monsters.forEach((monsterGroup: any) => { - const { uuid, count, affixes, enhancedStats, buffData, isBoss, rogueHp, rogueAttack } = monsterGroup; + // 为每个怪物配置生成怪物 + monsterConfigs.forEach((monsterConfig: any, index: number) => { + const { uuid, type, enhancement, stageMultipliers } = monsterConfig; - // 为每个怪物组生成指定数量的怪物 - for (let i = 0; i < count; i++) { - // 位置循环使用 (0-9),如果怪物数量超过10个位置,则循环使用 - const position = i % 5; - this.addToSpawnQueueWithAffixes( - uuid, - position, - isBoss || false, - monsterLevel, - affixes, - buffData, // 现在传递buffData而不是enhancedStats和specialEffects - rogueHp, // 传递固定血量 - rogueAttack // 传递固定攻击力 - ); - } + // 位置循环使用 (0-4) + const position = index % 5; + + this.addToStageSpawnQueue( + uuid, + position, + type, + 1, // 默认等级1 + enhancement, + stageMultipliers + ); }); - const totalMonsters = monsters.reduce((total: number, group: any) => total + group.count, 0); - console.log(`[MissionMonComp]:肉鸽模式本波次将生成 ${totalMonsters} 只怪物,等级: ${monsterLevel}`); + console.log(`[MissionMonComp]:关卡${currentStage}将生成 ${monsterConfigs.length} 只怪物`); - // 输出词条信息 - monsters.forEach((monsterGroup: any) => { - if (monsterGroup.buffData && monsterGroup.buffData.length > 0) { - console.log(`[MissionMonComp]:怪物 ${monsterGroup.uuid} 拥有词条:`, monsterGroup.buffData); - // 输出词条名称 - monsterGroup.buffData.forEach((buff: any) => { - const config = MonsterAffixConfig[buff.buff_type]; - if (config) { - console.log(`[MissionMonComp]: - ${config.name}: ${config.description}`); - } - }); + // 输出增强属性信息 + monsterConfigs.forEach((monsterConfig: any) => { + if (monsterConfig.enhancement && monsterConfig.enhancement.buffList.length > 0) { + console.log(`[MissionMonComp]:怪物 ${monsterConfig.uuid} (${monsterConfig.type}) 拥有增强属性:`, + monsterConfig.enhancement.buffList.map((buff: any) => `${buff.name}:+${buff.value}`)); } }); } - // 新增:添加到刷怪队列 - 增加level参数(普通模式) - private addToSpawnQueue(uuid: number, position: number, isBoss: boolean = false, level: number = 1) { - this.monsterQueue.push({ - uuid: uuid, - position: position, - isBoss: isBoss, - level: level - }); - } - - // 新增:添加到刷怪队列 - 支持词条(肉鸽模式) - private addToSpawnQueueWithAffixes( + // 添加到关卡刷怪队列 - 使用新的配置格式 + private addToStageSpawnQueue( uuid: number, position: number, - isBoss: boolean = false, + type: MonsterType, level: number = 1, - affixes?: any[], - buffData?: any[], - rogueHp?: number, - rogueAttack?: number + enhancement?: any, + stageMultipliers?: any ) { this.monsterQueue.push({ uuid: uuid, position: position, - isBoss: isBoss, + type: type, level: level, - affixes: affixes, - buffData: buffData, - rogueHp: rogueHp, - rogueAttack: rogueAttack + enhancement: enhancement, + stageMultipliers: stageMultipliers }); } - // 新增:从队列中生成下一个怪物 - 传递词条参数 + // 从队列中生成下一个怪物 - 使用新的配置格式 private spawnNextMonster() { if (this.monsterQueue.length === 0) return; const monsterData = this.monsterQueue.shift(); if (monsterData) { + const isBoss = monsterData.type === MonsterType.BOSS; + this.addMonster( monsterData.uuid, monsterData.position, - monsterData.isBoss, + isBoss, false, monsterData.level, - monsterData.buffData, - monsterData.rogueHp, - monsterData.rogueAttack + monsterData.enhancement, + monsterData.stageMultipliers ); // 增加召唤计数 this.spawnCount++; - console.log(`[MissionMonComp]: 召唤第${this.spawnCount}只怪物,剩余队列: ${this.monsterQueue.length}`); + console.log(`[MissionMonComp]: 召唤第${this.spawnCount}只${monsterData.type}怪物,剩余队列: ${this.monsterQueue.length}`); } } @@ -218,25 +199,25 @@ export class MissionMonCompComp extends CCComp { // 添加刷怪队列 - 扩 is_boss: boolean = false, is_call: boolean = false, lv: number = 1, - buffData?: any[], - rogueHp?: number, - rogueAttack?: number + enhancement?: any, + stageMultipliers?: any ) { let mon = ecs.getEntity(Monster); let scale = -1; let pos: Vec3 = v3(MonSet[i].pos); - // 生成怪物,传递词条buff数据和肉鸽固定数值 - mon.load(pos, scale, uuid, is_boss, is_call, lv, buffData, rogueHp, rogueAttack); + // 生成怪物,传递增强属性和关卡倍数 + mon.load(pos, scale, uuid, is_boss, is_call, lv, enhancement, stageMultipliers); - // 如果有词条buff数据,记录到控制台 - if (buffData && buffData.length > 0) { - console.log(`[MissionMonComp]: 怪物 ${uuid} 获得肉鸽词条Buff:`, buffData); + // 如果有增强属性,记录到控制台 + if (enhancement && enhancement.buffList && enhancement.buffList.length > 0) { + console.log(`[MissionMonComp]: 怪物 ${uuid} 获得增强属性:`, + enhancement.buffList.map((buff: any) => `${buff.name}:+${buff.value}`)); } - // 如果有肉鸽固定数值,记录到控制台 - if (rogueHp !== undefined && rogueAttack !== undefined) { - console.log(`[MissionMonComp]: 怪物 ${uuid} 使用肉鸽固定数值 - HP: ${rogueHp}, 攻击: ${rogueAttack}`); + // 如果有关卡倍数,记录到控制台 + if (stageMultipliers) { + console.log(`[MissionMonComp]: 怪物 ${uuid} 关卡倍数 - HP: x${stageMultipliers.hp.toFixed(2)}, 攻击: x${stageMultipliers.attack.toFixed(2)}`); } } /** 视图对象通过 ecs.Entity.remove(ModuleViewComp) 删除组件是触发组件处理自定义释放逻辑 */ diff --git a/assets/script/game/map/RogueConfig.ts b/assets/script/game/map/RogueConfig.ts index cb357e32..6d02a69a 100644 --- a/assets/script/game/map/RogueConfig.ts +++ b/assets/script/game/map/RogueConfig.ts @@ -1,696 +1,382 @@ /** - * 肉鸽模式配置脚本 + * 肉鸽模式配置脚本 - 简化版 * * 功能说明: - * - 提供肉鸽模式的波次生成配置 - * - 包含词条系统和怪物强化逻辑 - * - 供 MissionMonComp.ts 等组件调用 - * - * 波次规则(固定9波模式): - * - 1-3波:普通波次 - * - 4-6波:怪物潮波次(大量低级怪物) - * - 7-8波:精英波次 - * - 9波:最终Boss波次 + * - 提供基于怪物类型的属性加成配置 + * - 使用BuffAttr枚举定义属性增强 + * - 供游戏系统调用获取怪物增强数据 * * @author 游戏开发团队 - * @version 2.0 + * @version 3.0 简化版 * @date 2025-07-12 */ -// 导入配置 -import { HQuality, HeroInfo, MonsterSeriesConfig, getRandomSeries } from "../common/config/heroSet"; import { BuffAttr } from "../common/config/SkillSet"; - -// ==================== 核心配置 ==================== +import { getMonList, HQuality } from "../common/config/heroSet"; /** - * 肉鸽模式波次类型枚举 + * 怪物类型枚举 */ -export enum RogueWaveType { - NORMAL = "normal", // 普通波次(1-3波) - HORDE = "horde", // 怪物潮波次(4-6波) - ELITE = "elite", // 精英波次(7-8波) - FINAL_BOSS = "final_boss" // 最终Boss波次(9波) -} - -//波次和天赋对应关系 -export const RogueTalWave = { - 0:{tal_slot_key:0,wave:1}, - 1:{tal_slot_key:1,wave:2}, - 2:{tal_slot_key:2,wave:3}, - 3:{tal_slot_key:3,wave:4}, - 4:{tal_slot_key:4,wave:5}, - 5:{tal_slot_key:5,wave:6}, +export enum MonsterType { + NORMAL = "normal", // 普通怪物 + ELITE = "elite", // 精英怪物 + BOSS = "boss" // Boss怪物 } /** - * 固定数值配置(根据波次固定血量和攻击力) + * 怪物类型增强属性个数配置 */ -export const RogueStatsConfig = { - // 血量配置 - hp: { - 1: 10, // 波次1:小怪血量10 - 2: 15, // 波次2:小怪血量15(插值) - 3: 25, // 波次3:小怪血量25 - 4: 35, // 波次4:怪物潮血量35(插值) - 5: 60, // 波次5:怪物潮血量60 - 6: 80, // 波次6:怪物潮血量80(插值) - 7: 100, // 波次7:精英血量100 - 8: 150, // 波次8:精英血量150(插值) - 9: 500 // 波次9:boss血量500 +export const MonsterEnhancementCountConfig = { + [MonsterType.NORMAL]: 0, // 普通怪物:0个增强属性 + [MonsterType.ELITE]: 1, // 精英怪物:1个增强属性 + [MonsterType.BOSS]: 2 // Boss怪物:2个增强属性 +}; + +/** + * 关卡类型枚举 + */ +export enum StageType { + NORMAL = "normal", // 普通关卡(1-4关) + ELITE = "elite", // 精英关卡(5关) + BOSS = "boss" // Boss关卡(10关) +} + +/** + * 关卡配置数据接口 + */ +export interface StageConfig { + stageNumber: number; + stageType: StageType; + description: string; + monsters: Array<{ + type: MonsterType; + count: number; + }>; +} + +/** + * 关卡配置规则 + */ +export const StageConfigRules = { + // 普通关卡(1-4关) + [StageType.NORMAL]: { + description: "普通关卡", + monsters: [ + { type: MonsterType.NORMAL, count: 5 } // 5个小怪 + ] }, - // 攻击力配置 - attack: { - 1: 5, // 1-3波:攻击力5 - 2: 5, // 1-3波:攻击力5 - 3: 5, // 1-3波:攻击力5 - 4: 8, // 4-6波:攻击力8 - 5: 8, // 4-6波:攻击力8 - 6: 8, // 4-6波:攻击力8 - 7: 12, // 7-8波:攻击力12 - 8: 12, // 7-8波:攻击力12 - 9: 30 // 9波boss:攻击力30 + // 精英关卡(5关) + [StageType.ELITE]: { + description: "精英关卡", + monsters: [ + { type: MonsterType.ELITE, count: 2 }, // 2个精英 + { type: MonsterType.NORMAL, count: 3 } // 3个小怪 + ] }, - /** - * 获取指定波次的血量 - */ - getHp(waveNumber: number): number { - return this.hp[waveNumber] || this.hp[9]; // 默认返回boss血量 - }, - - /** - * 获取指定波次的攻击力 - */ - getAttack(waveNumber: number): number { - return this.attack[waveNumber] || this.attack[9]; // 默认返回boss攻击力 + // Boss关卡(10关) + [StageType.BOSS]: { + description: "Boss关卡", + monsters: [ + { type: MonsterType.BOSS, count: 1 }, // 1个Boss + { type: MonsterType.ELITE, count: 2 }, // 2个精英 + { type: MonsterType.NORMAL, count: 2 } // 2个小怪 + ] } }; /** - * 怪物词条配置(直接使用BuffAttr作为词条类型) - * 这样可以直接复用Mon.ts中的Buff处理逻辑 + * 可用的增强属性池 + * 按权重排序,数值越大优先级越高 */ -export const MonsterAffixConfig = { - [BuffAttr.ATK]: { - name: "狂暴", - description: "攻击力提升50%", - value: 50, - rarity: "common", - applicableQualities: [HQuality.GREEN, HQuality.BLUE, HQuality.PURPLE] +export const AvailableEnhancementPool = [ + { buffType: BuffAttr.HP, weight: 10, baseValue: 80, name: "生命值增强" }, + { buffType: BuffAttr.ATK, weight: 9, baseValue: 50, name: "攻击力增强" }, + { buffType: BuffAttr.CRITICAL, weight: 8, baseValue: 30, name: "暴击率增强" }, + { buffType: BuffAttr.DEF, weight: 7, baseValue: 40, name: "防御增强" }, + { buffType: BuffAttr.CRITICAL_DMG, weight: 6, baseValue: 60, name: "暴击伤害增强" }, + { buffType: BuffAttr.DODGE, weight: 5, baseValue: 25, name: "闪避增强" }, + { buffType: BuffAttr.ATK_CD, weight: 4, baseValue: 20, name: "攻击速度增强" }, + { buffType: BuffAttr.LIFESTEAL, weight: 3, baseValue: 15, name: "吸血" }, + { buffType: BuffAttr.DMG_RED, weight: 2, baseValue: 20, name: "免伤" }, + { buffType: BuffAttr.PUNCTURE, weight: 1, baseValue: 2, name: "穿刺" } +]; + +/** + * 基于怪物类型的基础配置 + */ +export const MonsterTypeBaseConfig = { + [MonsterType.NORMAL]: { + name: "普通怪物", + description: "基础属性无增强" }, - [BuffAttr.ATK_CD]: { - name: "迅捷", - description: "攻击速度提升30%", - value: 30, // 正值表示提升,Mon.ts中会转换为负值 - rarity: "common", - applicableQualities: [HQuality.GREEN, HQuality.BLUE] + [MonsterType.ELITE]: { + name: "精英怪物", + description: "单一属性增强" }, - [BuffAttr.CRITICAL]: { - name: "致命", - description: "暴击率提升25%", - value: 25, - rarity: "uncommon", - applicableQualities: [HQuality.BLUE, HQuality.PURPLE] - }, - [BuffAttr.DEF]: { - name: "装甲", - description: "减少受到的伤害30%", - value: 30, - rarity: "common", - applicableQualities: [HQuality.GREEN, HQuality.BLUE, HQuality.PURPLE] - }, - [BuffAttr.HP]: { - name: "坚韧", - description: "生命值提升50%", - value: 50, - rarity: "common", - applicableQualities: [HQuality.GREEN, HQuality.BLUE, HQuality.PURPLE] - }, - [BuffAttr.CRITICAL_DMG]: { - name: "嗜血", - description: "暴击伤害提升40%", - value: 40, - rarity: "uncommon", - applicableQualities: [HQuality.BLUE, HQuality.PURPLE] - }, - [BuffAttr.DODGE]: { - name: "敏捷", - description: "闪避率提升25%", - value: 25, - rarity: "uncommon", - applicableQualities: [HQuality.GREEN, HQuality.BLUE] - }, - [BuffAttr.BURN_COUNT]: { - name: "燃烧", - description: "攻击附带易伤效果,额外持续3次", - value: 3, - rarity: "uncommon", - applicableQualities: [HQuality.GREEN, HQuality.BLUE, HQuality.PURPLE] - }, - [BuffAttr.PUNCTURE]: { - name: "穿刺", - description: "攻击穿透1个敌人", - value: 1, - rarity: "uncommon", - applicableQualities: [HQuality.BLUE, HQuality.PURPLE] - }, - [BuffAttr.FROST_RATIO]: { - name: "冰冻", - description: "攻击有20%概率冰冻敌人", - value: 20, - rarity: "rare", - applicableQualities: [HQuality.BLUE, HQuality.PURPLE] + [MonsterType.BOSS]: { + name: "Boss怪物", + description: "双重属性增强" } }; /** - * 词条数量配置(9波固定模式) + * 怪物增强数据接口 */ -export const AffixCountConfig = { - currentMode: "normal" as "normal" | "enhanced", - - modes: { - normal: { - [RogueWaveType.NORMAL]: 0, // 1-3波:无词条 - [RogueWaveType.HORDE]: 0, // 4-6波:无词条(数量取胜) - [RogueWaveType.ELITE]: 1, // 7-8波:1个词条 - [RogueWaveType.FINAL_BOSS]: 2, // 9波:2个词条 - }, - enhanced: { - [RogueWaveType.NORMAL]: 1, // 1-3波:1个词条 - [RogueWaveType.HORDE]: 1, // 4-6波:1个词条 - [RogueWaveType.ELITE]: 2, // 7-8波:2个词条 - [RogueWaveType.FINAL_BOSS]: 3, // 9波:3个词条 - } - }, - - setMode(mode: "normal" | "enhanced") { - this.currentMode = mode; - }, - - getAffixCount(waveType: RogueWaveType): number { - return this.modes[this.currentMode][waveType] || 0; - }, - - enableNormalMode() { - this.setMode("normal"); - }, - - enableEnhancedMode() { - this.setMode("enhanced"); - } -}; +export interface MonsterEnhancementData { + name: string; + description: string; + buffs: { [key in BuffAttr]?: number }; + buffList: Array<{ buffType: BuffAttr; value: number; name: string }>; +} /** - * 波次配置(固定9波模式) + * 根据权重随机选择增强属性 + * @param count 需要选择的属性个数 + * @param excludeTypes 排除的属性类型 + * @returns 选中的增强属性数组 */ -export const RogueWaveConfig = { - // 固定9波模式,每波类型固定 - getWaveType: (waveNumber: number): RogueWaveType => { - if (waveNumber <= 3) { - return RogueWaveType.NORMAL; // 1-3波:普通 - } else if (waveNumber <= 6) { - return RogueWaveType.HORDE; // 4-6波:怪物潮 - } else if (waveNumber <= 8) { - return RogueWaveType.ELITE; // 7-8波:精英 - } else if (waveNumber === 9) { - return RogueWaveType.FINAL_BOSS; // 9波:最终Boss - } else { - // 超过9波的情况(如果需要循环) - const cycleWave = ((waveNumber - 1) % 9) + 1; - return RogueWaveConfig.getWaveType(cycleWave); - } - }, +export function selectRandomEnhancements(count: number, excludeTypes: BuffAttr[] = []): Array<{buffType: BuffAttr, weight: number, baseValue: number, name: string}> { + if (count <= 0) return []; - maxWaves: 9 // 固定最大波数 -}; - -// ==================== 肉鸽配置生成器 ==================== - -/** - * 肉鸽配置生成器 - */ -export class RogueConfig { + // 过滤掉排除的属性类型 + const availablePool = AvailableEnhancementPool.filter(item => !excludeTypes.includes(item.buffType)); - /** - * 生成波次配置(主入口) - */ - static generateWaveConfig(waveNumber: number) { - const waveType = RogueWaveConfig.getWaveType(waveNumber); - const fixedHp = RogueStatsConfig.getHp(waveNumber); - const fixedAttack = RogueStatsConfig.getAttack(waveNumber); - - console.log(`[RogueConfig]: 第${waveNumber}波 - 类型: ${waveType} - 固定HP: ${fixedHp}, 固定攻击: ${fixedAttack} (固定9波模式)`); - - // 根据类型生成配置 - switch (waveType) { - case RogueWaveType.NORMAL: - return this.generateNormalWave(waveNumber); - case RogueWaveType.HORDE: - return this.generateHordeWave(waveNumber); - case RogueWaveType.ELITE: - return this.generateEliteWave(waveNumber); - case RogueWaveType.FINAL_BOSS: - return this.generateFinalBossWave(waveNumber); - default: - return this.generateNormalWave(waveNumber); - } - } + if (availablePool.length === 0) return []; - /** - * 生成普通波次(1-3波) - */ - static generateNormalWave(waveNumber: number) { - const series = getRandomSeries(); - const seriesConfig = MonsterSeriesConfig[series]; - // 普通波次固定数量:10个怪物 - const baseCount = 10; - const monsters = []; - - // 选择怪物类型 - const availableTypes = []; - if (seriesConfig.monsters.warrior.length > 0) availableTypes.push("warrior"); - if (seriesConfig.monsters.remote.length > 0) availableTypes.push("remote"); - if (seriesConfig.monsters.mage.length > 0) availableTypes.push("mage"); - - if (availableTypes.length > 0) { - const randomType = availableTypes[Math.floor(Math.random() * availableTypes.length)]; - const typeMonsters = seriesConfig.monsters[randomType]; - const randomMonster = typeMonsters[Math.floor(Math.random() * typeMonsters.length)]; - const monsterInfo = HeroInfo[randomMonster]; - - // 生成词条 - const affixes = this.generateMonsterAffixes( - monsterInfo.quality, - waveNumber, - RogueWaveType.NORMAL - ); - - // 应用强化 - const enhanced = this.applyAffixesToMonster(affixes, monsterInfo); - - monsters.push({ - uuid: randomMonster, - count: baseCount, - type: randomType, - series: series, - affixes: affixes, - enhancedStats: enhanced.stats, - buffData: enhanced.buffData, - // 肉鸽固定数值 - rogueHp: RogueStatsConfig.getHp(waveNumber), - rogueAttack: RogueStatsConfig.getAttack(waveNumber) - }); - } - - return { - waveType: RogueWaveType.NORMAL, - monsters: monsters, - description: `第${waveNumber}波 - 普通波次 (10个怪物)`, - waveNumber: waveNumber - }; - } + const selectedEnhancements = []; + const usedTypes = new Set(); - /** - * 生成怪物潮波次(4-6波) - */ - static generateHordeWave(waveNumber: number) { - const series = getRandomSeries(); - const seriesConfig = MonsterSeriesConfig[series]; + for (let i = 0; i < count && i < availablePool.length; i++) { + // 计算权重总和 + const totalWeight = availablePool + .filter(item => !usedTypes.has(item.buffType)) + .reduce((sum, item) => sum + item.weight, 0); - // 怪物潮固定数量:20个怪物 - const baseCount = 20; + if (totalWeight === 0) break; - const monsters = []; + // 随机选择 + let randomValue = Math.random() * totalWeight; - // 怪物潮主要使用绿色品质的小怪 - const hordeMonsters = seriesConfig.allMonsters.filter(uuid => { - return HeroInfo[uuid] && HeroInfo[uuid].quality === HQuality.GREEN; - }); - - if (hordeMonsters.length > 0) { - const hordeMonster = hordeMonsters[Math.floor(Math.random() * hordeMonsters.length)]; - const monsterInfo = HeroInfo[hordeMonster]; + for (const enhancement of availablePool) { + if (usedTypes.has(enhancement.buffType)) continue; - // 生成词条(怪物潮通常没有词条,靠数量取胜) - const affixes = this.generateMonsterAffixes( - monsterInfo.quality, - waveNumber, - RogueWaveType.HORDE - ); - - const enhanced = this.applyAffixesToMonster(affixes, monsterInfo); - - monsters.push({ - uuid: hordeMonster, - count: baseCount, - type: "warrior", - series: series, - isHorde: true, - affixes: affixes, - enhancedStats: enhanced.stats, - buffData: enhanced.buffData, - // 肉鸽固定数值 - rogueHp: RogueStatsConfig.getHp(waveNumber), - rogueAttack: RogueStatsConfig.getAttack(waveNumber) - }); - } else { - // 如果没有绿色怪物,使用其他怪物 - const availableTypes = []; - if (seriesConfig.monsters.warrior.length > 0) availableTypes.push("warrior"); - if (seriesConfig.monsters.remote.length > 0) availableTypes.push("remote"); - if (seriesConfig.monsters.mage.length > 0) availableTypes.push("mage"); - - if (availableTypes.length > 0) { - const randomType = availableTypes[Math.floor(Math.random() * availableTypes.length)]; - const typeMonsters = seriesConfig.monsters[randomType]; - const randomMonster = typeMonsters[Math.floor(Math.random() * typeMonsters.length)]; - const monsterInfo = HeroInfo[randomMonster]; - - const affixes = this.generateMonsterAffixes( - monsterInfo.quality, - waveNumber, - RogueWaveType.HORDE - ); - - const enhanced = this.applyAffixesToMonster(affixes, monsterInfo); - - monsters.push({ - uuid: randomMonster, - count: baseCount, - type: randomType, - series: series, - isHorde: true, - affixes: affixes, - enhancedStats: enhanced.stats, - buffData: enhanced.buffData, - // 肉鸽固定数值 - rogueHp: RogueStatsConfig.getHp(waveNumber), - rogueAttack: RogueStatsConfig.getAttack(waveNumber) - }); + randomValue -= enhancement.weight; + if (randomValue <= 0) { + selectedEnhancements.push(enhancement); + usedTypes.add(enhancement.buffType); + break; } } - - return { - waveType: RogueWaveType.HORDE, - monsters: monsters, - description: `第${waveNumber}波 - 怪物潮 (20个怪物)`, - waveNumber: waveNumber - }; } - /** - * 生成精英波次(7-8波) - */ - static generateEliteWave(waveNumber: number) { - const series = getRandomSeries(); - const seriesConfig = MonsterSeriesConfig[series]; - - const monsters = []; - - // 1. 生成5个精英怪物 - const eliteMonsters = seriesConfig.allMonsters.filter(uuid => { - return HeroInfo[uuid] && HeroInfo[uuid].quality === HQuality.BLUE; + return selectedEnhancements; +} + +/** + * 获取怪物类型的属性加成配置 + * @param monsterType 怪物类型 + * @param useRandom 是否使用随机生成(默认true) + * @returns 属性加成配置,包含buffs字段 + */ +export function getMonsterEnhancement(monsterType: MonsterType, useRandom: boolean = true): MonsterEnhancementData { + const baseConfig = MonsterTypeBaseConfig[monsterType]; + const enhancementCount = MonsterEnhancementCountConfig[monsterType]; + + let selectedEnhancements: Array<{buffType: BuffAttr, weight: number, baseValue: number, name: string}> = []; + + if (useRandom) { + // 随机生成增强属性 + selectedEnhancements = selectRandomEnhancements(enhancementCount); + } else { + // 使用固定的最高权重属性 + selectedEnhancements = AvailableEnhancementPool + .slice(0, enhancementCount) + .map(item => ({...item})); + } + + // 构建buffs对象 + const buffs: { [key in BuffAttr]?: number } = {}; + const buffList: Array<{ buffType: BuffAttr; value: number; name: string }> = []; + + selectedEnhancements.forEach(enhancement => { + buffs[enhancement.buffType] = enhancement.baseValue; + buffList.push({ + buffType: enhancement.buffType, + value: enhancement.baseValue, + name: enhancement.name }); - - if (eliteMonsters.length > 0) { - const eliteMonster = eliteMonsters[Math.floor(Math.random() * eliteMonsters.length)]; - const monsterInfo = HeroInfo[eliteMonster]; - - // 生成精英词条 - const affixes = this.generateMonsterAffixes( - monsterInfo.quality, - waveNumber, - RogueWaveType.ELITE - ); - - const enhanced = this.applyAffixesToMonster(affixes, monsterInfo); - - monsters.push({ - uuid: eliteMonster, - count: 5, // 固定5个精英 - type: "elite", - series: series, - affixes: affixes, - enhancedStats: enhanced.stats, - buffData: enhanced.buffData, - // 肉鸽固定数值 - rogueHp: RogueStatsConfig.getHp(waveNumber), - rogueAttack: RogueStatsConfig.getAttack(waveNumber) - }); - } - - // 2. 生成10个普通小怪 - const availableTypes = []; - if (seriesConfig.monsters.warrior.length > 0) availableTypes.push("warrior"); - if (seriesConfig.monsters.remote.length > 0) availableTypes.push("remote"); - if (seriesConfig.monsters.mage.length > 0) availableTypes.push("mage"); - - if (availableTypes.length > 0) { - const randomType = availableTypes[Math.floor(Math.random() * availableTypes.length)]; - const typeMonsters = seriesConfig.monsters[randomType]; - const randomMonster = typeMonsters[Math.floor(Math.random() * typeMonsters.length)]; - const monsterInfo = HeroInfo[randomMonster]; - - // 小怪没有词条 - const affixes = this.generateMonsterAffixes( - monsterInfo.quality, - waveNumber, - RogueWaveType.NORMAL // 小怪使用普通词条规则 - ); - - const enhanced = this.applyAffixesToMonster(affixes, monsterInfo); - - monsters.push({ - uuid: randomMonster, - count: 10, // 固定10个小怪 - type: "normal", - series: series, - affixes: affixes, - enhancedStats: enhanced.stats, - buffData: enhanced.buffData, - // 肉鸽固定数值 - rogueHp: RogueStatsConfig.getHp(waveNumber), - rogueAttack: RogueStatsConfig.getAttack(waveNumber) - }); - } + }); return { - waveType: RogueWaveType.ELITE, - monsters: monsters, - description: `第${waveNumber}波 - 精英波次 (5个精英+10个小怪)`, - waveNumber: waveNumber + name: baseConfig.name, + description: `${baseConfig.description} (${enhancementCount}个属性)`, + buffs: buffs, + buffList: buffList }; } /** - * 生成最终Boss波次(第9波) - */ - static generateFinalBossWave(waveNumber: number) { - const series = getRandomSeries(); - const seriesConfig = MonsterSeriesConfig[series]; - - // 查找Boss怪物 - const bossMonsters = seriesConfig.allMonsters.filter(uuid => { - return HeroInfo[uuid] && HeroInfo[uuid].quality === HQuality.PURPLE; - }); - - const bossMonster = bossMonsters.length > 0 ? - bossMonsters[Math.floor(Math.random() * bossMonsters.length)] : - seriesConfig.allMonsters[Math.floor(Math.random() * seriesConfig.allMonsters.length)]; - - const bossInfo = HeroInfo[bossMonster]; - - // 生成最终Boss词条 - const bossAffixes = this.generateMonsterAffixes( - bossInfo.quality, - waveNumber, - RogueWaveType.FINAL_BOSS - ); - - const enhancedBoss = this.applyAffixesToMonster(bossAffixes, bossInfo); - - // 1个Boss + 5个小怪 - const monsters = []; - - // 1. 添加Boss - monsters.push({ - uuid: bossMonster, - count: 1, - type: "final_boss", - series: series, - isFinalBoss: true, - affixes: bossAffixes, - enhancedStats: enhancedBoss.stats, - buffData: enhancedBoss.buffData, - // 肉鸽固定数值 - rogueHp: RogueStatsConfig.getHp(waveNumber), - rogueAttack: RogueStatsConfig.getAttack(waveNumber) - }); - - // 2. 添加5个小怪 - const availableTypes = []; - if (seriesConfig.monsters.warrior.length > 0) availableTypes.push("warrior"); - if (seriesConfig.monsters.remote.length > 0) availableTypes.push("remote"); - if (seriesConfig.monsters.mage.length > 0) availableTypes.push("mage"); - - if (availableTypes.length > 0) { - const randomType = availableTypes[Math.floor(Math.random() * availableTypes.length)]; - const typeMonsters = seriesConfig.monsters[randomType]; - const randomMonster = typeMonsters[Math.floor(Math.random() * typeMonsters.length)]; - const monsterInfo = HeroInfo[randomMonster]; - - // 小怪没有词条 - const affixes = this.generateMonsterAffixes( - monsterInfo.quality, - waveNumber, - RogueWaveType.NORMAL // 小怪使用普通词条规则 - ); - - const enhanced = this.applyAffixesToMonster(affixes, monsterInfo); - - monsters.push({ - uuid: randomMonster, - count: 5, // 固定5个小怪 - type: "normal", - series: series, - affixes: affixes, - enhancedStats: enhanced.stats, - buffData: enhanced.buffData, - // 肉鸽固定数值 - rogueHp: RogueStatsConfig.getHp(waveNumber), - rogueAttack: RogueStatsConfig.getAttack(waveNumber) - }); - } - - return { - waveType: RogueWaveType.FINAL_BOSS, - monsters: monsters, - description: `第${waveNumber}波 - 最终Boss战 (1个Boss+5个小怪)`, - waveNumber: waveNumber - }; - } - - /** - * 生成怪物词条(现在直接返回BuffAttr数组) - */ - static generateMonsterAffixes( - monsterQuality: number, - waveNumber: number, - waveType: RogueWaveType - ): BuffAttr[] { - const affixCount = AffixCountConfig.getAffixCount(waveType); - if (affixCount === 0) return []; - - const availableAffixes = Object.keys(MonsterAffixConfig).filter(affixType => { - const buffAttr = parseInt(affixType) as BuffAttr; - const config = MonsterAffixConfig[buffAttr]; - return config.applicableQualities.includes(monsterQuality); - }).map(key => parseInt(key) as BuffAttr); - - const selectedAffixes: BuffAttr[] = []; - - for (let i = 0; i < affixCount && availableAffixes.length > 0; i++) { - const randomIndex = Math.floor(Math.random() * availableAffixes.length); - const selectedAffix = availableAffixes[randomIndex]; - selectedAffixes.push(selectedAffix); - availableAffixes.splice(randomIndex, 1); - } - - return selectedAffixes; - } - - /** - * 应用词条到怪物(简化版本,主要用于日志显示) - */ - static applyAffixesToMonster(affixes: BuffAttr[], baseStats: any) { - const modifiedStats = { ...baseStats }; - const buffData = []; - - // 怪物能力提升倍数(3倍强化) - const enhancementMultiplier = 3; - - for (const affix of affixes) { - const config = MonsterAffixConfig[affix]; - if (config) { - // 应用3倍强化到配置值 - const enhancedValue = config.value * enhancementMultiplier; - - buffData.push({ - buff_type: affix, - value: enhancedValue // 使用强化后的值 - }); - - // 预览属性变化(实际应用在Mon.ts中) - switch (affix) { - case BuffAttr.ATK: - // 攻击力提升幅度加大,每波提升额外增加10%,再乘以3倍 - modifiedStats.ap = Math.floor(modifiedStats.ap * (1 + enhancedValue / 100 + baseStats.lv * 0.1 * enhancementMultiplier)); - break; - case BuffAttr.HP: - // 生命值提升幅度加大,每波提升额外增加15%,再乘以3倍 - modifiedStats.hp = Math.floor(modifiedStats.hp * (1 + enhancedValue / 100 + baseStats.lv * 0.15 * enhancementMultiplier)); - break; - case BuffAttr.ATK_CD: - // 攻击速度提升也应用3倍效果 - modifiedStats.cd = Math.max(0.1, modifiedStats.cd * (1 - enhancedValue / 100)); - break; - case BuffAttr.DEF: - // 防御力提升3倍效果 - modifiedStats.def = (modifiedStats.def || 0) + enhancedValue; - break; - case BuffAttr.CRITICAL: - // 暴击率提升3倍效果 - modifiedStats.crit = (modifiedStats.crit || 0) + enhancedValue; - break; - case BuffAttr.CRITICAL_DMG: - // 暴击伤害提升3倍效果 - modifiedStats.crit_d = (modifiedStats.crit_d || 0) + enhancedValue; - break; - case BuffAttr.DODGE: - // 闪避率提升3倍效果 - modifiedStats.dod = (modifiedStats.dod || 0) + enhancedValue; - break; - case BuffAttr.BURN_COUNT: - // 燃烧次数提升3倍效果 - modifiedStats.burn_count = (modifiedStats.burn_count || 0) + enhancedValue; - break; - case BuffAttr.PUNCTURE: - // 穿刺数量提升3倍效果 - modifiedStats.puncture = (modifiedStats.puncture || 0) + enhancedValue; - break; - case BuffAttr.FROST_RATIO: - // 冰冻概率提升3倍效果 - modifiedStats.frost_ratio = (modifiedStats.frost_ratio || 0) + enhancedValue; - break; - } - - console.log(`[RogueConfig]: 应用3倍强化词条 ${BuffAttr[affix]} - 原始值: ${config.value}% → 强化值: ${enhancedValue}%`); - } - } - - return { - stats: modifiedStats, - buffData: buffData, // 返回Buff数据格式,与Mon.ts兼容 - affixes: affixes - }; - } - - /** - * 获取怪物等级 - */ - static getMonsterLevel(waveNumber: number): number { - return Math.max(1, Math.floor(waveNumber / 1) + 1); + * 根据关卡号判断关卡类型 + * @param stageNumber 关卡号(从1开始) + * @returns 关卡类型 + */ +export function getStageType(stageNumber: number): StageType { + if (stageNumber % 10 === 0) { + return StageType.BOSS; // 每10关为Boss关 + } else if (stageNumber % 5 === 0) { + return StageType.ELITE; // 每5关(非10的倍数)为精英关 + } else { + return StageType.NORMAL; // 其他关卡为普通关 } } -// ==================== 导出接口 ==================== +/** + * 生成关卡配置 + * @param stageNumber 关卡号(从1开始) + * @returns MonsterType数组格式 + */ +export function generateStageConfig(stageNumber: number): MonsterType[] { + const stageType = getStageType(stageNumber); + const rule = StageConfigRules[stageType]; + const monsterArray: MonsterType[] = []; + + // 根据配置生成怪物类型数组 + rule.monsters.forEach(monsterGroup => { + for (let i = 0; i < monsterGroup.count; i++) { + monsterArray.push(monsterGroup.type); + } + }); + + return monsterArray; +} /** - * 外部调用接口 - 获取波次配置 + * 根据怪物类型获取对应品质的怪物UUID数组 + * @param monsterType 怪物类型 + * @returns 怪物UUID数组 */ -export const getRogueWaveConfig = (waveNumber: number) => { - return RogueConfig.generateWaveConfig(waveNumber); -}; \ No newline at end of file +export function getMonsterUUIDsByType(monsterType: MonsterType): number[] { + switch (monsterType) { + case MonsterType.NORMAL: + return getMonList(HQuality.GREEN); // 绿色品质为普通怪物 + case MonsterType.ELITE: + return getMonList(HQuality.BLUE); // 蓝色品质为精英怪物 + case MonsterType.BOSS: + // 紫色及以上品质为Boss怪物 + const purpleMonsters = getMonList(HQuality.PURPLE); + const orangeMonsters = getMonList(HQuality.ORANGE); + return [...purpleMonsters, ...orangeMonsters]; + default: + return []; + } +} + +/** + * 获取当前关卡对应的所有怪物UUID数组 + * @param stageNumber 关卡号 + * @returns 怪物UUID数组,按关卡配置顺序排列 + */ +export function getStageMonsterUUIDs(stageNumber: number): number[] { + const monsterTypes = generateStageConfig(stageNumber); + const monsterUUIDs: number[] = []; + + monsterTypes.forEach(monsterType => { + const availableUUIDs = getMonsterUUIDsByType(monsterType); + if (availableUUIDs.length > 0) { + // 随机选择一个该类型的怪物 + const randomUUID = availableUUIDs[Math.floor(Math.random() * availableUUIDs.length)]; + monsterUUIDs.push(randomUUID); + } + }); + + return monsterUUIDs; +} + +/** + * 获取关卡怪物配置(包含UUID和增强属性) + * @param stageNumber 关卡号 + * @param useRandomBuff 是否使用随机buff + * @returns 完整的怪物配置数组 + */ +export function getStageMonsterConfigs(stageNumber: number, useRandomBuff: boolean = true) { + const monsterTypes = generateStageConfig(stageNumber); + const stageMultipliers = getStageAllMultipliers(stageNumber); + const monsterConfigs = []; + + monsterTypes.forEach((monsterType, index) => { + const availableUUIDs = getMonsterUUIDsByType(monsterType); + if (availableUUIDs.length > 0) { + const randomUUID = availableUUIDs[Math.floor(Math.random() * availableUUIDs.length)]; + const enhancement = getMonsterEnhancement(monsterType, useRandomBuff); + + monsterConfigs.push({ + id: `stage_${stageNumber}_${index}`, + uuid: randomUUID, + type: monsterType, + stageNumber: stageNumber, + enhancement: enhancement, + stageMultipliers: stageMultipliers + }); + } + }); + + return monsterConfigs; +} + +/** + * 关卡基础属性倍数配置 + */ +export const StageMultiplierConfig = { + // 每级提升的基础倍数 + baseMultiplierPerLevel: 0.05, // 每级基础属性提升5% + + // 每10级的大幅提升倍数 + bigBoostMultiplier: 0.3, // 每10级额外提升30% + + // 不同属性的提升权重 + attributeWeights: { + hp: 1.2, // 生命值提升权重较高 + attack: 1.0, // 攻击力标准权重 + } +}; + +/** + * 计算关卡的基础属性倍数 + * @param stageNumber 关卡号(从1开始) + * @param attributeType 属性类型(hp, attack) + * @returns 属性倍数 + */ +export function calculateStageMultiplier(stageNumber: number, attributeType: 'hp' | 'attack'): number { + const config = StageMultiplierConfig; + + // 基础倍数:1.0(第1关不变) + let multiplier = 1.0; + + // 每级小提升:(关卡-1) * 每级提升率 * 属性权重 + const levelBoost = (stageNumber - 1) * config.baseMultiplierPerLevel * config.attributeWeights[attributeType]; + + // 每10级大提升:向下取整(关卡/10) * 大幅提升率 * 属性权重 + const bigBoostCount = Math.floor(stageNumber / 10); + const bigBoost = bigBoostCount * config.bigBoostMultiplier * config.attributeWeights[attributeType]; + + multiplier += levelBoost + bigBoost; + + return multiplier; +} + +/** + * 获取关卡所有属性的倍数 + * @param stageNumber 关卡号 + * @returns 所有属性倍数对象 + */ +export function getStageAllMultipliers(stageNumber: number) { + return { + stageNumber: stageNumber, + hp: calculateStageMultiplier(stageNumber, 'hp'), + attack: calculateStageMultiplier(stageNumber, 'attack'), + description: `第${stageNumber}关基础属性倍数` + }; +} +