Compare commits
4 Commits
8e5c0d3852
...
812cc3ee9f
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
812cc3ee9f | ||
|
|
b31cb877fe | ||
|
|
667ec1abfb | ||
|
|
e8c6a7ca6a |
File diff suppressed because it is too large
Load Diff
@@ -251,9 +251,9 @@
|
|||||||
"__prefab": {
|
"__prefab": {
|
||||||
"__id__": 11
|
"__id__": 11
|
||||||
},
|
},
|
||||||
"atk_x": 0,
|
"atk_x": 20,
|
||||||
"atk_y": 0,
|
"atk_y": 20,
|
||||||
"runType": 0,
|
"runType": 1,
|
||||||
"endType": 2,
|
"endType": 2,
|
||||||
"speed": 720,
|
"speed": 720,
|
||||||
"time": 0,
|
"time": 0,
|
||||||
|
|||||||
@@ -181,7 +181,7 @@
|
|||||||
},
|
},
|
||||||
"_type": 0,
|
"_type": 0,
|
||||||
"_fillType": 0,
|
"_fillType": 0,
|
||||||
"_sizeMode": 1,
|
"_sizeMode": 0,
|
||||||
"_fillCenter": {
|
"_fillCenter": {
|
||||||
"__type__": "cc.Vec2",
|
"__type__": "cc.Vec2",
|
||||||
"x": 0,
|
"x": 0,
|
||||||
@@ -389,11 +389,12 @@
|
|||||||
},
|
},
|
||||||
"atk_x": 0,
|
"atk_x": 0,
|
||||||
"atk_y": 0,
|
"atk_y": 0,
|
||||||
"_id": "",
|
|
||||||
"runType": 0,
|
"runType": 0,
|
||||||
"endType": 2,
|
"endType": 2,
|
||||||
"speed": 720,
|
"speed": 720,
|
||||||
"time": 0
|
"time": 0,
|
||||||
|
"distance": 0,
|
||||||
|
"_id": ""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"__type__": "cc.CompPrefabInfo",
|
"__type__": "cc.CompPrefabInfo",
|
||||||
|
|||||||
@@ -251,9 +251,9 @@
|
|||||||
"__prefab": {
|
"__prefab": {
|
||||||
"__id__": 11
|
"__id__": 11
|
||||||
},
|
},
|
||||||
"atk_x": 0,
|
"atk_x": 20,
|
||||||
"atk_y": 0,
|
"atk_y": 20,
|
||||||
"runType": 0,
|
"runType": 1,
|
||||||
"endType": 2,
|
"endType": 2,
|
||||||
"speed": 720,
|
"speed": 720,
|
||||||
"time": 0,
|
"time": 0,
|
||||||
|
|||||||
@@ -251,8 +251,8 @@
|
|||||||
"__prefab": {
|
"__prefab": {
|
||||||
"__id__": 11
|
"__id__": 11
|
||||||
},
|
},
|
||||||
"atk_x": 0,
|
"atk_x": 20,
|
||||||
"atk_y": 0,
|
"atk_y": 30,
|
||||||
"runType": 0,
|
"runType": 0,
|
||||||
"endType": 2,
|
"endType": 2,
|
||||||
"speed": 720,
|
"speed": 720,
|
||||||
|
|||||||
@@ -251,8 +251,8 @@
|
|||||||
"__prefab": {
|
"__prefab": {
|
||||||
"__id__": 11
|
"__id__": 11
|
||||||
},
|
},
|
||||||
"atk_x": 0,
|
"atk_x": 20,
|
||||||
"atk_y": 0,
|
"atk_y": 20,
|
||||||
"runType": 0,
|
"runType": 0,
|
||||||
"endType": 2,
|
"endType": 2,
|
||||||
"speed": 720,
|
"speed": 720,
|
||||||
|
|||||||
@@ -251,8 +251,8 @@
|
|||||||
"__prefab": {
|
"__prefab": {
|
||||||
"__id__": 11
|
"__id__": 11
|
||||||
},
|
},
|
||||||
"atk_x": 0,
|
"atk_x": 20,
|
||||||
"atk_y": 0,
|
"atk_y": 20,
|
||||||
"runType": 0,
|
"runType": 0,
|
||||||
"endType": 2,
|
"endType": 2,
|
||||||
"speed": 720,
|
"speed": 720,
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -29,6 +29,38 @@ export interface BuffTickEffect {
|
|||||||
scale_by_ap_pct: number; // 按施法者 ap 缩放百分比,0=不吃加成
|
scale_by_ap_pct: number; // 按施法者 ap 缩放百分比,0=不吃加成
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* debuff 图标节点名枚举。
|
||||||
|
* 取值即 prefab 节点名:top.prefab 的 top/debuff 容器 与 tooltip.prefab 的 loss_life/hp/debuff 容器
|
||||||
|
* 下存在同名子节点(两处共用一套图标)。
|
||||||
|
* 注意:LightningDamag 为 prefab 原始拼写(少个 e),勿"修正"。
|
||||||
|
*/
|
||||||
|
export enum DebuffIcon {
|
||||||
|
AttackDebuff = "AttackDebuff", // 攻击类 debuff
|
||||||
|
IceDamage = "IceDamage", // 冰系伤害
|
||||||
|
FireDamage = "FireDamage", // 火系伤害(灼烧)
|
||||||
|
LightningDamag = "LightningDamag", // 雷系伤害
|
||||||
|
Penetration = "Penetration", // 穿透
|
||||||
|
Stun = "Stun", // 击晕
|
||||||
|
Poison = "Poison", // 中毒
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* buffId → debuff 图标映射。
|
||||||
|
* 仅伤害类/控制类 debuff 需要图标;未映射的 buff 不显示。
|
||||||
|
* 新增 debuff 时:1) BuffList 加配置 2) 此处加一行映射。
|
||||||
|
*/
|
||||||
|
export const DEBUFF_ICON_MAP: Record<number, DebuffIcon> = {
|
||||||
|
7002: DebuffIcon.FireDamage, // 易伤(灼热火球附加)
|
||||||
|
7003: DebuffIcon.IceDamage, // 冰冻
|
||||||
|
7004: DebuffIcon.Stun, // 击晕
|
||||||
|
7005: DebuffIcon.Poison, // 中毒
|
||||||
|
7006: DebuffIcon.AttackDebuff, // 减攻
|
||||||
|
};
|
||||||
|
|
||||||
|
/** 易伤 buff 的 id(HeroAtkSystem 结算时按此 id 汇总易伤值) */
|
||||||
|
export const VULNERABLE_BUFF_ID = 7002;
|
||||||
|
|
||||||
/** Buff 静态定义 */
|
/** Buff 静态定义 */
|
||||||
export interface BuffConfig {
|
export interface BuffConfig {
|
||||||
id: number;
|
id: number;
|
||||||
@@ -53,12 +85,13 @@ export const BuffList: Record<number, BuffConfig> = {
|
|||||||
modifiers: [{ attr: Attrs.ap, op: ModOp.Flat, value: 5 }],
|
modifiers: [{ attr: Attrs.ap, op: ModOp.Flat, value: 5 }],
|
||||||
info: "攻击力 +5,持续 10 秒",
|
info: "攻击力 +5,持续 10 秒",
|
||||||
},
|
},
|
||||||
// 灼烧(DoT,可叠层)
|
// 易伤(灼热火球附加;受到伤害时附加固定值,可被易伤抗性百分比减免)
|
||||||
|
// 注:modifiers.attr 用 hp 仅为占位以通过 aggregateTimedMods 结构校验,实际易伤值由 HeroAtkSystem 按 VULNERABLE_BUFF_ID 直接汇总
|
||||||
7002: {
|
7002: {
|
||||||
id: 7002, name: "灼烧", icon: "Stat_Burn",
|
id: 7002, name: "易伤", icon: "Stat_Burn",
|
||||||
category: BuffCategory.Debuff, duration: 5, max_stack: 5,
|
category: BuffCategory.Debuff, duration: 5, max_stack: 5,
|
||||||
tick: { interval: 0.5, damage_or_heal: -10, scale_by_ap_pct: 30 },
|
modifiers: [{ attr: Attrs.hp, op: ModOp.Flat, value: 10 }],
|
||||||
info: "每 0.5 秒受到 10 伤害,可叠加",
|
info: "受到的伤害附加 10 点易伤,可叠加,持续 5 秒",
|
||||||
},
|
},
|
||||||
// 冰冻(控制,走统一框架,双写兼容)
|
// 冰冻(控制,走统一框架,双写兼容)
|
||||||
7003: {
|
7003: {
|
||||||
@@ -74,6 +107,20 @@ export const BuffList: Record<number, BuffConfig> = {
|
|||||||
is_control: true, control_kind: 'stun',
|
is_control: true, control_kind: 'stun',
|
||||||
info: "击晕目标,无法行动",
|
info: "击晕目标,无法行动",
|
||||||
},
|
},
|
||||||
|
// 中毒(纯伤害 DoT,可叠层)
|
||||||
|
7005: {
|
||||||
|
id: 7005, name: "中毒", icon: "Stat_PoisonChanceIncrease",
|
||||||
|
category: BuffCategory.Debuff, duration: 5, max_stack: 5,
|
||||||
|
tick: { interval: 0.5, damage_or_heal: -10, scale_by_ap_pct: 30 },
|
||||||
|
info: "每 0.5 秒受到 10 点中毒伤害,可叠加,持续 5 秒",
|
||||||
|
},
|
||||||
|
// 减攻(降低目标攻击力)
|
||||||
|
7006: {
|
||||||
|
id: 7006, name: "减攻", icon: "Stat_Attack_01",
|
||||||
|
category: BuffCategory.Debuff, duration: 5, max_stack: 1,
|
||||||
|
modifiers: [{ attr: Attrs.ap, op: ModOp.Flat, value: -10 }],
|
||||||
|
info: "攻击力降低 10 点,持续 5 秒",
|
||||||
|
},
|
||||||
// 占卜师战前攻击强化(基础档:+30/5s;高阶通过 buff_value/buff_duration 覆写成长)
|
// 占卜师战前攻击强化(基础档:+30/5s;高阶通过 buff_value/buff_duration 覆写成长)
|
||||||
7111: {
|
7111: {
|
||||||
id: 7111, name: "战前强攻", icon: "Stat_Attack_03",
|
id: 7111, name: "战前强攻", icon: "Stat_Attack_03",
|
||||||
|
|||||||
@@ -38,6 +38,7 @@ export enum Attrs {
|
|||||||
puncture_chance = "puncture_chance", // 穿透概率
|
puncture_chance = "puncture_chance", // 穿透概率
|
||||||
puncture_dmg_bonus = "puncture_dmg_bonus", // 穿透后伤害增量(百分点;最终穿透系数 = PUNCTURE_DMG_RATIO * (1 + bonus/100))
|
puncture_dmg_bonus = "puncture_dmg_bonus", // 穿透后伤害增量(百分点;最终穿透系数 = PUNCTURE_DMG_RATIO * (1 + bonus/100))
|
||||||
wfuny = "wfuny", // 风怒
|
wfuny = "wfuny", // 风怒
|
||||||
|
vulnerable_res = "vulnerable_res", // 易伤抗性(百分比减免易伤附加伤害)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
// ========== 从 HeroAttrs.ts 导入属性相关定义 ==========
|
// ========== 从 HeroAttrs.ts 导入属性相关定义 ==========
|
||||||
import { Attrs } from "./HeroAttrs";
|
import { Attrs } from "./HeroAttrs";
|
||||||
|
|
||||||
export enum HSSet {
|
export enum HSSet {
|
||||||
@@ -311,6 +311,12 @@ export const SkillSet: Record<number, SkillConfig> = {
|
|||||||
DTType: DTType.single, ap: 100, hit_count: 2, hitcd: 0.3, speed: 720, with: 90, ready: 0.2, EAnm: 0, DAnm: "", IType: IType.remote,
|
DTType: DTType.single, ap: 100, hit_count: 2, hitcd: 0.3, speed: 720, with: 90, ready: 0.2, EAnm: 0, DAnm: "", IType: IType.remote,
|
||||||
RType: RType.linear, EType: EType.collision, info: "造成攻击力100%的伤害, 高阶技能",
|
RType: RType.linear, EType: EType.collision, info: "造成攻击力100%的伤害, 高阶技能",
|
||||||
},
|
},
|
||||||
|
// DoT 技能:命中附加易伤(7002,受到伤害附加固定值,可被易伤抗性减免)
|
||||||
|
6104: {
|
||||||
|
uuid: 6104, name: "灼热火球", sp_name: "fb-1", icon: "Stat_FireDamage", TGroup: TGroup.Enemy, readyAnm: "", endAnm: "", act: "atk",
|
||||||
|
DTType: DTType.single, ap: 80, hit_count: 2, hitcd: 0.3, speed: 720, with: 90, ready: 0.2, EAnm: 0, DAnm: "", IType: IType.remote,
|
||||||
|
RType: RType.bezier, EType: EType.collision, timed_buff_id: 7002, info: "造成攻击力80%的伤害, 命中附加易伤(5秒内受到伤害附加固定值)",
|
||||||
|
},
|
||||||
6201: {
|
6201: {
|
||||||
uuid: 6201, name: "陨石术", sp_name: "fb-3", icon: "Stat_Tripleshot", TGroup: TGroup.Enemy, readyAnm: "blues", endAnm: "", act: "max",
|
uuid: 6201, name: "陨石术", sp_name: "fb-3", icon: "Stat_Tripleshot", TGroup: TGroup.Enemy, readyAnm: "blues", endAnm: "", act: "max",
|
||||||
DTType: DTType.aoe_grid, stun: 0, ap: 150, hit_count: 6, hitcd: 0.2, speed: 720, with: 0, ready: 0.2, EAnm: 0, DAnm: "", IType: IType.remote,
|
DTType: DTType.aoe_grid, stun: 0, ap: 150, hit_count: 6, hitcd: 0.2, speed: 720, with: 0, ready: 0.2, EAnm: 0, DAnm: "", IType: IType.remote,
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { v3 } from "cc"
|
import { v3 } from "cc"
|
||||||
import { BoxSet, FacSet, FightSet } from "./GameSet"
|
import { BoxSet, FacSet, FightSet } from "./GameSet"
|
||||||
import { SkillOverrides, TGroup, SkillSet, FieldSkillSet, SkillConfig, SkillKind, FieldSkillConfig, FieldSkillType, mergeSkillParams } from "./SkillSet"
|
import { SkillOverrides, TGroup, SkillSet, FieldSkillSet, SkillConfig, SkillKind, FieldSkillConfig, FieldSkillType, mergeSkillParams } from "./SkillSet"
|
||||||
import { BuffList, BuffConfig, ModOp } from "./BuffSet"
|
import { BuffList, BuffConfig, ModOp } from "./BuffSet"
|
||||||
@@ -424,7 +424,7 @@ export const HeroInfo: Record<number, heroInfo> = {
|
|||||||
// 5004 破晓先知 — fstart 全队攻击
|
// 5004 破晓先知 — fstart 全队攻击
|
||||||
5004: {
|
5004: {
|
||||||
uuid: 5004, name: "破晓先知", path: "hm1", fac: FacSet.HERO, card_lv: 1, lv: 1, type: HType.Long, grow_type: HGrowType.Mage, role: HRole.Mage, hp: 143, ap: 32,
|
uuid: 5004, name: "破晓先知", path: "hm1", fac: FacSet.HERO, card_lv: 1, lv: 1, type: HType.Long, grow_type: HGrowType.Mage, role: HRole.Mage, hp: 143, ap: 32,
|
||||||
skills: { 6013: { uuid: 6013, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.Slow].cd, ccd: 0 } },
|
skills: { 6104: { uuid: 6104, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.Slow].cd, ccd: 0 } },
|
||||||
fstart: {
|
fstart: {
|
||||||
6401: [
|
6401: [
|
||||||
{ lv: 1, s_lv: SkillLv.Lv1, t_num: 1, overrides: { TGroup: TGroup.Team, ap: 3 } },
|
{ lv: 1, s_lv: SkillLv.Lv1, t_num: 1, overrides: { TGroup: TGroup.Team, ap: 3 } },
|
||||||
@@ -437,7 +437,7 @@ export const HeroInfo: Record<number, heroInfo> = {
|
|||||||
// 5005 战歌法师 — field 攻击光环
|
// 5005 战歌法师 — field 攻击光环
|
||||||
5005: {
|
5005: {
|
||||||
uuid: 5005, name: "战歌法师", path: "hm2", fac: FacSet.HERO, card_lv: 1, lv: 1, type: HType.Long, grow_type: HGrowType.Mage, role: HRole.Support, hp: 143, ap: 32,
|
uuid: 5005, name: "战歌法师", path: "hm2", fac: FacSet.HERO, card_lv: 1, lv: 1, type: HType.Long, grow_type: HGrowType.Mage, role: HRole.Support, hp: 143, ap: 32,
|
||||||
skills: { 6013: { uuid: 6013, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.Slow].cd, ccd: 0 } },
|
skills: { 6104: { uuid: 6104, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.Slow].cd, ccd: 0 } },
|
||||||
field: [
|
field: [
|
||||||
{ lv: 1, uuids: [{ uuid: 7002, value: 0.1 }] },
|
{ lv: 1, uuids: [{ uuid: 7002, value: 0.1 }] },
|
||||||
{ lv: 3, uuids: [{ uuid: 7002, value: 0.2 }] },
|
{ lv: 3, uuids: [{ uuid: 7002, value: 0.2 }] },
|
||||||
@@ -490,7 +490,7 @@ export const HeroInfo: Record<number, heroInfo> = {
|
|||||||
// 5104 圣光祭司 — fstart 全队护盾(更高数值)
|
// 5104 圣光祭司 — fstart 全队护盾(更高数值)
|
||||||
5104: {
|
5104: {
|
||||||
uuid: 5104, name: "圣光祭司", path: "hm3", fac: FacSet.HERO, card_lv: 2, lv: 1, type: HType.Long, grow_type: HGrowType.Mage, role: HRole.Mage, hp: 287, ap: 64,
|
uuid: 5104, name: "圣光祭司", path: "hm3", fac: FacSet.HERO, card_lv: 2, lv: 1, type: HType.Long, grow_type: HGrowType.Mage, role: HRole.Mage, hp: 287, ap: 64,
|
||||||
skills: { 6013: { uuid: 6013, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.Slow].cd, ccd: 0 } },
|
skills: { 6104: { uuid: 6104, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.Slow].cd, ccd: 0 } },
|
||||||
fstart: {
|
fstart: {
|
||||||
6301: [
|
6301: [
|
||||||
{ lv: 1, s_lv: SkillLv.Lv1, t_num: 1, overrides: { TGroup: TGroup.Team, ap: 3 } },
|
{ lv: 1, s_lv: SkillLv.Lv1, t_num: 1, overrides: { TGroup: TGroup.Team, ap: 3 } },
|
||||||
@@ -503,7 +503,7 @@ export const HeroInfo: Record<number, heroInfo> = {
|
|||||||
// 5105 风怒先知 — field 攻速光环
|
// 5105 风怒先知 — field 攻速光环
|
||||||
5105: {
|
5105: {
|
||||||
uuid: 5105, name: "风怒先知", path: "hm1", fac: FacSet.HERO, card_lv: 2, lv: 1, type: HType.Long, grow_type: HGrowType.Mage, role: HRole.Support, hp: 287, ap: 64,
|
uuid: 5105, name: "风怒先知", path: "hm1", fac: FacSet.HERO, card_lv: 2, lv: 1, type: HType.Long, grow_type: HGrowType.Mage, role: HRole.Support, hp: 287, ap: 64,
|
||||||
skills: { 6013: { uuid: 6013, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.Slow].cd, ccd: 0 } },
|
skills: { 6104: { uuid: 6104, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.Slow].cd, ccd: 0 } },
|
||||||
field: [
|
field: [
|
||||||
{ lv: 1, uuids: [{ uuid: 7006, value: 0.1 }] },
|
{ lv: 1, uuids: [{ uuid: 7006, value: 0.1 }] },
|
||||||
{ lv: 3, uuids: [{ uuid: 7006, value: 0.2 }] },
|
{ lv: 3, uuids: [{ uuid: 7006, value: 0.2 }] },
|
||||||
@@ -569,7 +569,7 @@ export const HeroInfo: Record<number, heroInfo> = {
|
|||||||
// 5204 晨光贤者 — fstart 全队暴击(范围扩大)
|
// 5204 晨光贤者 — fstart 全队暴击(范围扩大)
|
||||||
5204: {
|
5204: {
|
||||||
uuid: 5204, name: "晨光贤者", path: "hm2", fac: FacSet.HERO, card_lv: 3, lv: 1, type: HType.Long, grow_type: HGrowType.Mage, role: HRole.Mage, hp: 430, ap: 96,
|
uuid: 5204, name: "晨光贤者", path: "hm2", fac: FacSet.HERO, card_lv: 3, lv: 1, type: HType.Long, grow_type: HGrowType.Mage, role: HRole.Mage, hp: 430, ap: 96,
|
||||||
skills: { 6013: { uuid: 6013, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.Slow].cd, ccd: 0 } },
|
skills: { 6104: { uuid: 6104, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.Slow].cd, ccd: 0 } },
|
||||||
fstart: {
|
fstart: {
|
||||||
6403: [
|
6403: [
|
||||||
{ lv: 1, s_lv: SkillLv.Lv1, t_num: 1, overrides: { TGroup: TGroup.Team, timed_buff_id: 7012, buff_value: 5, buff_duration: 5 } },
|
{ lv: 1, s_lv: SkillLv.Lv1, t_num: 1, overrides: { TGroup: TGroup.Team, timed_buff_id: 7012, buff_value: 5, buff_duration: 5 } },
|
||||||
@@ -582,7 +582,7 @@ export const HeroInfo: Record<number, heroInfo> = {
|
|||||||
// 5205 精准术士 — field 暴击光环(范围扩大)
|
// 5205 精准术士 — field 暴击光环(范围扩大)
|
||||||
5205: {
|
5205: {
|
||||||
uuid: 5205, name: "精准术士", path: "hm3", fac: FacSet.HERO, card_lv: 3, lv: 1, type: HType.Long, grow_type: HGrowType.Mage, role: HRole.Support, hp: 430, ap: 96,
|
uuid: 5205, name: "精准术士", path: "hm3", fac: FacSet.HERO, card_lv: 3, lv: 1, type: HType.Long, grow_type: HGrowType.Mage, role: HRole.Support, hp: 430, ap: 96,
|
||||||
skills: { 6013: { uuid: 6013, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.Slow].cd, ccd: 0 } },
|
skills: { 6104: { uuid: 6104, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.Slow].cd, ccd: 0 } },
|
||||||
field: [
|
field: [
|
||||||
{ lv: 1, uuids: [{ uuid: 7004, value: 0.1 }] },
|
{ lv: 1, uuids: [{ uuid: 7004, value: 0.1 }] },
|
||||||
{ lv: 3, uuids: [{ uuid: 7004, value: 0.2 }] },
|
{ lv: 3, uuids: [{ uuid: 7004, value: 0.2 }] },
|
||||||
@@ -640,7 +640,7 @@ export const HeroInfo: Record<number, heroInfo> = {
|
|||||||
// 5304 战吼术士 — fstart 全队攻击+生命(双效果)
|
// 5304 战吼术士 — fstart 全队攻击+生命(双效果)
|
||||||
5304: {
|
5304: {
|
||||||
uuid: 5304, name: "战吼术士", path: "hm1", fac: FacSet.HERO, card_lv: 4, lv: 1, type: HType.Long, grow_type: HGrowType.Mage, role: HRole.Mage, hp: 573, ap: 128,
|
uuid: 5304, name: "战吼术士", path: "hm1", fac: FacSet.HERO, card_lv: 4, lv: 1, type: HType.Long, grow_type: HGrowType.Mage, role: HRole.Mage, hp: 573, ap: 128,
|
||||||
skills: { 6013: { uuid: 6013, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.Slow].cd, ccd: 0 } },
|
skills: { 6104: { uuid: 6104, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.Slow].cd, ccd: 0 } },
|
||||||
fstart: {
|
fstart: {
|
||||||
6401: [
|
6401: [
|
||||||
{ lv: 1, s_lv: SkillLv.Lv1, t_num: 1, overrides: { TGroup: TGroup.Team, ap: 5 } },
|
{ lv: 1, s_lv: SkillLv.Lv1, t_num: 1, overrides: { TGroup: TGroup.Team, ap: 5 } },
|
||||||
@@ -658,7 +658,7 @@ export const HeroInfo: Record<number, heroInfo> = {
|
|||||||
// 5305 领域贤者 — field 暴伤+攻速光环(双效果)
|
// 5305 领域贤者 — field 暴伤+攻速光环(双效果)
|
||||||
5305: {
|
5305: {
|
||||||
uuid: 5305, name: "领域贤者", path: "hm2", fac: FacSet.HERO, card_lv: 4, lv: 1, type: HType.Long, grow_type: HGrowType.Mage, role: HRole.Support, hp: 573, ap: 128,
|
uuid: 5305, name: "领域贤者", path: "hm2", fac: FacSet.HERO, card_lv: 4, lv: 1, type: HType.Long, grow_type: HGrowType.Mage, role: HRole.Support, hp: 573, ap: 128,
|
||||||
skills: { 6013: { uuid: 6013, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.Slow].cd, ccd: 0 } },
|
skills: { 6104: { uuid: 6104, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.Slow].cd, ccd: 0 } },
|
||||||
field: [
|
field: [
|
||||||
{ lv: 1, uuids: [{ uuid: 7005, value: 0.2 }, { uuid: 7006, value: 0.1 }] },
|
{ lv: 1, uuids: [{ uuid: 7005, value: 0.2 }, { uuid: 7006, value: 0.1 }] },
|
||||||
{ lv: 3, uuids: [{ uuid: 7005, value: 0.4 }, { uuid: 7006, value: 0.2 }] },
|
{ lv: 3, uuids: [{ uuid: 7005, value: 0.4 }, { uuid: 7006, value: 0.2 }] },
|
||||||
@@ -731,7 +731,7 @@ export const HeroInfo: Record<number, heroInfo> = {
|
|||||||
// 5404 涅槃贤者 — fstart 护盾+攻击 + revive(双技能)
|
// 5404 涅槃贤者 — fstart 护盾+攻击 + revive(双技能)
|
||||||
5404: {
|
5404: {
|
||||||
uuid: 5404, name: "涅槃贤者", path: "hm3", fac: FacSet.HERO, card_lv: 5, lv: 1, type: HType.Long, grow_type: HGrowType.Mage, role: HRole.Mage, hp: 717, ap: 160,
|
uuid: 5404, name: "涅槃贤者", path: "hm3", fac: FacSet.HERO, card_lv: 5, lv: 1, type: HType.Long, grow_type: HGrowType.Mage, role: HRole.Mage, hp: 717, ap: 160,
|
||||||
skills: { 6013: { uuid: 6013, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.Slow].cd, ccd: 0 } },
|
skills: { 6104: { uuid: 6104, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.Slow].cd, ccd: 0 } },
|
||||||
fstart: {
|
fstart: {
|
||||||
6301: [
|
6301: [
|
||||||
{ lv: 1, s_lv: SkillLv.Lv1, t_num: 1, overrides: { TGroup: TGroup.Team, ap: 5 } },
|
{ lv: 1, s_lv: SkillLv.Lv1, t_num: 1, overrides: { TGroup: TGroup.Team, ap: 5 } },
|
||||||
|
|||||||
@@ -13,17 +13,23 @@ export class ActiveBuff {
|
|||||||
source_uuid: number;
|
source_uuid: number;
|
||||||
/** 施法者攻击力快照(用于 DoT/HoT 的 ap 缩放) */
|
/** 施法者攻击力快照(用于 DoT/HoT 的 ap 缩放) */
|
||||||
source_ap_snapshot: number;
|
source_ap_snapshot: number;
|
||||||
|
/**
|
||||||
|
* 施法者完整属性快照(DoT tick 判定暴击/冰冻/击晕用)。
|
||||||
|
* 结构同 DamageEvent.Attrs;仅 DoT 类 buff 需要,普通 modifier buff 为 undefined。
|
||||||
|
*/
|
||||||
|
source_attrs_snapshot?: any;
|
||||||
/** 周期效果累计时间(秒) */
|
/** 周期效果累计时间(秒) */
|
||||||
tick_acc: number = 0;
|
tick_acc: number = 0;
|
||||||
/** 修饰数值覆写(来自药水卡 buff_value),优先于 BuffList 配置值;undefined 表示用配置值 */
|
/** 修饰数值覆写(来自药水卡 buff_value),优先于 BuffList 配置值;undefined 表示用配置值 */
|
||||||
value_override?: number;
|
value_override?: number;
|
||||||
|
|
||||||
constructor(cfg_id: number, dur: number, src_uuid: number, src_ap: number, value_override?: number) {
|
constructor(cfg_id: number, dur: number, src_uuid: number, src_ap: number, value_override?: number, src_attrs?: any) {
|
||||||
this.config_id = cfg_id;
|
this.config_id = cfg_id;
|
||||||
this.remaining = dur;
|
this.remaining = dur;
|
||||||
this.source_uuid = src_uuid;
|
this.source_uuid = src_uuid;
|
||||||
this.source_ap_snapshot = src_ap;
|
this.source_ap_snapshot = src_ap;
|
||||||
this.value_override = value_override;
|
this.value_override = value_override;
|
||||||
|
this.source_attrs_snapshot = src_attrs;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -21,6 +21,8 @@ export interface BuffApplyOverrides {
|
|||||||
duration?: number;
|
duration?: number;
|
||||||
/** 覆写计时 buff 的修饰数值(modifiers.value / tick.damage_or_heal),由药水卡 buff_value 自定义档位 */
|
/** 覆写计时 buff 的修饰数值(modifiers.value / tick.damage_or_heal),由药水卡 buff_value 自定义档位 */
|
||||||
value?: number;
|
value?: number;
|
||||||
|
/** 施法者完整属性快照(DoT tick 判定暴击/冰冻/击晕用),结构同 DamageEvent.Attrs */
|
||||||
|
source_attrs?: any;
|
||||||
}
|
}
|
||||||
|
|
||||||
class BuffManagerImpl {
|
class BuffManagerImpl {
|
||||||
@@ -55,7 +57,7 @@ class BuffManagerImpl {
|
|||||||
buffComp.buffs.set(buffId, layers);
|
buffComp.buffs.set(buffId, layers);
|
||||||
}
|
}
|
||||||
|
|
||||||
const newLayer = new ActiveBuff(buffId, duration, sourceUuid, sourceAp, overrides?.value);
|
const newLayer = new ActiveBuff(buffId, duration, sourceUuid, sourceAp, overrides?.value, overrides?.source_attrs);
|
||||||
|
|
||||||
if (cfg.max_stack === 0 || layers.length < cfg.max_stack) {
|
if (cfg.max_stack === 0 || layers.length < cfg.max_stack) {
|
||||||
layers.push(newLayer);
|
layers.push(newLayer);
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ import { Timer } from "db://oops-framework/core/common/timer/Timer";
|
|||||||
import { BuffList } from "../common/config/BuffSet";
|
import { BuffList } from "../common/config/BuffSet";
|
||||||
import { HeroAttrsComp } from "./HeroAttrsComp";
|
import { HeroAttrsComp } from "./HeroAttrsComp";
|
||||||
import { BuffComp, ActiveBuff } from "./BuffComp";
|
import { BuffComp, ActiveBuff } from "./BuffComp";
|
||||||
|
import { DamageQueueHelper } from "./DamageQueueComp";
|
||||||
import { mLogger } from "../common/Logger";
|
import { mLogger } from "../common/Logger";
|
||||||
|
|
||||||
/** Buff 模块调试日志开关 */
|
/** Buff 模块调试日志开关 */
|
||||||
@@ -52,7 +53,7 @@ export class BuffSystem extends ecs.ComblockSystem implements ecs.ISystemUpdate
|
|||||||
|
|
||||||
// 周期效果结算(先于到期判断,避免到期帧丢失末次 tick)
|
// 周期效果结算(先于到期判断,避免到期帧丢失末次 tick)
|
||||||
if (cfg.tick && attrsComp) {
|
if (cfg.tick && attrsComp) {
|
||||||
this.processTick(layer, cfg.tick, attrsComp);
|
this.processTick(e, buffId, layer, cfg.tick, attrsComp);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 永久 buff(duration<=0)不递减 remaining
|
// 永久 buff(duration<=0)不递减 remaining
|
||||||
@@ -84,11 +85,17 @@ export class BuffSystem extends ecs.ComblockSystem implements ecs.ISystemUpdate
|
|||||||
* 处理单层的周期效果(DoT/HoT)。
|
* 处理单层的周期效果(DoT/HoT)。
|
||||||
* 累计 tick_acc 到 interval 时结算一次伤害/治疗。
|
* 累计 tick_acc 到 interval 时结算一次伤害/治疗。
|
||||||
*
|
*
|
||||||
|
* DoT(负值):转为 DamageEvent 入队,由 HeroAtkSystem.doAttack 走完整结算链
|
||||||
|
* (护盾抵扣 / 暴击 / 冰冻 / 击晕 / 飘字 / 死亡链),Attrs 取 buff 层的施法者属性快照;
|
||||||
|
* HoT(正值):保持直接回血,不走伤害链。
|
||||||
|
*
|
||||||
|
* @param target 被作用者实体(DoT 入队用)
|
||||||
|
* @param buffId buff 配置 id(DoT 事件借 s_uuid 字段携带,仅作日志追溯)
|
||||||
* @param layer 当前 buff 层实例
|
* @param layer 当前 buff 层实例
|
||||||
* @param tick 周期效果配置
|
* @param tick 周期效果配置
|
||||||
* @param attrs 被作用者属性组件(调用 add_hp)
|
* @param attrs 被作用者属性组件
|
||||||
*/
|
*/
|
||||||
private processTick(layer: ActiveBuff, tick: { interval: number; damage_or_heal: number; scale_by_ap_pct: number }, attrs: HeroAttrsComp): void {
|
private processTick(target: ecs.Entity, buffId: number, layer: ActiveBuff, tick: { interval: number; damage_or_heal: number; scale_by_ap_pct: number }, attrs: HeroAttrsComp): void {
|
||||||
// interval 非正值守卫,避免死循环
|
// interval 非正值守卫,避免死循环
|
||||||
if (tick.interval <= 0) return;
|
if (tick.interval <= 0) return;
|
||||||
layer.tick_acc += TICK_STEP;
|
layer.tick_acc += TICK_STEP;
|
||||||
@@ -99,7 +106,12 @@ export class BuffSystem extends ecs.ComblockSystem implements ecs.ISystemUpdate
|
|||||||
const baseAmount = layer.value_override !== undefined ? layer.value_override : tick.damage_or_heal;
|
const baseAmount = layer.value_override !== undefined ? layer.value_override : tick.damage_or_heal;
|
||||||
const scale = 1 + layer.source_ap_snapshot * tick.scale_by_ap_pct / 10000;
|
const scale = 1 + layer.source_ap_snapshot * tick.scale_by_ap_pct / 10000;
|
||||||
const amount = Math.floor(baseAmount * scale);
|
const amount = Math.floor(baseAmount * scale);
|
||||||
|
if (amount < 0) {
|
||||||
|
// DoT 走伤害队列:dot_dmg 传正值,doAttack 内识别并走固定伤害分支
|
||||||
|
DamageQueueHelper.addDamageToEntity(target, layer.source_attrs_snapshot ?? null, layer.source_uuid, buffId, 0, 1, -amount);
|
||||||
|
} else if (amount > 0) {
|
||||||
attrs.add_hp(amount);
|
attrs.add_hp(amount);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -24,6 +24,11 @@ export interface DamageEvent {
|
|||||||
|
|
||||||
ext_dmg:number //额外伤害
|
ext_dmg:number //额外伤害
|
||||||
dmg_ratio:number//伤害比例
|
dmg_ratio:number//伤害比例
|
||||||
|
/**
|
||||||
|
* DoT 固定伤害值(>0 时本事件为 DoT tick 结算):
|
||||||
|
* 跳过 dmgCount 公式直接用该值,且不走击退/受击动画,其余(暴击/冰冻/击晕/护盾/死亡链)与普攻一致
|
||||||
|
*/
|
||||||
|
dot_dmg?:number
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -60,7 +65,7 @@ export class DamageQueueComp extends ecs.Comp {
|
|||||||
/**
|
/**
|
||||||
* 添加伤害事件到队列
|
* 添加伤害事件到队列
|
||||||
*/
|
*/
|
||||||
addDamageEvent(attrs: any, casterEid: number, s_uuid: number,ext_dmg:number=0,dmg_ratio:number=1): void {
|
addDamageEvent(attrs: any, casterEid: number, s_uuid: number,ext_dmg:number=0,dmg_ratio:number=1,dot_dmg:number=0): void {
|
||||||
const timestamp = Date.now();
|
const timestamp = Date.now();
|
||||||
|
|
||||||
const damageEvent: DamageEvent = {
|
const damageEvent: DamageEvent = {
|
||||||
@@ -71,6 +76,7 @@ export class DamageQueueComp extends ecs.Comp {
|
|||||||
eventId: "",
|
eventId: "",
|
||||||
ext_dmg:ext_dmg,
|
ext_dmg:ext_dmg,
|
||||||
dmg_ratio:dmg_ratio,
|
dmg_ratio:dmg_ratio,
|
||||||
|
dot_dmg:dot_dmg,
|
||||||
};
|
};
|
||||||
|
|
||||||
this.damageEvents.push(damageEvent);
|
this.damageEvents.push(damageEvent);
|
||||||
@@ -176,7 +182,7 @@ export class DamageQueueHelper {
|
|||||||
* 为实体添加伤害事件
|
* 为实体添加伤害事件
|
||||||
* 如果实体没有伤害队列组件,会自动创建
|
* 如果实体没有伤害队列组件,会自动创建
|
||||||
*/
|
*/
|
||||||
static addDamageToEntity(entity: ecs.Entity, attrs: any, casterEid: number, s_uuid: number,ext_dmg:number=0,dmg_ratio:number=1): void {
|
static addDamageToEntity(entity: ecs.Entity, attrs: any, casterEid: number, s_uuid: number,ext_dmg:number=0,dmg_ratio:number=1,dot_dmg:number=0): void {
|
||||||
let damageQueue = entity.get(DamageQueueComp);
|
let damageQueue = entity.get(DamageQueueComp);
|
||||||
|
|
||||||
// 如果实体没有伤害队列组件,创建一个
|
// 如果实体没有伤害队列组件,创建一个
|
||||||
@@ -185,7 +191,7 @@ export class DamageQueueHelper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 添加伤害事件到队列
|
// 添加伤害事件到队列
|
||||||
damageQueue.addDamageEvent(attrs, casterEid, s_uuid,ext_dmg,dmg_ratio);
|
damageQueue.addDamageEvent(attrs, casterEid, s_uuid,ext_dmg,dmg_ratio,dot_dmg);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -18,6 +18,9 @@ import { SkillTriggerHelper } from "./SkillTriggerHelper";
|
|||||||
import { getMonsterGoldDrop } from "../map/RogueConfig";
|
import { getMonsterGoldDrop } from "../map/RogueConfig";
|
||||||
import { MissionEconomy } from "../map/MissionEconomy";
|
import { MissionEconomy } from "../map/MissionEconomy";
|
||||||
import { MoveComp } from "./MoveComp";
|
import { MoveComp } from "./MoveComp";
|
||||||
|
import { buffManager, BuffApplyOverrides } from "./BuffManager";
|
||||||
|
import { DEBUFF_ICON_MAP, VULNERABLE_BUFF_ID, BuffList } from "../common/config/BuffSet";
|
||||||
|
import { BuffComp } from "./BuffComp";
|
||||||
|
|
||||||
/** 最终伤害数据接口
|
/** 最终伤害数据接口
|
||||||
* 用于封装一次攻击计算的所有结果数据
|
* 用于封装一次攻击计算的所有结果数据
|
||||||
@@ -119,10 +122,14 @@ export class HeroAtkSystem extends ecs.ComblockSystem implements ecs.ISystemUpda
|
|||||||
if (!TAttrsComp || TAttrsComp.is_dead || TAttrsComp.is_reviving) return reDate;
|
if (!TAttrsComp || TAttrsComp.is_dead || TAttrsComp.is_reviving) return reDate;
|
||||||
|
|
||||||
const casterEid = damageEvent.casterEid;
|
const casterEid = damageEvent.casterEid;
|
||||||
|
// DoT 事件:dot_dmg>0 时伤害为固定 tick 值,无对应 SkillSet 配置(s_uuid 位置是 buffId)
|
||||||
|
const isDot = (damageEvent.dot_dmg ?? 0) > 0;
|
||||||
|
// DoT 事件的 Attrs 来自 ActiveBuff.source_attrs_snapshot,可能为空,兜底空对象避免取属性报错
|
||||||
|
if (isDot && !damageEvent.Attrs) damageEvent.Attrs = {};
|
||||||
|
|
||||||
// 获取技能配置
|
// 获取技能配置
|
||||||
const skillConf = SkillSet[damageEvent.s_uuid];
|
const skillConf = SkillSet[damageEvent.s_uuid];
|
||||||
if (!skillConf) return reDate;
|
if (!skillConf && !isDot) return reDate;
|
||||||
|
|
||||||
// 触发被攻击事件
|
// 触发被攻击事件
|
||||||
this.onAttacked(target);
|
this.onAttacked(target);
|
||||||
@@ -132,8 +139,8 @@ export class HeroAtkSystem extends ecs.ComblockSystem implements ecs.ISystemUpda
|
|||||||
const criticalChance = (damageEvent.Attrs[Attrs.critical] || 0) - TAttrsComp.getFinalCriticalRes();
|
const criticalChance = (damageEvent.Attrs[Attrs.critical] || 0) - TAttrsComp.getFinalCriticalRes();
|
||||||
const isCrit = this.checkChance(criticalChance);
|
const isCrit = this.checkChance(criticalChance);
|
||||||
|
|
||||||
// 计算基础伤害
|
// 计算基础伤害:DoT 直接用固定 tick 值,普攻走 dmgCount 公式
|
||||||
let damage = this.dmgCount(damageEvent, TAttrsComp);
|
let damage = isDot ? (damageEvent.dot_dmg ?? 0) : this.dmgCount(damageEvent, TAttrsComp);
|
||||||
|
|
||||||
mLogger.log(this.debugMode, 'HeroAtkSystem', " dmgCount", damage)
|
mLogger.log(this.debugMode, 'HeroAtkSystem', " dmgCount", damage)
|
||||||
if (isCrit) {
|
if (isCrit) {
|
||||||
@@ -147,6 +154,9 @@ export class HeroAtkSystem extends ecs.ComblockSystem implements ecs.ISystemUpda
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
mLogger.log(this.debugMode, 'HeroAtkSystem', " after crit", damage)
|
mLogger.log(this.debugMode, 'HeroAtkSystem', " after crit", damage)
|
||||||
|
// 易伤附加:目标每层易伤 buff 附加固定伤害,被易伤抗性百分比减免;普攻与 DoT 均生效
|
||||||
|
damage += this.calcVulnerableBonus(target, TAttrsComp);
|
||||||
|
mLogger.log(this.debugMode, 'HeroAtkSystem', " after vulnerable", damage)
|
||||||
// 护盾数值减免(1 点护盾吸收 1 点伤害,扣完为止,溢出部分继续扣血)
|
// 护盾数值减免(1 点护盾吸收 1 点伤害,扣完为止,溢出部分继续扣血)
|
||||||
const shieldResult = this.absorbShield(TAttrsComp, damage);
|
const shieldResult = this.absorbShield(TAttrsComp, damage);
|
||||||
damage = shieldResult.remainingDamage;
|
damage = shieldResult.remainingDamage;
|
||||||
@@ -172,9 +182,11 @@ export class HeroAtkSystem extends ecs.ComblockSystem implements ecs.ISystemUpda
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 受击计数:只有实际造成伤害才 +1(被格挡不计数)
|
// 受击计数:只有实际造成伤害才 +1(被格挡不计数);DoT 不计受击、不触发受击技
|
||||||
|
if (!isDot) {
|
||||||
TAttrsComp.atked_count++;
|
TAttrsComp.atked_count++;
|
||||||
this.checkAndTriggerAtkedSkills(TAttrsComp, targetView);
|
this.checkAndTriggerAtkedSkills(TAttrsComp, targetView);
|
||||||
|
}
|
||||||
|
|
||||||
mLogger.log(this.debugMode, 'HeroAtkSystem', ` 英雄${TAttrsComp.hero_name} (uuid: ${TAttrsComp.hero_uuid}) 受到 eid:${casterEid} 的 伤害 ${damage},${isCrit ? "暴击" : "普通"}攻击,技能ID ${damageEvent.s_uuid}`);
|
mLogger.log(this.debugMode, 'HeroAtkSystem', ` 英雄${TAttrsComp.hero_name} (uuid: ${TAttrsComp.hero_uuid}) 受到 eid:${casterEid} 的 伤害 ${damage},${isCrit ? "暴击" : "普通"}攻击,技能ID ${damageEvent.s_uuid}`);
|
||||||
|
|
||||||
@@ -186,13 +198,18 @@ export class HeroAtkSystem extends ecs.ComblockSystem implements ecs.ISystemUpda
|
|||||||
const stunChance = (damageEvent.Attrs[Attrs.stun_chance] || 0) - TAttrsComp.getFinalStunRes();
|
const stunChance = (damageEvent.Attrs[Attrs.stun_chance] || 0) - TAttrsComp.getFinalStunRes();
|
||||||
const isStun = !TAttrsComp.isStun() && this.checkChance(stunChance);
|
const isStun = !TAttrsComp.isStun() && this.checkChance(stunChance);
|
||||||
|
|
||||||
|
// ✅ 触发视图层表现(伤害数字、受击动画、冰冻、击晕、击退)
|
||||||
|
if (targetView) {
|
||||||
|
if (isDot) {
|
||||||
|
// DoT:只飘伤害数字 + 刷新血条,不播受击动画/音效/击退;
|
||||||
|
// s_uuid 位置是 buffId,据此激活 loss_life/hp/debuff 下的对应 debuff 图标
|
||||||
|
targetView.showDamage(damage, isCrit, DEBUFF_ICON_MAP[damageEvent.s_uuid] ?? "");
|
||||||
|
} else {
|
||||||
// 击退:受击默认后退,击退属性不再作为概率,而是转换为后退距离的增量
|
// 击退:受击默认后退,击退属性不再作为概率,而是转换为后退距离的增量
|
||||||
// 击退增量 = 施法者击退强化(原击退概率)- 被攻击者击退抗性 + 击退距离强化
|
// 击退增量 = 施法者击退强化(原击退概率)- 被攻击者击退抗性 + 击退距离强化
|
||||||
const knockbackBonus = (damageEvent.Attrs[Attrs.knockback_chance] || 0) - (TAttrsComp.getFinalKnockbackRes() || 0);
|
const knockbackBonus = (damageEvent.Attrs[Attrs.knockback_chance] || 0) - (TAttrsComp.getFinalKnockbackRes() || 0);
|
||||||
const knockbackExtra = Math.max(0, knockbackBonus + (damageEvent.Attrs[Attrs.knockback_distance] || 0));
|
const knockbackExtra = Math.max(0, knockbackBonus + (damageEvent.Attrs[Attrs.knockback_distance] || 0));
|
||||||
|
|
||||||
// ✅ 触发视图层表现(伤害数字、受击动画、冰冻、击晕、击退)
|
|
||||||
if (targetView) {
|
|
||||||
targetView.do_atked(damage, isCrit, damageEvent.s_uuid, knockbackExtra);
|
targetView.do_atked(damage, isCrit, damageEvent.s_uuid, knockbackExtra);
|
||||||
targetView.playEnd(skillConf.endAnm);
|
targetView.playEnd(skillConf.endAnm);
|
||||||
|
|
||||||
@@ -205,6 +222,7 @@ export class HeroAtkSystem extends ecs.ComblockSystem implements ecs.ISystemUpda
|
|||||||
const knockbackSpeed = dist * 16;
|
const knockbackSpeed = dist * 16;
|
||||||
moveComp.knockbackVelocity = isHero ? -knockbackSpeed : knockbackSpeed;
|
moveComp.knockbackVelocity = isHero ? -knockbackSpeed : knockbackSpeed;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (isFrost) {
|
if (isFrost) {
|
||||||
TAttrsComp.toFrost();
|
TAttrsComp.toFrost();
|
||||||
@@ -222,6 +240,15 @@ export class HeroAtkSystem extends ecs.ComblockSystem implements ecs.ISystemUpda
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 命中附带 debuff(如灼烧 DoT):仅普攻路径,复用友方 timed_buff_id 机制;
|
||||||
|
// 施法者 ap/完整属性快照取自伤害事件,供 BuffSystem tick 缩放与暴击/冰冻/击晕判定
|
||||||
|
if (!isDot && skillConf.timed_buff_id) {
|
||||||
|
const buffOverrides: BuffApplyOverrides = { source_attrs: damageEvent.Attrs };
|
||||||
|
if (skillConf.buff_value !== undefined) buffOverrides.value = skillConf.buff_value;
|
||||||
|
if (skillConf.buff_duration !== undefined) buffOverrides.duration = skillConf.buff_duration;
|
||||||
|
buffManager.applyBuff(target, skillConf.timed_buff_id, casterEid, damageEvent.Attrs[Attrs.ap] || 0, buffOverrides);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// 检查死亡
|
// 检查死亡
|
||||||
if (TAttrsComp.hp <= 0) {
|
if (TAttrsComp.hp <= 0) {
|
||||||
@@ -435,6 +462,26 @@ export class HeroAtkSystem extends ecs.ComblockSystem implements ecs.ISystemUpda
|
|||||||
* @param damage 原始伤害值
|
* @param damage 原始伤害值
|
||||||
* @returns {remainingDamage, absorbedDamage} 剩余伤害值和被护盾减免的伤害值
|
* @returns {remainingDamage, absorbedDamage} 剩余伤害值和被护盾减免的伤害值
|
||||||
*/
|
*/
|
||||||
|
/**
|
||||||
|
* 计算易伤附加伤害:汇总目标每层易伤 buff 的数值(value_override 优先),再被易伤抗性百分比减免。
|
||||||
|
* @returns 附加伤害值(向下取整,非负)
|
||||||
|
*/
|
||||||
|
private calcVulnerableBonus(target: ecs.Entity, TAttrsComp: HeroAttrsComp): number {
|
||||||
|
if (!target.has(BuffComp)) return 0;
|
||||||
|
const layers = target.get(BuffComp).buffs.get(VULNERABLE_BUFF_ID);
|
||||||
|
if (!layers || layers.length === 0) return 0;
|
||||||
|
const cfg = BuffList[VULNERABLE_BUFF_ID];
|
||||||
|
const baseVal = cfg?.modifiers?.[0]?.value ?? 0;
|
||||||
|
let sum = 0;
|
||||||
|
for (const layer of layers) {
|
||||||
|
sum += layer.value_override !== undefined ? layer.value_override : baseVal;
|
||||||
|
}
|
||||||
|
if (sum <= 0) return 0;
|
||||||
|
// 易伤抗性:百分比减免(vulnerable_res=30 即减免 30%)
|
||||||
|
const res = TAttrsComp.getFinalVulnerableRes();
|
||||||
|
return Math.max(0, Math.floor(sum * (1 - res / 100)));
|
||||||
|
}
|
||||||
|
|
||||||
private absorbShield(TAttrsComp: HeroAttrsComp, damage: number): { remainingDamage: number, absorbedDamage: number } {
|
private absorbShield(TAttrsComp: HeroAttrsComp, damage: number): { remainingDamage: number, absorbedDamage: number } {
|
||||||
if (TAttrsComp.shield <= 0) {
|
if (TAttrsComp.shield <= 0) {
|
||||||
mLogger.log(this.debugMode, 'HeroAtkSystem', " 护盾值小于等于0,无法吸收伤害");
|
mLogger.log(this.debugMode, 'HeroAtkSystem', " 护盾值小于等于0,无法吸收伤害");
|
||||||
|
|||||||
@@ -86,6 +86,7 @@ export class HeroAttrsComp extends ecs.Comp {
|
|||||||
puncture_chance: number = 0; // 穿透概率
|
puncture_chance: number = 0; // 穿透概率
|
||||||
puncture_dmg_bonus: number = 0; // 穿透后伤害增量(百分点,乘算加成)
|
puncture_dmg_bonus: number = 0; // 穿透后伤害增量(百分点,乘算加成)
|
||||||
wfuny: number = 0; // 风怒
|
wfuny: number = 0; // 风怒
|
||||||
|
vulnerable_res: number = 0; // 易伤抗性(百分比减免易伤附加伤害)
|
||||||
|
|
||||||
revived_count: number = 0; // 已复活次数
|
revived_count: number = 0; // 已复活次数
|
||||||
invincible_time: number = 0;// 无敌时间
|
invincible_time: number = 0;// 无敌时间
|
||||||
@@ -510,6 +511,12 @@ export class HeroAttrsComp extends ecs.Comp {
|
|||||||
return this.knockback_res + mods.flatSum + mods.pctSum;
|
return this.knockback_res + mods.flatSum + mods.pctSum;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** 最终易伤抗性 = 基础 + 限时修饰(加法模型),百分比减免易伤附加伤害 */
|
||||||
|
public getFinalVulnerableRes(): number {
|
||||||
|
const mods = this.aggregateTimedMods(Attrs.vulnerable_res);
|
||||||
|
return this.vulnerable_res + mods.flatSum + mods.pctSum;
|
||||||
|
}
|
||||||
|
|
||||||
/** 根据攻速加成换算实际攻击间隔,避免直接改写配置里的基础 CD。 */
|
/** 根据攻速加成换算实际攻击间隔,避免直接改写配置里的基础 CD。 */
|
||||||
public getEffectiveSkillCd(skillId: number): number {
|
public getEffectiveSkillCd(skillId: number): number {
|
||||||
const skill = this.skills[skillId];
|
const skill = this.skills[skillId];
|
||||||
@@ -605,6 +612,7 @@ export class HeroAttrsComp extends ecs.Comp {
|
|||||||
this.puncture_chance = 0;
|
this.puncture_chance = 0;
|
||||||
this.puncture_dmg_bonus = 0;
|
this.puncture_dmg_bonus = 0;
|
||||||
this.wfuny = 0;
|
this.wfuny = 0;
|
||||||
|
this.vulnerable_res = 0;
|
||||||
this.boom = false;
|
this.boom = false;
|
||||||
|
|
||||||
// 重置技能距离缓存
|
// 重置技能距离缓存
|
||||||
|
|||||||
@@ -1,7 +1,9 @@
|
|||||||
import { _decorator, ProgressBar, Sprite, UIOpacity, Vec3, v3, tween, Tween, Color, clamp } from "cc";
|
import { _decorator, ProgressBar, Sprite, UIOpacity, Vec3, v3, tween, Tween, Color, clamp, Node } from "cc";
|
||||||
import { ecs } from "../../../../extensions/oops-plugin-framework/assets/libs/ecs/ECS";
|
import { ecs } from "../../../../extensions/oops-plugin-framework/assets/libs/ecs/ECS";
|
||||||
import { CCComp } from "../../../../extensions/oops-plugin-framework/assets/module/common/CCComp";
|
import { CCComp } from "../../../../extensions/oops-plugin-framework/assets/module/common/CCComp";
|
||||||
import { HeroAttrsComp } from "./HeroAttrsComp";
|
import { HeroAttrsComp } from "./HeroAttrsComp";
|
||||||
|
import { BuffComp } from "./BuffComp";
|
||||||
|
import { BuffList, BuffCategory, DEBUFF_ICON_MAP } from "../common/config/BuffSet";
|
||||||
import { FacSet, FightSet } from "../common/config/GameSet";
|
import { FacSet, FightSet } from "../common/config/GameSet";
|
||||||
|
|
||||||
const { ccclass, property } = _decorator;
|
const { ccclass, property } = _decorator;
|
||||||
@@ -35,6 +37,10 @@ export class HeroTopBarComp extends CCComp {
|
|||||||
// ==================== 内部引用 ====================
|
// ==================== 内部引用 ====================
|
||||||
private topOpacity: UIOpacity = null!;
|
private topOpacity: UIOpacity = null!;
|
||||||
private basePos: Vec3 = v3();
|
private basePos: Vec3 = v3();
|
||||||
|
/** debuff 容器节点(top 下的 debuff 子节点,按名字管理各 debuff 图标) */
|
||||||
|
private debuffNode: Node = null!;
|
||||||
|
/** 当前点亮的 debuff 图标节点名集合(用于 diff,避免每帧重复 set active) */
|
||||||
|
private activeDebuffNames: Set<string> = new Set();
|
||||||
|
|
||||||
// ==================== 配置 ====================
|
// ==================== 配置 ====================
|
||||||
private hp_height: number = 90;
|
private hp_height: number = 90;
|
||||||
@@ -87,6 +93,15 @@ export class HeroTopBarComp extends CCComp {
|
|||||||
this.node.getChildByName("lv")!.active = false;
|
this.node.getChildByName("lv")!.active = false;
|
||||||
this.node.active = true;
|
this.node.active = true;
|
||||||
|
|
||||||
|
// debuff 图标容器(无该节点的旧 prefab 容错为 null)
|
||||||
|
this.debuffNode = this.node.getChildByName("debuff")!;
|
||||||
|
this.activeDebuffNames.clear();
|
||||||
|
if (this.debuffNode) {
|
||||||
|
for (const child of this.debuffNode.children) {
|
||||||
|
child.active = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
this.setTopBarOpacity(false);
|
this.setTopBarOpacity(false);
|
||||||
this.hpShow();
|
this.hpShow();
|
||||||
this.shieldShow(model.shield);
|
this.shieldShow(model.shield);
|
||||||
@@ -120,6 +135,43 @@ export class HeroTopBarComp extends CCComp {
|
|||||||
this.shieldProgressBar.node.active = shield > 0;
|
this.shieldProgressBar.node.active = shield > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 刷新 debuff 图标显隐:按 BuffComp 中当前生效的 debuff 种类点亮对应图标。
|
||||||
|
* 由 HeroViewComp 在 dirty_buffs 脏标记时调用;与上次状态做 diff,避免重复 set active。
|
||||||
|
* @param buffComp 目标的 buff 组件(无 BuffComp 时全部隐藏)
|
||||||
|
*/
|
||||||
|
public debuffShow(buffComp: BuffComp | null): void {
|
||||||
|
if (!this.debuffNode) return;
|
||||||
|
|
||||||
|
// 收集当前生效的、有图标映射的 debuff 节点名
|
||||||
|
const wantActive = new Set<string>();
|
||||||
|
if (buffComp) {
|
||||||
|
for (const [buffId, layers] of buffComp.buffs) {
|
||||||
|
if (layers.length === 0) continue;
|
||||||
|
const cfg = BuffList[buffId];
|
||||||
|
// 只显示伤害类 debuff(tick 负值)与控制类 debuff;普通 Buff 不占用 debuff 栏
|
||||||
|
if (!cfg || cfg.category === BuffCategory.Buff) continue;
|
||||||
|
const nodeName = DEBUFF_ICON_MAP[buffId];
|
||||||
|
if (nodeName) wantActive.add(nodeName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// diff:先隐藏不再需要的,再点亮新增的
|
||||||
|
for (const name of this.activeDebuffNames) {
|
||||||
|
if (!wantActive.has(name)) {
|
||||||
|
const child = this.debuffNode.getChildByName(name);
|
||||||
|
if (child) child.active = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (const name of wantActive) {
|
||||||
|
if (!this.activeDebuffNames.has(name)) {
|
||||||
|
const child = this.debuffNode.getChildByName(name);
|
||||||
|
if (child) child.active = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.activeDebuffNames = wantActive;
|
||||||
|
}
|
||||||
|
|
||||||
/** 激活顶栏(高亮 + 延迟恢复闲置透明度) */
|
/** 激活顶栏(高亮 + 延迟恢复闲置透明度) */
|
||||||
public activateTopBar(): void {
|
public activateTopBar(): void {
|
||||||
this.setTopBarOpacity(true);
|
this.setTopBarOpacity(true);
|
||||||
@@ -165,6 +217,12 @@ export class HeroTopBarComp extends CCComp {
|
|||||||
/** 对象池回收 / 组件重置时调用 */
|
/** 对象池回收 / 组件重置时调用 */
|
||||||
public reset(): void {
|
public reset(): void {
|
||||||
this.unscheduleAllCallbacks();
|
this.unscheduleAllCallbacks();
|
||||||
|
this.activeDebuffNames.clear();
|
||||||
|
if (this.debuffNode && this.debuffNode.isValid) {
|
||||||
|
for (const child of this.debuffNode.children) {
|
||||||
|
child.active = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
if (this.node && this.node.isValid) {
|
if (this.node && this.node.isValid) {
|
||||||
Tween.stopAllByTarget(this.node);
|
Tween.stopAllByTarget(this.node);
|
||||||
this.node.setPosition(this.basePos);
|
this.node.setPosition(this.basePos);
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import { CCComp } from "../../../../extensions/oops-plugin-framework/assets/modu
|
|||||||
import { mLogger } from "../common/Logger";
|
import { mLogger } from "../common/Logger";
|
||||||
import { HeroSpine } from "./HeroSpine";
|
import { HeroSpine } from "./HeroSpine";
|
||||||
import { HeroTopBarComp } from "./HeroTopBarComp";
|
import { HeroTopBarComp } from "./HeroTopBarComp";
|
||||||
|
import { BuffComp } from "./BuffComp";
|
||||||
import { BoxSet, FacSet, FightSet, NumberFormatter, TooltipTypes } from "../common/config/GameSet";
|
import { BoxSet, FacSet, FightSet, NumberFormatter, TooltipTypes } from "../common/config/GameSet";
|
||||||
import { smc } from "../common/SingletonModuleComp";
|
import { smc } from "../common/SingletonModuleComp";
|
||||||
import { SkillSet, } from "../common/config/SkillSet";
|
import { SkillSet, } from "../common/config/SkillSet";
|
||||||
@@ -56,6 +57,7 @@ export class HeroViewComp extends CCComp {
|
|||||||
private damageQueue: Array<{
|
private damageQueue: Array<{
|
||||||
damage: number,
|
damage: number,
|
||||||
isCrit: boolean,
|
isCrit: boolean,
|
||||||
|
debuffIcon: string,
|
||||||
}> = [];
|
}> = [];
|
||||||
private isProcessingDamage: boolean = false;
|
private isProcessingDamage: boolean = false;
|
||||||
private damageInterval: number = 0.01; // 伤害数字显示间隔
|
private damageInterval: number = 0.01; // 伤害数字显示间隔
|
||||||
@@ -139,6 +141,13 @@ export class HeroViewComp extends CCComp {
|
|||||||
this.topBar.shieldShow(this.model.shield);
|
this.topBar.shieldShow(this.model.shield);
|
||||||
this.model.dirty_shield = false;
|
this.model.dirty_shield = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ✅ buff 变更脏标记:刷新 debuff 图标显隐(灼烧等)
|
||||||
|
const buffComp = this.ent.has(BuffComp) ? this.ent.get(BuffComp) : null;
|
||||||
|
if (buffComp && buffComp.dirty_buffs) {
|
||||||
|
this.topBar.debuffShow(buffComp);
|
||||||
|
buffComp.dirty_buffs = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public cd_show() {
|
public cd_show() {
|
||||||
@@ -201,7 +210,7 @@ export class HeroViewComp extends CCComp {
|
|||||||
Tooltip.load(pos, TooltipTypes.skill, value, s_uuid, this.node, 1, this.model?.fac ?? FacSet.MON, triggerType);
|
Tooltip.load(pos, TooltipTypes.skill, value, s_uuid, this.node, 1, this.model?.fac ?? FacSet.MON, triggerType);
|
||||||
}
|
}
|
||||||
/** 血量提示(伤害数字) */
|
/** 血量提示(伤害数字) */
|
||||||
private hp_tip(type: number = 1, value: string = "", s_uuid: number = 1001, y: number = 0) {
|
private hp_tip(type: number = 1, value: string = "", s_uuid: number = 1001, y: number = 0, debuffIcon: string = "") {
|
||||||
let x = this.node.position.x;
|
let x = this.node.position.x;
|
||||||
// 获取怪物高度的一半,定位到中心点
|
// 获取怪物高度的一半,定位到中心点
|
||||||
let halfHeight = 0;
|
let halfHeight = 0;
|
||||||
@@ -213,7 +222,7 @@ export class HeroViewComp extends CCComp {
|
|||||||
// 起点设为怪物中心偏下位置,使其在血条下方
|
// 起点设为怪物中心偏下位置,使其在血条下方
|
||||||
let ny = this.node.position.y + halfHeight - 15;
|
let ny = this.node.position.y + halfHeight - 15;
|
||||||
let pos = v3(x, ny, 0);
|
let pos = v3(x, ny, 0);
|
||||||
Tooltip.load(pos, type, value, s_uuid, this.node.parent, 1, this.model?.fac ?? FacSet.MON);
|
Tooltip.load(pos, type, value, s_uuid, this.node.parent, 1, this.model?.fac ?? FacSet.MON, "", debuffIcon);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 护盾减免提示 */
|
/** 护盾减免提示 */
|
||||||
@@ -441,11 +450,11 @@ export class HeroViewComp extends CCComp {
|
|||||||
|
|
||||||
|
|
||||||
/** 显示伤害数字 */
|
/** 显示伤害数字 */
|
||||||
|
showDamage(damage: number, isCrit: boolean, debuffIcon: string = "") {
|
||||||
showDamage(damage: number, isCrit: boolean) {
|
|
||||||
this.damageQueue.push({
|
this.damageQueue.push({
|
||||||
damage,
|
damage,
|
||||||
isCrit,
|
isCrit,
|
||||||
|
debuffIcon,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -456,7 +465,7 @@ export class HeroViewComp extends CCComp {
|
|||||||
this.isProcessingDamage = true;
|
this.isProcessingDamage = true;
|
||||||
const damageInfo = this.damageQueue.shift()!;
|
const damageInfo = this.damageQueue.shift()!;
|
||||||
|
|
||||||
this.showDamageImmediate(damageInfo.damage, damageInfo.isCrit);
|
this.showDamageImmediate(damageInfo.damage, damageInfo.isCrit, damageInfo.debuffIcon);
|
||||||
|
|
||||||
// 设置延时处理下一个伤
|
// 设置延时处理下一个伤
|
||||||
this.scheduleOnce(() => {
|
this.scheduleOnce(() => {
|
||||||
@@ -465,7 +474,7 @@ export class HeroViewComp extends CCComp {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** 立即显示伤害效果 */
|
/** 立即显示伤害效果 */
|
||||||
private showDamageImmediate(damage: number, isCrit: boolean) {
|
private showDamageImmediate(damage: number, isCrit: boolean, debuffIcon: string = "") {
|
||||||
if (!this.model) return;
|
if (!this.model) return;
|
||||||
|
|
||||||
const damageText = NumberFormatter.formatNumber(Math.max(0, Math.floor(damage)));
|
const damageText = NumberFormatter.formatNumber(Math.max(0, Math.floor(damage)));
|
||||||
@@ -473,7 +482,7 @@ export class HeroViewComp extends CCComp {
|
|||||||
if (isCrit) {
|
if (isCrit) {
|
||||||
this.hp_tip(TooltipTypes.crit, damageText);
|
this.hp_tip(TooltipTypes.crit, damageText);
|
||||||
} else {
|
} else {
|
||||||
this.hp_tip(TooltipTypes.life, damageText);
|
this.hp_tip(TooltipTypes.life, damageText, 1001, 0, debuffIcon);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
reset() {
|
reset() {
|
||||||
|
|||||||
@@ -60,7 +60,7 @@ export class Tooltip extends ecs.Entity {
|
|||||||
this.remove(TooltipCom);
|
this.remove(TooltipCom);
|
||||||
super.destroy();
|
super.destroy();
|
||||||
}
|
}
|
||||||
static load(pos: Vec3 = Vec3.ZERO,type:number=1,vaule:string="",s_uuid:number=1001,parent:any=null,cd:number=1,fac:number=FacSet.MON,triggerType:string="") {
|
static load(pos: Vec3 = Vec3.ZERO,type:number=1,vaule:string="",s_uuid:number=1001,parent:any=null,cd:number=1,fac:number=FacSet.MON,triggerType:string="",debuffIcon:string="") {
|
||||||
let node: Node;
|
let node: Node;
|
||||||
if (Tooltip.pool.size() > 0) {
|
if (Tooltip.pool.size() > 0) {
|
||||||
node = Tooltip.pool.get()!;
|
node = Tooltip.pool.get()!;
|
||||||
@@ -75,7 +75,7 @@ export class Tooltip extends ecs.Entity {
|
|||||||
node.active = true;
|
node.active = true;
|
||||||
|
|
||||||
var sv = node.getComponent(TooltipCom)!;
|
var sv = node.getComponent(TooltipCom)!;
|
||||||
sv.init(type, vaule, s_uuid, fac, triggerType);
|
sv.init(type, vaule, s_uuid, fac, triggerType, debuffIcon);
|
||||||
|
|
||||||
// this.add(sv); // 不要添加到单例实体上,否则会覆盖或导致单例被销毁
|
// this.add(sv); // 不要添加到单例实体上,否则会覆盖或导致单例被销毁
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,6 +29,8 @@ export class TooltipCom extends CCComp {
|
|||||||
fac: number = FacSet.MON;
|
fac: number = FacSet.MON;
|
||||||
/** 当前技能喊话对应的触发类型(空字符串表示普通主动技能) */
|
/** 当前技能喊话对应的触发类型(空字符串表示普通主动技能) */
|
||||||
triggerType: string = "";
|
triggerType: string = "";
|
||||||
|
/** DoT 飘字需激活的 debuff 图标节点名(loss_life/hp/debuff 下的子节点,如 FireDamage);空串=普通伤害 */
|
||||||
|
debuffIcon: string = "";
|
||||||
|
|
||||||
// 动画参数配置
|
// 动画参数配置
|
||||||
private readonly popDuration = 0.15;
|
private readonly popDuration = 0.15;
|
||||||
@@ -43,12 +45,13 @@ export class TooltipCom extends CCComp {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** 初始化并播放动画 */
|
/** 初始化并播放动画 */
|
||||||
init(type: number, value: string, uuid: number, fac: number = FacSet.MON, triggerType: string = "") {
|
init(type: number, value: string, uuid: number, fac: number = FacSet.MON, triggerType: string = "", debuffIcon: string = "") {
|
||||||
this.stype = type;
|
this.stype = type;
|
||||||
this.value = value;
|
this.value = value;
|
||||||
this.s_uuid = uuid;
|
this.s_uuid = uuid;
|
||||||
this.fac = fac;
|
this.fac = fac;
|
||||||
this.triggerType = triggerType;
|
this.triggerType = triggerType;
|
||||||
|
this.debuffIcon = debuffIcon;
|
||||||
|
|
||||||
// 初始化或获取 UIOpacity 组件
|
// 初始化或获取 UIOpacity 组件
|
||||||
this._uiOpacity = this.node.getComponent(UIOpacity);
|
this._uiOpacity = this.node.getComponent(UIOpacity);
|
||||||
@@ -94,6 +97,7 @@ export class TooltipCom extends CCComp {
|
|||||||
this.node.setPosition(v3(this.node.position.x + offsetX, currentY));
|
this.node.setPosition(v3(this.node.position.x + offsetX, currentY));
|
||||||
this.node.setSiblingIndex(topSiblingIndex);
|
this.node.setSiblingIndex(topSiblingIndex);
|
||||||
this.setupLabel(this.fac === FacSet.HERO ? "hloss" : "loss_life", "hp", this.value);
|
this.setupLabel(this.fac === FacSet.HERO ? "hloss" : "loss_life", "hp", this.value);
|
||||||
|
this.setupDebuffIcon(); // DoT 伤害时点亮 loss_life/hp/debuff 下的对应图标
|
||||||
scaleMax = 1.5;
|
scaleMax = 1.5;
|
||||||
break;
|
break;
|
||||||
case TooltipTypes.health: // 治疗
|
case TooltipTypes.health: // 治疗
|
||||||
@@ -164,6 +168,20 @@ export class TooltipCom extends CCComp {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* DoT 伤害飘字:激活 loss_life/hp/debuff 下指定的 debuff 图标子节点。
|
||||||
|
* 仅怪物普通伤害(loss_life)路径调用;debuffIcon 为空或未找到节点时静默跳过。
|
||||||
|
*/
|
||||||
|
private setupDebuffIcon() {
|
||||||
|
if (!this.debuffIcon) return;
|
||||||
|
const debuffNode = this.node.getChildByName("loss_life")?.getChildByName("hp")?.getChildByName("debuff");
|
||||||
|
if (!debuffNode) return;
|
||||||
|
// 先全部隐藏(对象池复用防残留),再点亮目标图标
|
||||||
|
for (const child of debuffNode.children) {
|
||||||
|
child.active = child.name === this.debuffIcon;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 根据技能触发类型激活对应的背景标识节点
|
* 根据技能触发类型激活对应的背景标识节点
|
||||||
* 仅 TooltipTypes.skill 走此分支,其他飘字类型不受影响
|
* 仅 TooltipTypes.skill 走此分支,其他飘字类型不受影响
|
||||||
|
|||||||
Reference in New Issue
Block a user