48 Commits

Author SHA1 Message Date
f359eae788 docs(Design): 添加非关键成长三选一的设计文档
补充非关键成长系统的详细设计,包括选项池、数值范围、阶段建议和实现参考
2025-11-28 16:54:46 +08:00
d3ca31fcfa ui变动 2025-11-28 16:14:38 +08:00
509539760d refactor(hero): 优化调试日志输出并添加调试工具方法
添加条件日志方法 debugLog 和 debugWarn 来统一管理调试输出
将 HeroAtkSystem 中的 console.log 调用改为条件输出
启用 HeroViewComp 的调试模式以便开发时查看日志
2025-11-28 10:29:54 +08:00
7a7a6fa02c fix(战斗系统): 修复伤害数值出错问题
- 修复在DamageEvent接口和DamageQueueComp缺少ext_dmg和dmg_ratio字段问题
- 修复HeroAtkSystem的伤害计算逻辑
- 优化HeroViewComp的hp_show和mp_show方法,直接使用model数据
- 默认显示血条并增加调试日志输出
- 移除冗余的debug日志,优化伤害计算流程
2025-11-28 09:59:01 +08:00
40c430546c feat(英雄系统): 添加击杀计数并优化攻击系统变量命名
添加英雄击杀计数功能,用于统计英雄击杀敌人数量
优化HeroAtkSystem中变量命名,将attackerTAttrsComp改为更清晰的CAttrsComp
修复荆棘伤害可能导致英雄死亡时未触发死亡表现的问题
2025-11-27 16:31:22 +08:00
b2cc25b32b feat(战斗系统): 添加反伤机制并优化属性变量命名
添加新的技能配置5000(反伤)和实现反伤逻辑
将targetAttrs统一重命名为TAttrsComp以提高代码一致性
2025-11-27 16:12:23 +08:00
0692d58e01 refactor(天赋系统): 重构天赋效果枚举和属性处理逻辑
- 重新组织TalEffet枚举,按功能分类并添加注释说明
- 移除冗余的DMG_RED属性
- 为HeroAttrsComp添加详细的JSDoc注释
- 优化天赋buff处理方法,区分数值型和计数型天赋
2025-11-27 16:12:12 +08:00
cdfcf1f8f1 refactor(HeroAtkSystem): 移除未使用的DamageQueueHelper导入 2025-11-27 10:49:26 +08:00
dcf739d093 refactor(战斗系统): 重构伤害计算逻辑并统一属性命名
- 将DAMAGE_REDUCTION统一重命名为DMG_RED以提高一致性
- 优化暴击判定逻辑,加入暴击抗性计算
- 重构伤害计算公式,整合易伤和免伤效果
- 移除冗余的calculateDamage方法
- 为枚举值添加注释说明
2025-11-27 10:19:54 +08:00
bbf8dbb8cb refactor(战斗系统): 统一伤害减免属性命名并优化伤害计算逻辑
- 将LDMG枚举值重命名为DAMAGE_REDUCTION以提高可读性
- 修改HeroAtkSystem中的dmgCount方法,直接接收HeroAttrsComp参数
- 在伤害计算中整合天赋系统的伤害减免效果
2025-11-26 16:35:44 +08:00
df3ad88c3e fix(英雄属性): 修复MP更新时视图未同步的问题
修改HeroAttrsComp在更新MP值时调用HeroViewComp的mp_add方法同步视图
重命名HeroViewComp的mp方法为mp_add以更准确描述其功能
移除HeroViewComp中未使用的pow_show方法
2025-11-26 10:14:06 +08:00
ab4d29d42b refactor(GameEvent): 移除未使用的HeroSpeek事件枚举
清理代码中未使用的事件枚举,保持事件列表简洁
2025-11-26 10:09:17 +08:00
9c33bb0f7b feat(技能提示): 添加MP恢复提示功能
添加MP恢复提示类型到TooltipTypes枚举
在TooltipCom组件中实现MP恢复提示的显示逻辑
更新tooltip.prefab结构以支持MP恢复提示
移除未使用的tooltip.prefab.meta文件
移除英雄prefab中的tooltip 说话节点
2025-11-26 10:07:21 +08:00
b965c88961 feat(英雄属性): 添加HP/MP基础属性管理方法并移除health方法冗余参数
添加add_hp、add_mp和add_shield方法用于管理英雄基础属性
移除HeroViewComp.health方法中不再使用的is_num参数
恢复TalComp中HP和MP天赋效果的处理逻辑
2025-11-25 16:45:05 +08:00
b73d756106 refactor(hero): 移除怒气值相关属性和逻辑,修改hp显示逻辑
移除英雄属性组件中的怒气值(pow)属性及相关配置
删除英雄视图组件中怒气值显示和使用的逻辑
简化资源管理,移除不再使用的代码
2025-11-25 16:35:35 +08:00
3edc69deff refactor(skill): 移除溅射伤害设定,溅射以后有特定技能触发
清理不再使用的溅射伤害功能,包括移除SDataCom中的splash字段、Skill和SACastSystem中的相关参数,
以及删除TalSet中的溅射天赋配置
2025-11-25 15:24:38 +08:00
03a8a41980 feat(战斗系统): 添加伤害比例属性并应用到伤害计算
在SDataCom中添加dmg_ratio属性用于调整伤害比例
修改HeroAtkSystem中的伤害计算公式,将dmg_ratio纳入计算
2025-11-24 16:58:13 +08:00
91c18004eb feat(技能系统): 添加额外伤害和溅射伤害功能
在技能组件中新增ext_dmg和splash字段用于处理额外伤害和溅射伤害
修改技能创建和伤害计算逻辑以支持新功能
2025-11-24 16:58:04 +08:00
6df4abadd1 feat(战斗系统): 添加必杀技能类型并优化天赋触发逻辑
- 在TriType枚举中添加MAX类型用于必杀技能触发
- 重构SACastSystem中的技能处理逻辑,将普通攻击、技能和必杀技能分开处理
- 优化天赋触发条件判断,确保不同类型技能触发正确的天赋效果
- 调整技能动画播放和伤害计算逻辑,使风怒和双技能天赋能正确生效
2025-11-24 15:52:28 +08:00
8d2ec76b01 feat(战斗系统): 实现攻击和技能伤害加成天赋效果
添加ATK_DMG和SKILL_DMG天赋类型,支持在普通攻击和技能释放时应用额外伤害
修改SACastSystem以处理不同类型的伤害加成
重构TalEffet枚举并更新相关配置
2025-11-24 15:39:05 +08:00
4ed531e100 refactor(hero): 重命名天赋相关方法以区分计数型和数值型
将计数型天赋操作方法从addTalent/consumeTalent重命名为addCountTal/useCountTal
将数值型天赋操作方法从addTalBuff/clearTalBuff重命名为addValueTal/useValueTalByUuid
更新相关文档和调用代码以保持一致性
2025-11-24 10:27:38 +08:00
aefe3d6d06 refactor(战斗系统): 重构伤害计算逻辑并完善注释
重构 HeroAtkSystem 中的伤害计算方法,将基础伤害计算升级为详细的伤害计算流程
新增 applyPR 方法的详细注释,说明其计算公式和使用场景
优化代码结构,添加计算步骤的注释说明
2025-11-21 10:36:54 +08:00
2dc43b5b81 refactor(HeroAtkSystem): 重构伤害计算逻辑以提高可维护性
将原有的伤害计算逻辑拆分为更清晰的步骤,引入applyPR方法统一处理伤害加成和抗性计算
根据技能类型(DType)应用对应的元素伤害计算
使用防御和魔防的百分比减免公式替代原有的固定值减免
2025-11-21 10:28:14 +08:00
58fa6527ee feat(战斗系统): 扩展战斗属性配置和元素伤害类型
- 在GameSet.ts中添加物理和魔法防御常数
- 在SkillSet.ts中细化元素伤害类型并移除冗余字段
- 在HeroAttrs.ts中重构抗性和伤害加成属性,增加物理和魔法相关属性
2025-11-21 10:24:39 +08:00
df23e3787d feat(战斗系统): 完善伤害计算逻辑并添加元素伤害支持
修改 HeroAtkSystem 的 dmgCount 方法,增加目标属性参数并实现完整的伤害计算逻辑,包括物理/魔法伤害区分、防御减免和元素伤害计算。同时在 SkillSet 配置中新增 map 属性和元素伤害配置,支持冰/火/风三种元素伤害类型。
2025-11-21 10:23:35 +08:00
8a0cfb78dd refactor(combat): 重构战斗系统伤害计算逻辑并完善文档
- 将getNeAttrs函数移动到更合理的位置
- 重构伤害计算逻辑,明确区分施法者和被攻击者属性使用
- 完善接口和核心方法的文档注释
- 修正暴击伤害计算错误,使用施法者暴击伤害属性
- 优化闪避判定公式,考虑施法者命中率
2025-11-21 09:18:49 +08:00
3990799046 refactor: 移除废弃脚本并迁移ECS文档至assets目录
删除不再使用的update-oops-plugin-framework.bat脚本
将ecs.md文档从根目录迁移至assets/script目录并更新内容
2025-11-20 16:54:15 +08:00
1c49649c00 refactor(hero): 重构英雄攻击系统并重命名文件 2025-11-20 16:48:23 +08:00
51f32b1d29 refactor(战斗系统): 重构攻击处理逻辑并优化击退机制
- 将闪避、暴击和击退的概率检查统一为checkChance方法
- 移除HeroAtkComp类并清理无用代码
- 新增clearTalBuffByAttr方法用于清除特定属性的天赋buff
- 修改HeroViewComp.do_atked方法支持可选击退参数
- 移除Attrs.BACK属性及相关配置
2025-11-20 16:48:14 +08:00
b4fd807ddc feat(天赋系统): 添加天赋执行次数功能并实现必暴效果
为天赋系统添加count字段控制执行次数,并实现C_ATK、C_SKILL、C_MSKILL三种必暴效果类型
2025-11-20 16:22:36 +08:00
ff4ce76482 fix: 修复技能属性引用问题并移除无用代码
- 在Skill.ts中修改Attrs为浅拷贝避免引用问题
- 移除HeroAtk.ts中未使用的casterModel变量
2025-11-20 15:19:27 +08:00
8113ec671f refactor(技能系统): 统一额外伤害参数命名从exr_dmg改为ext_dmg
修改Skill.ts和SACastSystem.ts中的参数命名,保持代码一致性
2025-11-20 15:11:59 +08:00
5a81704379 refactor(hero): 重构天赋系统使用统一管理方式
- 将分散的天赋属性管理改为统一的Talents记录
- 添加addTalent和consumeTalent方法来管理天赋状态
- 修改技能系统使用新的天赋管理接口
2025-11-20 14:51:26 +08:00
f2ec48bd2b feat(天赋系统): 重构天赋buff处理逻辑并添加vType支持
- 在TalSlot接口和talConf配置中添加vType字段区分数值型和百分比型buff
- 重构HeroAttrsComp中BUFFS_TAL数据结构,改为以天赋uuid为key的映射
- 实现新的addTalBuff和clearTalBuff方法处理天赋buff
- 在TalComp中添加BUFF类型天赋的触发处理
2025-11-20 14:35:29 +08:00
94d5aa8920 refactor(hero): 重构天赋触发机制和属性类型
将天赋触发值从布尔类型改为数值类型以支持更灵活的触发条件
修改天赋配置描述和数值以更准确反映效果
优化天赋触发逻辑,支持同时检查多个天赋
添加天赋触发后的具体效果处理
2025-11-19 16:51:36 +08:00
bcaa377cf6 refactor(英雄技能): 重构天赋触发逻辑和技能施放系统
- 将HeroAttrsComp中的isDSill和isWFuny改为talTrigger结构体
- 移除TalComp中不再使用的checkTriggers和checkIsTrigger方法
- 优化SACastSystem中的技能施放逻辑,分离天赋处理代码块
- 为Skill.load方法添加damage参数
- 重命名executeCast返回变量为castSucess以提高可读性
2025-11-19 16:03:19 +08:00
e577ed976c feat(技能系统): 添加目标数量配置并优化目标选择逻辑
- 在SkillSet枚举中添加t_num字段用于配置技能目标数量
- 修改sTargets方法,根据技能配置中的t_num确定最大目标数量
- 重构findNearbyEnemies方法,实现基于距离和位置偏差的目标排序
- 添加对技能范围配置的灵活处理,支持range和dis字段
2025-11-19 15:39:57 +08:00
209d550e87 fix(SACastSystem): 修复技能目标选择逻辑并添加默认值
当sDamageTargets未找到目标时,回退到使用sDefaultTargets获取默认目标
同时为createSkill方法的isWFuny参数添加默认值false
2025-11-19 15:37:34 +08:00
5935b20094 refactor(game): 统一游戏地平线高度并优化技能目标选择
将GameSet中的GAME_LINE从0调整为120,并在英雄和怪物位置配置中使用该常量
简化SACastSystem中的目标选择逻辑,移除未使用的治疗和BUFF目标选择方法
使用BoxSet.GAME_LINE作为技能目标的默认Y坐标
2025-11-19 14:59:50 +08:00
78ac2e949f feat(英雄系统): 优化天赋触发机制和技能施放逻辑
重构HeroAttrsComp组件结构,新增天赋触发相关属性
调整SACastSystem技能施放逻辑,支持风怒和双施天赋效果
删除无用的SCastSystem.ts.meta文件
2025-11-19 11:18:11 +08:00
9f809b1ffa feat(技能系统): 添加最大技能自动施放开关并重构施法逻辑
- 在HeroSkillsComp中添加max_auto字段控制最大技能自动施放
- 重构SACastSystem的施法逻辑,增加返回值判断
- 新增manualCast和manualCastMax方法支持手动施法
- 删除废弃的SCastSystem文件
2025-11-19 10:34:37 +08:00
e42bdbb671 refactor(天赋系统): 优化天赋触发逻辑和代码结构
重构 TalComp 类的触发检查方法,将 checkIsTrigger 拆分为 getTriggers 和 checkIsTrigger
简化 SACastSystem 中的天赋触发判断逻辑,使用新的 checkIsTrigger 返回值
2025-11-19 10:34:15 +08:00
9798930879 feat(技能系统): 添加技能类型枚举并重构天赋系统
- 在SkillSet.ts中新增HSSet枚举区分普通攻击、技能和必杀技
- 重构TalSet.ts中的天赋效果枚举,移除N_ATK和N_SKILL类型
- 在HeroSkillsComp中增加hset字段标识技能类型
- 修改SACastSystem以支持根据技能类型触发不同天赋
- 完全重写TalComp组件,实现更完善的天赋触发和效果管理
2025-11-18 23:54:25 +08:00
7b067213c0 feat(天赋系统): 重构天赋系统并添加新天赋效果
- 重构天赋类型和效果枚举,简化触发条件分类
- 添加天赋buff数组支持叠加效果计算
- 实现多种新天赋效果包括风怒、溅射、护盾等
- 修改熟练天赋触发条件从3次改为10次攻击
2025-11-18 16:46:13 +08:00
ab8bb01dee refactor(配置): 重构英雄属性和天赋系统配置
- 将HeroAttrs中的KNOCKBACK和CHAIN_CHANCE重命名为BACK_CHANCE和SILENCE_CHANCE以保持命名一致性
- 简化TalSet.ts中的天赋配置接口,移除冗余字段并优化结构
- 添加新的天赋配置示例
2025-11-18 13:44:44 +08:00
deb224b067 refactor(game): 重构天赋系统配置和组件逻辑
重构天赋系统配置,包括:
1. 调整天赋类型枚举和效果枚举
2. 移除旧的天赋配置数据
3. 简化天赋组件实现
4. 更新设计文档中的天赋描述

同时修正地图组件中的英雄位置坐标和缩放值
2025-11-18 11:00:18 +08:00
078787ccf2 docs(Design): 更新游戏设计文档中的战斗和天赋描述
更新战斗部分的结构,并重新组织天赋系统的描述,使其更清晰易读。修改了天赋触发条件和效果说明,保持文档与实际设计一致。
2025-11-18 08:41:25 +08:00
3daddd6935 docs(Design.md): 更新游戏设计文档,简化核心概念并添加战斗关键词
重写游戏设计文档,移除了详细机制描述,聚焦于核心玩法概念。新增战斗系统关键词定义,包括风怒、护盾、溅射等效果及其天赋增强机制。
2025-11-17 16:57:23 +08:00
42 changed files with 3158 additions and 4206 deletions

View File

@@ -29,31 +29,28 @@
},
{
"__id__": 37
},
{
"__id__": 46
}
],
"_active": true,
"_components": [
{
"__id__": 55
"__id__": 46
},
{
"__id__": 57
"__id__": 48
},
{
"__id__": 59
"__id__": 50
},
{
"__id__": 61
"__id__": 52
},
{
"__id__": 63
"__id__": 54
}
],
"_prefab": {
"__id__": 65
"__id__": 56
},
"_lpos": {
"__type__": "cc.Vec3",
@@ -674,10 +671,10 @@
"__id__": 37
},
"asset": {
"__uuid__": "5b4ca49e-0f12-4478-b56d-bf8198b36b90",
"__uuid__": "ae4493bd-cbcc-4392-921c-3e2b0fcd5338",
"__expectedType__": "cc.Prefab"
},
"fileId": "0d6ZXmA5dHkZxoGONDL2sE",
"fileId": "91yoyAQGNDm5ziI7NUChZ+",
"instance": {
"__id__": 39
},
@@ -685,7 +682,7 @@
},
{
"__type__": "cc.PrefabInstance",
"fileId": "fe79INE+JI1Jy2Hu0iKLMn",
"fileId": "08n1IzuupL3YNn2/tFvc8M",
"prefabRootNode": {
"__id__": 1
},
@@ -718,131 +715,6 @@
"propertyPath": [
"_name"
],
"value": "tooltip"
},
{
"__type__": "cc.TargetInfo",
"localID": [
"0d6ZXmA5dHkZxoGONDL2sE"
]
},
{
"__type__": "CCPropertyOverrideInfo",
"targetInfo": {
"__id__": 41
},
"propertyPath": [
"_lpos"
],
"value": {
"__type__": "cc.Vec3",
"x": 4.65,
"y": 129.718,
"z": 0
}
},
{
"__type__": "CCPropertyOverrideInfo",
"targetInfo": {
"__id__": 41
},
"propertyPath": [
"_lrot"
],
"value": {
"__type__": "cc.Quat",
"x": 0,
"y": 0,
"z": 0,
"w": 1
}
},
{
"__type__": "CCPropertyOverrideInfo",
"targetInfo": {
"__id__": 41
},
"propertyPath": [
"_euler"
],
"value": {
"__type__": "cc.Vec3",
"x": 0,
"y": 0,
"z": 0
}
},
{
"__type__": "CCPropertyOverrideInfo",
"targetInfo": {
"__id__": 41
},
"propertyPath": [
"_active"
],
"value": false
},
{
"__type__": "cc.Node",
"_objFlags": 0,
"_parent": {
"__id__": 1
},
"_prefab": {
"__id__": 47
},
"__editorExtras__": {}
},
{
"__type__": "cc.PrefabInfo",
"root": {
"__id__": 46
},
"asset": {
"__uuid__": "ae4493bd-cbcc-4392-921c-3e2b0fcd5338",
"__expectedType__": "cc.Prefab"
},
"fileId": "91yoyAQGNDm5ziI7NUChZ+",
"instance": {
"__id__": 48
},
"targetOverrides": null
},
{
"__type__": "cc.PrefabInstance",
"fileId": "08n1IzuupL3YNn2/tFvc8M",
"prefabRootNode": {
"__id__": 1
},
"mountedChildren": [],
"mountedComponents": [],
"propertyOverrides": [
{
"__id__": 49
},
{
"__id__": 51
},
{
"__id__": 52
},
{
"__id__": 53
},
{
"__id__": 54
}
],
"removedComponents": []
},
{
"__type__": "CCPropertyOverrideInfo",
"targetInfo": {
"__id__": 50
},
"propertyPath": [
"_name"
],
"value": "up"
},
{
@@ -854,7 +726,7 @@
{
"__type__": "CCPropertyOverrideInfo",
"targetInfo": {
"__id__": 50
"__id__": 41
},
"propertyPath": [
"_lpos"
@@ -869,7 +741,7 @@
{
"__type__": "CCPropertyOverrideInfo",
"targetInfo": {
"__id__": 50
"__id__": 41
},
"propertyPath": [
"_lrot"
@@ -885,7 +757,7 @@
{
"__type__": "CCPropertyOverrideInfo",
"targetInfo": {
"__id__": 50
"__id__": 41
},
"propertyPath": [
"_euler"
@@ -900,7 +772,7 @@
{
"__type__": "CCPropertyOverrideInfo",
"targetInfo": {
"__id__": 50
"__id__": 41
},
"propertyPath": [
"_active"
@@ -917,7 +789,7 @@
},
"_enabled": true,
"__prefab": {
"__id__": 56
"__id__": 47
},
"_contentSize": {
"__type__": "cc.Size",
@@ -945,7 +817,7 @@
},
"_enabled": true,
"__prefab": {
"__id__": 58
"__id__": 49
},
"anm": {
"__id__": 5
@@ -960,12 +832,13 @@
"__type__": "873f8d+SolMEo8DiTTxZRh4",
"_name": "",
"_objFlags": 0,
"__editorExtras__": {},
"node": {
"__id__": 1
},
"_enabled": true,
"__prefab": {
"__id__": 60
"__id__": 51
},
"_id": ""
},
@@ -983,7 +856,7 @@
},
"_enabled": true,
"__prefab": {
"__id__": 62
"__id__": 53
},
"enabledContactListener": true,
"bullet": false,
@@ -1017,7 +890,7 @@
},
"_enabled": true,
"__prefab": {
"__id__": 64
"__id__": 55
},
"tag": 0,
"_group": 4,
@@ -1053,9 +926,6 @@
"instance": null,
"targetOverrides": null,
"nestedPrefabInstanceRoots": [
{
"__id__": 46
},
{
"__id__": 37
},

View File

@@ -29,31 +29,28 @@
},
{
"__id__": 37
},
{
"__id__": 46
}
],
"_active": true,
"_components": [
{
"__id__": 55
"__id__": 46
},
{
"__id__": 57
"__id__": 48
},
{
"__id__": 59
"__id__": 50
},
{
"__id__": 61
"__id__": 52
},
{
"__id__": 63
"__id__": 54
}
],
"_prefab": {
"__id__": 65
"__id__": 56
},
"_lpos": {
"__type__": "cc.Vec3",
@@ -674,10 +671,10 @@
"__id__": 37
},
"asset": {
"__uuid__": "5b4ca49e-0f12-4478-b56d-bf8198b36b90",
"__uuid__": "ae4493bd-cbcc-4392-921c-3e2b0fcd5338",
"__expectedType__": "cc.Prefab"
},
"fileId": "0d6ZXmA5dHkZxoGONDL2sE",
"fileId": "91yoyAQGNDm5ziI7NUChZ+",
"instance": {
"__id__": 39
},
@@ -685,7 +682,7 @@
},
{
"__type__": "cc.PrefabInstance",
"fileId": "fe79INE+JI1Jy2Hu0iKLMn",
"fileId": "08n1IzuupL3YNn2/tFvc8M",
"prefabRootNode": {
"__id__": 1
},
@@ -718,131 +715,6 @@
"propertyPath": [
"_name"
],
"value": "tooltip"
},
{
"__type__": "cc.TargetInfo",
"localID": [
"0d6ZXmA5dHkZxoGONDL2sE"
]
},
{
"__type__": "CCPropertyOverrideInfo",
"targetInfo": {
"__id__": 41
},
"propertyPath": [
"_lpos"
],
"value": {
"__type__": "cc.Vec3",
"x": 4.65,
"y": 129.718,
"z": 0
}
},
{
"__type__": "CCPropertyOverrideInfo",
"targetInfo": {
"__id__": 41
},
"propertyPath": [
"_lrot"
],
"value": {
"__type__": "cc.Quat",
"x": 0,
"y": 0,
"z": 0,
"w": 1
}
},
{
"__type__": "CCPropertyOverrideInfo",
"targetInfo": {
"__id__": 41
},
"propertyPath": [
"_euler"
],
"value": {
"__type__": "cc.Vec3",
"x": 0,
"y": 0,
"z": 0
}
},
{
"__type__": "CCPropertyOverrideInfo",
"targetInfo": {
"__id__": 41
},
"propertyPath": [
"_active"
],
"value": false
},
{
"__type__": "cc.Node",
"_objFlags": 0,
"_parent": {
"__id__": 1
},
"_prefab": {
"__id__": 47
},
"__editorExtras__": {}
},
{
"__type__": "cc.PrefabInfo",
"root": {
"__id__": 46
},
"asset": {
"__uuid__": "ae4493bd-cbcc-4392-921c-3e2b0fcd5338",
"__expectedType__": "cc.Prefab"
},
"fileId": "91yoyAQGNDm5ziI7NUChZ+",
"instance": {
"__id__": 48
},
"targetOverrides": null
},
{
"__type__": "cc.PrefabInstance",
"fileId": "08n1IzuupL3YNn2/tFvc8M",
"prefabRootNode": {
"__id__": 1
},
"mountedChildren": [],
"mountedComponents": [],
"propertyOverrides": [
{
"__id__": 49
},
{
"__id__": 51
},
{
"__id__": 52
},
{
"__id__": 53
},
{
"__id__": 54
}
],
"removedComponents": []
},
{
"__type__": "CCPropertyOverrideInfo",
"targetInfo": {
"__id__": 50
},
"propertyPath": [
"_name"
],
"value": "up"
},
{
@@ -854,7 +726,7 @@
{
"__type__": "CCPropertyOverrideInfo",
"targetInfo": {
"__id__": 50
"__id__": 41
},
"propertyPath": [
"_lpos"
@@ -869,7 +741,7 @@
{
"__type__": "CCPropertyOverrideInfo",
"targetInfo": {
"__id__": 50
"__id__": 41
},
"propertyPath": [
"_lrot"
@@ -885,7 +757,7 @@
{
"__type__": "CCPropertyOverrideInfo",
"targetInfo": {
"__id__": 50
"__id__": 41
},
"propertyPath": [
"_euler"
@@ -900,7 +772,7 @@
{
"__type__": "CCPropertyOverrideInfo",
"targetInfo": {
"__id__": 50
"__id__": 41
},
"propertyPath": [
"_active"
@@ -917,7 +789,7 @@
},
"_enabled": true,
"__prefab": {
"__id__": 56
"__id__": 47
},
"_contentSize": {
"__type__": "cc.Size",
@@ -945,7 +817,7 @@
},
"_enabled": true,
"__prefab": {
"__id__": 58
"__id__": 49
},
"anm": {
"__id__": 5
@@ -960,12 +832,13 @@
"__type__": "873f8d+SolMEo8DiTTxZRh4",
"_name": "",
"_objFlags": 0,
"__editorExtras__": {},
"node": {
"__id__": 1
},
"_enabled": true,
"__prefab": {
"__id__": 60
"__id__": 51
},
"_id": ""
},
@@ -983,7 +856,7 @@
},
"_enabled": true,
"__prefab": {
"__id__": 62
"__id__": 53
},
"enabledContactListener": true,
"bullet": false,
@@ -1017,7 +890,7 @@
},
"_enabled": true,
"__prefab": {
"__id__": 64
"__id__": 55
},
"tag": 0,
"_group": 4,
@@ -1053,9 +926,6 @@
"instance": null,
"targetOverrides": null,
"nestedPrefabInstanceRoots": [
{
"__id__": 46
},
{
"__id__": 37
},

View File

@@ -29,31 +29,28 @@
},
{
"__id__": 37
},
{
"__id__": 46
}
],
"_active": true,
"_components": [
{
"__id__": 55
"__id__": 46
},
{
"__id__": 57
"__id__": 48
},
{
"__id__": 59
"__id__": 50
},
{
"__id__": 61
"__id__": 52
},
{
"__id__": 63
"__id__": 54
}
],
"_prefab": {
"__id__": 65
"__id__": 56
},
"_lpos": {
"__type__": "cc.Vec3",
@@ -674,10 +671,10 @@
"__id__": 37
},
"asset": {
"__uuid__": "5b4ca49e-0f12-4478-b56d-bf8198b36b90",
"__uuid__": "ae4493bd-cbcc-4392-921c-3e2b0fcd5338",
"__expectedType__": "cc.Prefab"
},
"fileId": "0d6ZXmA5dHkZxoGONDL2sE",
"fileId": "91yoyAQGNDm5ziI7NUChZ+",
"instance": {
"__id__": 39
},
@@ -685,7 +682,7 @@
},
{
"__type__": "cc.PrefabInstance",
"fileId": "fe79INE+JI1Jy2Hu0iKLMn",
"fileId": "08n1IzuupL3YNn2/tFvc8M",
"prefabRootNode": {
"__id__": 1
},
@@ -718,131 +715,6 @@
"propertyPath": [
"_name"
],
"value": "tooltip"
},
{
"__type__": "cc.TargetInfo",
"localID": [
"0d6ZXmA5dHkZxoGONDL2sE"
]
},
{
"__type__": "CCPropertyOverrideInfo",
"targetInfo": {
"__id__": 41
},
"propertyPath": [
"_lpos"
],
"value": {
"__type__": "cc.Vec3",
"x": 4.65,
"y": 129.718,
"z": 0
}
},
{
"__type__": "CCPropertyOverrideInfo",
"targetInfo": {
"__id__": 41
},
"propertyPath": [
"_lrot"
],
"value": {
"__type__": "cc.Quat",
"x": 0,
"y": 0,
"z": 0,
"w": 1
}
},
{
"__type__": "CCPropertyOverrideInfo",
"targetInfo": {
"__id__": 41
},
"propertyPath": [
"_euler"
],
"value": {
"__type__": "cc.Vec3",
"x": 0,
"y": 0,
"z": 0
}
},
{
"__type__": "CCPropertyOverrideInfo",
"targetInfo": {
"__id__": 41
},
"propertyPath": [
"_active"
],
"value": false
},
{
"__type__": "cc.Node",
"_objFlags": 0,
"_parent": {
"__id__": 1
},
"_prefab": {
"__id__": 47
},
"__editorExtras__": {}
},
{
"__type__": "cc.PrefabInfo",
"root": {
"__id__": 46
},
"asset": {
"__uuid__": "ae4493bd-cbcc-4392-921c-3e2b0fcd5338",
"__expectedType__": "cc.Prefab"
},
"fileId": "91yoyAQGNDm5ziI7NUChZ+",
"instance": {
"__id__": 48
},
"targetOverrides": null
},
{
"__type__": "cc.PrefabInstance",
"fileId": "08n1IzuupL3YNn2/tFvc8M",
"prefabRootNode": {
"__id__": 1
},
"mountedChildren": [],
"mountedComponents": [],
"propertyOverrides": [
{
"__id__": 49
},
{
"__id__": 51
},
{
"__id__": 52
},
{
"__id__": 53
},
{
"__id__": 54
}
],
"removedComponents": []
},
{
"__type__": "CCPropertyOverrideInfo",
"targetInfo": {
"__id__": 50
},
"propertyPath": [
"_name"
],
"value": "up"
},
{
@@ -854,7 +726,7 @@
{
"__type__": "CCPropertyOverrideInfo",
"targetInfo": {
"__id__": 50
"__id__": 41
},
"propertyPath": [
"_lpos"
@@ -869,7 +741,7 @@
{
"__type__": "CCPropertyOverrideInfo",
"targetInfo": {
"__id__": 50
"__id__": 41
},
"propertyPath": [
"_lrot"
@@ -885,7 +757,7 @@
{
"__type__": "CCPropertyOverrideInfo",
"targetInfo": {
"__id__": 50
"__id__": 41
},
"propertyPath": [
"_euler"
@@ -900,7 +772,7 @@
{
"__type__": "CCPropertyOverrideInfo",
"targetInfo": {
"__id__": 50
"__id__": 41
},
"propertyPath": [
"_active"
@@ -917,7 +789,7 @@
},
"_enabled": true,
"__prefab": {
"__id__": 56
"__id__": 47
},
"_contentSize": {
"__type__": "cc.Size",
@@ -945,7 +817,7 @@
},
"_enabled": true,
"__prefab": {
"__id__": 58
"__id__": 49
},
"anm": {
"__id__": 5
@@ -960,12 +832,13 @@
"__type__": "873f8d+SolMEo8DiTTxZRh4",
"_name": "",
"_objFlags": 0,
"__editorExtras__": {},
"node": {
"__id__": 1
},
"_enabled": true,
"__prefab": {
"__id__": 60
"__id__": 51
},
"_id": ""
},
@@ -983,7 +856,7 @@
},
"_enabled": true,
"__prefab": {
"__id__": 62
"__id__": 53
},
"enabledContactListener": true,
"bullet": false,
@@ -1017,7 +890,7 @@
},
"_enabled": true,
"__prefab": {
"__id__": 64
"__id__": 55
},
"tag": 0,
"_group": 4,
@@ -1053,9 +926,6 @@
"instance": null,
"targetOverrides": null,
"nestedPrefabInstanceRoots": [
{
"__id__": 46
},
{
"__id__": 37
},

View File

@@ -29,31 +29,28 @@
},
{
"__id__": 37
},
{
"__id__": 46
}
],
"_active": true,
"_components": [
{
"__id__": 55
"__id__": 46
},
{
"__id__": 57
"__id__": 48
},
{
"__id__": 59
"__id__": 50
},
{
"__id__": 61
"__id__": 52
},
{
"__id__": 63
"__id__": 54
}
],
"_prefab": {
"__id__": 65
"__id__": 56
},
"_lpos": {
"__type__": "cc.Vec3",
@@ -674,10 +671,10 @@
"__id__": 37
},
"asset": {
"__uuid__": "5b4ca49e-0f12-4478-b56d-bf8198b36b90",
"__uuid__": "ae4493bd-cbcc-4392-921c-3e2b0fcd5338",
"__expectedType__": "cc.Prefab"
},
"fileId": "0d6ZXmA5dHkZxoGONDL2sE",
"fileId": "91yoyAQGNDm5ziI7NUChZ+",
"instance": {
"__id__": 39
},
@@ -685,7 +682,7 @@
},
{
"__type__": "cc.PrefabInstance",
"fileId": "fe79INE+JI1Jy2Hu0iKLMn",
"fileId": "08n1IzuupL3YNn2/tFvc8M",
"prefabRootNode": {
"__id__": 1
},
@@ -718,131 +715,6 @@
"propertyPath": [
"_name"
],
"value": "tooltip"
},
{
"__type__": "cc.TargetInfo",
"localID": [
"0d6ZXmA5dHkZxoGONDL2sE"
]
},
{
"__type__": "CCPropertyOverrideInfo",
"targetInfo": {
"__id__": 41
},
"propertyPath": [
"_lpos"
],
"value": {
"__type__": "cc.Vec3",
"x": 4.65,
"y": 129.718,
"z": 0
}
},
{
"__type__": "CCPropertyOverrideInfo",
"targetInfo": {
"__id__": 41
},
"propertyPath": [
"_lrot"
],
"value": {
"__type__": "cc.Quat",
"x": 0,
"y": 0,
"z": 0,
"w": 1
}
},
{
"__type__": "CCPropertyOverrideInfo",
"targetInfo": {
"__id__": 41
},
"propertyPath": [
"_euler"
],
"value": {
"__type__": "cc.Vec3",
"x": 0,
"y": 0,
"z": 0
}
},
{
"__type__": "CCPropertyOverrideInfo",
"targetInfo": {
"__id__": 41
},
"propertyPath": [
"_active"
],
"value": false
},
{
"__type__": "cc.Node",
"_objFlags": 0,
"_parent": {
"__id__": 1
},
"_prefab": {
"__id__": 47
},
"__editorExtras__": {}
},
{
"__type__": "cc.PrefabInfo",
"root": {
"__id__": 46
},
"asset": {
"__uuid__": "ae4493bd-cbcc-4392-921c-3e2b0fcd5338",
"__expectedType__": "cc.Prefab"
},
"fileId": "91yoyAQGNDm5ziI7NUChZ+",
"instance": {
"__id__": 48
},
"targetOverrides": null
},
{
"__type__": "cc.PrefabInstance",
"fileId": "08n1IzuupL3YNn2/tFvc8M",
"prefabRootNode": {
"__id__": 1
},
"mountedChildren": [],
"mountedComponents": [],
"propertyOverrides": [
{
"__id__": 49
},
{
"__id__": 51
},
{
"__id__": 52
},
{
"__id__": 53
},
{
"__id__": 54
}
],
"removedComponents": []
},
{
"__type__": "CCPropertyOverrideInfo",
"targetInfo": {
"__id__": 50
},
"propertyPath": [
"_name"
],
"value": "up"
},
{
@@ -854,7 +726,7 @@
{
"__type__": "CCPropertyOverrideInfo",
"targetInfo": {
"__id__": 50
"__id__": 41
},
"propertyPath": [
"_lpos"
@@ -869,7 +741,7 @@
{
"__type__": "CCPropertyOverrideInfo",
"targetInfo": {
"__id__": 50
"__id__": 41
},
"propertyPath": [
"_lrot"
@@ -885,7 +757,7 @@
{
"__type__": "CCPropertyOverrideInfo",
"targetInfo": {
"__id__": 50
"__id__": 41
},
"propertyPath": [
"_euler"
@@ -900,7 +772,7 @@
{
"__type__": "CCPropertyOverrideInfo",
"targetInfo": {
"__id__": 50
"__id__": 41
},
"propertyPath": [
"_active"
@@ -917,7 +789,7 @@
},
"_enabled": true,
"__prefab": {
"__id__": 56
"__id__": 47
},
"_contentSize": {
"__type__": "cc.Size",
@@ -945,7 +817,7 @@
},
"_enabled": true,
"__prefab": {
"__id__": 58
"__id__": 49
},
"anm": {
"__id__": 5
@@ -960,12 +832,13 @@
"__type__": "873f8d+SolMEo8DiTTxZRh4",
"_name": "",
"_objFlags": 0,
"__editorExtras__": {},
"node": {
"__id__": 1
},
"_enabled": true,
"__prefab": {
"__id__": 60
"__id__": 51
},
"_id": ""
},
@@ -983,7 +856,7 @@
},
"_enabled": true,
"__prefab": {
"__id__": 62
"__id__": 53
},
"enabledContactListener": false,
"bullet": false,
@@ -1017,7 +890,7 @@
},
"_enabled": true,
"__prefab": {
"__id__": 64
"__id__": 55
},
"tag": 0,
"_group": 4,
@@ -1053,9 +926,6 @@
"instance": null,
"targetOverrides": null,
"nestedPrefabInstanceRoots": [
{
"__id__": 46
},
{
"__id__": 37
},

View File

@@ -29,31 +29,28 @@
},
{
"__id__": 37
},
{
"__id__": 46
}
],
"_active": true,
"_components": [
{
"__id__": 55
"__id__": 46
},
{
"__id__": 57
"__id__": 48
},
{
"__id__": 59
"__id__": 50
},
{
"__id__": 61
"__id__": 52
},
{
"__id__": 63
"__id__": 54
}
],
"_prefab": {
"__id__": 65
"__id__": 56
},
"_lpos": {
"__type__": "cc.Vec3",
@@ -674,10 +671,10 @@
"__id__": 37
},
"asset": {
"__uuid__": "5b4ca49e-0f12-4478-b56d-bf8198b36b90",
"__uuid__": "ae4493bd-cbcc-4392-921c-3e2b0fcd5338",
"__expectedType__": "cc.Prefab"
},
"fileId": "0d6ZXmA5dHkZxoGONDL2sE",
"fileId": "91yoyAQGNDm5ziI7NUChZ+",
"instance": {
"__id__": 39
},
@@ -685,7 +682,7 @@
},
{
"__type__": "cc.PrefabInstance",
"fileId": "fe79INE+JI1Jy2Hu0iKLMn",
"fileId": "08n1IzuupL3YNn2/tFvc8M",
"prefabRootNode": {
"__id__": 1
},
@@ -718,131 +715,6 @@
"propertyPath": [
"_name"
],
"value": "tooltip"
},
{
"__type__": "cc.TargetInfo",
"localID": [
"0d6ZXmA5dHkZxoGONDL2sE"
]
},
{
"__type__": "CCPropertyOverrideInfo",
"targetInfo": {
"__id__": 41
},
"propertyPath": [
"_lpos"
],
"value": {
"__type__": "cc.Vec3",
"x": 4.65,
"y": 129.718,
"z": 0
}
},
{
"__type__": "CCPropertyOverrideInfo",
"targetInfo": {
"__id__": 41
},
"propertyPath": [
"_lrot"
],
"value": {
"__type__": "cc.Quat",
"x": 0,
"y": 0,
"z": 0,
"w": 1
}
},
{
"__type__": "CCPropertyOverrideInfo",
"targetInfo": {
"__id__": 41
},
"propertyPath": [
"_euler"
],
"value": {
"__type__": "cc.Vec3",
"x": 0,
"y": 0,
"z": 0
}
},
{
"__type__": "CCPropertyOverrideInfo",
"targetInfo": {
"__id__": 41
},
"propertyPath": [
"_active"
],
"value": false
},
{
"__type__": "cc.Node",
"_objFlags": 0,
"_parent": {
"__id__": 1
},
"_prefab": {
"__id__": 47
},
"__editorExtras__": {}
},
{
"__type__": "cc.PrefabInfo",
"root": {
"__id__": 46
},
"asset": {
"__uuid__": "ae4493bd-cbcc-4392-921c-3e2b0fcd5338",
"__expectedType__": "cc.Prefab"
},
"fileId": "91yoyAQGNDm5ziI7NUChZ+",
"instance": {
"__id__": 48
},
"targetOverrides": null
},
{
"__type__": "cc.PrefabInstance",
"fileId": "08n1IzuupL3YNn2/tFvc8M",
"prefabRootNode": {
"__id__": 1
},
"mountedChildren": [],
"mountedComponents": [],
"propertyOverrides": [
{
"__id__": 49
},
{
"__id__": 51
},
{
"__id__": 52
},
{
"__id__": 53
},
{
"__id__": 54
}
],
"removedComponents": []
},
{
"__type__": "CCPropertyOverrideInfo",
"targetInfo": {
"__id__": 50
},
"propertyPath": [
"_name"
],
"value": "up"
},
{
@@ -854,7 +726,7 @@
{
"__type__": "CCPropertyOverrideInfo",
"targetInfo": {
"__id__": 50
"__id__": 41
},
"propertyPath": [
"_lpos"
@@ -869,7 +741,7 @@
{
"__type__": "CCPropertyOverrideInfo",
"targetInfo": {
"__id__": 50
"__id__": 41
},
"propertyPath": [
"_lrot"
@@ -885,7 +757,7 @@
{
"__type__": "CCPropertyOverrideInfo",
"targetInfo": {
"__id__": 50
"__id__": 41
},
"propertyPath": [
"_euler"
@@ -900,7 +772,7 @@
{
"__type__": "CCPropertyOverrideInfo",
"targetInfo": {
"__id__": 50
"__id__": 41
},
"propertyPath": [
"_active"
@@ -917,7 +789,7 @@
},
"_enabled": true,
"__prefab": {
"__id__": 56
"__id__": 47
},
"_contentSize": {
"__type__": "cc.Size",
@@ -945,7 +817,7 @@
},
"_enabled": true,
"__prefab": {
"__id__": 58
"__id__": 49
},
"anm": {
"__id__": 5
@@ -960,12 +832,13 @@
"__type__": "873f8d+SolMEo8DiTTxZRh4",
"_name": "",
"_objFlags": 0,
"__editorExtras__": {},
"node": {
"__id__": 1
},
"_enabled": true,
"__prefab": {
"__id__": 60
"__id__": 51
},
"_id": ""
},
@@ -983,7 +856,7 @@
},
"_enabled": true,
"__prefab": {
"__id__": 62
"__id__": 53
},
"enabledContactListener": true,
"bullet": false,
@@ -1017,7 +890,7 @@
},
"_enabled": true,
"__prefab": {
"__id__": 64
"__id__": 55
},
"tag": 0,
"_group": 4,
@@ -1053,9 +926,6 @@
"instance": null,
"targetOverrides": null,
"nestedPrefabInstanceRoots": [
{
"__id__": 46
},
{
"__id__": 37
},

View File

@@ -29,31 +29,28 @@
},
{
"__id__": 37
},
{
"__id__": 46
}
],
"_active": true,
"_components": [
{
"__id__": 55
"__id__": 46
},
{
"__id__": 57
"__id__": 48
},
{
"__id__": 59
"__id__": 50
},
{
"__id__": 61
"__id__": 52
},
{
"__id__": 63
"__id__": 54
}
],
"_prefab": {
"__id__": 65
"__id__": 56
},
"_lpos": {
"__type__": "cc.Vec3",
@@ -674,10 +671,10 @@
"__id__": 37
},
"asset": {
"__uuid__": "5b4ca49e-0f12-4478-b56d-bf8198b36b90",
"__uuid__": "ae4493bd-cbcc-4392-921c-3e2b0fcd5338",
"__expectedType__": "cc.Prefab"
},
"fileId": "0d6ZXmA5dHkZxoGONDL2sE",
"fileId": "91yoyAQGNDm5ziI7NUChZ+",
"instance": {
"__id__": 39
},
@@ -685,7 +682,7 @@
},
{
"__type__": "cc.PrefabInstance",
"fileId": "fe79INE+JI1Jy2Hu0iKLMn",
"fileId": "08n1IzuupL3YNn2/tFvc8M",
"prefabRootNode": {
"__id__": 1
},
@@ -718,131 +715,6 @@
"propertyPath": [
"_name"
],
"value": "tooltip"
},
{
"__type__": "cc.TargetInfo",
"localID": [
"0d6ZXmA5dHkZxoGONDL2sE"
]
},
{
"__type__": "CCPropertyOverrideInfo",
"targetInfo": {
"__id__": 41
},
"propertyPath": [
"_lpos"
],
"value": {
"__type__": "cc.Vec3",
"x": 4.65,
"y": 129.718,
"z": 0
}
},
{
"__type__": "CCPropertyOverrideInfo",
"targetInfo": {
"__id__": 41
},
"propertyPath": [
"_lrot"
],
"value": {
"__type__": "cc.Quat",
"x": 0,
"y": 0,
"z": 0,
"w": 1
}
},
{
"__type__": "CCPropertyOverrideInfo",
"targetInfo": {
"__id__": 41
},
"propertyPath": [
"_euler"
],
"value": {
"__type__": "cc.Vec3",
"x": 0,
"y": 0,
"z": 0
}
},
{
"__type__": "CCPropertyOverrideInfo",
"targetInfo": {
"__id__": 41
},
"propertyPath": [
"_active"
],
"value": false
},
{
"__type__": "cc.Node",
"_objFlags": 0,
"_parent": {
"__id__": 1
},
"_prefab": {
"__id__": 47
},
"__editorExtras__": {}
},
{
"__type__": "cc.PrefabInfo",
"root": {
"__id__": 46
},
"asset": {
"__uuid__": "ae4493bd-cbcc-4392-921c-3e2b0fcd5338",
"__expectedType__": "cc.Prefab"
},
"fileId": "91yoyAQGNDm5ziI7NUChZ+",
"instance": {
"__id__": 48
},
"targetOverrides": null
},
{
"__type__": "cc.PrefabInstance",
"fileId": "08n1IzuupL3YNn2/tFvc8M",
"prefabRootNode": {
"__id__": 1
},
"mountedChildren": [],
"mountedComponents": [],
"propertyOverrides": [
{
"__id__": 49
},
{
"__id__": 51
},
{
"__id__": 52
},
{
"__id__": 53
},
{
"__id__": 54
}
],
"removedComponents": []
},
{
"__type__": "CCPropertyOverrideInfo",
"targetInfo": {
"__id__": 50
},
"propertyPath": [
"_name"
],
"value": "up"
},
{
@@ -854,7 +726,7 @@
{
"__type__": "CCPropertyOverrideInfo",
"targetInfo": {
"__id__": 50
"__id__": 41
},
"propertyPath": [
"_lpos"
@@ -869,7 +741,7 @@
{
"__type__": "CCPropertyOverrideInfo",
"targetInfo": {
"__id__": 50
"__id__": 41
},
"propertyPath": [
"_lrot"
@@ -885,7 +757,7 @@
{
"__type__": "CCPropertyOverrideInfo",
"targetInfo": {
"__id__": 50
"__id__": 41
},
"propertyPath": [
"_euler"
@@ -900,7 +772,7 @@
{
"__type__": "CCPropertyOverrideInfo",
"targetInfo": {
"__id__": 50
"__id__": 41
},
"propertyPath": [
"_active"
@@ -917,7 +789,7 @@
},
"_enabled": true,
"__prefab": {
"__id__": 56
"__id__": 47
},
"_contentSize": {
"__type__": "cc.Size",
@@ -945,7 +817,7 @@
},
"_enabled": true,
"__prefab": {
"__id__": 58
"__id__": 49
},
"anm": {
"__id__": 5
@@ -960,12 +832,13 @@
"__type__": "873f8d+SolMEo8DiTTxZRh4",
"_name": "",
"_objFlags": 0,
"__editorExtras__": {},
"node": {
"__id__": 1
},
"_enabled": true,
"__prefab": {
"__id__": 60
"__id__": 51
},
"_id": ""
},
@@ -983,7 +856,7 @@
},
"_enabled": true,
"__prefab": {
"__id__": 62
"__id__": 53
},
"enabledContactListener": true,
"bullet": false,
@@ -1017,7 +890,7 @@
},
"_enabled": true,
"__prefab": {
"__id__": 64
"__id__": 55
},
"tag": 0,
"_group": 4,
@@ -1053,9 +926,6 @@
"instance": null,
"targetOverrides": null,
"nestedPrefabInstanceRoots": [
{
"__id__": 46
},
{
"__id__": 37
},

View File

@@ -29,31 +29,28 @@
},
{
"__id__": 37
},
{
"__id__": 46
}
],
"_active": true,
"_components": [
{
"__id__": 55
"__id__": 46
},
{
"__id__": 57
"__id__": 48
},
{
"__id__": 59
"__id__": 50
},
{
"__id__": 61
"__id__": 52
},
{
"__id__": 63
"__id__": 54
}
],
"_prefab": {
"__id__": 65
"__id__": 56
},
"_lpos": {
"__type__": "cc.Vec3",
@@ -674,10 +671,10 @@
"__id__": 37
},
"asset": {
"__uuid__": "5b4ca49e-0f12-4478-b56d-bf8198b36b90",
"__uuid__": "ae4493bd-cbcc-4392-921c-3e2b0fcd5338",
"__expectedType__": "cc.Prefab"
},
"fileId": "0d6ZXmA5dHkZxoGONDL2sE",
"fileId": "91yoyAQGNDm5ziI7NUChZ+",
"instance": {
"__id__": 39
},
@@ -685,7 +682,7 @@
},
{
"__type__": "cc.PrefabInstance",
"fileId": "fe79INE+JI1Jy2Hu0iKLMn",
"fileId": "08n1IzuupL3YNn2/tFvc8M",
"prefabRootNode": {
"__id__": 1
},
@@ -718,131 +715,6 @@
"propertyPath": [
"_name"
],
"value": "tooltip"
},
{
"__type__": "cc.TargetInfo",
"localID": [
"0d6ZXmA5dHkZxoGONDL2sE"
]
},
{
"__type__": "CCPropertyOverrideInfo",
"targetInfo": {
"__id__": 41
},
"propertyPath": [
"_lpos"
],
"value": {
"__type__": "cc.Vec3",
"x": 4.65,
"y": 129.718,
"z": 0
}
},
{
"__type__": "CCPropertyOverrideInfo",
"targetInfo": {
"__id__": 41
},
"propertyPath": [
"_lrot"
],
"value": {
"__type__": "cc.Quat",
"x": 0,
"y": 0,
"z": 0,
"w": 1
}
},
{
"__type__": "CCPropertyOverrideInfo",
"targetInfo": {
"__id__": 41
},
"propertyPath": [
"_euler"
],
"value": {
"__type__": "cc.Vec3",
"x": 0,
"y": 0,
"z": 0
}
},
{
"__type__": "CCPropertyOverrideInfo",
"targetInfo": {
"__id__": 41
},
"propertyPath": [
"_active"
],
"value": false
},
{
"__type__": "cc.Node",
"_objFlags": 0,
"_parent": {
"__id__": 1
},
"_prefab": {
"__id__": 47
},
"__editorExtras__": {}
},
{
"__type__": "cc.PrefabInfo",
"root": {
"__id__": 46
},
"asset": {
"__uuid__": "ae4493bd-cbcc-4392-921c-3e2b0fcd5338",
"__expectedType__": "cc.Prefab"
},
"fileId": "91yoyAQGNDm5ziI7NUChZ+",
"instance": {
"__id__": 48
},
"targetOverrides": null
},
{
"__type__": "cc.PrefabInstance",
"fileId": "08n1IzuupL3YNn2/tFvc8M",
"prefabRootNode": {
"__id__": 1
},
"mountedChildren": [],
"mountedComponents": [],
"propertyOverrides": [
{
"__id__": 49
},
{
"__id__": 51
},
{
"__id__": 52
},
{
"__id__": 53
},
{
"__id__": 54
}
],
"removedComponents": []
},
{
"__type__": "CCPropertyOverrideInfo",
"targetInfo": {
"__id__": 50
},
"propertyPath": [
"_name"
],
"value": "up"
},
{
@@ -854,7 +726,7 @@
{
"__type__": "CCPropertyOverrideInfo",
"targetInfo": {
"__id__": 50
"__id__": 41
},
"propertyPath": [
"_lpos"
@@ -869,7 +741,7 @@
{
"__type__": "CCPropertyOverrideInfo",
"targetInfo": {
"__id__": 50
"__id__": 41
},
"propertyPath": [
"_lrot"
@@ -885,7 +757,7 @@
{
"__type__": "CCPropertyOverrideInfo",
"targetInfo": {
"__id__": 50
"__id__": 41
},
"propertyPath": [
"_euler"
@@ -900,7 +772,7 @@
{
"__type__": "CCPropertyOverrideInfo",
"targetInfo": {
"__id__": 50
"__id__": 41
},
"propertyPath": [
"_active"
@@ -917,7 +789,7 @@
},
"_enabled": true,
"__prefab": {
"__id__": 56
"__id__": 47
},
"_contentSize": {
"__type__": "cc.Size",
@@ -945,7 +817,7 @@
},
"_enabled": true,
"__prefab": {
"__id__": 58
"__id__": 49
},
"anm": {
"__id__": 5
@@ -960,12 +832,13 @@
"__type__": "873f8d+SolMEo8DiTTxZRh4",
"_name": "",
"_objFlags": 0,
"__editorExtras__": {},
"node": {
"__id__": 1
},
"_enabled": true,
"__prefab": {
"__id__": 60
"__id__": 51
},
"_id": ""
},
@@ -983,7 +856,7 @@
},
"_enabled": true,
"__prefab": {
"__id__": 62
"__id__": 53
},
"enabledContactListener": true,
"bullet": false,
@@ -1017,7 +890,7 @@
},
"_enabled": true,
"__prefab": {
"__id__": 64
"__id__": 55
},
"tag": 0,
"_group": 4,
@@ -1053,9 +926,6 @@
"instance": null,
"targetOverrides": null,
"nestedPrefabInstanceRoots": [
{
"__id__": 46
},
{
"__id__": 37
},

View File

@@ -29,31 +29,28 @@
},
{
"__id__": 37
},
{
"__id__": 46
}
],
"_active": true,
"_components": [
{
"__id__": 55
"__id__": 46
},
{
"__id__": 57
"__id__": 48
},
{
"__id__": 59
"__id__": 50
},
{
"__id__": 61
"__id__": 52
},
{
"__id__": 63
"__id__": 54
}
],
"_prefab": {
"__id__": 65
"__id__": 56
},
"_lpos": {
"__type__": "cc.Vec3",
@@ -671,10 +668,10 @@
"__id__": 37
},
"asset": {
"__uuid__": "5b4ca49e-0f12-4478-b56d-bf8198b36b90",
"__uuid__": "ae4493bd-cbcc-4392-921c-3e2b0fcd5338",
"__expectedType__": "cc.Prefab"
},
"fileId": "0d6ZXmA5dHkZxoGONDL2sE",
"fileId": "91yoyAQGNDm5ziI7NUChZ+",
"instance": {
"__id__": 39
},
@@ -682,7 +679,7 @@
},
{
"__type__": "cc.PrefabInstance",
"fileId": "fe79INE+JI1Jy2Hu0iKLMn",
"fileId": "08n1IzuupL3YNn2/tFvc8M",
"prefabRootNode": {
"__id__": 1
},
@@ -715,131 +712,6 @@
"propertyPath": [
"_name"
],
"value": "tooltip"
},
{
"__type__": "cc.TargetInfo",
"localID": [
"0d6ZXmA5dHkZxoGONDL2sE"
]
},
{
"__type__": "CCPropertyOverrideInfo",
"targetInfo": {
"__id__": 41
},
"propertyPath": [
"_lpos"
],
"value": {
"__type__": "cc.Vec3",
"x": 4.65,
"y": 129.718,
"z": 0
}
},
{
"__type__": "CCPropertyOverrideInfo",
"targetInfo": {
"__id__": 41
},
"propertyPath": [
"_lrot"
],
"value": {
"__type__": "cc.Quat",
"x": 0,
"y": 0,
"z": 0,
"w": 1
}
},
{
"__type__": "CCPropertyOverrideInfo",
"targetInfo": {
"__id__": 41
},
"propertyPath": [
"_euler"
],
"value": {
"__type__": "cc.Vec3",
"x": 0,
"y": 0,
"z": 0
}
},
{
"__type__": "CCPropertyOverrideInfo",
"targetInfo": {
"__id__": 41
},
"propertyPath": [
"_active"
],
"value": false
},
{
"__type__": "cc.Node",
"_objFlags": 0,
"_parent": {
"__id__": 1
},
"_prefab": {
"__id__": 47
},
"__editorExtras__": {}
},
{
"__type__": "cc.PrefabInfo",
"root": {
"__id__": 46
},
"asset": {
"__uuid__": "ae4493bd-cbcc-4392-921c-3e2b0fcd5338",
"__expectedType__": "cc.Prefab"
},
"fileId": "91yoyAQGNDm5ziI7NUChZ+",
"instance": {
"__id__": 48
},
"targetOverrides": null
},
{
"__type__": "cc.PrefabInstance",
"fileId": "08n1IzuupL3YNn2/tFvc8M",
"prefabRootNode": {
"__id__": 1
},
"mountedChildren": [],
"mountedComponents": [],
"propertyOverrides": [
{
"__id__": 49
},
{
"__id__": 51
},
{
"__id__": 52
},
{
"__id__": 53
},
{
"__id__": 54
}
],
"removedComponents": []
},
{
"__type__": "CCPropertyOverrideInfo",
"targetInfo": {
"__id__": 50
},
"propertyPath": [
"_name"
],
"value": "up"
},
{
@@ -851,7 +723,7 @@
{
"__type__": "CCPropertyOverrideInfo",
"targetInfo": {
"__id__": 50
"__id__": 41
},
"propertyPath": [
"_lpos"
@@ -866,7 +738,7 @@
{
"__type__": "CCPropertyOverrideInfo",
"targetInfo": {
"__id__": 50
"__id__": 41
},
"propertyPath": [
"_lrot"
@@ -882,7 +754,7 @@
{
"__type__": "CCPropertyOverrideInfo",
"targetInfo": {
"__id__": 50
"__id__": 41
},
"propertyPath": [
"_euler"
@@ -897,7 +769,7 @@
{
"__type__": "CCPropertyOverrideInfo",
"targetInfo": {
"__id__": 50
"__id__": 41
},
"propertyPath": [
"_active"
@@ -914,7 +786,7 @@
},
"_enabled": true,
"__prefab": {
"__id__": 56
"__id__": 47
},
"_contentSize": {
"__type__": "cc.Size",
@@ -942,7 +814,7 @@
},
"_enabled": true,
"__prefab": {
"__id__": 58
"__id__": 49
},
"anm": {
"__id__": 5
@@ -957,12 +829,13 @@
"__type__": "873f8d+SolMEo8DiTTxZRh4",
"_name": "",
"_objFlags": 0,
"__editorExtras__": {},
"node": {
"__id__": 1
},
"_enabled": true,
"__prefab": {
"__id__": 60
"__id__": 51
},
"_id": ""
},
@@ -980,7 +853,7 @@
},
"_enabled": true,
"__prefab": {
"__id__": 62
"__id__": 53
},
"enabledContactListener": true,
"bullet": false,
@@ -1014,7 +887,7 @@
},
"_enabled": true,
"__prefab": {
"__id__": 64
"__id__": 55
},
"tag": 0,
"_group": 4,
@@ -1050,9 +923,6 @@
"instance": null,
"targetOverrides": null,
"nestedPrefabInstanceRoots": [
{
"__id__": 46
},
{
"__id__": 37
},

View File

@@ -29,31 +29,28 @@
},
{
"__id__": 37
},
{
"__id__": 46
}
],
"_active": true,
"_components": [
{
"__id__": 55
"__id__": 46
},
{
"__id__": 57
"__id__": 48
},
{
"__id__": 59
"__id__": 50
},
{
"__id__": 61
"__id__": 52
},
{
"__id__": 63
"__id__": 54
}
],
"_prefab": {
"__id__": 65
"__id__": 56
},
"_lpos": {
"__type__": "cc.Vec3",
@@ -674,10 +671,10 @@
"__id__": 37
},
"asset": {
"__uuid__": "5b4ca49e-0f12-4478-b56d-bf8198b36b90",
"__uuid__": "ae4493bd-cbcc-4392-921c-3e2b0fcd5338",
"__expectedType__": "cc.Prefab"
},
"fileId": "0d6ZXmA5dHkZxoGONDL2sE",
"fileId": "91yoyAQGNDm5ziI7NUChZ+",
"instance": {
"__id__": 39
},
@@ -685,7 +682,7 @@
},
{
"__type__": "cc.PrefabInstance",
"fileId": "fe79INE+JI1Jy2Hu0iKLMn",
"fileId": "08n1IzuupL3YNn2/tFvc8M",
"prefabRootNode": {
"__id__": 1
},
@@ -718,131 +715,6 @@
"propertyPath": [
"_name"
],
"value": "tooltip"
},
{
"__type__": "cc.TargetInfo",
"localID": [
"0d6ZXmA5dHkZxoGONDL2sE"
]
},
{
"__type__": "CCPropertyOverrideInfo",
"targetInfo": {
"__id__": 41
},
"propertyPath": [
"_lpos"
],
"value": {
"__type__": "cc.Vec3",
"x": 4.65,
"y": 129.718,
"z": 0
}
},
{
"__type__": "CCPropertyOverrideInfo",
"targetInfo": {
"__id__": 41
},
"propertyPath": [
"_lrot"
],
"value": {
"__type__": "cc.Quat",
"x": 0,
"y": 0,
"z": 0,
"w": 1
}
},
{
"__type__": "CCPropertyOverrideInfo",
"targetInfo": {
"__id__": 41
},
"propertyPath": [
"_euler"
],
"value": {
"__type__": "cc.Vec3",
"x": 0,
"y": 0,
"z": 0
}
},
{
"__type__": "CCPropertyOverrideInfo",
"targetInfo": {
"__id__": 41
},
"propertyPath": [
"_active"
],
"value": false
},
{
"__type__": "cc.Node",
"_objFlags": 0,
"_parent": {
"__id__": 1
},
"_prefab": {
"__id__": 47
},
"__editorExtras__": {}
},
{
"__type__": "cc.PrefabInfo",
"root": {
"__id__": 46
},
"asset": {
"__uuid__": "ae4493bd-cbcc-4392-921c-3e2b0fcd5338",
"__expectedType__": "cc.Prefab"
},
"fileId": "91yoyAQGNDm5ziI7NUChZ+",
"instance": {
"__id__": 48
},
"targetOverrides": null
},
{
"__type__": "cc.PrefabInstance",
"fileId": "08n1IzuupL3YNn2/tFvc8M",
"prefabRootNode": {
"__id__": 1
},
"mountedChildren": [],
"mountedComponents": [],
"propertyOverrides": [
{
"__id__": 49
},
{
"__id__": 51
},
{
"__id__": 52
},
{
"__id__": 53
},
{
"__id__": 54
}
],
"removedComponents": []
},
{
"__type__": "CCPropertyOverrideInfo",
"targetInfo": {
"__id__": 50
},
"propertyPath": [
"_name"
],
"value": "up"
},
{
@@ -854,7 +726,7 @@
{
"__type__": "CCPropertyOverrideInfo",
"targetInfo": {
"__id__": 50
"__id__": 41
},
"propertyPath": [
"_lpos"
@@ -869,7 +741,7 @@
{
"__type__": "CCPropertyOverrideInfo",
"targetInfo": {
"__id__": 50
"__id__": 41
},
"propertyPath": [
"_lrot"
@@ -885,7 +757,7 @@
{
"__type__": "CCPropertyOverrideInfo",
"targetInfo": {
"__id__": 50
"__id__": 41
},
"propertyPath": [
"_euler"
@@ -900,7 +772,7 @@
{
"__type__": "CCPropertyOverrideInfo",
"targetInfo": {
"__id__": 50
"__id__": 41
},
"propertyPath": [
"_active"
@@ -917,7 +789,7 @@
},
"_enabled": true,
"__prefab": {
"__id__": 56
"__id__": 47
},
"_contentSize": {
"__type__": "cc.Size",
@@ -945,7 +817,7 @@
},
"_enabled": true,
"__prefab": {
"__id__": 58
"__id__": 49
},
"anm": {
"__id__": 5
@@ -960,12 +832,13 @@
"__type__": "873f8d+SolMEo8DiTTxZRh4",
"_name": "",
"_objFlags": 0,
"__editorExtras__": {},
"node": {
"__id__": 1
},
"_enabled": true,
"__prefab": {
"__id__": 60
"__id__": 51
},
"_id": ""
},
@@ -983,7 +856,7 @@
},
"_enabled": true,
"__prefab": {
"__id__": 62
"__id__": 53
},
"enabledContactListener": true,
"bullet": false,
@@ -1017,7 +890,7 @@
},
"_enabled": true,
"__prefab": {
"__id__": 64
"__id__": 55
},
"tag": 0,
"_group": 4,
@@ -1053,9 +926,6 @@
"instance": null,
"targetOverrides": null,
"nestedPrefabInstanceRoots": [
{
"__id__": 46
},
{
"__id__": 37
},

View File

@@ -29,31 +29,28 @@
},
{
"__id__": 37
},
{
"__id__": 46
}
],
"_active": true,
"_components": [
{
"__id__": 55
"__id__": 46
},
{
"__id__": 57
"__id__": 48
},
{
"__id__": 59
"__id__": 50
},
{
"__id__": 61
"__id__": 52
},
{
"__id__": 63
"__id__": 54
}
],
"_prefab": {
"__id__": 65
"__id__": 56
},
"_lpos": {
"__type__": "cc.Vec3",
@@ -674,10 +671,10 @@
"__id__": 37
},
"asset": {
"__uuid__": "5b4ca49e-0f12-4478-b56d-bf8198b36b90",
"__uuid__": "ae4493bd-cbcc-4392-921c-3e2b0fcd5338",
"__expectedType__": "cc.Prefab"
},
"fileId": "0d6ZXmA5dHkZxoGONDL2sE",
"fileId": "91yoyAQGNDm5ziI7NUChZ+",
"instance": {
"__id__": 39
},
@@ -685,7 +682,7 @@
},
{
"__type__": "cc.PrefabInstance",
"fileId": "fe79INE+JI1Jy2Hu0iKLMn",
"fileId": "08n1IzuupL3YNn2/tFvc8M",
"prefabRootNode": {
"__id__": 1
},
@@ -718,131 +715,6 @@
"propertyPath": [
"_name"
],
"value": "tooltip"
},
{
"__type__": "cc.TargetInfo",
"localID": [
"0d6ZXmA5dHkZxoGONDL2sE"
]
},
{
"__type__": "CCPropertyOverrideInfo",
"targetInfo": {
"__id__": 41
},
"propertyPath": [
"_lpos"
],
"value": {
"__type__": "cc.Vec3",
"x": 4.65,
"y": 129.718,
"z": 0
}
},
{
"__type__": "CCPropertyOverrideInfo",
"targetInfo": {
"__id__": 41
},
"propertyPath": [
"_lrot"
],
"value": {
"__type__": "cc.Quat",
"x": 0,
"y": 0,
"z": 0,
"w": 1
}
},
{
"__type__": "CCPropertyOverrideInfo",
"targetInfo": {
"__id__": 41
},
"propertyPath": [
"_euler"
],
"value": {
"__type__": "cc.Vec3",
"x": 0,
"y": 0,
"z": 0
}
},
{
"__type__": "CCPropertyOverrideInfo",
"targetInfo": {
"__id__": 41
},
"propertyPath": [
"_active"
],
"value": false
},
{
"__type__": "cc.Node",
"_objFlags": 0,
"_parent": {
"__id__": 1
},
"_prefab": {
"__id__": 47
},
"__editorExtras__": {}
},
{
"__type__": "cc.PrefabInfo",
"root": {
"__id__": 46
},
"asset": {
"__uuid__": "ae4493bd-cbcc-4392-921c-3e2b0fcd5338",
"__expectedType__": "cc.Prefab"
},
"fileId": "91yoyAQGNDm5ziI7NUChZ+",
"instance": {
"__id__": 48
},
"targetOverrides": null
},
{
"__type__": "cc.PrefabInstance",
"fileId": "08n1IzuupL3YNn2/tFvc8M",
"prefabRootNode": {
"__id__": 1
},
"mountedChildren": [],
"mountedComponents": [],
"propertyOverrides": [
{
"__id__": 49
},
{
"__id__": 51
},
{
"__id__": 52
},
{
"__id__": 53
},
{
"__id__": 54
}
],
"removedComponents": []
},
{
"__type__": "CCPropertyOverrideInfo",
"targetInfo": {
"__id__": 50
},
"propertyPath": [
"_name"
],
"value": "up"
},
{
@@ -854,7 +726,7 @@
{
"__type__": "CCPropertyOverrideInfo",
"targetInfo": {
"__id__": 50
"__id__": 41
},
"propertyPath": [
"_lpos"
@@ -869,7 +741,7 @@
{
"__type__": "CCPropertyOverrideInfo",
"targetInfo": {
"__id__": 50
"__id__": 41
},
"propertyPath": [
"_lrot"
@@ -885,7 +757,7 @@
{
"__type__": "CCPropertyOverrideInfo",
"targetInfo": {
"__id__": 50
"__id__": 41
},
"propertyPath": [
"_euler"
@@ -900,7 +772,7 @@
{
"__type__": "CCPropertyOverrideInfo",
"targetInfo": {
"__id__": 50
"__id__": 41
},
"propertyPath": [
"_active"
@@ -917,7 +789,7 @@
},
"_enabled": true,
"__prefab": {
"__id__": 56
"__id__": 47
},
"_contentSize": {
"__type__": "cc.Size",
@@ -945,7 +817,7 @@
},
"_enabled": true,
"__prefab": {
"__id__": 58
"__id__": 49
},
"anm": {
"__id__": 5
@@ -960,12 +832,13 @@
"__type__": "873f8d+SolMEo8DiTTxZRh4",
"_name": "",
"_objFlags": 0,
"__editorExtras__": {},
"node": {
"__id__": 1
},
"_enabled": true,
"__prefab": {
"__id__": 60
"__id__": 51
},
"_id": ""
},
@@ -983,7 +856,7 @@
},
"_enabled": true,
"__prefab": {
"__id__": 62
"__id__": 53
},
"enabledContactListener": true,
"bullet": false,
@@ -1017,7 +890,7 @@
},
"_enabled": true,
"__prefab": {
"__id__": 64
"__id__": 55
},
"tag": 0,
"_group": 4,
@@ -1053,9 +926,6 @@
"instance": null,
"targetOverrides": null,
"nestedPrefabInstanceRoots": [
{
"__id__": 46
},
{
"__id__": 37
},

View File

@@ -29,31 +29,28 @@
},
{
"__id__": 37
},
{
"__id__": 46
}
],
"_active": true,
"_components": [
{
"__id__": 55
"__id__": 46
},
{
"__id__": 57
"__id__": 48
},
{
"__id__": 59
"__id__": 50
},
{
"__id__": 61
"__id__": 52
},
{
"__id__": 63
"__id__": 54
}
],
"_prefab": {
"__id__": 65
"__id__": 56
},
"_lpos": {
"__type__": "cc.Vec3",
@@ -674,10 +671,10 @@
"__id__": 37
},
"asset": {
"__uuid__": "5b4ca49e-0f12-4478-b56d-bf8198b36b90",
"__uuid__": "ae4493bd-cbcc-4392-921c-3e2b0fcd5338",
"__expectedType__": "cc.Prefab"
},
"fileId": "0d6ZXmA5dHkZxoGONDL2sE",
"fileId": "91yoyAQGNDm5ziI7NUChZ+",
"instance": {
"__id__": 39
},
@@ -685,7 +682,7 @@
},
{
"__type__": "cc.PrefabInstance",
"fileId": "fe79INE+JI1Jy2Hu0iKLMn",
"fileId": "08n1IzuupL3YNn2/tFvc8M",
"prefabRootNode": {
"__id__": 1
},
@@ -718,131 +715,6 @@
"propertyPath": [
"_name"
],
"value": "tooltip"
},
{
"__type__": "cc.TargetInfo",
"localID": [
"0d6ZXmA5dHkZxoGONDL2sE"
]
},
{
"__type__": "CCPropertyOverrideInfo",
"targetInfo": {
"__id__": 41
},
"propertyPath": [
"_lpos"
],
"value": {
"__type__": "cc.Vec3",
"x": 4.65,
"y": 129.718,
"z": 0
}
},
{
"__type__": "CCPropertyOverrideInfo",
"targetInfo": {
"__id__": 41
},
"propertyPath": [
"_lrot"
],
"value": {
"__type__": "cc.Quat",
"x": 0,
"y": 0,
"z": 0,
"w": 1
}
},
{
"__type__": "CCPropertyOverrideInfo",
"targetInfo": {
"__id__": 41
},
"propertyPath": [
"_euler"
],
"value": {
"__type__": "cc.Vec3",
"x": 0,
"y": 0,
"z": 0
}
},
{
"__type__": "CCPropertyOverrideInfo",
"targetInfo": {
"__id__": 41
},
"propertyPath": [
"_active"
],
"value": false
},
{
"__type__": "cc.Node",
"_objFlags": 0,
"_parent": {
"__id__": 1
},
"_prefab": {
"__id__": 47
},
"__editorExtras__": {}
},
{
"__type__": "cc.PrefabInfo",
"root": {
"__id__": 46
},
"asset": {
"__uuid__": "ae4493bd-cbcc-4392-921c-3e2b0fcd5338",
"__expectedType__": "cc.Prefab"
},
"fileId": "91yoyAQGNDm5ziI7NUChZ+",
"instance": {
"__id__": 48
},
"targetOverrides": null
},
{
"__type__": "cc.PrefabInstance",
"fileId": "08n1IzuupL3YNn2/tFvc8M",
"prefabRootNode": {
"__id__": 1
},
"mountedChildren": [],
"mountedComponents": [],
"propertyOverrides": [
{
"__id__": 49
},
{
"__id__": 51
},
{
"__id__": 52
},
{
"__id__": 53
},
{
"__id__": 54
}
],
"removedComponents": []
},
{
"__type__": "CCPropertyOverrideInfo",
"targetInfo": {
"__id__": 50
},
"propertyPath": [
"_name"
],
"value": "up"
},
{
@@ -854,7 +726,7 @@
{
"__type__": "CCPropertyOverrideInfo",
"targetInfo": {
"__id__": 50
"__id__": 41
},
"propertyPath": [
"_lpos"
@@ -869,7 +741,7 @@
{
"__type__": "CCPropertyOverrideInfo",
"targetInfo": {
"__id__": 50
"__id__": 41
},
"propertyPath": [
"_lrot"
@@ -885,7 +757,7 @@
{
"__type__": "CCPropertyOverrideInfo",
"targetInfo": {
"__id__": 50
"__id__": 41
},
"propertyPath": [
"_euler"
@@ -900,7 +772,7 @@
{
"__type__": "CCPropertyOverrideInfo",
"targetInfo": {
"__id__": 50
"__id__": 41
},
"propertyPath": [
"_active"
@@ -917,7 +789,7 @@
},
"_enabled": true,
"__prefab": {
"__id__": 56
"__id__": 47
},
"_contentSize": {
"__type__": "cc.Size",
@@ -945,7 +817,7 @@
},
"_enabled": true,
"__prefab": {
"__id__": 58
"__id__": 49
},
"anm": {
"__id__": 5
@@ -966,7 +838,7 @@
},
"_enabled": true,
"__prefab": {
"__id__": 60
"__id__": 51
},
"_id": ""
},
@@ -984,7 +856,7 @@
},
"_enabled": true,
"__prefab": {
"__id__": 62
"__id__": 53
},
"enabledContactListener": true,
"bullet": false,
@@ -1018,7 +890,7 @@
},
"_enabled": true,
"__prefab": {
"__id__": 64
"__id__": 55
},
"tag": 0,
"_group": 4,
@@ -1054,9 +926,6 @@
"instance": null,
"targetOverrides": null,
"nestedPrefabInstanceRoots": [
{
"__id__": 46
},
{
"__id__": 37
},

View File

@@ -1,801 +0,0 @@
[
{
"__type__": "cc.Prefab",
"_name": "tooltip",
"_objFlags": 0,
"__editorExtras__": {},
"_native": "",
"data": {
"__id__": 1
},
"optimizationPolicy": 0,
"persistent": false
},
{
"__type__": "cc.Node",
"_name": "tooltip",
"_objFlags": 0,
"__editorExtras__": {},
"_parent": null,
"_children": [
{
"__id__": 2
},
{
"__id__": 24
}
],
"_active": true,
"_components": [
{
"__id__": 32
}
],
"_prefab": {
"__id__": 34
},
"_lpos": {
"__type__": "cc.Vec3",
"x": 0,
"y": 0,
"z": 0
},
"_lrot": {
"__type__": "cc.Quat",
"x": 0,
"y": 0,
"z": 0,
"w": 1
},
"_lscale": {
"__type__": "cc.Vec3",
"x": 1,
"y": 1,
"z": 1
},
"_mobility": 0,
"_layer": 1,
"_euler": {
"__type__": "cc.Vec3",
"x": 0,
"y": 0,
"z": 0
},
"_id": ""
},
{
"__type__": "cc.Node",
"_name": "bg",
"_objFlags": 0,
"__editorExtras__": {},
"_parent": {
"__id__": 1
},
"_children": [
{
"__id__": 3
}
],
"_active": true,
"_components": [
{
"__id__": 17
},
{
"__id__": 19
},
{
"__id__": 21
}
],
"_prefab": {
"__id__": 23
},
"_lpos": {
"__type__": "cc.Vec3",
"x": 0,
"y": 0,
"z": 0
},
"_lrot": {
"__type__": "cc.Quat",
"x": 0,
"y": 0,
"z": 0,
"w": 1
},
"_lscale": {
"__type__": "cc.Vec3",
"x": -1,
"y": 1,
"z": 1
},
"_mobility": 0,
"_layer": 1,
"_euler": {
"__type__": "cc.Vec3",
"x": 0,
"y": 0,
"z": 0
},
"_id": ""
},
{
"__type__": "cc.Node",
"_name": "Button_Border_Circle_H53_White_Bg",
"_objFlags": 0,
"__editorExtras__": {},
"_parent": {
"__id__": 2
},
"_children": [
{
"__id__": 4
}
],
"_active": true,
"_components": [
{
"__id__": 10
},
{
"__id__": 12
},
{
"__id__": 14
}
],
"_prefab": {
"__id__": 16
},
"_lpos": {
"__type__": "cc.Vec3",
"x": 0,
"y": 0,
"z": 0
},
"_lrot": {
"__type__": "cc.Quat",
"x": 0,
"y": 0,
"z": 0,
"w": 1
},
"_lscale": {
"__type__": "cc.Vec3",
"x": 1,
"y": 1,
"z": 1
},
"_mobility": 0,
"_layer": 1,
"_euler": {
"__type__": "cc.Vec3",
"x": 0,
"y": 0,
"z": 0
},
"_id": ""
},
{
"__type__": "cc.Node",
"_name": "BubbleFrame_01_ArrowBg",
"_objFlags": 0,
"__editorExtras__": {},
"_parent": {
"__id__": 3
},
"_children": [],
"_active": true,
"_components": [
{
"__id__": 5
},
{
"__id__": 7
}
],
"_prefab": {
"__id__": 9
},
"_lpos": {
"__type__": "cc.Vec3",
"x": 70.583,
"y": -43.963,
"z": 0
},
"_lrot": {
"__type__": "cc.Quat",
"x": 0,
"y": 0,
"z": 0,
"w": 1
},
"_lscale": {
"__type__": "cc.Vec3",
"x": 1,
"y": 1,
"z": 1
},
"_mobility": 0,
"_layer": 1,
"_euler": {
"__type__": "cc.Vec3",
"x": 0,
"y": 0,
"z": 0
},
"_id": ""
},
{
"__type__": "cc.UITransform",
"_name": "",
"_objFlags": 0,
"__editorExtras__": {},
"node": {
"__id__": 4
},
"_enabled": true,
"__prefab": {
"__id__": 6
},
"_contentSize": {
"__type__": "cc.Size",
"width": 31,
"height": 37
},
"_anchorPoint": {
"__type__": "cc.Vec2",
"x": 0.5,
"y": 0.5
},
"_id": ""
},
{
"__type__": "cc.CompPrefabInfo",
"fileId": "0cSf9kAD1DFbHiUjMIIH+g"
},
{
"__type__": "cc.Sprite",
"_name": "",
"_objFlags": 0,
"__editorExtras__": {},
"node": {
"__id__": 4
},
"_enabled": true,
"__prefab": {
"__id__": 8
},
"_customMaterial": null,
"_srcBlendFactor": 2,
"_dstBlendFactor": 4,
"_color": {
"__type__": "cc.Color",
"r": 255,
"g": 255,
"b": 255,
"a": 255
},
"_spriteFrame": {
"__uuid__": "cb93c900-b440-4571-91d1-7da1636e3d73@8b3ab",
"__expectedType__": "cc.SpriteFrame"
},
"_type": 0,
"_fillType": 0,
"_sizeMode": 1,
"_fillCenter": {
"__type__": "cc.Vec2",
"x": 0,
"y": 0
},
"_fillStart": 0,
"_fillRange": 0,
"_isTrimmedMode": true,
"_useGrayscale": false,
"_atlas": {
"__uuid__": "cb93c900-b440-4571-91d1-7da1636e3d73",
"__expectedType__": "cc.SpriteAtlas"
},
"_id": ""
},
{
"__type__": "cc.CompPrefabInfo",
"fileId": "837tIFMjhFy6LI1VDae3SQ"
},
{
"__type__": "cc.PrefabInfo",
"root": {
"__id__": 1
},
"asset": {
"__id__": 0
},
"fileId": "9bbsSellpJ/7mfHLWpToGK",
"instance": null,
"targetOverrides": null,
"nestedPrefabInstanceRoots": null
},
{
"__type__": "cc.UITransform",
"_name": "",
"_objFlags": 0,
"__editorExtras__": {},
"node": {
"__id__": 3
},
"_enabled": true,
"__prefab": {
"__id__": 11
},
"_contentSize": {
"__type__": "cc.Size",
"width": 228,
"height": 73
},
"_anchorPoint": {
"__type__": "cc.Vec2",
"x": 0.5,
"y": 0.5
},
"_id": ""
},
{
"__type__": "cc.CompPrefabInfo",
"fileId": "55OEMGRiREoarVbxxS4xtp"
},
{
"__type__": "cc.Sprite",
"_name": "",
"_objFlags": 0,
"__editorExtras__": {},
"node": {
"__id__": 3
},
"_enabled": true,
"__prefab": {
"__id__": 13
},
"_customMaterial": null,
"_srcBlendFactor": 2,
"_dstBlendFactor": 4,
"_color": {
"__type__": "cc.Color",
"r": 255,
"g": 255,
"b": 255,
"a": 255
},
"_spriteFrame": {
"__uuid__": "cb93c900-b440-4571-91d1-7da1636e3d73@df277",
"__expectedType__": "cc.SpriteFrame"
},
"_type": 1,
"_fillType": 0,
"_sizeMode": 0,
"_fillCenter": {
"__type__": "cc.Vec2",
"x": 0,
"y": 0
},
"_fillStart": 0,
"_fillRange": 0,
"_isTrimmedMode": true,
"_useGrayscale": false,
"_atlas": {
"__uuid__": "cb93c900-b440-4571-91d1-7da1636e3d73",
"__expectedType__": "cc.SpriteAtlas"
},
"_id": ""
},
{
"__type__": "cc.CompPrefabInfo",
"fileId": "de5EHTIPtGUoEgaAHAhhfE"
},
{
"__type__": "cc.Widget",
"_name": "",
"_objFlags": 0,
"__editorExtras__": {},
"node": {
"__id__": 3
},
"_enabled": true,
"__prefab": {
"__id__": 15
},
"_alignFlags": 45,
"_target": null,
"_left": 1,
"_right": 1,
"_top": 1,
"_bottom": 1,
"_horizontalCenter": 0,
"_verticalCenter": 0,
"_isAbsLeft": true,
"_isAbsRight": true,
"_isAbsTop": true,
"_isAbsBottom": true,
"_isAbsHorizontalCenter": true,
"_isAbsVerticalCenter": true,
"_originalWidth": 50,
"_originalHeight": 53,
"_alignMode": 2,
"_lockFlags": 0,
"_id": ""
},
{
"__type__": "cc.CompPrefabInfo",
"fileId": "53LMej0GtNaJyk91eOlrcd"
},
{
"__type__": "cc.PrefabInfo",
"root": {
"__id__": 1
},
"asset": {
"__id__": 0
},
"fileId": "79W04mlENAn6oQ1y1oZyNg",
"instance": null,
"targetOverrides": null,
"nestedPrefabInstanceRoots": null
},
{
"__type__": "cc.UITransform",
"_name": "",
"_objFlags": 0,
"__editorExtras__": {},
"node": {
"__id__": 2
},
"_enabled": true,
"__prefab": {
"__id__": 18
},
"_contentSize": {
"__type__": "cc.Size",
"width": 230,
"height": 75
},
"_anchorPoint": {
"__type__": "cc.Vec2",
"x": 0.5,
"y": 0.5
},
"_id": ""
},
{
"__type__": "cc.CompPrefabInfo",
"fileId": "d1/BqGCLlHV4LOZCExXtbR"
},
{
"__type__": "cc.Sprite",
"_name": "",
"_objFlags": 0,
"__editorExtras__": {},
"node": {
"__id__": 2
},
"_enabled": true,
"__prefab": {
"__id__": 20
},
"_customMaterial": null,
"_srcBlendFactor": 2,
"_dstBlendFactor": 4,
"_color": {
"__type__": "cc.Color",
"r": 255,
"g": 255,
"b": 255,
"a": 255
},
"_spriteFrame": null,
"_type": 0,
"_fillType": 0,
"_sizeMode": 0,
"_fillCenter": {
"__type__": "cc.Vec2",
"x": 0,
"y": 0
},
"_fillStart": 0,
"_fillRange": 0,
"_isTrimmedMode": true,
"_useGrayscale": false,
"_atlas": null,
"_id": ""
},
{
"__type__": "cc.CompPrefabInfo",
"fileId": "09S6er24tADYna5lfOQEkl"
},
{
"__type__": "cc.Widget",
"_name": "",
"_objFlags": 0,
"__editorExtras__": {},
"node": {
"__id__": 2
},
"_enabled": true,
"__prefab": {
"__id__": 22
},
"_alignFlags": 45,
"_target": null,
"_left": 0,
"_right": 0,
"_top": 0,
"_bottom": 0,
"_horizontalCenter": 0,
"_verticalCenter": 0,
"_isAbsLeft": true,
"_isAbsRight": true,
"_isAbsTop": true,
"_isAbsBottom": true,
"_isAbsHorizontalCenter": true,
"_isAbsVerticalCenter": true,
"_originalWidth": 100,
"_originalHeight": 50,
"_alignMode": 2,
"_lockFlags": 0,
"_id": ""
},
{
"__type__": "cc.CompPrefabInfo",
"fileId": "3b5Bvues1P/qDyLQHYI8J7"
},
{
"__type__": "cc.PrefabInfo",
"root": {
"__id__": 1
},
"asset": {
"__id__": 0
},
"fileId": "fadwGZO+5HPqK+IqWjAe1I",
"instance": null,
"targetOverrides": null,
"nestedPrefabInstanceRoots": null
},
{
"__type__": "cc.Node",
"_name": "words",
"_objFlags": 0,
"__editorExtras__": {},
"_parent": {
"__id__": 1
},
"_children": [],
"_active": true,
"_components": [
{
"__id__": 25
},
{
"__id__": 27
},
{
"__id__": 29
}
],
"_prefab": {
"__id__": 31
},
"_lpos": {
"__type__": "cc.Vec3",
"x": 0,
"y": 0,
"z": 0
},
"_lrot": {
"__type__": "cc.Quat",
"x": 0,
"y": 0,
"z": 0,
"w": 1
},
"_lscale": {
"__type__": "cc.Vec3",
"x": 1,
"y": 1,
"z": 1
},
"_mobility": 0,
"_layer": 1,
"_euler": {
"__type__": "cc.Vec3",
"x": 0,
"y": 0,
"z": 0
},
"_id": ""
},
{
"__type__": "cc.UITransform",
"_name": "",
"_objFlags": 0,
"__editorExtras__": {},
"node": {
"__id__": 24
},
"_enabled": true,
"__prefab": {
"__id__": 26
},
"_contentSize": {
"__type__": "cc.Size",
"width": 220,
"height": 65
},
"_anchorPoint": {
"__type__": "cc.Vec2",
"x": 0.5,
"y": 0.5
},
"_id": ""
},
{
"__type__": "cc.CompPrefabInfo",
"fileId": "60n+Hxfa1P5qORRYWRA3am"
},
{
"__type__": "cc.Label",
"_name": "",
"_objFlags": 0,
"__editorExtras__": {},
"node": {
"__id__": 24
},
"_enabled": true,
"__prefab": {
"__id__": 28
},
"_customMaterial": null,
"_srcBlendFactor": 2,
"_dstBlendFactor": 4,
"_color": {
"__type__": "cc.Color",
"r": 255,
"g": 255,
"b": 255,
"a": 255
},
"_string": "点我可以调整出战英雄",
"_horizontalAlign": 1,
"_verticalAlign": 1,
"_actualFontSize": 21,
"_fontSize": 20,
"_fontFamily": "Arial",
"_lineHeight": 25,
"_overflow": 2,
"_enableWrapText": true,
"_font": null,
"_isSystemFontUsed": true,
"_spacingX": 0,
"_isItalic": false,
"_isBold": false,
"_isUnderline": false,
"_underlineHeight": 2,
"_cacheMode": 0,
"_enableOutline": true,
"_outlineColor": {
"__type__": "cc.Color",
"r": 0,
"g": 0,
"b": 0,
"a": 255
},
"_outlineWidth": 1.5,
"_enableShadow": false,
"_shadowColor": {
"__type__": "cc.Color",
"r": 0,
"g": 0,
"b": 0,
"a": 255
},
"_shadowOffset": {
"__type__": "cc.Vec2",
"x": 2,
"y": 2
},
"_shadowBlur": 2,
"_id": ""
},
{
"__type__": "cc.CompPrefabInfo",
"fileId": "6e8rPYem5HYojc44/ZRvP+"
},
{
"__type__": "cc.Widget",
"_name": "",
"_objFlags": 0,
"__editorExtras__": {},
"node": {
"__id__": 24
},
"_enabled": true,
"__prefab": {
"__id__": 30
},
"_alignFlags": 45,
"_target": null,
"_left": 5,
"_right": 5,
"_top": 5,
"_bottom": 5,
"_horizontalCenter": 0,
"_verticalCenter": 0,
"_isAbsLeft": true,
"_isAbsRight": true,
"_isAbsTop": true,
"_isAbsBottom": true,
"_isAbsHorizontalCenter": true,
"_isAbsVerticalCenter": true,
"_originalWidth": 63,
"_originalHeight": 59.49999999999999,
"_alignMode": 2,
"_lockFlags": 0,
"_id": ""
},
{
"__type__": "cc.CompPrefabInfo",
"fileId": "9cjyQ0wVdFkrdMNAqOGW27"
},
{
"__type__": "cc.PrefabInfo",
"root": {
"__id__": 1
},
"asset": {
"__id__": 0
},
"fileId": "9d+dPANj1LBo7dJI/bx9b5",
"instance": null,
"targetOverrides": null,
"nestedPrefabInstanceRoots": null
},
{
"__type__": "cc.UITransform",
"_name": "",
"_objFlags": 0,
"__editorExtras__": {},
"node": {
"__id__": 1
},
"_enabled": true,
"__prefab": {
"__id__": 33
},
"_contentSize": {
"__type__": "cc.Size",
"width": 230,
"height": 75
},
"_anchorPoint": {
"__type__": "cc.Vec2",
"x": 0.5,
"y": 0.5
},
"_id": ""
},
{
"__type__": "cc.CompPrefabInfo",
"fileId": "0alpB0Wg1E+5gOjL4DZ451"
},
{
"__type__": "cc.PrefabInfo",
"root": {
"__id__": 1
},
"asset": {
"__id__": 0
},
"fileId": "0d6ZXmA5dHkZxoGONDL2sE",
"instance": null,
"targetOverrides": null
}
]

View File

@@ -1,13 +0,0 @@
{
"ver": "1.1.50",
"importer": "prefab",
"imported": true,
"uuid": "5b4ca49e-0f12-4478-b56d-bf8198b36b90",
"files": [
".json"
],
"subMetas": {},
"userData": {
"syncNodeName": "tooltip"
}
}

View File

@@ -41,22 +41,25 @@
},
{
"__id__": 112
},
{
"__id__": 128
}
],
"_active": true,
"_components": [
{
"__id__": 128
"__id__": 146
},
{
"__id__": 130
"__id__": 148
},
{
"__id__": 132
"__id__": 150
}
],
"_prefab": {
"__id__": 134
"__id__": 152
},
"_lpos": {
"__type__": "cc.Vec3",
@@ -3229,6 +3232,465 @@
"targetOverrides": null,
"nestedPrefabInstanceRoots": null
},
{
"__type__": "cc.Node",
"_name": "add_mp",
"_objFlags": 0,
"__editorExtras__": {},
"_parent": {
"__id__": 1
},
"_children": [
{
"__id__": 129
}
],
"_active": false,
"_components": [
{
"__id__": 143
}
],
"_prefab": {
"__id__": 145
},
"_lpos": {
"__type__": "cc.Vec3",
"x": 0,
"y": 100,
"z": 0
},
"_lrot": {
"__type__": "cc.Quat",
"x": 0,
"y": 0,
"z": 0,
"w": 1
},
"_lscale": {
"__type__": "cc.Vec3",
"x": 1,
"y": 1,
"z": 1
},
"_mobility": 0,
"_layer": 1,
"_euler": {
"__type__": "cc.Vec3",
"x": 0,
"y": 0,
"z": 0
},
"_id": ""
},
{
"__type__": "cc.Node",
"_name": "mp",
"_objFlags": 0,
"__editorExtras__": {},
"_parent": {
"__id__": 128
},
"_children": [
{
"__id__": 130
}
],
"_active": true,
"_components": [
{
"__id__": 138
},
{
"__id__": 140
}
],
"_prefab": {
"__id__": 142
},
"_lpos": {
"__type__": "cc.Vec3",
"x": 0,
"y": 0,
"z": 0
},
"_lrot": {
"__type__": "cc.Quat",
"x": 0,
"y": 0,
"z": 0,
"w": 1
},
"_lscale": {
"__type__": "cc.Vec3",
"x": 1,
"y": 1,
"z": 1
},
"_mobility": 0,
"_layer": 1,
"_euler": {
"__type__": "cc.Vec3",
"x": 0,
"y": 0,
"z": 0
},
"_id": ""
},
{
"__type__": "cc.Node",
"_name": "Label",
"_objFlags": 0,
"__editorExtras__": {},
"_parent": {
"__id__": 129
},
"_children": [],
"_active": true,
"_components": [
{
"__id__": 131
},
{
"__id__": 133
},
{
"__id__": 135
}
],
"_prefab": {
"__id__": 137
},
"_lpos": {
"__type__": "cc.Vec3",
"x": -36.930390625,
"y": 0,
"z": 0
},
"_lrot": {
"__type__": "cc.Quat",
"x": 0,
"y": 0,
"z": 0,
"w": 1
},
"_lscale": {
"__type__": "cc.Vec3",
"x": 1,
"y": 1,
"z": 1
},
"_mobility": 0,
"_layer": 1,
"_euler": {
"__type__": "cc.Vec3",
"x": 0,
"y": 0,
"z": 0
},
"_id": ""
},
{
"__type__": "cc.UITransform",
"_name": "",
"_objFlags": 0,
"__editorExtras__": {},
"node": {
"__id__": 130
},
"_enabled": true,
"__prefab": {
"__id__": 132
},
"_contentSize": {
"__type__": "cc.Size",
"width": 29.19921875,
"height": 50
},
"_anchorPoint": {
"__type__": "cc.Vec2",
"x": 0.5,
"y": 0.5
},
"_id": ""
},
{
"__type__": "cc.CompPrefabInfo",
"fileId": "f7pa95arBMLryPjDchPW2u"
},
{
"__type__": "cc.Label",
"_name": "",
"_objFlags": 0,
"__editorExtras__": {},
"node": {
"__id__": 130
},
"_enabled": true,
"__prefab": {
"__id__": 134
},
"_customMaterial": null,
"_srcBlendFactor": 2,
"_dstBlendFactor": 4,
"_color": {
"__type__": "cc.Color",
"r": 78,
"g": 187,
"b": 248,
"a": 255
},
"_string": "+",
"_horizontalAlign": 1,
"_verticalAlign": 1,
"_actualFontSize": 50,
"_fontSize": 50,
"_fontFamily": "Arial",
"_lineHeight": 50,
"_overflow": 2,
"_enableWrapText": true,
"_font": {
"__uuid__": "983a109b-a5e3-4ba7-84c5-1c53817ba177",
"__expectedType__": "cc.BitmapFont"
},
"_isSystemFontUsed": false,
"_spacingX": 0,
"_isItalic": false,
"_isBold": true,
"_isUnderline": false,
"_underlineHeight": 2,
"_cacheMode": 0,
"_enableOutline": true,
"_outlineColor": {
"__type__": "cc.Color",
"r": 0,
"g": 0,
"b": 0,
"a": 255
},
"_outlineWidth": 2,
"_enableShadow": false,
"_shadowColor": {
"__type__": "cc.Color",
"r": 0,
"g": 0,
"b": 0,
"a": 255
},
"_shadowOffset": {
"__type__": "cc.Vec2",
"x": 2,
"y": 2
},
"_shadowBlur": 2,
"_id": ""
},
{
"__type__": "cc.CompPrefabInfo",
"fileId": "f59zx54hJB37o3wtSqIGBV"
},
{
"__type__": "cc.Widget",
"_name": "",
"_objFlags": 0,
"__editorExtras__": {},
"node": {
"__id__": 130
},
"_enabled": true,
"__prefab": {
"__id__": 136
},
"_alignFlags": 8,
"_target": null,
"_left": -26.875,
"_right": 0,
"_top": 0,
"_bottom": 0,
"_horizontalCenter": 0,
"_verticalCenter": 0,
"_isAbsLeft": true,
"_isAbsRight": true,
"_isAbsTop": true,
"_isAbsBottom": true,
"_isAbsHorizontalCenter": true,
"_isAbsVerticalCenter": true,
"_originalWidth": 0,
"_originalHeight": 0,
"_alignMode": 2,
"_lockFlags": 0,
"_id": ""
},
{
"__type__": "cc.CompPrefabInfo",
"fileId": "bff7l/qFpNO5oNUSmuFSLr"
},
{
"__type__": "cc.PrefabInfo",
"root": {
"__id__": 1
},
"asset": {
"__id__": 0
},
"fileId": "dde8Se2FBP6YgwyTh2rZbf",
"instance": null,
"targetOverrides": null,
"nestedPrefabInstanceRoots": null
},
{
"__type__": "cc.UITransform",
"_name": "",
"_objFlags": 0,
"__editorExtras__": {},
"node": {
"__id__": 129
},
"_enabled": true,
"__prefab": {
"__id__": 139
},
"_contentSize": {
"__type__": "cc.Size",
"width": 49.31,
"height": 50
},
"_anchorPoint": {
"__type__": "cc.Vec2",
"x": 0.5,
"y": 0.5
},
"_id": ""
},
{
"__type__": "cc.CompPrefabInfo",
"fileId": "a7muNmCwZAKpIRc8MvTGGv"
},
{
"__type__": "cc.Label",
"_name": "",
"_objFlags": 0,
"__editorExtras__": {},
"node": {
"__id__": 129
},
"_enabled": true,
"__prefab": {
"__id__": 141
},
"_customMaterial": null,
"_srcBlendFactor": 2,
"_dstBlendFactor": 4,
"_color": {
"__type__": "cc.Color",
"r": 78,
"g": 187,
"b": 248,
"a": 255
},
"_string": "50",
"_horizontalAlign": 1,
"_verticalAlign": 1,
"_actualFontSize": 50,
"_fontSize": 50,
"_fontFamily": "Arial",
"_lineHeight": 50,
"_overflow": 0,
"_enableWrapText": true,
"_font": {
"__uuid__": "983a109b-a5e3-4ba7-84c5-1c53817ba177",
"__expectedType__": "cc.BitmapFont"
},
"_isSystemFontUsed": false,
"_spacingX": 0,
"_isItalic": false,
"_isBold": false,
"_isUnderline": false,
"_underlineHeight": 2,
"_cacheMode": 0,
"_enableOutline": true,
"_outlineColor": {
"__type__": "cc.Color",
"r": 0,
"g": 0,
"b": 0,
"a": 255
},
"_outlineWidth": 1,
"_enableShadow": false,
"_shadowColor": {
"__type__": "cc.Color",
"r": 0,
"g": 0,
"b": 0,
"a": 255
},
"_shadowOffset": {
"__type__": "cc.Vec2",
"x": 2,
"y": 2
},
"_shadowBlur": 2,
"_id": ""
},
{
"__type__": "cc.CompPrefabInfo",
"fileId": "2aXJDSKKZKIbjQcZu71V+X"
},
{
"__type__": "cc.PrefabInfo",
"root": {
"__id__": 1
},
"asset": {
"__id__": 0
},
"fileId": "38i7UtIApLjqUtKEKBvdcg",
"instance": null,
"targetOverrides": null,
"nestedPrefabInstanceRoots": null
},
{
"__type__": "cc.UITransform",
"_name": "",
"_objFlags": 0,
"__editorExtras__": {},
"node": {
"__id__": 128
},
"_enabled": true,
"__prefab": {
"__id__": 144
},
"_contentSize": {
"__type__": "cc.Size",
"width": 200,
"height": 100
},
"_anchorPoint": {
"__type__": "cc.Vec2",
"x": 0.5,
"y": 0.5
},
"_id": ""
},
{
"__type__": "cc.CompPrefabInfo",
"fileId": "59w5YrumVHsLzq3Hx6nzWc"
},
{
"__type__": "cc.PrefabInfo",
"root": {
"__id__": 1
},
"asset": {
"__id__": 0
},
"fileId": "240I/BD+VEa7lFN2Uv61xY",
"instance": null,
"targetOverrides": null,
"nestedPrefabInstanceRoots": null
},
{
"__type__": "cc.UITransform",
"_name": "",
@@ -3239,7 +3701,7 @@
},
"_enabled": true,
"__prefab": {
"__id__": 129
"__id__": 147
},
"_contentSize": {
"__type__": "cc.Size",
@@ -3267,7 +3729,7 @@
},
"_enabled": true,
"__prefab": {
"__id__": 131
"__id__": 149
},
"_id": ""
},
@@ -3285,7 +3747,7 @@
},
"_enabled": true,
"__prefab": {
"__id__": 133
"__id__": 151
},
"playOnLoad": true,
"_clips": [

File diff suppressed because it is too large Load Diff

View File

@@ -1,108 +1,98 @@
# 游戏设计文档
## 游戏核心概念
本游戏是一款单局制肉鸽Roguelike塔防游戏玩家通过策略性地选择每波怪物清理后的奖励来强化自己的英雄队伍最终挑战强大的Boss。
本游戏是一款单局制肉鸽Roguelike自走,战斗,塔防 游戏玩家通过策略性地选择每波怪物清理后的奖励来强化自己的英雄队伍最终挑战强大的Boss。
## 核心玩法机制
### 1. 自动战斗系统
- 所有攻击和战斗均为自动进行,玩家无需手动操作
- 玩家只需在每波怪物清理后选择奖励选项
- 英雄会根据配置自动释放技能攻击敌人
## 战斗
技能: 普攻技能,一般技能,必杀技能
普攻和一般技能自动触发,必杀技能默认自动触发,可以手动触发
### 2. 奖励选择系统
- 每波怪物清理后提供三种奖励选项:弱、一般、强
- 不同奖励选项消耗不同的金币数量
- 奖励类型包括:英雄强化、技能升级、装备获取、属性提升,新技能获得等
- 每个奖励有一个战力评分,评分越高,能力越强,消耗金币越多
## 天赋
风怒: 普通攻击3次后, 目标额外收到1次150%伤害
溅射: 普通攻击3次后, 会对目标100像素外的敌人额外造成30%伤害
### 3. 金币经济系统
- 金币通过击败怪物固定掉落获得
- 总体金币数量是固定的,需要玩家合理分配
- 金币用于购买奖励选项,策略性消费是游戏核心
回蓝: 普通攻击3次后恢复5%的蓝值
回血: 普通攻击3次后, 恢复5%的生命值
### 4. 特殊事件系统
- 特定关卡设置事件管卡
- 事件管卡提供特殊奖励:
- 额外金币奖励
- 额外属性加成
- 额外技能奖励
- 稀有装备获取
冰封: 普通攻击3次后, 获得5%的冻结率(可叠加,触发清零) :冻结受到伤害的目标,目标无法移动和攻击(cd继续) 3秒后自动解冻
沉默: 普通攻击3次后, 获得5%的沉默率(可叠加,触发清零) 沉默收到伤害的目标目标一般技能和必杀技能技能cd清零
击晕: 普通攻击3次后, 获得5%的击晕率(可叠加,触发清零) 击晕收到伤害的目标目标无移动和cd暂停
击退: 普通攻击3次后, 获得5%的击退率(可叠加,触发清零) :击退收到伤害的目标, cd减少5点,
会心: 普通攻击1次后, 获得5%的暴击率(可叠加,触发清零)
### 5. 评分与成就系统
- 建立评分机制评价:
- 装备评分:根据装备属性加成计算
- 技能评分:根据技能效果计算
- 杀怪数量评分:根据击败怪物数量计算
- 特殊事件奖励评分:根据特殊事件奖励计算
- 受伤评分:根据英雄受伤hp值和受伤次数进行评分
- DPS评分:根据英雄每秒伤害能力计算
- 最大伤害值评分:根据英雄最大伤害值计算
- 高评分可解锁特殊成就和奖励
熟练: 普通攻击10次后, 获得下2次一般技能触发2次
## 游戏进程设计
反击: 被攻击3次后, 给于目标50%的伤害
护盾: 被攻击3次后获得20%生命值护盾
减伤: 被攻击3次后下1次伤害减50%
### 关卡结构
1. **普通关卡**:基础怪物波次,提供常规奖励选择
2. **精英关卡**:更强的精英怪物,提供高级奖励
3. **Boss关卡**强大的Boss敌人胜利后获得丰厚奖励
4. **事件关卡**:特殊事件触发,提供独特奖励或挑战
背水: 每失去50%生命值获得下10次普通攻击暴击
### 难度递增机制
- 随着关卡推进,怪物强度逐步提升
- 后期关卡出现组合怪物群,需要策略应对
- 特殊机制随进度解锁,增加游戏深度
勤勉: 每升1级获得下5次技能暴击
## 英雄系统设计
### 英雄类型
- **战士型**:高生命值,近战输出
- **远程型**:远程攻击,较高攻击力
- **法师职业**:魔法攻击,范围伤害
- **辅助类型**:支援型技能,团队增益
- **刺客类型**:高爆发,机动性强
## 特殊状态说明
冰封: 目标无法移动和攻击(cd继续) 3秒后自动解冻
沉默: 目标一般技能和必杀技能技能cd清零
击晕: 目标无移动和cd暂停
击退: 后退15像素cd减少5点,
### 英雄成长
- 三选一奖励中,有属性提升,有技能升级,有新技能解锁,有装备获取
- 属性提升:
- 提升英雄基础属性,包括生命值、攻击力、防御力、速度等
- 提升属性值根据奖励评分确定
- 技能升级:
- 升级普通攻击技能或大招技能
- 升级后技能效果提升,消耗金币
- 新技能解锁:
- 解锁新技能,增加英雄战斗能力
- 解锁新技能后,可选择升级或不升级
- 装备获取:
- 获取新装备,增加英雄属性加成
- 装备属性根据奖励评分确定
## 非关键成长三选一(示例池)
用于非关键的成长选项,提供小步稳定增益,不抢关键天赋存在感。数值为建议区间,可按实际平衡调整。
### 技能系统
- 每个英雄拥初始拥有1个普通攻击技能和大招技能,技能消耗mp值和固定cd
- 后续通过,每次的奖励可选择升级普通攻击技能、大招技能或新技能
-
| 组别 | 选项A | 选项B | 选项C | 推荐数值范围 | 阶段建议 | 说明 |
| --- | --- | --- | --- | --- | --- | --- |
| 基础属性(点数) | 力量 +3 | 智力 +3 | 敏捷 +3 | +3 点 | 全阶段 | 走职业系数转化,稳定推动 HP/AP/MAP/AS 等 |
| 攻速系 | 攻速(AS) +10% | 技速(SS) +10% | 移速(SPEED) +8% | +812% | 中期 | 普攻/技能循环提速,维持心流 |
| 暴击系 | 暴击率(CRITICAL) +10% | 暴伤(CRITICAL_DMG) +15% | 命中(HIT) +8% | +815% | 中后期 | 命中稳态配合暴击上限,防过度摇摆 |
| 射击系 | 攻击距离(DIS) +10% | 作用范围(AOE) +10% | 穿透(PIERCE) +1 | +812% / +1 | 中期 | 影响站位与清杂效率PIERCE建议≤2 |
| 生存上限 | 生命上限(HP_MAX) +10% | 护盾上限(SHIELD_MAX) +12% | 生命回复(HP_REGEN) +15% | +1015% | 早期 | 提升容错,抗压波次优先出现 |
| 防御姿态 | 闪避(DODGE) +8% | 格挡(BLOCK) +10% | 减伤(DMG_RED) +10% | +810% | 中期 | 三防不叠加过猛,设软上限 5060% |
| 元素抗性 | 冰抗(ICE_RES) +12% | 火抗(FIRE_RES) +12% | 风抗(WIND_RES) +12% | +1012% | 中后期 | 元素场景针对性减伤,补短板 |
| 元素伤害 | 冰伤(ICE_POWER) +10% | 火伤(FIRE_POWER) +10% | 风伤(WIND_POWER) +10% | +810% | 中期 | 与技能元素类型联动,避免单系过度 |
| 控制概率 | 眩晕(STUN_CHANCE) +6% | 沉默(SILENCE_CHANCE) +6% | 减速(SLOW_CHANCE) +10% | +610% | 中期 | 软控为主CD/停顿联动合理抑制强控链 |
| 妨害状态 | 冻结(FREEZE_CHANCE) +6% | 中毒(POISON_CHANCE) +8% | 燃烧(BURN_CHANCE) +8% | +68% | 中期 | 面向清杂、溃散,触发期望受控 |
| 蓝量循环 | 蓝上限(MP_MAX) +10% | 蓝回复(MP_REGEN) +15% | 吸蓝(MANASTEAL) +6% | +1015% | 早中期 | 技能密度稳定来源,支撑法系 |
| 续航强化 | 吸血(LIFESTEAL) +6% | 治疗效果(HEAL_EFFECT) +12% | 护盾效果(SHIELD_UP) +12% | +612% | 中后期 | 对应不同生存风格,数值递减避免堆满 |
| 稳定系 | 命中(HIT) +10% | 控抗(CON_RES) +10% | 暴抗(CRITICAL_RESIST) +10% | +810% | 中后期 | 降低波动,克制高暴击/高控敌群 |
| 经济成长 | 经验(EXP_GAIN) +10% | 金币(GOLD_GAIN) +10% | 掉落(DROP_CHANCE) +8% | +810% | 转场期 | 低战力节点给经济,避免战斗失衡 |
| 复活保障 | 复活次数(REVIVE_COUNT) +1 | 无敌时间(INVINCIBLE_TIME) +1s | 复活时间(REVIVE_TIME) -10% | +1 / +1s / -10% | 后期 | 高压波次救命,不与关键天赋冲突 |
| 元素对抗 | 物抗(PHYS_RES) +10% | 魔抗(MAGIC_RES) +10% | 物伤加成(PHYS_POWER) +8% | +810% | 中后期 | 根据敌群构成动态出现 |
| 资源提效 | 技能持续(SKILL_DURATION) +8% | 范围(AOE) +10% | 技速(SS) +8% | +810% | 中期 | DOT/场控/召唤类技能收益更佳 |
## 策略深度设计
## 设计理念
- 非关键增益:提供轻量、可叠加的稳定成长,不与关键三选一争夺注意力。
- ERG需求存在(生存)–关系(交互与反馈)–成长(能力提升)均衡覆盖,维持心流。
- 小步快跑:每次选择形成可感知的小增量,累计 35 次后出现显著体感。
- 动态补偿:三选一含“补缺/增强/探索”三类,提高决策质量与多样性。
- 软上限与递减:概率类、穿透等设软上限并递减,避免极端堆叠破坏体验。
### Build构筑
- 玩家通过不同奖励选择形成独特的英雄Build
- 鼓励尝试不同的流派和策略组合
- 多样化的成长路径提供重玩价值
## 出现规则与阶段
- 频率:每 23 波或每升 2 级出现一次,单局给予 35 次非关键成长选择。
- 阶段:早期主生存与蓝量,中期主效率与控制,后期主稳定与复活保障。
- 去重:同池短时间不重复,鼓励构筑分散与策略多样性。
- 池权重:根据敌群/技能元素/职业类型动态调整池权重,提升贴合度。
### 资源管理
- 固定金币总量要求玩家合理分配资源
- 不同奖励选项的价值评估增加策略性
- 短期收益与长期发展之间的权衡
## 数值与软上限建议
- 概率类软上限 5060%,暴击率软上限 6070%,穿透 ≤ 2。
- 递减系数:同类堆叠每层收益降低 1530%,维持平衡与选择张力。
## 界面与交互设计
## IAA激励可选
- 单局一次:允许“刷新一次三选一”或“临时解锁第四备选(低权重强项)”。
- 公平性:激励数值较同池低 1020%,避免破坏对局公平与关键天赋权重。
### 核心界面
1. **战斗界面**:显示英雄、怪物、战斗过程
2. **奖励选择界面**:三选一奖励展示与选择
3. **英雄信息界面**:查看英雄属性、技能、装备
4. **关卡进度界面**:显示当前关卡进度和目标
### 交互逻辑
- 简化操作,主要通过点击进行选择
- 清晰的视觉反馈显示战斗结果
- 直观的奖励预览帮助玩家决策
## 落地建议
- 配置复用:非关键三选一统一走天赋 `BUFF` 模式,即时或升级触发。
- 属性枚举:在 TalSet 的 `TalAttrs` 扩充基础属性(HP/MP/AS/SS/CRITICAL/HIT 等)。
- 阶段配表:按波次/等级给不同池的权重与范围,避免压制关键天赋。
- 上限与递减:对核心概率类与强度类属性设置软上限与递减曲线。
## 与代码映射(实现参考)
- 触发类型:可用升级或初始触发,见 `assets/script/game/common/config/TalSet.ts:7` 枚举。
- 效果类型:建议统一使用 `TalEffet.BUFF` + `vType(BType.VALUE/RATIO)`
- 可选属性来源:`assets/script/game/common/config/HeroAttrs.ts:27113` 定义完整 `Attrs`
- 职业成长差异:`assets/script/game/common/config/HeroAttrs.ts:272422` 提供成长系数。
- 攻速/技速影响CD`assets/script/game/hero/HeroSkills.ts:139158`
- 命中/闪避/暴击联动:`assets/script/game/hero/HeroAtkSystem.ts:141162`
- 元素伤害与抗性修正:`assets/script/game/hero/HeroAtkSystem.ts:295306`
- 护盾吸收:`assets/script/game/hero/HeroAtkSystem.ts:422450`

11
assets/script/ecs.md.meta Normal file
View File

@@ -0,0 +1,11 @@
{
"ver": "1.0.1",
"importer": "text",
"imported": true,
"uuid": "1f3ba9b7-02ad-406f-86b3-895009bcb3e7",
"files": [
".json"
],
"subMetas": {},
"userData": {}
}

View File

@@ -63,5 +63,4 @@ export enum GameEvent {
GOLD_UPDATE = "GOLD_UPDATE",
DIAMOND_UPDATE = "DIAMOND_UPDATE",
MEAT_UPDATE = "MEAT_UPDATE",
HeroSpeek = "HeroSpeek",
}

View File

@@ -14,19 +14,11 @@ export enum BoxSet {
DEFAULT = 1,
MONSTER = 2,
HERO = 4,
// MONSTER_SKILL = 8,
// HERO_SKILL = 16,
// PLAYER=32,
// BOSS=64,
// BOX_WIDTH = 64,
// BOX_HEIGHT = 64,
//地图边界
LETF_END = -420,
RIGHT_END = 420,
//游戏地平线
GAME_LINE = 0,
GAME_LINE = 120,
//攻击距离
}
@@ -97,6 +89,8 @@ export enum FightSet {
ATK_ADD_COUNT=4,//伙伴攻击力增加
ATK_ADD_GLOD=1,//金币增加
CRIT_DAMAGE=50,//暴击伤害
DEF_C=100,//物理防御常数C
MDEF_C=100,//魔法防御常数C
DOUBLE_ATK_RATE=100,//额外攻击默认概率
GREEN_GOLD=1,//绿色金币
BLUE_GOLD=2,//蓝色金币
@@ -152,4 +146,5 @@ export const TooltipTypes = {
lvup:6,
apup:7,
hpup:8,
addmp:9,
}

View File

@@ -12,23 +12,12 @@ export enum BType {
}
export enum NeAttrs {
IN_FROST = 0,
IN_STUN = 1,
IN_BURN = 2,
IN_POISON = 3,
}
export const getNeAttrs = () => {
let reAttrs = {};
Object.keys(NeAttrs).forEach(key => {
if (!isNaN(Number(key))) {
reAttrs[Number(key)] = {
value: 0,
time: 0,
};
}
});
return reAttrs;
IN_FROST = 0, // 冰冻状态
IN_STUN = 1, // 眩晕状态
IN_BURN = 2, // 灼烧状态
IN_POISON = 3, // 中毒状态
}
// ========== 属性枚举 ==========
/**
* 英雄属性枚举
@@ -43,8 +32,6 @@ export enum Attrs {
HP_REGEN = 3, // 生命回复
MP_REGEN = 4, // 魔法回复
HEAL_EFFECT = 5, // 治疗效果
POW_MAX = 6, // 最大怒气值
POW_REGEN = 7, // 怒气值回复
// ========== 攻击属性 (10-19) ==========
AP = 10, // 攻击力
@@ -61,11 +48,10 @@ export enum Attrs {
MDEF = 21, // 魔法防御
DODGE = 22, // 闪避率
BLOCK = 23, // 格挡率
DAMAGE_REDUCTION = 24, // 伤害减免
DMG_RED = 24, // 伤害减免
THORNS = 25, // 反伤
CRITICAL_RESIST = 26, // 暴击抗性
CON_RES = 27, // 控制抗性
MAGIC_RES = 28, // 魔法抗性
// ========== 暴击与命中属性 (30-39) ==========
CRITICAL = 30, // 暴击率
@@ -76,9 +62,13 @@ export enum Attrs {
ICE_RES = 40, // 冰冻抗性
FIRE_RES = 41, // 火焰抗性
WIND_RES = 42, // 自然抗性
ICE_POWER = 43, // 冰冻伤害加成
FIRE_POWER = 44, // 火焰伤害加成
WIND_POWER = 45, // 自然伤害加成
PHYS_RES = 43, // 物理抗性
MAGIC_RES = 44, // 魔法抗性
ICE_POWER = 45, // 冰冻伤害加成
FIRE_POWER = 46, // 火焰伤害加成
WIND_POWER = 47, // 自然伤害加成
PHYS_POWER = 48, // 物理伤害加成
MAGIC_POWER= 49,
// ========== 特殊效果属性 (50-59) ==========
@@ -87,10 +77,10 @@ export enum Attrs {
FREEZE_CHANCE = 52, // 冰冻概率
BURN_CHANCE = 53, // 燃烧概率
STUN_CHANCE = 54, // 眩晕概率
KNOCKBACK = 55, // 击退概率
BACK_CHANCE = 55, // 击退概率
SLOW_CHANCE = 56, // 减速概率
POISON_CHANCE = 57, // 中毒概率
CHAIN_CHANCE = 58, // 连锁概率
SILENCE_CHANCE = 58, // 沉默概率
EXPLOSION_CHANCE = 59, // 爆炸概率
// ========== 增益效果属性 (60-69) ==========
@@ -108,16 +98,13 @@ export enum Attrs {
// ========== 武器进化相关 (70-79) ==========
PUNCTURE = 70, // 穿刺次数
PUNCTURE_DMG = 71, // 穿刺伤害
BACK = 73, // 被击退概率(兼容旧代码)
MOVE_SPEED = 74, // 移动速度
BURN = 75, // 易伤效果
WFUNY = 77, // 风怒
// ========== 生存与恢复相关 (80-89) ==========
// ========== 负面状态相关 (90-99) ==========
// ========== 基础属性(影响其他属性)(100-104) ==========
// ========== 负面状态相关 (80-89) ==========
DMG_INVUL = 80, //易伤
// ========== 基础属性(影响其他属性) (90-99)==========
STRENGTH = 90, // 力量(影响物理相关)
INTELLIGENCE = 91, // 智力(影响魔法相关)
AGILITY = 92, // 敏捷(影响速度和闪避)
@@ -141,6 +128,18 @@ export const getAttrs = () => {
return reAttrs;
}
export const getNeAttrs = () => {
let reAttrs = {};
Object.keys(NeAttrs).forEach(key => {
if (!isNaN(Number(key))) {
reAttrs[Number(key)] = {
value: 0,
time: 0,
};
}
});
return reAttrs;
}
/**
* 属性类型配置表
* 用于区分每个属性是数值型还是百分比型
@@ -155,8 +154,6 @@ export const AttrsType: Record<Attrs, BType> = {
[Attrs.SHIELD_MAX]: BType.VALUE, // 最大护盾值 - 数值型
[Attrs.HP_REGEN]: BType.VALUE, // 生命回复 - 数值型
[Attrs.MP_REGEN]: BType.VALUE, // 魔法回复 - 数值型
[Attrs.POW_MAX]: BType.VALUE, // 最大怒气值 - 数值型
[Attrs.POW_REGEN]: BType.VALUE, // 怒气值回复 - 数值型
[Attrs.HEAL_EFFECT]: BType.RATIO, // 治疗效果 - 百分比型
// ========== 攻击属性(数值型) ==========
@@ -174,7 +171,7 @@ export const AttrsType: Record<Attrs, BType> = {
[Attrs.MDEF]: BType.VALUE, // 魔法防御 - 数值型
[Attrs.DODGE]: BType.RATIO, // 闪避率 - 百分比型
[Attrs.BLOCK]: BType.RATIO, // 格挡率 - 百分比型
[Attrs.DAMAGE_REDUCTION]: BType.RATIO, // 伤害减免 - 百分比型
[Attrs.DMG_RED]: BType.RATIO, // 伤害减免 - 百分比型
[Attrs.THORNS]: BType.RATIO, // 反伤 - 百分比型
// ========== 暴击与命中属性(百分比型) ==========
@@ -183,15 +180,19 @@ export const AttrsType: Record<Attrs, BType> = {
[Attrs.HIT]: BType.RATIO, // 命中率 - 百分比型
[Attrs.CRITICAL_RESIST]: BType.RATIO, // 暴击抗性 - 百分比型
[Attrs.CON_RES]: BType.RATIO, // 控制抗性 - 百分比型
[Attrs.MAGIC_RES]: BType.RATIO, // 魔法抗性 - 百分比型
// ========== 元素属性(百分比型) ==========
[Attrs.ICE_RES]: BType.RATIO, // 冰冻抗性 - 百分比型
[Attrs.FIRE_RES]: BType.RATIO, // 火焰抗性 - 百分比型
[Attrs.WIND_RES]: BType.RATIO, // 风抗性 - 百分比型
[Attrs.PHYS_RES]: BType.RATIO, // 物理抗性 - 百分比型
[Attrs.MAGIC_RES]:BType.RATIO,
[Attrs.ICE_POWER]: BType.RATIO, // 冰冻伤害加成 - 百分比型
[Attrs.FIRE_POWER]: BType.RATIO, // 火焰伤害加成 - 百分比型
[Attrs.WIND_POWER]: BType.RATIO, // 风伤害加成 - 百分比型
[Attrs.PHYS_POWER]: BType.RATIO, // 物理伤害加成 - 百分比型
[Attrs.MAGIC_POWER]: BType.RATIO, // 物理伤害加成 - 百分比型
// ========== 特殊效果属性(百分比型) ==========
[Attrs.LIFESTEAL]: BType.RATIO, // 吸血比率 - 百分比型
@@ -199,10 +200,10 @@ export const AttrsType: Record<Attrs, BType> = {
[Attrs.FREEZE_CHANCE]: BType.RATIO, // 冰冻概率 - 百分比型
[Attrs.BURN_CHANCE]: BType.RATIO, // 燃烧概率 - 百分比型
[Attrs.STUN_CHANCE]: BType.RATIO, // 眩晕概率 - 百分比型
[Attrs.KNOCKBACK]: BType.RATIO, // 击退 - 百分比型
[Attrs.BACK_CHANCE]: BType.RATIO, // 击退概率 - 百分比型
[Attrs.SLOW_CHANCE]: BType.RATIO, // 减速概率 - 百分比型
[Attrs.POISON_CHANCE]: BType.RATIO, // 中毒概率 - 百分比型
[Attrs.CHAIN_CHANCE]: BType.RATIO, // 连锁概率 - 百分比型
[Attrs.SILENCE_CHANCE]: BType.RATIO, // 沉默概率 - 百分比型
[Attrs.EXPLOSION_CHANCE]: BType.RATIO, // 爆炸概率 - 百分比型
// ========== 增益效果属性(百分比型) ==========
@@ -220,14 +221,13 @@ export const AttrsType: Record<Attrs, BType> = {
// ========== 武器进化相关(混合类型) ==========
[Attrs.PUNCTURE]: BType.VALUE, // 穿刺次数 - 数值型
[Attrs.PUNCTURE_DMG]: BType.RATIO, // 穿刺伤害 - 百分比型
[Attrs.BACK]: BType.RATIO, // 被击退概率(兼容)- 百分比型
[Attrs.MOVE_SPEED]: BType.VALUE, // 移动速度 - 数值型
[Attrs.BURN]: BType.RATIO, // 易伤效果 - 百分比型
[Attrs.WFUNY]: BType.RATIO, // 未知特殊属性 - 百分比型
// ========== 生存与恢复相关(混合类型) ==========
// ========== 负面状态相关(混合类型) ==========
[Attrs.DMG_INVUL]: BType.RATIO, //易伤
// ========== 基础属性(数值型) ==========
[Attrs.STRENGTH]: BType.VALUE, // 力量 - 数值型

View File

@@ -1,5 +1,12 @@
// ========== 从 HeroAttrs.ts 导入属性相关定义 ==========
import { Attrs, NeAttrs,BType, getAttrs, AttrsType, isRatioAttr } from "./HeroAttrs";
export enum HSSet {
atk = 0, // 普通攻击
skill = 1, // 一般技能
max = 2, // 必杀技
}
export enum TGroup {
Self = 0, // 自身
Ally = 1, // 所有敌人
@@ -74,7 +81,6 @@ export enum EType {
//debuff类型
/*
=== 技能配置系统使用说明 ===
@@ -100,6 +106,7 @@ export enum EType {
- ap: 攻击力百分比
- cd: 冷却时间
- hit_num: 范围攻击 伤害敌人数量
- t_num: 目标数量
- hit: 穿刺个数
- hitcd: 持续伤害的伤害间隔
- speed: 移动速度
@@ -107,7 +114,9 @@ export enum EType {
*/
export enum DType {
ATK= 0, // 物理
MAGE=1, // 魔法
ICE=1, // 冰元素
FIRE=2, // 火元素
WIND=3, // 风元素
}
export const HeroSkillList = [6001,6001,6001,6001,6001,6001]
@@ -144,26 +153,30 @@ interface IEndAnm {
// 技能配置接口 - 按照6001格式排列
export interface SkillConfig {
uuid:number,name:string,sp_name:string,icon:string,TGroup:TGroup,SType:SType,act:string,DTType:DTType,DType:DType,
ap:number,cd:number,t_num:number,hit_num:number,hit:number,hitcd:number,speed:number,cost:number,with:number,dis:Number,ready:number,EAnm:number,DAnm:number,RType:RType,EType:EType,
ap:number,map:number,cd:number,t_num:number,hit_num:number,hit:number,hitcd:number,speed:number,cost:number,with:number,dis:Number,ready:number,EAnm:number,DAnm:number,RType:RType,EType:EType,
buffs:BuffConf[],neAttrs:NeAttrsConf[],info:string,hero?:number ,
}
export const SkillSet: Record<number, SkillConfig> = {
5000:{uuid:5000,name:"反伤",sp_name:"thorns",icon:"3036",TGroup:TGroup.Enemy,SType:SType.damage,act:"atk",DTType:DTType.single,DType:DType.ATK,
ap:0,map:0,cd:0,t_num:1,hit_num:1,hit:1,hitcd:0.2,speed:720,cost:0,with:0,dis:80,ready:0,EAnm:0,DAnm:9001,RType:RType.fixed,EType:EType.animationEnd,
buffs:[],neAttrs:[],info:"反伤",
},
// ========== 基础攻击 ========== 6001-6099
6001: {
uuid:6001,name:"挥击",sp_name:"atk_s1",icon:"3036",TGroup:TGroup.Enemy,SType:SType.damage,act:"atk",DTType:DTType.single,DType:DType.ATK,
ap:100,cd:1,t_num:1,hit_num:1,hit:1,hitcd:0.2,speed:720,cost:0,with:0,dis:80,ready:0,EAnm:0,DAnm:9001,RType:RType.fixed,EType:EType.animationEnd,
ap:100,map:0,cd:1,t_num:1,hit_num:1,hit:1,hitcd:0.2,speed:720,cost:0,with:0,dis:80,ready:0,EAnm:0,DAnm:9001,RType:RType.fixed,EType:EType.animationEnd,
buffs:[],neAttrs:[],info:"向最前方敌人扔出石斧,造成100%攻击的伤害",
},
6002: {
uuid:6002,name:"挥砍",sp_name:"atk_s4",icon:"3036",TGroup:TGroup.Enemy,SType:SType.damage,act:"atk",DTType:DTType.single,DType:DType.ATK,
ap:100,cd:1,t_num:1,hit_num:1,hit:1,hitcd:0.2,speed:720,cost:0,with:0,dis:80,ready:0,EAnm:0,DAnm:9001,RType:RType.fixed,EType:EType.animationEnd,
ap:100,map:0,cd:1,t_num:1,hit_num:1,hit:1,hitcd:0.2,speed:720,cost:0,with:0,dis:80,ready:0,EAnm:0,DAnm:9001,RType:RType.fixed,EType:EType.animationEnd,
buffs:[],neAttrs:[],info:"向最前方敌人扔出石斧,造成100%攻击的伤害",
},
6005: {
uuid:6005,name:"水球",sp_name:"m_water_ball_1",icon:"3039",TGroup:TGroup.Enemy,SType:SType.damage,act:"atk",DTType:DTType.single,DType:DType.MAGE,
ap:100,cd:5,t_num:1,hit_num:1,hit:2,hitcd:0.3,speed:720,cost:0,with:90,dis:360,ready:8001,EAnm:0,DAnm:9001,RType:RType.linear,EType:EType.collision,
buffs:[],neAttrs:[],info:"召唤大火球攻击前方所有敌人,造成300%攻击的伤害,有一定几率施加灼烧",
uuid:6005,name:"水球",sp_name:"m_water_ball_1",icon:"3039",TGroup:TGroup.Enemy,SType:SType.damage,act:"atk",DTType:DTType.single,DType:DType.ICE,
ap:0,map:100,cd:5,t_num:1,hit_num:1,hit:2,hitcd:0.3,speed:720,cost:0,with:90,dis:360,ready:8001,EAnm:0,DAnm:9001,RType:RType.linear,EType:EType.collision,
buffs:[],neAttrs:[],info:"召唤球攻击前方敌人,造成100%魔法攻击的伤害",
},
};

View File

@@ -1,56 +1,76 @@
/**
* 天赋系统配置文件
* 支持定义英雄的特殊能力或特性
*/
import { count } from "console";
import { Attrs, BType } from "./HeroAttrs";
import { SkillSet } from "./SkillSet";
// ========== 枚举定义 ==========
/**
* 天赋类型枚举,也是触发条件
*/
export enum TalType {
LEVEL = 1, // 基于特定等级触发
LEVEL_UP = 2, // 基于等级升级触发
ACTION_COUNT = 3, // 基于普通攻击触发, skills[0]计数触发
SKILL_COUNT = 4, // 基于技能触发, > skills[0]计数触发
DAMAGE_COUNT = 5, // 基于受伤次数触发
INIT = 6, // 初始触发,如:多1个技能
DEAD = 7 // 基于死亡触发
}
/**
* 触发效果
*/
export enum TalEType {
ATTRS = 1, // 属性修改
SKILL = 2, // 技能触发
SKILL_MORE = 3, // 天生多1个技能
export enum TriType {
LUP = 1, // 等级触发
ATK = 2, //普通攻击触发
DMG = 3, // 受伤触发
SKILL = 4, // 技能触发
MAX = 5, // 必杀触发
HPL = 6, // 失去生命值触发
HPA = 7, // 获得生命值触发
INIT = 8, // 初始触发,如:多1个技能
DEAD = 9, // 基于死亡触发
}
export enum TalEffet {
ATK_DMG=1, // 伤害 次数+伤害加成如额外5次 伤害+20%
SKILL_DMG=2, // 技能伤害 次数+伤害加成如额外5次 伤害+20%
DMG_RED=10, // 减伤 次数+减伤加成如额外5次 伤害-20%
THORNS=14, //反伤 百分比 次数+反伤加成如额外5次 反伤-20%
///////////////////////////////////////////////////////////////////////
HP=3, // 回血 百分比 直接触发回血20%
MP=4, //回蓝 百分比 直接触发回蓝20%
SHIELD=9, // 护盾 直接触发获得20%的生命值护盾
////////////////////////////////////////////////////////////////////////
BUFF = 5, // 数值叠加 触发后清零: 暴击率,闪避率等,触发后效果取消
////////////////////////////////////////////////////////////////////////////////
STATS=6, // 状态 待定
WFUNY=7, // 风怒 次数 叠加 如额外5次 风怒
D_SKILL=8, //两次技能 次数 叠加如额外5次 两次技能
C_MSKILL=11, // 必杀技能必暴 次数 叠加 如额外5次 必杀技能必暴
C_ATK=12, // 普工必爆 次数 叠加 如额外5次 普工必爆
C_SKILL=13, // 一般技能必暴 次数 叠加 如额外5次 一般技能必暴
}
export enum TalTarget {
SELF = 1, // 自己触发
ENEMY = 2, // 敌人触发
}
export enum TalAttrs {
NON=0,
FREEZE_CHANCE=Attrs.FREEZE_CHANCE, // 冰冻概率
STUN_CHANCE=Attrs.STUN_CHANCE, // 冰冻概率
BACK_CHANCE=Attrs.BACK_CHANCE, // 击退概率
SILENCE_CHANCE=Attrs.SILENCE_CHANCE, // 沉默概率
CRITICAL=Attrs.CRITICAL, // 暴击率
AP=Attrs.AP, // 攻击力
MP=Attrs.MAP, // 魔法攻击力
}
/**
* 天赋配置接口
* 定义一个完整的天赋效果
*/
export interface ItalConf {
uuid: number; // 天赋ID
name: string; // 天赋名称
triType: TriType;
target: TalTarget;
effet: TalEffet;
vType:BType; //数值型还是百分比型
value: number; // 触发的效果值如增加10%攻击力, 触发的技能uuid,增加1个技能uuid
attrs?:TalAttrs //触发的attrs效果的对应attrs
Trigger:number //触发值
desc: string; // 天赋描述(说明触发条件和效果)
type: TalType;
triggerType: TalEType; // 触发效果类型
chance: number; // 触发概率,默认100,`0-100`之间的数字
t_value: number; // 触发的阈值如5级触发一次, 5次攻击触发一次,初始触发)
e_value: number; // 触发的效果值如增加10%攻击力, 触发的技能uuid,增加1个技能uuid
e_name: number; // 触发的特殊值,如具体属性类型, 0表示没有特定值,对应Attrs枚举
e_type: BType; // 效果类型, 主要针对属性修改,是百分比还是固定值
e_scaling: number; // 效果随等级缩放系数,默认1, 0.5表示效果随等级减半
e_count: number; // 触发效果的累计次数如触发2次技能实现召唤2个召唤物
stackable?: boolean; // 是否可堆叠效果默认true
maxStack?: number; // 最大堆叠次数(不设置表示无限制)
count:number //执行次数,及可以触发的次数
}
// ========== 天赋配置表 ==========
@@ -70,44 +90,43 @@ export interface ItalConf {
* 4. 技能触发类:当特定条件满足时自动触发指定技能
*/
export const talConf: Record<number, ItalConf> = {
// ========== 等级类天赋 ==========
/*** 普通攻击触发 ***/
7001:{uuid:7001,name:"风怒",triType:TriType.ATK,Trigger:3,count:1,target:TalTarget.ENEMY,effet:TalEffet.WFUNY,vType:BType.RATIO, value:50,attrs:TalAttrs.NON,
desc:"普通攻击3次后, 立即给与目标150%伤害的额外打击"},
// 剑意提升 - 刘邦专属 | 每5级 | 攻击力+10%
7001: {uuid: 7001, name: "剑意提升", desc: "每升5级攻击力增加10%", type: TalType.LEVEL_UP, triggerType: TalEType.ATTRS,
chance: 100, t_value: 5, e_value: 0.10, e_name: Attrs.AP, e_type: BType.RATIO, e_scaling: 1, e_count: 1, stackable: true, maxStack: 10},
7003:{uuid:7003,name:"回血",triType:TriType.ATK,Trigger:3,count:1,target:TalTarget.SELF,effet:TalEffet.HP,vType:BType.RATIO, value:1,attrs:TalAttrs.NON,
desc:"普通攻击3次后, 会回复10%的生命值"},
7004:{uuid:7004,name:"回蓝",triType:TriType.ATK,Trigger:3,count:1,target:TalTarget.SELF,effet:TalEffet.MP,vType:BType.RATIO, value:1,attrs:TalAttrs.NON,
desc:"普通攻击3次后, 会回复10%的蓝值"},
7005:{uuid:7005,name:"冰冻",triType:TriType.ATK,Trigger:3,count:1,target:TalTarget.ENEMY,effet:TalEffet.BUFF,vType:BType.RATIO, value:5,attrs:TalAttrs.FREEZE_CHANCE,
desc:"普通攻击3次后, 获得5%的冻结率"},
7006:{uuid:7006,name:"沉默",triType:TriType.ATK,Trigger:3,count:1,target:TalTarget.ENEMY,effet:TalEffet.BUFF,vType:BType.RATIO, value:5,attrs:TalAttrs.SILENCE_CHANCE,
desc:"普通攻击3次后, 获得5%的沉默率"},
7007:{uuid:7007,name:"击退",triType:TriType.ATK,Trigger:3,count:1,target:TalTarget.ENEMY,effet:TalEffet.BUFF,vType:BType.RATIO, value:5,attrs:TalAttrs.BACK_CHANCE,
desc:"普通攻击3次后, 获得5%的击退率"},
7008:{uuid:7008,name:"会心",triType:TriType.ATK,Trigger:3,count:1,target:TalTarget.SELF,effet:TalEffet.BUFF,vType:BType.RATIO, value:5,attrs:TalAttrs.CRITICAL,
desc:"普通攻击3次后, 获得5%的暴击率"},
7009:{uuid:7009,name:"眩晕",triType:TriType.ATK,Trigger:3,count:1,target:TalTarget.ENEMY,effet:TalEffet.BUFF,vType:BType.RATIO, value:5,attrs:TalAttrs.STUN_CHANCE,
desc:"普通攻击3次后, 获得5%的眩晕率"},
7010:{uuid:7010,name:"熟练",triType:TriType.ATK,Trigger:10,count:1,target:TalTarget.SELF,effet:TalEffet.D_SKILL,vType:BType.RATIO, value:0,attrs:TalAttrs.NON,
desc:"普通攻击10次后, 下次一般技能额外释放1次,伤害100%"},
// 胡服骑射 - 赵武灵王专属 | 每3级 | 攻击速度+5%
7002: {uuid: 7002, name: "胡服骑射", desc: "每升3级攻击速度增加5%", type: TalType.LEVEL_UP, triggerType: TalEType.ATTRS,
chance: 100, t_value: 3, e_value: 0.05, e_name: Attrs.AS, e_type: BType.RATIO, e_scaling: 1.2, e_count: 1, stackable: true, maxStack: 15},
/*** 受伤触发 ***/
7101:{uuid:7101,name:"反击",triType:TriType.DMG,Trigger:3,count:1,target:TalTarget.ENEMY,effet:TalEffet.ATK_DMG,vType:BType.RATIO, value:50,attrs:TalAttrs.NON,
desc:"被攻击3次后, 给于目标50%的伤害"},
7102:{uuid:7102,name:"护盾",triType:TriType.DMG,Trigger:3,count:1,target:TalTarget.SELF,effet:TalEffet.SHIELD,vType:BType.RATIO, value:20,attrs:TalAttrs.NON,
desc:"被攻击3次后, 获得20%的生命值护盾"},
7103:{uuid:7103,name:"减伤",triType:TriType.DMG,Trigger:3,count:1,target:TalTarget.ENEMY,effet:TalEffet.DMG_RED,vType:BType.RATIO, value:50,attrs:TalAttrs.NON,
desc:"被攻击3次后, 下1次伤害减50%"},
// 运筹帷幄 - 张良专属 | 每4级 | 魔法攻击力+8%
7004: {uuid: 7004, name: "运筹帷幄", desc: "每升4级魔法攻击力增加8%", type: TalType.LEVEL_UP, triggerType: TalEType.ATTRS,
chance: 100, t_value: 4, e_value: 0.08, e_name: Attrs.MAP, e_type: BType.RATIO, e_scaling: 1.3, e_count: 1, stackable: true, maxStack: 12},
// 后勤保障 - 萧何专属 | 每6级 | 生命回复+3点
7006: {uuid: 7006, name: "后勤保障", desc: "每升6级生命回复增加3点", type: TalType.LEVEL_UP, triggerType: TalEType.ATTRS,
chance: 100, t_value: 6, e_value: 3, e_name: Attrs.HP_REGEN, e_type: BType.VALUE, e_scaling: 1, e_count: 1, stackable: true, maxStack: 8},
/*** 失去血量触发 ***/
7201:{uuid:7201,name:"背水",triType:TriType.HPL,Trigger:50,count:10,target:TalTarget.SELF,effet:TalEffet.C_ATK,vType:BType.VALUE, value:0,attrs:TalAttrs.NON,
desc:"每失去50%生命值,获得下10次普通攻击暴击"},
// 离骚诗韵 - 屈原专属 | 每8次攻击 | 火焰伤害+2%
7101: {uuid: 7101, name: "离骚诗韵", desc: "每攻击8次触发火焰buff,火焰山航海加成增加2%,持续10秒", type: TalType.ACTION_COUNT, triggerType: TalEType.SKILL,
chance: 100, t_value: 8, e_value: SkillSet[6005].uuid, e_name: 0, e_type: BType.VALUE, e_scaling: 1, e_count: 1, stackable: true, maxStack: 15},
// ========== 初始触发类天赋 ==========
// 霸王之威 - 项羽专属 | 初始 | 生命值+100
7201: {uuid: 7201, name: "霸王之威", desc: "初始获得额外100点生命值", type: TalType.INIT, triggerType: TalEType.ATTRS,
chance: 100, t_value: 1, e_value: 100, e_name: Attrs.HP_MAX, e_type: BType.VALUE, e_scaling: 1, e_count: 1, stackable: false},
// 兵圣之道 - 孙武专属 | 初始 | 额外技能
7202: {uuid: 7202, name: "兵圣之道", desc: "初始获得额外一个技能", type: TalType.INIT, triggerType: TalEType.SKILL_MORE,
chance: 100, t_value: 1, e_value: SkillSet[6005].uuid, e_name: 0, e_type: BType.VALUE, e_scaling: 1, e_count: 1, stackable: false},
// ========== 受伤触发类天赋 ==========
// 坚韧意志 - 通用 | 每3次受伤 | 防御力+2点
7301: {uuid: 7301, name: "坚韧意志", desc: "每受伤3次50%纪律,触发[坚韧意志],防御力增加2点,持续10秒", type: TalType.DAMAGE_COUNT, triggerType: TalEType.SKILL,
chance: 50, t_value: 3, e_value: SkillSet[6005].uuid, e_name: 0, e_type: BType.VALUE, e_scaling: 1, e_count: 1, stackable: true, maxStack: 12},
// ========== 特定等级触发类天赋 ==========
// 坚韧意志 - 通用 | 每3次受伤 | 防御力+2点
7401: {uuid: 7401, name: "坚韧意志", desc: "20级是获得[坚韧意志]技能,防御力增加2点,持续10秒", type: TalType.LEVEL, triggerType: TalEType.SKILL_MORE,
chance: 100, t_value: 20, e_value: SkillSet[6005].uuid, e_name: 0, e_type: BType.VALUE, e_scaling: 1, e_count: 1, stackable: true, maxStack: 12},
/*** 升级触发 ***/
7301:{uuid:7301,name:"勤勉",triType:TriType.LUP,Trigger:1,count:5,target:TalTarget.SELF,effet:TalEffet.C_SKILL,vType:BType.VALUE, value:0,attrs:TalAttrs.NON,
desc:"每升1级,获得下5次技能暴击"},
};

View File

@@ -1,5 +1,5 @@
import { v3 } from "cc"
import { FacSet } from "./GameSet"
import { BoxSet, FacSet } from "./GameSet"
import { smc } from "../SingletonModuleComp"
import { BuffConf } from "./SkillSet"
@@ -46,23 +46,23 @@ export const getMonList = ()=>{
}
export const HeroPos={
0:{pos:v3(-240,120,0)},
1:{pos:v3(0,120,0)},
2:{pos:v3(0,120,0)},
0:{pos:v3(-240,BoxSet.GAME_LINE,0)},
1:{pos:v3(0,BoxSet.GAME_LINE,0)},
2:{pos:v3(0,BoxSet.GAME_LINE,0)},
}
export const MonSet = {
0:{pos:v3(240,130,0)},
1:{pos:v3(240,110,0)},
2:{pos:v3(300,130,0)},
3:{pos:v3(300,110,0)},
4:{pos:v3(320,130,0)},
5:{pos:v3(320,110,0)},
6:{pos:v3(360,130,0)},
7:{pos:v3(360,110,0)},
8:{pos:v3(400,130,0)},
9:{pos:v3(400,110,0)},
10:{pos:v3(440,130,0)},
11:{pos:v3(440,110,0)},
0:{pos:v3(240,BoxSet.GAME_LINE+10,0)},
1:{pos:v3(240,BoxSet.GAME_LINE-10,0)},
2:{pos:v3(300,BoxSet.GAME_LINE+10,0)},
3:{pos:v3(300,BoxSet.GAME_LINE-10,0)},
4:{pos:v3(320,BoxSet.GAME_LINE+10,0)},
5:{pos:v3(320,BoxSet.GAME_LINE-10,0)},
6:{pos:v3(360,BoxSet.GAME_LINE+10,0)},
7:{pos:v3(360,BoxSet.GAME_LINE-10,0)},
8:{pos:v3(400,BoxSet.GAME_LINE+10,0)},
9:{pos:v3(400,BoxSet.GAME_LINE-10,0)},
10:{pos:v3(440,BoxSet.GAME_LINE+10,0)},
11:{pos:v3(440,BoxSet.GAME_LINE-10,0)},
}
export enum MonStart {

View File

@@ -21,6 +21,9 @@ export interface DamageEvent {
/** 伤害事件ID用于去重和调试 */
eventId: string;
ext_dmg:number //额外伤害
dmg_ratio:number//伤害比例
}
/**
@@ -55,7 +58,7 @@ export class DamageQueueComp extends ecs.Comp {
/**
* 添加伤害事件到队列
*/
addDamageEvent(attrs: any, caster: HeroViewComp, s_uuid: number): void {
addDamageEvent(attrs: any, caster: HeroViewComp, s_uuid: number,ext_dmg:number=0,dmg_ratio:number=1): void {
const timestamp = Date.now();
const eventId = `${caster.ent.eid}_${s_uuid}_${timestamp}_${Math.random()}`;
@@ -64,7 +67,9 @@ export class DamageQueueComp extends ecs.Comp {
caster: caster,
s_uuid: s_uuid,
timestamp: timestamp,
eventId: eventId
eventId: eventId,
ext_dmg:ext_dmg,
dmg_ratio:dmg_ratio,
};
this.damageEvents.push(damageEvent);
@@ -155,7 +160,7 @@ export class DamageQueueHelper {
* 为实体添加伤害事件
* 如果实体没有伤害队列组件,会自动创建
*/
static addDamageToEntity(entity: ecs.Entity, attrs: any, caster: HeroViewComp, s_uuid: number): void {
static addDamageToEntity(entity: ecs.Entity, attrs: any, caster: HeroViewComp, s_uuid: number,ext_dmg:number=0,dmg_ratio:number=1): void {
let damageQueue = entity.get(DamageQueueComp);
// 如果实体没有伤害队列组件,创建一个
@@ -164,7 +169,7 @@ export class DamageQueueHelper {
}
// 添加伤害事件到队列
damageQueue.addDamageEvent(attrs, caster, s_uuid);
damageQueue.addDamageEvent(attrs, caster, s_uuid,ext_dmg,dmg_ratio);
}
/**

View File

@@ -1,306 +0,0 @@
import { ecs } from "../../../../extensions/oops-plugin-framework/assets/libs/ecs/ECS";
import { FacSet } from "../common/config/GameSet";
import { Attrs } from "../common/config/HeroAttrs";
import { FightSet } from "../common/config/GameSet";
import { SkillSet } from "../common/config/SkillSet";
import { HeroAttrsComp } from "./HeroAttrsComp";
import { HeroViewComp } from "./HeroViewComp";
import { DamageQueueComp, DamageEvent, DamageQueueHelper } from "./DamageQueueComp";
import { smc } from "../common/SingletonModuleComp";
/** 业务层对象 */
@ecs.register('HeroAtk')
export class HeroAtkComp extends ecs.Comp {
/** 业务层组件移除时,重置所有数据为默认值 */
reset() {
}
}
/** 最终伤害数据接口 */
interface FinalData {
damage: number;
isCrit: boolean;
isDodge: boolean;
}
/** 业务层业务逻辑处理对象 伤害处理系统 */
@ecs.register('HeroAtkSystem')
export class HeroAtkSystem extends ecs.ComblockSystem implements ecs.ISystemUpdate {
private debugMode: boolean = false; // 是否启用调试模式
/**
* 过滤器:处理拥有伤害队列的实体
*/
filter(): ecs.IMatcher {
return ecs.allOf(HeroAttrsComp, DamageQueueComp);
}
/**
* 系统更新(每帧调用)
* 处理伤害队列中的所有伤害事件
*/
update(e: ecs.Entity): void {
if(!smc.mission.play || smc.mission.pause) return;
const model = e.get(HeroAttrsComp);
const damageQueue = e.get(DamageQueueComp);
if (!model || !damageQueue || damageQueue.isEmpty()) return;
// 标记正在处理
damageQueue.isProcessing = true;
// 处理队列中的所有伤害事件
let processedCount = 0;
while (!damageQueue.isEmpty()) {
const damageEvent = damageQueue.getNextDamageEvent();
if (!damageEvent) break;
// 处理单个伤害事件
const FDData = this.doAttack(e, damageEvent);
processedCount++;
damageQueue.processedCount++;
if (this.debugMode) {
const casterName = damageEvent.caster?.ent?.get(HeroAttrsComp)?.hero_name || "未知";
const casterUuid = damageEvent.caster?.ent?.get(HeroAttrsComp)?.hero_uuid || 0;
console.log(`[HeroAtkSystem] 英雄${model.hero_name} (uuid: ${model.hero_uuid}) 受到 ${casterName}(uuid: ${casterUuid})的 伤害 ${FDData.damage},${FDData.isCrit?"暴击":"普通"}攻击技能ID ${damageEvent.s_uuid}`);
}
// 如果目标已死亡,停止处理后续伤害
if (model.is_dead) {
if (this.debugMode) {
console.log(`[HeroAtkSystem] ${model.hero_name} 已死亡,停止处理剩余伤害`);
}
damageQueue.clear(); // 清空剩余伤害
break;
}
}
// 如果队列已空,移除伤害队列组件
if (damageQueue.isEmpty()) {
e.remove(DamageQueueComp);
if (this.debugMode && processedCount > 0) {
console.log(`[HeroAtkSystem] ${model.hero_name} 伤害队列处理完成,共处理 ${processedCount} 个伤害事件`);
}
}
}
/**
* 执行攻击计算
* @param target 目标实体
* @param damageEvent 伤害事件数据
* @returns 最终伤害数据
*/
private doAttack(target: ecs.Entity, damageEvent: DamageEvent): FinalData {
const targetModel = target.get(HeroAttrsComp);
const targetView = target.get(HeroViewComp);
let reDate:FinalData={
damage:0,
isCrit:false,
isDodge:false,
}
if (!targetModel || targetModel.is_dead) return reDate;
// 获取攻击者数据
const caster = damageEvent.caster;
const casterModel = caster.ent.get(HeroAttrsComp);
if (!casterModel) return reDate;
// 获取技能配置
const skillConf = SkillSet[damageEvent.s_uuid];
if (!skillConf) return reDate;
// 触发被攻击事件
this.onAttacked(target);
// 闪避判定
if (this.checkDodge(targetModel)) {
// TODO: 触发闪避视图表现
reDate.isDodge=true;
return reDate;
}
// 暴击判定
const isCrit = this.checkCrit(targetModel.Attrs[Attrs.CRITICAL]);
let damage = this.dmgCount(damageEvent.Attrs,damageEvent.s_uuid);
if (isCrit) {
damage = Math.floor(damage * (1 + (FightSet.CRIT_DAMAGE + targetModel.Attrs[Attrs.CRITICAL_DMG]) / 100));
reDate.isCrit=true;
}
// 伤害计算考虑易伤等debuff
damage = this.calculateDamage(targetModel, damage);
// 护盾吸收
damage =Math.floor(this.absorbShield(targetModel, damage))
if (damage <= 0) return reDate;
// 应用伤害到数据层
targetModel.hp -= damage;
targetModel.atked_count++;
// ✅ 触发视图层表现(伤害数字、受击动画、后退)
if (targetView) {
targetView.do_atked(damage, isCrit, damageEvent.s_uuid);
}
// 检查死亡
if (targetModel.hp <= 0) {
this.doDead(target);
// ✅ 触发死亡视图表现
if (targetView) {
targetView.do_dead();
}
}
if (this.debugMode) {
console.log(`[HeroAtkSystem] ${targetModel.hero_name} 受到 ${damage} 点伤害 (暴击: ${isCrit})`);
}
reDate.damage=damage;
return reDate;
}
//伤害计算,暂时简单计算
private dmgCount(CAttrs:any,s_uuid:number){
let sConf = SkillSet[s_uuid];
if (!sConf) return 0;
let AP = sConf.ap*CAttrs[Attrs.AP]/100;
return AP;
}
/**
* 处理角色死亡
*/
private doDead(entity: ecs.Entity): void {
const model = entity.get(HeroAttrsComp);
if (!model || model.is_dead) return;
model.is_dead = true;
// 触发死亡事件
this.onDeath(entity);
if (this.debugMode) {
console.log(`[HeroBattleSystem] ${model.hero_name} 死亡`);
}
}
/**
* 闪避判定
*/
private checkDodge(model: HeroAttrsComp): boolean {
if (model.Attrs[Attrs.DODGE] > 0) {
const random = Math.random() * 100;
if (random < model.Attrs[Attrs.DODGE]) {
if (this.debugMode) {
console.log(`[HeroBattleSystem] ${model.hero_name} 闪避了攻击`);
}
return true;
}
}
return false;
}
/**
* 暴击判定
*/
private checkCrit(critRate: number): boolean {
if (critRate > 0) {
const random = Math.random() * 100;
return random < critRate;
}
return false;
}
/**
* 伤害计算考虑易伤等debuff
*/
private calculateDamage(model: HeroAttrsComp, baseDamage: number): number {
// 这里可以添加易伤等debuff的计算逻辑
// 例如如果目标有易伤buff增加受到的伤害
return baseDamage;
}
/**
* 护盾吸收伤害
*/
private absorbShield(model: HeroAttrsComp, damage: number): number {
if (model.shield <= 0) return damage;
if (model.shield >= damage) {
model.shield -= damage;
if (model.shield <= 0) {
model.shield = 0;
model.Attrs[Attrs.SHIELD_MAX] = 0;
}
return 0;
} else {
const remainingDamage = damage - model.shield;
model.shield = 0;
model.Attrs[Attrs.SHIELD_MAX] = 0;
return remainingDamage;
}
}
/**
* 被攻击时触发的事件
*/
private onAttacked(entity: ecs.Entity): void {
const model = entity.get(HeroAttrsComp);
if (!model || model.is_dead) return;
// 这里可以添加被攻击时的特殊处理逻辑
if (model.fac === FacSet.MON) return;
// 例如:触发某些天赋效果、反击逻辑等
}
/**
* 死亡时触发的事件
*/
private onDeath(entity: ecs.Entity): void {
const model = entity.get(HeroAttrsComp);
if (!model) return;
if (model.fac === FacSet.MON) {
// 怪物死亡处理
this.scheduleDrop(entity);
} else if (model.fac === FacSet.HERO) {
// 英雄死亡处理
this.scheduleHeroDeath(entity);
}
}
/**
* 延迟执行掉落逻辑
*/
private scheduleDrop(entity: ecs.Entity): void {
// 这里可以添加掉落逻辑
// 例如:延迟一段时间后生成掉落物品
}
/**
* 延迟执行英雄死亡逻辑
*/
private scheduleHeroDeath(entity: ecs.Entity): void {
// 这里可以添加英雄死亡的特殊处理
// 例如:触发游戏结束、复活机制等
}
/**
* 启用调试模式
*/
enableDebug() {
this.debugMode = true;
}
/**
* 禁用调试模式
*/
disableDebug() {
this.debugMode = false;
}
}

View File

@@ -1,9 +0,0 @@
{
"ver": "4.0.24",
"importer": "typescript",
"imported": true,
"uuid": "85d8a2e5-f2a1-49b0-9439-fe9e1e98b7d9",
"files": [],
"subMetas": {},
"userData": {}
}

View File

@@ -0,0 +1,562 @@
import { ecs } from "../../../../extensions/oops-plugin-framework/assets/libs/ecs/ECS";
import { FacSet } from "../common/config/GameSet";
import { Attrs } from "../common/config/HeroAttrs";
import { FightSet } from "../common/config/GameSet";
import { SkillSet, DType } from "../common/config/SkillSet";
import { HeroAttrsComp } from "./HeroAttrsComp";
import { HeroViewComp } from "./HeroViewComp";
import { DamageQueueComp, DamageEvent } from "./DamageQueueComp";
import { smc } from "../common/SingletonModuleComp";
/** 最终伤害数据接口
* 用于封装一次攻击计算的所有结果数据
* @property damage - 最终造成的伤害值(已考虑所有加成和减免)
* @property isCrit - 是否为暴击攻击
* @property isDodge - 是否被闪避闪避时damage为0
*/
interface FinalData {
damage: number;
isCrit: boolean;
isDodge: boolean;
}
/**
* 英雄攻击系统 - 伤害处理核心系统
*
* 职责:
* 1. 处理所有伤害事件的计算和分发
* 2. 管理伤害队列的处理流程
* 3. 协调视图层的表现更新
*
* 重要概念:
* - damageEvent.Attrs: 施法者属性快照(创建技能时保存)
* - TAttrsComp: 被攻击者实时属性
* - 属性来源规范:攻击判定用施法者,防御判定用被攻击者
*/
@ecs.register('HeroAtkSystem')
export class HeroAtkSystem extends ecs.ComblockSystem implements ecs.ISystemUpdate {
private debugMode: boolean = false; // 是否启用调试模式
/**
* 过滤器:处理拥有伤害队列的实体
*/
filter(): ecs.IMatcher {
return ecs.allOf(HeroAttrsComp, DamageQueueComp);
}
/**
* 系统更新(每帧调用)
* 处理伤害队列中的所有伤害事件
*/
update(e: ecs.Entity): void {
if(!smc.mission.play || smc.mission.pause) return;
const TAttrsComp = e.get(HeroAttrsComp);
const damageQueue = e.get(DamageQueueComp);
if (!TAttrsComp || !damageQueue || damageQueue.isEmpty()) return;
// 标记正在处理
damageQueue.isProcessing = true;
// 处理队列中的所有伤害事件
let processedCount = 0;
while (!damageQueue.isEmpty()) {
const damageEvent = damageQueue.getNextDamageEvent();
if (!damageEvent) break;
// 处理单个伤害事件
this.doAttack(e, damageEvent);
processedCount++;
damageQueue.processedCount++;
// 如果目标已死亡,停止处理后续伤害
if (TAttrsComp.is_dead) {
if (this.debugMode) {
console.log(`[HeroAtkSystem] ${TAttrsComp.hero_name} 已死亡,停止处理剩余伤害`);
}
damageQueue.clear(); // 清空剩余伤害
break;
}
}
// 如果队列已空,移除伤害队列组件
if (damageQueue.isEmpty()) {
e.remove(DamageQueueComp);
if (this.debugMode && processedCount > 0) {
console.log(`[HeroAtkSystem] ${TAttrsComp.hero_name} 伤害队列处理完成,共处理 ${processedCount} 个伤害事件`);
}
}
}
/**
* 执行攻击计算 - 核心伤害计算逻辑
*
* 属性使用规范(重要!):
*
* ✅ 正确使用施法者属性damageEvent.Attrs - 快照):
* - CRITICAL: 暴击率判定
* - CRITICAL_DMG: 暴击伤害加成
* - BACK_CHANCE: 击退概率
* - HIT: 命中率(用于闪避计算)
* - AP/MAP: 攻击力(基础伤害计算)
*
* ✅ 正确使用被攻击者属性TAttrsComp - 实时):
* - DODGE: 闪避率(用于闪避计算)
* - SHIELD_MAX: 护盾最大值(护盾吸收)
* - hp: 当前生命值(伤害应用)
* - 各种抗性属性(预留扩展)
*
* ❌ 错误使用案例(已修复):
* - 不要混用施法者和被攻击者的属性进行同一计算
* - 暴击伤害应该基于施法者的暴击伤害属性
*
* @param target 目标实体(被攻击者)
* @param damageEvent 伤害事件数据(包含施法者信息和属性快照)
* @returns 最终伤害数据(包含伤害值、暴击标记、闪避标记)
*/
private doAttack(target: ecs.Entity, damageEvent: DamageEvent): FinalData {
const TAttrsComp = target.get(HeroAttrsComp);
const targetView = target.get(HeroViewComp);
let reDate:FinalData={
damage:0,
isCrit:false,
isDodge:false,
}
if (!TAttrsComp || TAttrsComp.is_dead) return reDate;
const caster = damageEvent.caster;
const CAttrsComp = caster?.ent?.get(HeroAttrsComp);
// 获取技能配置
const skillConf = SkillSet[damageEvent.s_uuid];
if (!skillConf) return reDate;
// 触发被攻击事件
this.onAttacked(target);
// 闪避判定
// 闪避成功概率 = 被攻击者闪避率 - 施法者命中率
// TAttrsComp.Attrs[Attrs.DODGE]: 被攻击者的实时闪避属性
// damageEvent.Attrs[Attrs.HIT]: 施法者在技能创建时的命中属性快照
const isDodge =this.checkChance((TAttrsComp.Attrs[Attrs.DODGE]-damageEvent.Attrs[Attrs.HIT]) || 0);
if (isDodge) {
// TODO: 触发闪避视图表现
reDate.isDodge=true;
return reDate;
}
// 暴击判定
// 使用施法者的暴击率属性damageEvent.Attrs 快照),- 被攻击者的暴击抗性属性TAttrsComp.Attrs[Attrs.CRITICAL_RESIST]
const isCrit = this.checkChance(damageEvent.Attrs[Attrs.CRITICAL]-TAttrsComp.Attrs[Attrs.CRITICAL_RESIST]);
// 计算基础伤害
let damage = this.dmgCount(damageEvent,TAttrsComp);
if (this.debugMode) console.log("[HeroAtkSystem] dmgCount",damage)
if (isCrit) {
// 暴击伤害计算
// 使用施法者的暴击伤害加成属性damageEvent.Attrs 快照)
// 公式:最终伤害 = 基础伤害 * (1 + 系统暴击倍率 + 施法者暴击伤害加成)
const casterCritDmg = damageEvent.Attrs[Attrs.CRITICAL_DMG] || 0;
damage = Math.floor(damage * (1 + (FightSet.CRIT_DAMAGE + casterCritDmg) / 100));
reDate.isCrit=true;
CAttrsComp?.useValueTalByAttr(Attrs.CRITICAL); // 清除施法者的暴击buff
}
if (this.debugMode) console.log("[HeroAtkSystem] after crit",damage)
// 护盾吸收
damage =Math.floor(this.absorbShield(TAttrsComp, damage))
if (this.debugMode) console.log("[HeroAtkSystem] after shield",damage)
if (damage <= 0) return reDate;
// 应用伤害到数据层
TAttrsComp.hp -= damage;
if (this.debugMode) {
const casterName = damageEvent.caster?.ent?.get(HeroAttrsComp)?.hero_name || "未知";
const casterUuid = damageEvent.caster?.ent?.get(HeroAttrsComp)?.hero_uuid || 0;
console.log(`[HeroAtkSystem] 英雄${TAttrsComp.hero_name} (uuid: ${TAttrsComp.hero_uuid}) 受到 ${casterName}(uuid: ${casterUuid})的 伤害 ${damage},${isCrit?"暴击":"普通"}攻击,技能ID ${damageEvent.s_uuid}`);
}
//反伤判定 并应用到施法者
this.check_thorns(TAttrsComp, caster?.ent,damage);
// 击退判定
// 使用施法者的击退概率属性damageEvent.Attrs 快照)
// 击退成功后需要清理施法者的相关天赋buff
const isBack = this.checkChance(damageEvent.Attrs[Attrs.BACK_CHANCE] || 0);
if (isBack) CAttrsComp?.useValueTalByAttr(Attrs.BACK_CHANCE);
// ✅ 触发视图层表现(伤害数字、受击动画、后退)
if (targetView) targetView.do_atked(damage, isCrit, damageEvent.s_uuid, isBack);
// 检查死亡
if (TAttrsComp.hp <= 0) {
// 增加被击杀计数
if (caster) CAttrsComp.Attrs.killed_count++;
this.doDead(target);
// ✅ 触发死亡视图表现
if (targetView) {
targetView.do_dead();
}
}
if (this.debugMode) console.log(`[HeroAtkSystem] ${TAttrsComp.hero_name} 受到 ${damage} 点伤害 (暴击: ${isCrit})`);
reDate.damage=damage;
return reDate;
}
check_thorns(TAttrsComp:HeroAttrsComp, caster: ecs.Entity, damage:number) {
// 检查目标是否有反伤属性,这里受伤的时时施法者
if (!caster||damage<=0) return;
let thornsDamage=0;
thornsDamage=TAttrsComp.Attrs[Attrs.THORNS]||0+TAttrsComp.useCountValTal(Attrs.THORNS);
let CAttrs=caster.get(HeroAttrsComp);
// 计算反伤伤害
let thornsDmg=Math.floor(thornsDamage*damage/100);
// 应用反伤伤害到数据层
CAttrs.hp -= thornsDmg;
CAttrs.atked_count++;
let CView=caster.get(HeroViewComp);
// ✅ 触发视图层表现(伤害数字、受击动画、后退)
if (CView) CView.do_atked(thornsDmg, false, SkillSet[5000].uuid, false);
// 检查死亡
if (CAttrs.hp <= 0) {
this.doDead(caster);
// 增加击杀计数
if (caster) TAttrsComp.Attrs.killed_count++;
// ✅ 触发死亡视图表现
if (CView) {
CView.do_dead();
}
}
}
/**
* 详细伤害计算核心方法
*
* 这是整个战斗系统中最核心的伤害计算方法,负责根据施法者属性、目标属性和技能配置
* 计算最终的基础伤害值。该方法采用多阶段的伤害计算公式,综合考虑了物理和魔法伤害
* 以及各种属性加成和抗性减免。
*
* 计算流程:
* 1. 获取技能配置
* 2. 计算原始物理伤害和魔法伤害
* 3. 应用防御减免
* 4. 应用物理/魔法攻击力和抗性修正
* 5. 应用元素属性加成和抗性修正
* 6. 应用最终伤害减免
* 7. 确保伤害值非负
*
* @param CAttrs 施法者属性快照对象,包含所有攻击力、属性加成等战斗属性
* @param TAttrs 目标属性对象,包含所有防御力、抗性等防御属性
* @param s_uuid 技能ID用于获取技能配置信息和伤害类型
* @returns 经过完整计算后的最终伤害值(未考虑暴击)
*
* @important 注意事项:
* - 此方法计算的是基础伤害,暴击计算在外部处理
* - 所有除法和乘法计算后都进行取整操作,确保游戏中的伤害值为整数
* - 元素伤害只应用于魔法伤害部分
*/
private dmgCount(damageEvent:DamageEvent,TAttrsComp:HeroAttrsComp){
// 1. 获取技能配置 - 如果技能不存在直接返回0伤害
const CAttrs=damageEvent.Attrs;
const TAttrs=TAttrsComp.Attrs;
let sConf = SkillSet[damageEvent.s_uuid];
if (!sConf) return 0;
if (this.debugMode) console.log(`[HeroAtkSystem] 伤害处理对象`,CAttrs,TAttrs);
// 2. 计算原始物理伤害和魔法伤害
// 物理伤害基础值 = 技能物理倍率 * (施法者物理攻击力 + 额外伤害) / 100 * 额外伤害比例
let apBase = (sConf.ap||0)*(CAttrs[Attrs.AP]+damageEvent.ext_dmg)/100*damageEvent.dmg_ratio;
// 魔法伤害基础值 = 技能魔法倍率 * (施法者魔法攻击力 + 额外伤害) / 100 * 额外伤害比例
let mapBase = (sConf.map||0)*(CAttrs[Attrs.MAP]+damageEvent.ext_dmg)/100*damageEvent.dmg_ratio;
if (this.debugMode) console.log(`[HeroAtkSystem] 物理伤害基础值: ${apBase}, 技能ap=${sConf.ap},施法者物理攻击力: ${CAttrs[Attrs.AP]}, 魔法伤害基础值: ${mapBase}技能map=${sConf.map}
额外伤害:${damageEvent.ext_dmg}, 额外伤害比例:${damageEvent.dmg_ratio}`);
// 3. 获取目标防御属性
const def = (TAttrs[Attrs.DEF]||0); // 目标物理防御
const mdef = (TAttrs[Attrs.MDEF]||0); // 目标魔法防御
// 4. 计算防御减免系数(采用公式:防御/(防御+常数)确保防御值不会导致伤害减到0
const apRed = def / (def + FightSet.DEF_C); // 物理防御减免系数
const mapRed = mdef / (mdef + FightSet.MDEF_C); // 魔法防御减免系数
// 5. 应用防御减免到基础伤害,向下取整
let apAfter = Math.floor(apBase * (1 - apRed)); // 物理伤害 - 防御减免
let mapAfter = Math.floor(mapBase * (1 - mapRed)); // 魔法伤害 - 防御减免
if (this.debugMode) console.log(`[HeroAtkSystem] 物理伤害基础值: ${apBase}, 物理伤害 - 防御减免: ${apAfter} 魔法伤害基础值: ${mapBase}, 魔法伤害 - 防御减免: ${mapAfter}`);
// 6. 应用物理/魔法攻击力和抗性修正
// 物理伤害修正:基础伤害 * (1 + 物理攻击力加成%) * (1 - 目标物理抗性%)
apAfter = this.applyPR(apAfter, CAttrs[Attrs.PHYS_POWER]||0, TAttrs[Attrs.PHYS_RES]||0);
// 魔法伤害修正:基础伤害 * (1 + 魔法攻击力加成%) * (1 - 目标魔法抗性%)
mapAfter = this.applyPR(mapAfter, CAttrs[Attrs.MAGIC_POWER]||0, TAttrs[Attrs.MAGIC_RES]||0);
if (this.debugMode) console.log(`[HeroAtkSystem] 物理伤害修正后: ${apAfter} 魔法伤害修正后: ${mapAfter} `);
// 7. 根据技能元素类型,应用元素属性加成和抗性修正
switch (sConf.DType) {
case DType.ICE:
// 冰系伤害修正:魔法伤害 * (1 + 冰系攻击力加成%) * (1 - 目标冰系抗性%)
mapAfter = this.applyPR(mapAfter, CAttrs[Attrs.ICE_POWER]||0, TAttrs[Attrs.ICE_RES]||0);
break;
case DType.FIRE:
// 火系伤害修正:魔法伤害 * (1 + 火系攻击力加成%) * (1 - 目标火系抗性%)
mapAfter = this.applyPR(mapAfter, CAttrs[Attrs.FIRE_POWER]||0, TAttrs[Attrs.FIRE_RES]||0);
break;
case DType.WIND:
// 风系伤害修正:魔法伤害 * (1 + 风系攻击力加成%) * (1 - 目标风系抗性%)
mapAfter = this.applyPR(mapAfter, CAttrs[Attrs.WIND_POWER]||0, TAttrs[Attrs.WIND_RES]||0);
break;
}
if (this.debugMode) console.log(`[HeroAtkSystem] 物理伤害修正后: ${apAfter} 元素伤害修正后: ${mapAfter}`);
// 8. 计算最终总伤害(物理伤害 + 魔法伤害)
let total = apAfter + mapAfter;
//9.1 易伤
let DMG_INVUL = TAttrs[Attrs.DMG_INVUL]||0
//9.2 免伤 属性免伤+天赋免伤
let DMG_RED =TAttrs[Attrs.DMG_RED]||0+TAttrsComp.useCountValTal(Attrs.DMG_RED);
// 10. 确保伤害值非负,返回最终伤害
total = Math.max(0,total);
//11. 易伤减免 免伤属性免伤+天赋免伤
total = Math.floor(total * (1 + ((DMG_INVUL-DMG_RED)/100)));
if (this.debugMode) console.log(`[HeroAtkSystem] 易伤减免后: ${total}`);
return Math.max(0,total);
}
/**
* 应用攻击力加成和抗性减免的通用计算方法
*
* 这是一个核心的伤害修正计算方法,用于处理各种类型的攻击力加成和抗性减免。
* 该方法采用乘法叠加的方式,分别应用攻击者的加成属性和目标的抗性属性。
*
* 计算公式:
* 最终值 = 基础值 × (1 + 攻击力加成% / 100) × (1 - 抗性% / 100)
*
* 适用场景:
* - 物理攻击力加成和物理抗性减免
* - 魔法攻击力加成和魔法抗性减免
* - 元素攻击力加成和元素抗性减免
* - 其他需要同时考虑加成和减免的属性修正
*
* 计算逻辑说明:
* 1. 首先将百分比转换为小数形式除以100
* 2. 应用攻击者的加成:基础值 × (1 + 加成系数)
* 3. 应用目标的抗性:上一步结果 × (1 - 抗性系数)
* 4. 向下取整,确保结果为整数
*
* @param base 基础值(通常是经过防御减免后的伤害值)
* @param power 攻击者的攻击力加成值百分比形式如50表示50%
* @param res 目标的抗性值百分比形式如30表示30%
* @returns 经过攻击力加成和抗性减免后的最终值(向下取整)
*
* @important 注意事项:
* - 当抗性值大于100时可能导致最终值为负数或零
* - 所有计算结果会向下取整,确保游戏中的数值为整数
* - 此方法可以被多次调用,以叠加不同类型的加成和减免
*/
private applyPR(base: number, power: number, res: number): number {
// 计算公式:基础值 × (1 + 攻击力加成%) × (1 - 抗性%)
// 1. 将百分比转换为小数power/100 和 res/100
// 2. 应用攻击力加成1 + (power/100)
// 3. 应用抗性减免1 - (res/100)
// 4. 最终计算并向下取整
return Math.floor(base * (1 + (power/100)) * (1 - (res/100)));
}
/**
* 处理角色死亡
*
* 死亡处理流程:
* 1. 标记死亡状态is_dead = true
* 2. 触发死亡事件onDeath
* 3. 记录调试信息(如启用调试模式)
*
* @param entity 死亡的实体
*
* @important 死亡状态一旦设置,该实体将不再处理新的伤害事件
* 这确保了死亡逻辑的单一性和一致性
*/
private doDead(entity: ecs.Entity): void {
const TAttrsComp = entity.get(HeroAttrsComp);
if (!TAttrsComp || TAttrsComp.is_dead) return;
TAttrsComp.is_dead = true;
// 触发死亡事件
this.onDeath(entity);
if (this.debugMode) {
console.log(`[HeroAtkSystem] ${TAttrsComp.hero_name} 死亡`);
}
}
/**
* 统一概率判定方法
*
* 用于所有概率相关的判定:
* - 暴击率判定
* - 闪避率判定
* - 击退概率判定
* - 其他特殊效果概率
*
* @param rate 概率值0-100的百分比
* @returns true-判定成功false-判定失败
*
* @example
* ```typescript
* // 10%概率触发
* if (this.checkChance(10)) {
* // 触发特殊效果
* }
* ```
*
* @important 概率为0或负数时直接返回false避免不必要的随机数计算
*/
private checkChance(rate: number): boolean {
if (rate <= 0) return false;
const r = Math.random() * 100;
return r < rate;
}
/**
* 护盾吸收伤害
*
* 护盾吸收逻辑:
* 1. 如果护盾值 >= 伤害值完全吸收剩余伤害为0
* 2. 如果护盾值 < 伤害值:部分吸收,剩余伤害 = 原伤害 - 护盾值
* 3. 护盾被击破时,重置护盾最大值属性
*
* @param TAttrsComp 被攻击者的属性组件(包含当前护盾值)
* @param damage 原始伤害值
* @returns 剩余伤害值(护盾吸收后的结果)
*/
private absorbShield(TAttrsComp: HeroAttrsComp, damage: number): number {
if (TAttrsComp.shield <= 0) return damage;
if (TAttrsComp.shield >= damage) {
TAttrsComp.shield -= damage;
if (TAttrsComp.shield <= 0) {
TAttrsComp.shield = 0;
TAttrsComp.Attrs[Attrs.SHIELD_MAX] = 0;
}
return 0;
} else {
const remainingDamage = damage - TAttrsComp.shield;
TAttrsComp.shield = 0;
TAttrsComp.Attrs[Attrs.SHIELD_MAX] = 0;
return remainingDamage;
}
}
/**
* 被攻击时触发的事件
*
* 预留的扩展点,用于处理被攻击时的特殊逻辑:
* - 触发反伤效果(荆棘光环等)
* - 触发被攻击天赋(如受击回血、受击反击等)
* - 触发特殊状态(如受伤狂暴、受伤护盾等)
*
* @param entity 被攻击的实体
*
* @todo 当前对怪物实体直接返回,后续可以根据需求扩展怪物的被攻击逻辑
*/
private onAttacked(entity: ecs.Entity): void {
const TAttrsComp = entity.get(HeroAttrsComp);
if (!TAttrsComp || TAttrsComp.is_dead) return;
TAttrsComp.atked_count++;
// 这里可以添加被攻击时的特殊处理逻辑
if (TAttrsComp.fac === FacSet.MON) return;
// 例如:触发某些天赋效果、反击逻辑等
}
/**
* 死亡时触发的事件
*
* 根据实体阵营类型处理不同的死亡逻辑:
*
* - FacSet.MON怪物触发掉落逻辑
* - 延迟执行掉落,避免阻塞主逻辑
* - 可以扩展:经验值计算、任务进度等
*
* - FacSet.HERO英雄触发英雄死亡特殊处理
* - 游戏结束判定
* - 复活机制检查
* - 死亡惩罚/奖励
*
* @param entity 死亡的实体
*
* @important 死亡事件应该幂等,避免重复触发
*/
private onDeath(entity: ecs.Entity): void {
const TAttrsComp = entity.get(HeroAttrsComp);
if (!TAttrsComp) return;
if (TAttrsComp.fac === FacSet.MON) {
// 怪物死亡处理
this.scheduleDrop(entity);
} else if (TAttrsComp.fac === FacSet.HERO) {
// 英雄死亡处理
this.scheduleHeroDeath(entity);
}
}
/**
* 延迟执行掉落逻辑
*
* 采用延迟执行的原因:
* 1. 避免在伤害计算过程中阻塞主线程
* 2. 给死亡动画播放留出时间
* 3. 可以批量处理多个掉落,优化性能
*
* @param entity 死亡的怪物实体
*
* @todo 具体实现可以包括:
* - 根据怪物等级计算基础掉落
* - 幸运值影响掉落品质
* - 特殊事件(双倍掉落、稀有掉落等)
* - 掉落物在场景中的生成位置计算
*/
private scheduleDrop(entity: ecs.Entity): void {
// 这里可以添加掉落逻辑
// 例如:延迟一段时间后生成掉落物品
}
/**
* 延迟执行英雄死亡逻辑
*
* 英雄死亡的特殊处理,比普通怪物复杂:
*
* 处理内容包括:
* - 检查复活次数和复活条件
* - 触发游戏结束界面(如适用)
* - 记录死亡统计信息
* - 处理死亡惩罚(经验损失、装备损坏等)
*
* @param entity 死亡的英雄实体
*
* @important 英雄死亡通常需要玩家交互,所以必须延迟处理
* 给玩家足够的反馈时间和操作空间
*/
private scheduleHeroDeath(entity: ecs.Entity): void {
// 这里可以添加英雄死亡的特殊处理
// 例如:触发游戏结束、复活机制等
}
/**
* 启用调试模式
*/
enableDebug() {
this.debugMode = true;
}
/**
* 禁用调试模式
*/
disableDebug() {
this.debugMode = false;
}
}

View File

@@ -2,7 +2,7 @@
"ver": "4.0.24",
"importer": "typescript",
"imported": true,
"uuid": "25f14ca0-5053-495e-bc3d-08b1bb4ee5d7",
"uuid": "bffb52f1-1843-437d-82ef-88d2d7ee2ec5",
"files": [],
"subMetas": {},
"userData": {}

View File

@@ -3,8 +3,13 @@ import { Attrs, AttrsType, BType, NeAttrs } from "../common/config/HeroAttrs";
import { BuffConf } from "../common/config/SkillSet";
import { HeroInfo, AttrSet } from "../common/config/heroSet";
import { HeroSkillsComp } from "./HeroSkills";
import { HeroViewComp } from "./HeroViewComp";
interface talTrigger{
value:number
count:number
}
@ecs.register('HeroAttrs')
export class HeroAttrsComp extends ecs.Comp {
Ebus:any=null!
@@ -27,10 +32,13 @@ export class HeroAttrsComp extends ecs.Comp {
// ==================== 动态属性值 ====================
hp: number = 100; // 当前血量
mp: number = 100; // 当前魔法值
pow: number = 0; // 当前怒气值
shield: number = 0; // 当前护盾
Attrs: any = []; // 最终属性数组经过Buff计算后
NeAttrs: any = []; // 负面状态数组
//计数型天赋buff
Talents: Record<number, talTrigger> = {};
//数值型天赋buff
BUFFS_TAL: Record<number, {count:number,BType:BType,attrIndex:number,value: number}> = {};
// ==================== 技能距离缓存 ====================
maxSkillDistance: number = 0; // 最远技能攻击距离缓存受MP影响
@@ -43,6 +51,7 @@ export class HeroAttrsComp extends ecs.Comp {
/** 临时型buff数组 - 按时间自动过期 */
BUFFS_TEMP: Record<number, Array<{value: number, BType: BType, remainTime: number}>> = {};
// ==================== 标记状态 ====================
is_dead: boolean = false;
is_count_dead: boolean = false;
@@ -56,7 +65,7 @@ export class HeroAttrsComp extends ecs.Comp {
// ==================== 计数统计 ====================
atk_count: number = 0; // 攻击次数
atked_count: number = 0; // 被攻击次数
killed_count:number=0;
// 注意:技能数据已迁移到 HeroSkillsComp不再存储在这里
start(){
@@ -70,6 +79,8 @@ export class HeroAttrsComp extends ecs.Comp {
// 清空现有 buff/debuff
this.BUFFS = {};
this.BUFFS_TEMP = {};
this.BUFFS_TAL = {};
this.Talents = {};
// 获取英雄配置
const heroInfo = HeroInfo[this.hero_uuid];
@@ -107,7 +118,37 @@ export class HeroAttrsComp extends ecs.Comp {
}
}
}
/*******************基础属性管理********************/
add_hp(value:number,isValue:boolean){
let addValue = value;
if(!isValue){
addValue = value * this.Attrs[Attrs.HP_MAX];
}
let heroView = this.ent.get(HeroViewComp);
if(heroView){
heroView.health(addValue);
}
this.hp += addValue;
this.hp = Math.max(0, Math.min(this.hp, this.Attrs[Attrs.HP_MAX]));
}
add_mp(value:number,isValue:boolean){
let addValue = value;
if(!isValue){
addValue = value * this.Attrs[Attrs.MP_MAX];
}
let heroView = this.ent.get(HeroViewComp);
if(heroView){
heroView.mp_add(addValue);
}
this.mp += addValue;
this.mp = Math.max(0, Math.min(this.mp, this.Attrs[Attrs.MP_MAX]));
}
add_shield(value:number,isValue:boolean){
let addValue = value;
this.shield += addValue;
this.shield = Math.max(0, Math.min(this.shield, this.Attrs[Attrs.HP_MAX]));
}
// ==================== BUFF 管理 ====================
/**
* 添加 buff 效果(支持多次叠加)
@@ -139,6 +180,8 @@ export class HeroAttrsComp extends ecs.Comp {
this.recalculateSingleAttr(attrIndex);
}
// ==================== 属性计算系统 ====================
/**
* 重新计算单个属性
@@ -177,6 +220,12 @@ export class HeroAttrsComp extends ecs.Comp {
}
}
}
for (const key in this.BUFFS_TAL) {
const buff = this.BUFFS_TAL[Number(key)];
if (buff.attrIndex === attrIndex && buff.BType === BType.VALUE) {
totalValue += buff.value;
}
}
// 3. 收集所有百分比型 buff/debuff
let totalRatio = 0;
@@ -197,6 +246,12 @@ export class HeroAttrsComp extends ecs.Comp {
}
}
}
for (const key in this.BUFFS_TAL) {
const buff = this.BUFFS_TAL[Number(key)];
if (buff.attrIndex === attrIndex && buff.BType === BType.RATIO) {
totalRatio += buff.value;
}
}
// 4. 根据属性类型计算最终值
const attrType = AttrsType[attrIndex];
@@ -386,6 +441,88 @@ export class HeroAttrsComp extends ecs.Comp {
}
/**
* 添加数值型天赋buff 数值会进行累加count 时叠加层数
* @param t_uuid 天赋唯一标识
* @param attrIndex 属性索引
* @param bType buff类型(VALUE:数值型, RATIO:百分比型)
* @param value buff值
*/
addValueTal(t_uuid: number, attrIndex?: number, bType?: BType, value: number = 0) {
if (attrIndex === undefined || bType === undefined) return;
const buff = this.BUFFS_TAL[t_uuid];
if (!buff) {
this.BUFFS_TAL[t_uuid] = { count: 1, BType: bType, attrIndex, value };
} else {
buff.count += 1;
buff.value += value;
}
this.recalculateSingleAttr(attrIndex);
}
/**
* 添加计数型天赋每次添加数值已最新额覆盖久的count为可用次数
* @param eff 天赋效果ID
* @param value 天赋值
*/
addCountTal(eff: number, value: number) {
const t = this.Talents[eff] || { value: 0, count: 0 };
t.value = value;
t.count += 1;
this.Talents[eff] = t;
}
/**
* 使用计数型天赋,如风怒 ,必爆等天赋,只需要返回是否暴击的,使用这个方法
* @param eff 天赋效果ID
* @returns 是否使用成功
*/
useCountTal(eff: number): boolean {
const t = this.Talents[eff];
if (!t || t.count <= 0) return false;
t.count -= 1;
return true;
}
/**
* 使用计数型天赋并返回天赋值如额外5次 伤害+20% 5次受伤免伤20% 使用这个方法
* @param eff 天赋效果ID
* @returns 天赋值
*/
useCountValTal(eff: number): number {
const t = this.Talents[eff];
if (!t || t.value <= 0) return 0;
t.count -= 1;
return t.value;
}
/**
* 根据UUID移除数值型天赋buff
* @param t_uuid 天赋唯一标识
*/
useValueTalByUuid(t_uuid: number) {
const buff = this.BUFFS_TAL[t_uuid];
if (!buff) return;
const attrIndex = buff.attrIndex;
delete this.BUFFS_TAL[t_uuid];
this.recalculateSingleAttr(attrIndex);
}
/**
* 根据属性索引移除数值型天赋buff
* @param attrIndex 属性索引
*/
useValueTalByAttr(attrIndex: number) {
let changed = false;
for (const key in this.BUFFS_TAL) {
const b = this.BUFFS_TAL[Number(key)];
if (b && b.attrIndex === attrIndex) {
delete this.BUFFS_TAL[Number(key)];
changed = true;
}
}
if (changed) this.recalculateSingleAttr(attrIndex);
}
reset() {
// 重置为初始状态
@@ -408,6 +545,8 @@ export class HeroAttrsComp extends ecs.Comp {
this.NeAttrs = [];
this.BUFFS = {};
this.BUFFS_TEMP = {};
this.BUFFS_TAL = {};
this.Talents = {};
// 重置技能距离缓存
this.maxSkillDistance = 0;
this.minSkillDistance = 0;
@@ -422,6 +561,12 @@ export class HeroAttrsComp extends ecs.Comp {
this.is_kalami = false;
this.atk_count = 0;
this.atked_count = 0;
this.killed_count =0;
}
}

View File

@@ -1,7 +1,7 @@
import { ecs } from "../../../../extensions/oops-plugin-framework/assets/libs/ecs/ECS";
import { Attrs } from "../common/config/HeroAttrs";
import { HeroInfo } from "../common/config/heroSet";
import { SkillSet } from "../common/config/SkillSet";
import { HSSet, SkillSet } from "../common/config/SkillSet";
import { HeroAttrsComp } from "./HeroAttrsComp";
/**
@@ -15,8 +15,10 @@ export interface SkillSlot {
cost: number; // MP消耗
level: number; // 技能等级(预留)
dis: number; // 攻击距离
hset: HSSet; // 技能设定, 0:普通攻击, 1:一般技能, 2:必杀技
}
/**
* ==================== 英雄技能数据组件 ====================
*
@@ -36,6 +38,7 @@ export class HeroSkillsComp extends ecs.Comp {
// ==================== 技能槽位列表 ====================
/** 技能槽位数组最多4个技能 */
skills: Record<number, SkillSlot> = {};
max_auto: boolean = true;
// ==================== 辅助方法 ====================
@@ -56,6 +59,9 @@ export class HeroSkillsComp extends ecs.Comp {
}
// 第0个技能的 cd_max 取 herosinfo[uuid].as
const cdMax = i === 0 ? HeroInfo[uuid].as : config.cd;
let hset = HSSet.atk;
if(i ===1) hset = HSSet.skill;
if(i ===2) hset = HSSet.max;
this.skills[s_uuid] = {
s_uuid: config.uuid,
cd: 0,
@@ -63,6 +69,7 @@ export class HeroSkillsComp extends ecs.Comp {
cost: config.cost,
level: 1,
dis: Number(config.dis),
hset: hset,
};
}
@@ -80,7 +87,7 @@ export class HeroSkillsComp extends ecs.Comp {
* @param s_uuid 技能配置ID
* @param entity 实体对象(用于更新技能距离缓存)
*/
addSkill(s_uuid: number, entity?: ecs.Entity) {
addSkill(s_uuid: number, entity?: ecs.Entity, hset: HSSet=HSSet.skill) {
const config = SkillSet[s_uuid];
if (!config) {
console.warn(`[HeroSkills] 技能配置不存在: ${s_uuid}`);
@@ -93,6 +100,7 @@ export class HeroSkillsComp extends ecs.Comp {
cost: config.cost,
level: 1,
dis: Number(config.dis),
hset: hset,
};
// 更新技能距离缓存
@@ -263,4 +271,7 @@ export class HeroSkillsComp extends ecs.Comp {
reset() {
this.skills = {};
}
setMaxAuto(on: boolean) {
this.max_auto = on;
}
}

View File

@@ -26,13 +26,25 @@ export interface BuffInfo {
@ccclass('HeroViewComp') // 定义Cocos Creator 组件
@ecs.register('HeroView', false) // 定义ECS 组件
export class HeroViewComp extends CCComp {
private debugMode: boolean = true; // 是否启用调试模式
// 添加条件日志方法
private debugLog(...args: any[]): void {
if (this.debugMode) {
console.log(...args);
}
}
private debugWarn(...args: any[]): void {
if (this.debugMode) {
console.warn(...args);
}
}
// ==================== View 层属性(表现相关)====================
as: HeroSpine = null!
status:String = "idle"
scale: number = 1; // 显示方向
box_group:number = BoxSet.HERO; // 碰撞组
usePower:boolean = false;
useMp:boolean = false;
realDeadTime:number=10
deadCD:number=0
// 血条显示相关
@@ -45,7 +57,7 @@ export class HeroViewComp extends CCComp {
get model() {
// 🔥 修复添加安全检查防止ent为null时的访问异常
if (!this.ent) {
console.warn("[HeroViewComp] ent is null, returning null for model");
this.debugWarn("[HeroViewComp] ent is null, returning null for model");
return null;
}
return this.ent.get(HeroAttrsComp);
@@ -89,12 +101,10 @@ export class HeroViewComp extends CCComp {
// }
/* 显示角色血*/
this.top_node.getChildByName("hp").active = true;
this.usePower=HeroInfo[this.model.hero_uuid].type==HType.warrior||HeroInfo[this.model.hero_uuid].type==HType.assassin;
this.useMp=HeroInfo[this.model.hero_uuid].type==HType.mage||HeroInfo[this.model.hero_uuid].type==HType.remote||HeroInfo[this.model.hero_uuid].type==HType.support;
this.top_node.getChildByName("pow").active = this.usePower;
this.top_node.getChildByName("mp").active = this.useMp;
this.top_node.getChildByName("mp").active = true;
// 初始隐藏血条(被攻击后才显示)
this.top_node.active = false;
this.top_node.active = true;
}
/** 初始化 UI 节点引用 */
@@ -140,9 +150,9 @@ export class HeroViewComp extends CCComp {
this.processDamageQueue(); // 伤害数字显示队列
// ✅ 更新 UI 显示(数据由 HeroAttrSystem 更新)
this.hp_show(this.model.hp, this.model.Attrs[Attrs.HP_MAX]);
if(this.useMp) this.mp_show(this.model.mp, this.model.Attrs[Attrs.MP_MAX]);
if(this.usePower) this.pow_show(this.model.pow, this.model.Attrs[Attrs.POW_MAX]);
// 移除了每帧调用的 hp_show改为仅在需要时调用
this.hp_show();
this.mp_show();
this.show_shield(this.model.shield, this.model.Attrs[Attrs.SHIELD_MAX]);
}
@@ -160,32 +170,29 @@ export class HeroViewComp extends CCComp {
}
/** 显示血量 */
private hp_show(hp: number, hp_max: number) {
private hp_show() {
// 不再基于血量是否满来决定显示状态,只更新进度条
if(!this.top_node.active) return;
let hp_progress = hp / hp_max;
this.top_node.getChildByName("hp").getComponent(ProgressBar).progress = hp_progress;
let hp=this.model.hp;
let hp_max=this.model.Attrs[Attrs.HP_MAX];
this.debugLog("hp_show",hp,hp_max)
this.top_node.getChildByName("hp").getComponent(ProgressBar).progress = hp / hp_max;;
this.scheduleOnce(() => {
this.top_node.getChildByName("hp").getChildByName("hpb").getComponent(ProgressBar).progress = hp_progress;
this.top_node.getChildByName("hp").getChildByName("hpb").getComponent(ProgressBar).progress = hp / hp_max;;
}, 0.15);
}
/** 显示魔法值 */
private mp_show(mp: number, mp_max: number) {
private mp_show() {
if(!this.top_node.active) return
let mp=this.model.mp;
let mp_max=this.model.Attrs[Attrs.MP_MAX];
this.debugLog("mp_show",mp,mp_max)
this.top_node.getChildByName("mp").getComponent(ProgressBar).progress = mp / mp_max;
this.scheduleOnce(() => {
this.top_node.getChildByName("mp").getChildByName("mpb").getComponent(ProgressBar).progress = mp / mp_max;
}, 0.15);
}
private pow_show(pow: number, pow_max: number) {
if(!this.top_node.active) return
this.top_node.getChildByName("pow").getComponent(ProgressBar).progress = pow / pow_max;
this.scheduleOnce(() => {
this.top_node.getChildByName("pow").getChildByName("mpb").getComponent(ProgressBar).progress = pow / pow_max;
}, 0.15);
}
/** 升级特效 */
private lv_up() {
var path = "game/skill/buff/buff_lvup";
@@ -294,12 +301,18 @@ export class HeroViewComp extends CCComp {
if(this.model && this.model.shield>0) this.show_shield(this.model.shield, this.model.Attrs[Attrs.SHIELD_MAX]);
}
health(hp: number = 0, is_num:boolean=true) {
health(hp: number = 0) {
// 生命值更新由 Model 层处理,这里只负责视图表现
this.heathed();
if(this.model) {
this.hp_show(hp, this.model.Attrs[Attrs.HP_MAX]);
}
this.hp_tip(TooltipTypes.health, hp.toFixed(0));
this.top_node.active=true
this.hp_show();
}
mp_add(mp: number = 0) {
// 生命值更新由 Model 层处理,这里只负责视图表现
this.hp_tip(TooltipTypes.addmp, mp.toFixed(0));
this.top_node.active=true
this.mp_show();
}
alive(){
@@ -331,7 +344,7 @@ export class HeroViewComp extends CCComp {
realDead(){
// 🔥 修复添加model安全检查防止实体销毁过程中的空指针异常
if (!this.model) {
console.warn("[HeroViewComp] realDead called but model is null, skipping");
this.debugWarn("[HeroViewComp] realDead called but model is null, skipping");
return;
}
if(this.model.fac === FacSet.HERO){
@@ -350,7 +363,7 @@ export class HeroViewComp extends CCComp {
this.ent.destroy();
}
do_atked(damage:number,isCrit:boolean,s_uuid:number){
do_atked(damage:number,isCrit:boolean,s_uuid:number,isBack:boolean=false){
// 受到攻击时显示血条并设置显示时间即使伤害为0也显示
this.top_node.active = true;
this.hpBarShowCD = this.hpBarShowTime;
@@ -359,8 +372,8 @@ export class HeroViewComp extends CCComp {
// 视图层表现
let SConf=SkillSet[s_uuid]
this.back()
this.showDamage(damage, isCrit, SConf.DAnm); // 暴击状态由战斗系统内部处理, DAnm和EAnm共用设定数组
if (isBack) this.back()
this.showDamage(damage, isCrit, SConf.DAnm);
}
private isBackingUp: boolean = false; // 🔥 添加后退状态标记
@@ -390,17 +403,6 @@ export class HeroViewComp extends CCComp {
}
// 伤害计算和战斗逻辑已迁移到 HeroBattleSystem
/** 死亡触发器(预留,用于天赋/特殊效果) */
do_dead_trigger(){
if(!this.model || this.model.is_dead || this.model.fac === FacSet.MON) return;
// 预留:天赋触发、复活检查等
}
/** 受击触发器(预留,用于天赋/特殊效果) */
do_atked_trigger(){
if(!this.model || this.model.is_dead || this.model.fac === FacSet.MON) return;
// 预留:反击、护盾触发等
}
@@ -415,7 +417,7 @@ export class HeroViewComp extends CCComp {
switch(skill.act){
case "max":
this.as.max()
this.tooltip(TooltipTypes.skill, skill.name, skill_id)
this.tooltip(TooltipTypes.skill, skill.name)
break
case "atk":
this.as.atk()
@@ -455,12 +457,12 @@ export class HeroViewComp extends CCComp {
private showDamageImmediate(damage: number, isCrit: boolean, anm:string="atked") {
if (!this.model) return;
this.hp_show(this.model.hp, this.model.Attrs[Attrs.HP_MAX]);
this.hp_show();
this.in_atked(anm, this.model.fac==FacSet.HERO?1:-1);
if (isCrit) {
this.hp_tip(TooltipTypes.crit, damage.toFixed(0), damage);
this.hp_tip(TooltipTypes.crit, damage.toFixed(0));
} else {
this.hp_tip(TooltipTypes.life, damage.toFixed(0), damage);
this.hp_tip(TooltipTypes.life, damage.toFixed(0));
}
}
reset() {
@@ -483,3 +485,8 @@ export class HeroViewComp extends CCComp {
}
}

View File

@@ -2,10 +2,13 @@ import { ecs } from "../../../../extensions/oops-plugin-framework/assets/libs/ec
import { Vec3, v3 } from "cc";
import { HeroAttrsComp } from "./HeroAttrsComp";
import { HeroViewComp } from "./HeroViewComp";
import { SkillSet, SType } from "../common/config/SkillSet";
import { HSSet, SkillSet, SType } from "../common/config/SkillSet";
import { HeroSkillsComp, SkillSlot } from "./HeroSkills";
import { Skill } from "../skill/Skill";
import { smc } from "../common/SingletonModuleComp";
import { TalComp } from "./TalComp";
import { TalEffet, TriType } from "../common/config/TalSet";
import { BoxSet } from "../common/config/GameSet";
/**
* ==================== 自动施法系统 ====================
@@ -50,6 +53,7 @@ export class SACastSystem extends ecs.ComblockSystem implements ecs.ISystemUpdat
for (const s_uuid of readySkills) {
const skill = skills.getSkill(s_uuid);
if (!skill) continue;
if (skill.hset === HSSet.max && !skills.max_auto) continue;
const config = SkillSet[skill.s_uuid];
if (!config || config.SType !== SType.damage) continue;
@@ -58,26 +62,50 @@ export class SACastSystem extends ecs.ComblockSystem implements ecs.ISystemUpdat
if (!this.hasEnemyInSkillRange(heroView, heroAttrs, skill.dis)) continue;
// ✅ 开始执行施法
this.startCast(e,skill);
this.startCast(e,skill,skill.hset);
// 一次只施放一个技能
break;
}
}
private startCast(e: ecs.Entity,skill:SkillSlot): void {
if (!skill||!e) return
private startCast(e: ecs.Entity,skill:SkillSlot,hset:HSSet): boolean {
if (!skill||!e) return false
const skills = e.get(HeroSkillsComp);
const heroAttrs = e.get(HeroAttrsComp);
const heroView = e.get(HeroViewComp);
// 3. 检查施法条件
if (!this.checkCastConditions(skills, heroAttrs, skill.s_uuid)) return
if (!this.checkCastConditions(skills, heroAttrs, skill.s_uuid)) return false
// 4. 执行施法
this.executeCast(e, skill.s_uuid, heroView);
const castSucess = this.executeCast(e, skill.s_uuid, heroView,hset);
// 5. 扣除资源和重置CD
heroAttrs.mp -= skill.cost;
skills.resetCD(skill.s_uuid);
if (castSucess) {
heroAttrs.mp -= skill.cost;
skills.resetCD(skill.s_uuid);
}
return castSucess;
}
public manualCast(e: ecs.Entity, s_uuid: number): boolean {
if (!e) return false
const skills = e.get(HeroSkillsComp)
const heroAttrs = e.get(HeroAttrsComp)
const heroView = e.get(HeroViewComp)
if (!skills || !heroAttrs || !heroView) return false
const slot = skills.getSkill(s_uuid)
if (!slot) return false
return this.startCast(e, slot, slot.hset)
}
public manualCastMax(e: ecs.Entity): boolean {
const skills = e.get(HeroSkillsComp)
if (!skills) return false
for (const key in skills.skills) {
const s_uuid = Number(key)
const slot = skills.getSkill(s_uuid)
if (slot && slot.hset === HSSet.max) {
return this.manualCast(e, s_uuid)
}
}
return false
}
/**
* 检查施法条件
@@ -104,29 +132,87 @@ export class SACastSystem extends ecs.ComblockSystem implements ecs.ISystemUpdat
/**
* 执行施法
*/
private executeCast(casterEntity: ecs.Entity, s_uuid: number, heroView: HeroViewComp) {
private executeCast(casterEntity: ecs.Entity, s_uuid: number, heroView: HeroViewComp,hset:HSSet): boolean {
const heroAttrs=casterEntity.get(HeroAttrsComp)
const config = SkillSet[s_uuid];
if (!config) {
console.error("[SACastSystem] 技能配置不存在:", s_uuid);
return;
return false;
}
// 1. 播放施法动画
heroView.playSkillEffect(s_uuid);
/**********************天赋处理*************************************************************************/
// 2. 更新攻击类型的天赋触发值,技能和必杀级
if(casterEntity.has(TalComp)){
const talComp = casterEntity.get(TalComp);
if (hset === HSSet.atk) talComp.updateCur(TriType.ATK);
if (hset === HSSet.skill) talComp.updateCur(TriType.SKILL);
if (hset === HSSet.max) talComp.updateCur(TriType.MAX);
}
/**********************天赋处理*************************************************************************/
// 获取目标位置
let targets = this.sTargets(heroView, s_uuid);
if (targets.length === 0) {
console.warn("[SACastSystem] 没有找到有效目标");
return false;
}
// 2.1 普通攻击逻辑
if (hset === HSSet.atk){
let delay = 0.3
let ext_dmg = heroAttrs.useCountValTal(TalEffet.ATK_DMG);
heroView.scheduleOnce(() => {
this.createSkill(s_uuid, heroView,targets,ext_dmg);
}, delay);
//风怒wfuny 只针对 普通攻击起效
if (heroAttrs.useCountTal(TalEffet.WFUNY)){
let ext2_dmg = heroAttrs.useCountValTal(TalEffet.ATK_DMG);
let delay = 0.3
heroView.playSkillEffect(s_uuid);
//需要再添加 风怒动画
heroView.scheduleOnce(() => {
this.createSkill(s_uuid, heroView,targets,ext2_dmg);
},delay);
}
}
// 2.2 技能攻击逻辑
if(hset === HSSet.skill){
let delay = 0.3
let ext_dmg = heroAttrs.useCountValTal(TalEffet.SKILL_DMG);
heroView.scheduleOnce(() => {
this.createSkill(s_uuid, heroView,targets,ext_dmg);
}, delay);
// 双技能 只针对 技能起效
if(heroAttrs.useCountTal(TalEffet.D_SKILL)){
let ext2_dmg = heroAttrs.useCountValTal(TalEffet.SKILL_DMG);
let delay = 0.3
heroView.playSkillEffect(s_uuid);
//需要再添加 双技能动画
heroView.scheduleOnce(() => {
this.createSkill(s_uuid, heroView,targets,ext2_dmg);
},delay);
}
}
// 2.3 必杀技能逻辑
if(hset === HSSet.max){
let delay = 0.3
heroView.playSkillEffect(s_uuid);
//需要再添加 最大伤害动画
heroView.scheduleOnce(() => {
this.createSkill(s_uuid, heroView,targets);
},delay);
}
// 2. 延迟创建技能实体(等待动画)
const delay = 0.3
heroView.scheduleOnce(() => {
this.createSkill(s_uuid, heroView);
}, delay);
const heroAttrs = casterEntity.get(HeroAttrsComp);
// console.log(`[SACastSystem] ${heroAttrs?.hero_name ?? '未知'} 施放技能: ${config.name}`);
return true;
}
/**
* 创建技能实体
*/
private createSkill(s_uuid: number, caster: HeroViewComp) {
private createSkill(s_uuid: number, caster: HeroViewComp,targets:Vec3[]=[],ext_dmg:number=0) {
// 检查节点有效性
if (!caster.node || !caster.node.isValid) {
console.warn("[SACastSystem] 施法者节点无效");
@@ -140,12 +226,7 @@ export class SACastSystem extends ecs.ComblockSystem implements ecs.ISystemUpdat
return;
}
// 获取目标位置
const targets = this.sTargets(caster);
if (targets.length === 0) {
console.warn("[SACastSystem] 没有找到有效目标");
return;
}
// 创建技能实体
const skill = ecs.getEntity<Skill>(Skill);
@@ -156,26 +237,22 @@ export class SACastSystem extends ecs.ComblockSystem implements ecs.ISystemUpdat
const targetPos = targets[0]; // 使用第一个目标位置
// console.log(`[SACastSystem]: ${s_uuid}, 起始位置: ${startPos}, 目标位置: ${targetPos}`);
// 加载技能实体(包括预制体、组件初始化等)
skill.load(startPos, parent, s_uuid, targetPos, caster);
skill.load(startPos, parent, s_uuid, targetPos, caster,ext_dmg);
}
/**
* 选择目标位置
*/
private sTargets(caster: HeroViewComp): Vec3[] {
// 简化版:选择最前方的敌人
const targets: Vec3[] = [];
// 这里可以调用 SkillConComp 的目标选择逻辑
// 暂时返回默认位置
if (caster == null) return targets;
if (caster.ent == null) return targets;
private sTargets(caster: HeroViewComp, s_uuid: number): Vec3[] {
const heroAttrs = caster.ent.get(HeroAttrsComp);
const fac = heroAttrs?.fac ?? 0;
const defaultX = fac === 0 ? 400 : -400;
targets.push(v3(defaultX, 0, 0));
if (!heroAttrs) return [];
const config = SkillSet[s_uuid];
if (!config) return this.sDefaultTargets(caster, heroAttrs.fac);
const maxTargets = Math.max(1, Number((config as any).t_num ?? 1));
const targets = this.sDamageTargets(caster, config, maxTargets);
if (targets.length === 0) {
targets.push(...this.sDefaultTargets(caster, heroAttrs.fac));
}
return targets;
}
@@ -187,8 +264,8 @@ export class SACastSystem extends ecs.ComblockSystem implements ecs.ISystemUpdat
const heroAttrs = caster.ent.get(HeroAttrsComp);
if (!heroAttrs) return targets;
// 寻找最近的敌人
const enemyPositions = this.findNearbyEnemies(caster, heroAttrs.fac, config.range || 300);
const range = Number((config as any).range ?? config.dis ?? 300);
const enemyPositions = this.findNearbyEnemies(caster, heroAttrs.fac, range);
// 选择最多maxTargets个目标
for (let i = 0; i < Math.min(maxTargets, enemyPositions.length); i++) {
@@ -203,82 +280,49 @@ export class SACastSystem extends ecs.ComblockSystem implements ecs.ISystemUpdat
return targets;
}
/**
* 选择治疗技能目标
*/
private sHealTargets(caster: HeroViewComp, config: any, maxTargets: number): Vec3[] {
const targets: Vec3[] = [];
const heroAttrs = caster.ent.get(HeroAttrsComp);
if (!heroAttrs) return targets;
// 寻找血量最低的友军
const allyPositions = this.findLowHealthAllies(caster, heroAttrs.fac, config.range || 200);
for (let i = 0; i < Math.min(maxTargets, allyPositions.length); i++) {
targets.push(allyPositions[i]);
}
// 如果没有找到友军,治疗自己
if (targets.length === 0 && caster.node) {
targets.push(caster.node.position.clone());
}
return targets;
}
/**
* 选择BUFF技能目标
*/
private sBuffTargets(caster: HeroViewComp, config: any, maxTargets: number): Vec3[] {
// BUFF技能通常施放在自己或友军身上
return this.sHealTargets(caster, config, maxTargets);
}
/**
* 选择DEBUFF技能目标
*/
private sDebuffTargets(caster: HeroViewComp, config: any, maxTargets: number): Vec3[] {
// DEBUFF技能通常施放在敌人身上
return this.sDamageTargets(caster, config, maxTargets);
}
/**
* 选择默认目标
*/
private sDefaultTargets(caster: HeroViewComp, faction: number): Vec3[] {
private sDefaultTargets(caster: HeroViewComp, fac: number): Vec3[] {
const targets: Vec3[] = [];
const defaultX = faction === 0 ? 400 : -400;
targets.push(v3(defaultX, 0, 0));
const defaultX = fac === 0 ? 400 : -400;
targets.push(v3(defaultX, BoxSet.GAME_LINE, 1));
return targets;
}
/**
* 查找附近的敌人
*/
private findNearbyEnemies(caster: HeroViewComp, faction: number, range: number): Vec3[] {
// 简化实现实际应该查询ECS中的敌方实体
private findNearbyEnemies(caster: HeroViewComp, fac: number, range: number): Vec3[] {
const enemies: Vec3[] = [];
// 模拟敌人位置
const enemyX = faction === 0 ? 300 : -300;
enemies.push(v3(enemyX, 0, 0));
enemies.push(v3(enemyX + 50, 20, 0));
if (!caster || !caster.node) return enemies;
const currentPos = caster.node.position;
const results: { pos: Vec3; dist: number; laneBias: number }[] = [];
ecs.query(ecs.allOf(HeroAttrsComp, HeroViewComp)).some(e => {
const model = e.get(HeroAttrsComp);
const view = e.get(HeroViewComp);
if (!model || !view || !view.node) return false;
if (model.is_dead) return false;
if (model.fac === fac) return false;
const pos = view.node.position;
const dist = Math.abs(currentPos.x - pos.x);
if (dist <= range) {
const laneBias = Math.abs(currentPos.y - pos.y);
results.push({ pos: pos.clone(), dist, laneBias });
}
return false;
});
results.sort((a, b) => {
if (a.laneBias !== b.laneBias) return a.laneBias - b.laneBias;
return a.dist - b.dist;
});
for (const r of results) enemies.push(r.pos);
return enemies;
}
/**
* 查找血量低的友军
*/
private findLowHealthAllies(caster: HeroViewComp, faction: number, range: number): Vec3[] {
// 简化实现实际应该查询ECS中的友方实体并按血量排序
const allies: Vec3[] = [];
// 如果自己血量低,优先治疗自己
return allies;
}
/**
* 检查技能攻击范围内是否有敌人

View File

@@ -1,145 +0,0 @@
import { ecs } from "../../../../extensions/oops-plugin-framework/assets/libs/ecs/ECS";
import { Vec3, v3 } from "cc";
import { HeroAttrsComp } from "./HeroAttrsComp";
import { HeroViewComp } from "./HeroViewComp";
import { SkillSet, SType } from "../common/config/SkillSet";
import { HeroSkillsComp } from "./HeroSkills";
import { Skill } from "../skill/Skill";
import { CSRequestComp } from "../skill/STagComps";
import { smc } from "../common/SingletonModuleComp";
/**
* ==================== 技能施法系统 手动施法====================
*
* 职责:
* 1. 监听 CSRequestComp 标记组件
* 2. 检查施法条件CD、MP、状态
* 3. 扣除资源MP
* 4. 创建技能实体
* 5. 触发施法动画
* 6. 移除请求标记
*
* 设计理念:
* - 使用标记组件驱动,符合 ECS 理念
* - 施法检查与执行分离
* - 自动处理资源消耗和CD重置
*/
// @ecs.register('SCastSystem')
export class SCastSystem extends ecs.ComblockSystem implements ecs.IEntityEnterSystem {
/**
* 过滤器:拥有技能数据 + 施法请求的实体
*/
filter(): ecs.IMatcher {
return ecs.allOf(HeroSkillsComp, HeroAttrsComp, CSRequestComp);
}
/**
* 实体进入时触发(即请求施法时)
*/
entityEnter(e: ecs.Entity): void {
if(!smc.mission.play || smc.mission.pause) return;
const skillsComp = e.get(HeroSkillsComp);
const heroAttrs = e.get(HeroAttrsComp);
const request = e.get(CSRequestComp);
const heroView = e.get(HeroViewComp);
// 1. 验证数据完整性
if (!skillsComp || !heroAttrs || !request || !heroView) {
console.warn("[SCastSystem] 数据不完整,取消施法");
e.remove(CSRequestComp);
return;
}
// 2. 获取技能数据
const skill = skillsComp.getSkill(request.s_uuid);
if (!skill) {
console.warn(`[SCastSystem] 技能索引无效: ${request.s_uuid }`);
e.remove(CSRequestComp);
return;
}
// 3. 检查施法条件
if (!this.checkCastConditions(skillsComp, heroAttrs, request.s_uuid)) {
e.remove(CSRequestComp);
return;
}
// 4. 执行施法
this.executeCast(e, skill, request.targets, heroView);
// 5. 扣除资源和重置CD
heroAttrs.mp -= skill.cost;
skillsComp.resetCD(request.s_uuid);
// 6. 移除请求标记
e.remove(CSRequestComp);
}
/**
* 检查施法条件
*/
private checkCastConditions(skillsComp: HeroSkillsComp, heroAttrs: HeroAttrsComp, skillIndex: number): boolean {
// 检查角色状态
if (heroAttrs.is_dead) {
return false;
}
// 检查控制状态(眩晕、冰冻)
if (heroAttrs.isStun() || heroAttrs.isFrost()) {
return false;
}
// 检查CD和MP
if (!skillsComp.canCast(skillIndex, heroAttrs.mp)) {
return false;
}
return true;
}
/**
* 执行施法
*/
private executeCast(casterEntity: ecs.Entity, skill: any, targets: Vec3[], heroView: HeroViewComp) {
const config = SkillSet[skill.uuid];
if (!config) {
console.error("[SCastSystem] 技能配置不存在:", skill.uuid);
return;
}
// 1. 播放施法动画
heroView.playSkillEffect(skill.uuid);
// 2. 延迟创建技能实体(等待动画)
const delay = config.with ?? 0.3; // 施法前摇时间
heroView.scheduleOnce(() => {
this.createSkill(skill.uuid, heroView, targets);
}, delay);
const heroAttrs = casterEntity.get(HeroAttrsComp);
console.log(`[SCastSystem] ${heroAttrs?.hero_name ?? '未知'} 施放技能: ${config.name}`);
}
/**
* 创建技能实体
*/
private createSkill(skillId: number, caster: HeroViewComp, targets: Vec3[]) {
// 检查节点有效性
if (!caster.node || !caster.node.isValid) {
console.warn("[SCastSystem] 施法者节点无效");
return;
}
// 获取场景节点
const parent = caster.node.parent;
if (!parent) {
console.warn("[SCastSystem] 场景节点无效");
return;
}
// ✅ 使用现有的 SkillEnt 创建技能
// const skill = ecs.getEntity<Skill>(Skill);
}
}

View File

@@ -1,169 +1,251 @@
import { _decorator } from "cc";
import { ecs } from "../../../../extensions/oops-plugin-framework/assets/libs/ecs/ECS";
import { CCComp } from "../../../../extensions/oops-plugin-framework/assets/module/common/CCComp";
import { ItalConf, TalType, TalEType, talConf } from "../common/config/TalSet";
import { BuffConf, SkillSet } from "../common/config/SkillSet";
import { HeroInfo } from "../common/config/heroSet";
import { BType } from "../common/config/HeroAttrs";
import { TalAttrs, talConf, TalEffet, TalTarget, TriType} from "../common/config/TalSet";
import { HeroAttrsComp } from "./HeroAttrsComp";
import { HeroViewComp } from "./HeroViewComp";
const { ccclass } = _decorator;
/**
* 天赋触发统计接口
* 记录各种触发条件的计数器,用于判断天赋是否满足触发条件
* 天赋槽位接口定义
* 描述单个天赋的数据结构
*/
interface FightStats {
aCount: number; // 普通攻击计数 - 用于 ACTION_COUNT 类型天赋
sCount: number; // 技能使用计数 - 用于 SKILL_COUNT 类型天赋
dCount: number; // 受伤次数计数 - 用于 DAMAGE_COUNT 类型天赋
level: number; // 当前等级 - 用于 LEVEL/LEVEL_UP 类型天赋
export interface TalSlot {
uuid: number; // 天赋唯一标识符
name: string; // 天赋名称
triType: TriType; // 天赋触发类型
target: TalTarget;
effet: TalEffet;
attrs?:TalAttrs //触发的attrs效果的对应attrs value: number; // 触发的效果数值
vType:BType; // 数值型还是百分比型
value: number; // 触发的效果数值
value_add: number; // 触发的效果数值增量
count: number; // 执行次数,及可以触发的次数
count_add: number; // 执行次数增量
Trigger: number; // 天赋触发阈值
Trigger_add: number; // 天赋触发阈值减值
desc: string; // 天赋描述(说明触发条件和效果)
cur: number; // 当前累积值
}
/**
* 天赋效果实例接口
* 记录已激活天赋的当前状态,包括堆叠层数和最后触发时间
*/
interface TalEffect {
uuid: number; // 天赋uuid
stack: number; // 当前堆叠层数,用于可堆叠天赋
lTTime: number; // 上次触发时间戳,可用于时效判断
}
/**
* 天赋系统组件类
* 继承自 CCComp作为 ECS 架构中的组件存在
* 负责管理英雄的天赋系统,包括天赋获取、触发、效果应用等
* 作为ECS架构中的组件,负责管理英雄的天赋系统
*
* 核心功能:
* - 初始化英雄天赋系统
* - 添加新天赋到英雄
* - 累积天赋触发进度
* - 检查并触发满足条件的天赋
* - 管理天赋效果数值
*/
@ccclass('TalComp')
@ecs.register('TalComp', false)
export class TalComp extends ecs.Comp {
/** 英雄视图组件引用,运行时获取避免循环引用 */
/** 英雄视图组件引用,运行时获取避免循环引用 */
private heroView: any = null;
private skillCon:any=null;
/** 英雄唯一标识符,用于从配置中获取英雄信息 */
/** 英雄唯一标识符,用于从配置中获取英雄相关信息 */
private heroUuid: number = 0;
/** 天赋触发统计,记录各种触发条件的当前状态 */
private FStats: FightStats = { aCount: 0, sCount: 0, dCount: 0, level: 1 };
/** 活跃天赋效果映射,存储已激活的天赋实例 */
private activeTals: TalEffect[] = [];
private talEffects: ItalConf[] = [];
/** 初始化标志,防止重复初始化 */
private isInitialized: boolean = false;
/** 天赋集合以天赋ID为键存储所有已获得的天赋 */
Tals: Record<number, TalSlot> = {};
/**
* 组件生命周期函数 - 启动时调用
* 获取英雄视图组件并初始化天赋系统
* 组件初始化方法
* @param heroUuid 英雄唯一标识符
*/
start() {
// 运行时获取组件,避免编译时循环引用
init(heroUuid: number) {
this.heroUuid = heroUuid;
// 从实体中获取英雄视图组件引用
this.heroView = this.ent.get(HeroViewComp);
if (this.heroView) {
this.heroUuid = this.heroView.hero_uuid;
this.initializeTalents();
// 初始化天赋集合
this.Tals = {};
}
/**
* 为英雄添加一个新天赋
* @param uuid 要添加的天赋ID
*
* 添加流程:
* 1. 检查天赋是否已存在
* 2. 检查天赋配置是否存在
* 3. 创建并初始化天赋数据
*/
addTal(uuid: number) {
// 检查天赋是否已存在
if (this.Tals[uuid]) {
console.error(`[TalComp]天赋已存在,天赋ID:${uuid}`);
return;
}
// 获取天赋配置
const tConf = talConf[uuid];
if (!tConf) {
console.error(`[TalComp]天赋配置不存在,天赋ID:${uuid}`);
return;
}
// 创建并初始化天赋数据
this.Tals[uuid] = {
uuid: uuid,
name: tConf.name,
triType: tConf.triType,
target: tConf.target,
effet: tConf.effet,
attrs: tConf.attrs,
vType: tConf.vType,
value: tConf.value, // 效果数值初始为配置值
value_add: 0, // 效果数值增量初始为0
count: 1, // 执行次数,及可以触发的次数
count_add:0, // 执行次数增量初始为0
Trigger: tConf.Trigger, // 触发阈值(后续可从配置中读取)
Trigger_add: 0, // 触发阈值增量初始为0
desc: tConf.desc,
cur: 0, // 当前累积值初始为0
};
}
checkTal() {
return Object.keys(this.Tals).length > 0;
}
getTriggers() {
// 存储所有触发的天赋
let Triggers: Record<string, TalSlot> = {};
// 遍历所有天赋
for (let uuid in this.Tals) {
const talent = this.Tals[uuid];
if (talent.cur >= (talent.Trigger - talent.Trigger_add)) { // 修复触发条件,累积值达到或超过触发阈值时触发
console.log(`[TalComp]天赋触发,天赋ID:${uuid}`);
// 重置累积值
talent.cur = 0;
// 添加到触发列表
Triggers[uuid] = talent;
}
}
// 判断是否有天赋被触发
return Triggers;
}
/**
* 更新天赋的效果数值
* @param uuid 天赋ID
* @param val 要增减的数值
*
* 功能:
* - 用于调整天赋的实际效果数值
* - 可通过正负数来增加或减少效果
*/
updateVal(uuid: number, val: number) {
// 检查天赋是否存在
if (!this.Tals[uuid]) {
console.error(`[TalComp]天赋不存在,天赋ID:${uuid}`);
return;
}
// 更新天赋效果数值
this.Tals[uuid].value_add += val;
}
updateTrigger(uuid: number, val: number) {
// 检查天赋是否存在
if (!this.Tals[uuid]) {
console.error(`[TalComp]天赋不存在,天赋ID:${uuid}`);
return;
}
// 更新天赋触发阈值
this.Tals[uuid].Trigger_add += val;
if (this.Tals[uuid].Trigger-this.Tals[uuid].Trigger_add <= 1) {
this.Tals[uuid].Trigger_add = this.Tals[uuid].Trigger-1;
}
}
/**
* 更新指定类型天赋的累积值
* @param triType 天赋触发类型
* @param val 要增加的累积值默认值为1
*
* 设计注意:
* - 当前实现只会更新第一个匹配类型的天赋
* - 累积值用于后续判断是否触发天赋效果
*/
updateCur(triType: TriType, val: number = 1) {
// 遍历所有天赋
for (let uuid in this.Tals) {
const talent = this.Tals[uuid];
private initializeTalents(): void {
if (this.isInitialized || !this.heroView) return;
this.FStats.level = this.heroView.lv || 1;
this.getHeroTalents()
this.isInitialized = true;
}
private getHeroTalents(): ItalConf[] {
this.activeTals = [];
this.talEffects = [];
if (!this.heroView) return [];
const heroInfo = HeroInfo[this.heroUuid];
if (!heroInfo?.tal) return [];
for(let id of heroInfo.tal){
let conf = talConf[id];
if(conf){
this.talEffects.push(conf)
// 找到所有匹配类型的天赋并更新
if (talent.triType == triType) {
talent.cur += val;
this.checkTrigger(talent.uuid);
}
}
}
private doTalEffect(tal:ItalConf){
console.log("doTalEffect",tal)
if(tal.triggerType == TalEType.ATTRS){
console.log("doTalEffect ATTRS",tal)
let buff:BuffConf = {
buff:tal.e_name,
BType:tal.e_type,
value:tal.e_value,
time:0,
chance:tal.chance,
checkTrigger(uuid:number){
const talent = this.Tals[uuid];
if (talent.cur >= (talent.Trigger - talent.Trigger_add)) { // 修复触发条件,累积值达到或超过触发阈值时触发
console.log(`[TalComp]天赋触发,天赋ID:${uuid}`);
for(let i=0;i<(talent.count+talent.count_add);i++){
this.doTriggerTal(talent.uuid);
}
this.heroView.addBuff(buff)
}
// 重置累积值
talent.cur = 0;
if(tal.triggerType == TalEType.SKILL){
console.log("doTalEffect SKILL",tal)
let skill = SkillSet[tal.e_value];
if(this.skillCon){
this.skillCon.doSkill(skill,false,0)
}
}
if(tal.triggerType == TalEType.SKILL_MORE){
console.log("doTalEffect SKILL_MORE",tal)
this.heroView.skills.push(tal.e_value)
}
}
private checkTrigger(tal:ItalConf) {
let stats = this.FStats;
switch (tal.type) {
case TalType.LEVEL: return stats.level >= tal.t_value;
case TalType.LEVEL_UP: return stats.level % tal.t_value === 0;
case TalType.ACTION_COUNT: return stats.aCount >= tal.t_value;
case TalType.SKILL_COUNT: return stats.sCount >= tal.t_value;
case TalType.DAMAGE_COUNT: return stats.dCount >= tal.t_value;
case TalType.INIT: return true;
case TalType.DEAD: return false; // 单独处理
default: return false;
}
}
private checkHasTal(TalType:TalType) {
for(let tal of this.talEffects){
if(TalType == tal.type){
if (this.checkTrigger(tal)){
this.doTalEffect(tal)
}
}
//执行天赋触发效果
// 功能:
// - 根据天赋类型执行相应的效果
// - 支持计数型和数值型天赋
// --heroAttrs.addTalent 是计数型天赋buff heroAttrs.addTalBuff 是数值型天赋buff
doTriggerTal(uuid: number) {
// 检查天赋是否存在
if (!this.Tals[uuid]) {
console.error(`[TalComp]天赋不存在,天赋ID:${uuid}`);
return;
}
const talent = this.Tals[uuid];
const heroAttrs=this.ent.get(HeroAttrsComp);
switch(talent.effet){
case TalEffet.ATK_DMG:
heroAttrs.addCountTal(TalEffet.ATK_DMG, talent.value + talent.value_add);
break;
case TalEffet.SKILL_DMG:
heroAttrs.addCountTal(TalEffet.SKILL_DMG, talent.value + talent.value_add);
break;
case TalEffet.DMG_RED:
heroAttrs.addCountTal(TalEffet.DMG_RED, talent.value + talent.value_add);
break;
case TalEffet.HP:
heroAttrs.add_hp(talent.value + talent.value_add,talent.vType == BType.VALUE);
break;
case TalEffet.MP:
heroAttrs.add_mp(talent.value + talent.value_add,talent.vType == BType.VALUE);
break;
case TalEffet.WFUNY:
heroAttrs.addCountTal(TalEffet.WFUNY, talent.value + talent.value_add);
break;
case TalEffet.D_SKILL:
heroAttrs.addCountTal(TalEffet.D_SKILL, talent.value + talent.value_add);
break;
case TalEffet.C_ATK:
heroAttrs.addCountTal(TalEffet.C_ATK, talent.value + talent.value_add);
break;
case TalEffet.C_SKILL:
heroAttrs.addCountTal(TalEffet.C_SKILL, talent.value + talent.value_add);
break;
case TalEffet.C_MSKILL:
heroAttrs.addCountTal(TalEffet.C_MSKILL, talent.value + talent.value_add);
break;
case TalEffet.BUFF:
heroAttrs.addValueTal(talent.uuid, talent.attrs, talent.vType, talent.value + talent.value_add);
break;
}
}
public onAction(): void {
this.FStats.aCount++;
this.checkHasTal(TalType.ACTION_COUNT);
}
public onSkillUse(): void {
this.FStats.sCount++;
this.checkHasTal(TalType.SKILL_COUNT);
}
public onDamageTaken(): void {
this.FStats.dCount++;
this.checkHasTal(TalType.DAMAGE_COUNT);
}
public onLevelUp(newLevel: number): void {
this.FStats.level = newLevel;
this.checkHasTal(TalType.LEVEL);
this.checkHasTal(TalType.LEVEL_UP);
}
public onDeath(): void {
this.checkHasTal(TalType.DEAD);
}
/**
* 重置组件状态
*/
reset() {
this.isInitialized = false;
this.Tals = {};
this.heroUuid = 0;
this.heroView = null;
}
}

View File

@@ -27,9 +27,9 @@ export class HInfoComp extends CCComp {
hero_pos:any={
0:v3(420,-30,0), // 不在屏幕内
1:v3(280,-30,0),
2:v3(160,-33,0),
2:v3(160,-30,0),
3:v3(0,-40,0),
4:v3(-160,-33,0),
4:v3(-160,-30,0),
5:v3(-280,-30,0),
6:v3(-420,-30,0), // 不在屏幕内
}
@@ -53,11 +53,11 @@ export class HInfoComp extends CCComp {
switch(posIndex) {
case 2:
case 4:
return v3(-1.6, 1.6, 1); // 2、4位置1.2倍缩放
return v3(-1.5, 1.5, 1); // 2、4位置1.5倍缩放
case 3:
return v3(-1.8, 1.8, 1); // 3位置中心1.5倍缩放
default:
return v3(-1.4, 1.4, 1); // 其他位置1倍缩放
return v3(-1.5, 1.5, 1); // 其他位置1.5倍缩放
}
}

View File

@@ -12,6 +12,8 @@ export class SDataCom extends ecs.Comp {
group:BoxSet=BoxSet.HERO
fac: number = 0; // 0:hero 1:monster
s_uuid:number=0
ext_dmg:number=0 //额外伤害
dmg_ratio:number=1 //伤害比例
hit_count:number=0 //击中数量
reset() {
this.Attrs=null
@@ -20,6 +22,8 @@ export class SDataCom extends ecs.Comp {
this.s_uuid=0
this.caster=null
this.hit_count=0
this.ext_dmg=0
this.dmg_ratio=1
}
}

View File

@@ -29,7 +29,7 @@ export class Skill extends ecs.Entity {
this.addComponents<SMoveDataComp>(SMoveDataComp);
}
load(startPos: Vec3, parent: Node, s_uuid: number, targetPos: Vec3,
caster:HeroViewComp) {
caster:HeroViewComp,ext_dmg:number=0) {
const config = SkillSet[s_uuid];
if (!config) {
@@ -90,9 +90,10 @@ export class Skill extends ecs.Entity {
const sDataCom = this.get(SDataCom);
sDataCom.group=caster.box_group
sDataCom.caster=caster
sDataCom.Attrs=cAttrsComp.Attrs
sDataCom.Attrs={...cAttrsComp.Attrs}
sDataCom.s_uuid=s_uuid
sDataCom.fac=cAttrsComp.fac
sDataCom.ext_dmg=ext_dmg
}
/** 模块资源释放 */

View File

@@ -149,7 +149,9 @@ export class SkillView extends CCComp {
target.ent,
this.sData.Attrs,
this.sData.caster,
this.sData.s_uuid
this.sData.s_uuid,
this.sData.ext_dmg,
this.sData.dmg_ratio,
);
// 更新技能命中次数
this.sData.hit_count++

View File

@@ -41,6 +41,14 @@ export class TooltipCom extends CCComp {
this.ent.destroy()
},0.5)
break
case TooltipTypes.addmp:
this.node.setSiblingIndex(110);
this.node.getChildByName("add_mp").getChildByName("mp").getComponent(Label).string = this.value;
this.node.getChildByName("add_mp").active=true;
this.scheduleOnce(()=>{
this.ent.destroy()
},0.5)
break
case TooltipTypes.crit:
this.node.setPosition(v3(this.node.position.x,this.node.position.y))
this.node.setSiblingIndex(200);

View File

@@ -201,10 +201,10 @@ console.log("道具1001数量:", itemInfo.result.data.count);
const talents = await WxCloudApi.getTalents();
// 添加天赋点
const result = await WxCloudApi.addTalent(1001, 1);
const result = await WxCloudApi.addCountTal(1001, 1);
// 消耗天赋点
const result = await WxCloudApi.consumeTalent(1001, 1);
const result = await WxCloudApi.useCountTal(1001, 1);
```
### 装备操作

View File

@@ -1,15 +0,0 @@
md extensions
cd extensions
IF EXIST oops-plugin-framework (
goto update
) ELSE (
goto clone
)
:clone
git clone -b master https://gitee.com/dgflash/oops-plugin-framework.git
:update
cd oops-plugin-framework
git pull