feat: 实现DoT灼烧技能与debuff图标系统
本次提交完成了以下核心改动: 1. 调整fb-1~fb-6技能预制件的攻击偏移坐标,优化技能弹道位置 2. 新增DoT伤害机制,支持周期伤害/治疗的独立结算 3. 为Buff系统添加施法者属性快照,让DoT暴击、控制判定更准确 4. 新增顶栏debuff图标显示功能,支持灼烧等负面状态可视化 5. 为破晓先知等英雄替换为新的灼烧火球技能6104 6. 修复fb-2预制件的配置字段顺序与多余属性问题
This commit is contained in:
@@ -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 { CCComp } from "../../../../extensions/oops-plugin-framework/assets/module/common/CCComp";
|
||||
import { HeroAttrsComp } from "./HeroAttrsComp";
|
||||
import { BuffComp } from "./BuffComp";
|
||||
import { BuffList, BuffCategory } from "../common/config/BuffSet";
|
||||
import { FacSet, FightSet } from "../common/config/GameSet";
|
||||
|
||||
const { ccclass, property } = _decorator;
|
||||
@@ -35,6 +37,10 @@ export class HeroTopBarComp extends CCComp {
|
||||
// ==================== 内部引用 ====================
|
||||
private topOpacity: UIOpacity = null!;
|
||||
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;
|
||||
@@ -87,6 +93,15 @@ export class HeroTopBarComp extends CCComp {
|
||||
this.node.getChildByName("lv")!.active = false;
|
||||
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.hpShow();
|
||||
this.shieldShow(model.shield);
|
||||
@@ -120,6 +135,51 @@ export class HeroTopBarComp extends CCComp {
|
||||
this.shieldProgressBar.node.active = shield > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* buffId → debuff 图标节点名映射(节点名为 top.prefab debuff 容器下的子节点名)。
|
||||
* 仅伤害类 debuff 需要图标;未映射的 buff 不显示。
|
||||
*/
|
||||
private static readonly DEBUFF_ICON_MAP: Record<number, string> = {
|
||||
7002: "FireDamage", // 灼烧
|
||||
};
|
||||
|
||||
/**
|
||||
* 刷新 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 = HeroTopBarComp.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 {
|
||||
this.setTopBarOpacity(true);
|
||||
@@ -165,6 +225,12 @@ export class HeroTopBarComp extends CCComp {
|
||||
/** 对象池回收 / 组件重置时调用 */
|
||||
public reset(): void {
|
||||
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) {
|
||||
Tween.stopAllByTarget(this.node);
|
||||
this.node.setPosition(this.basePos);
|
||||
|
||||
Reference in New Issue
Block a user