重构怪物属性系统,移除MonAttrsComp并替换为HeroAttrsComp。更新相关组件和系统以适应新属性结构,确保怪物逻辑与英雄逻辑一致。
This commit is contained in:
@@ -4,7 +4,7 @@ import { ecs } from "../../../../extensions/oops-plugin-framework/assets/libs/ec
|
|||||||
import { smc } from "../common/SingletonModuleComp";
|
import { smc } from "../common/SingletonModuleComp";
|
||||||
import { BoxSet, FacSet } from "../common/config/BoxSet";
|
import { BoxSet, FacSet } from "../common/config/BoxSet";
|
||||||
import { HeroInfo } from "../common/config/heroSet";
|
import { HeroInfo } from "../common/config/heroSet";
|
||||||
import { MonAttrsComp } from "./MonAttrsComp";
|
import { HeroAttrsComp } from "./HeroAttrsComp";
|
||||||
import { BattleMoveComp } from "../common/ecs/position/BattleMoveComp";
|
import { BattleMoveComp } from "../common/ecs/position/BattleMoveComp";
|
||||||
import { SkillConComp } from "./SkillConComp";
|
import { SkillConComp } from "./SkillConComp";
|
||||||
import { BuffConf, SkillSet } from "../common/config/SkillSet";
|
import { BuffConf, SkillSet } from "../common/config/SkillSet";
|
||||||
@@ -16,14 +16,14 @@ import { HeroViewComp } from "./HeroViewComp";
|
|||||||
/** 角色实体 */
|
/** 角色实体 */
|
||||||
@ecs.register(`Monster`)
|
@ecs.register(`Monster`)
|
||||||
export class Monster extends ecs.Entity {
|
export class Monster extends ecs.Entity {
|
||||||
HeroModel!: MonAttrsComp;
|
HeroModel!: HeroAttrsComp;
|
||||||
HeroView!: HeroViewComp;
|
HeroView!: HeroViewComp;
|
||||||
BattleMove!: BattleMoveComp;
|
BattleMove!: BattleMoveComp;
|
||||||
|
|
||||||
protected init() {
|
protected init() {
|
||||||
this.addComponents<ecs.Comp>(
|
this.addComponents<ecs.Comp>(
|
||||||
BattleMoveComp,
|
BattleMoveComp,
|
||||||
MonAttrsComp,
|
HeroAttrsComp,
|
||||||
TalComp,
|
TalComp,
|
||||||
EBusComp,
|
EBusComp,
|
||||||
);
|
);
|
||||||
@@ -31,7 +31,7 @@ export class Monster extends ecs.Entity {
|
|||||||
|
|
||||||
destroy(): void {
|
destroy(): void {
|
||||||
this.remove(HeroViewComp);
|
this.remove(HeroViewComp);
|
||||||
this.remove(MonAttrsComp);
|
this.remove(HeroAttrsComp);
|
||||||
this.remove(TalComp);
|
this.remove(TalComp);
|
||||||
this.remove(EBusComp);
|
this.remove(EBusComp);
|
||||||
super.destroy();
|
super.destroy();
|
||||||
@@ -53,7 +53,7 @@ export class Monster extends ecs.Entity {
|
|||||||
|
|
||||||
|
|
||||||
var view = node.getComponent(HeroViewComp)!;
|
var view = node.getComponent(HeroViewComp)!;
|
||||||
const model = this.get(MonAttrsComp);
|
const model = this.get(HeroAttrsComp);
|
||||||
let hero = HeroInfo[uuid]; // 共用英雄数据
|
let hero = HeroInfo[uuid]; // 共用英雄数据
|
||||||
// 设置 View 层属性(表现相关)
|
// 设置 View 层属性(表现相关)
|
||||||
view.scale = scale;
|
view.scale = scale;
|
||||||
@@ -116,16 +116,16 @@ export class MonLifecycleSystem extends ecs.ComblockSystem
|
|||||||
implements ecs.IEntityEnterSystem, ecs.IEntityRemoveSystem {
|
implements ecs.IEntityEnterSystem, ecs.IEntityRemoveSystem {
|
||||||
|
|
||||||
filter() {
|
filter() {
|
||||||
return ecs.allOf(MonAttrsComp);
|
return ecs.allOf(HeroAttrsComp);
|
||||||
}
|
}
|
||||||
|
|
||||||
entityEnter(e: ecs.Entity): void {
|
entityEnter(e: ecs.Entity): void {
|
||||||
// 英雄实体创建时的特殊处理
|
// 怪物实体创建时的特殊处理
|
||||||
console.log(`怪物进入世界: ${e.get(MonAttrsComp).hero_name}`);
|
console.log(`怪物进入世界: ${e.get(HeroAttrsComp).hero_name}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
entityRemove(e: ecs.Entity): void {
|
entityRemove(e: ecs.Entity): void {
|
||||||
// 英雄实体销毁时的清理工作
|
// 怪物实体销毁时的清理工作
|
||||||
console.log(`怪物离开世界: ${e.get(MonAttrsComp).hero_name}`);
|
console.log(`怪物离开世界: ${e.get(HeroAttrsComp).hero_name}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,204 +0,0 @@
|
|||||||
/*
|
|
||||||
* @Author: dgflash
|
|
||||||
* @Date: 2021-11-18 15:56:01
|
|
||||||
* @LastEditors: dgflash
|
|
||||||
* @LastEditTime: 2022-08-17 13:43:25
|
|
||||||
*/
|
|
||||||
import { ecs } from "../../../../extensions/oops-plugin-framework/assets/libs/ecs/ECS";
|
|
||||||
import { Attrs, AttrsType, BType, NeAttrs } from "../common/config/HeroAttrs";
|
|
||||||
import { BuffConf } from "../common/config/SkillSet";
|
|
||||||
import { HeroInfo, AttrSet } from "../common/config/heroSet";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 怪物属性数据模型 - 存储纯数据,不含表现逻辑
|
|
||||||
* 简化版本:只保留临时buff系统,移除持久型buff
|
|
||||||
*
|
|
||||||
* 注意:HeroAttrsComp 中有详细的 ECS 架构分析,迁移方案见那个文件
|
|
||||||
*/
|
|
||||||
@ecs.register('MonAttrsComp')
|
|
||||||
export class MonAttrsComp extends ecs.Comp {
|
|
||||||
|
|
||||||
// ==================== 角色基础信息 ====================
|
|
||||||
hero_uuid: number = 1001;
|
|
||||||
hero_name: string = "monster";
|
|
||||||
lv: number = 1;
|
|
||||||
type: number = 0; // 0近战 1远程 2辅助
|
|
||||||
fac: number = 1; // 0:hero 1:monster(默认为怪物)
|
|
||||||
|
|
||||||
|
|
||||||
// ==================== 动态属性值 ====================
|
|
||||||
hp: number = 100; // 当前血量
|
|
||||||
mp: number = 100; // 当前魔法值
|
|
||||||
shield: number = 0; // 当前护盾
|
|
||||||
Attrs: any = []; // 最终属性数组(经过Buff计算后)
|
|
||||||
NeAttrs: any = []; // 负面状态数组
|
|
||||||
|
|
||||||
// ==================== Buff/Debuff 系统 ====================
|
|
||||||
/** 临时型buff数组 - 按时间自动过期(怪物只使用临时buff) */
|
|
||||||
BUFFS_TEMP: Record<number, Array<{value: number, BType: BType, remainTime: number}>> = {};
|
|
||||||
|
|
||||||
// ==================== 标记状态 ====================
|
|
||||||
is_dead: boolean = false;
|
|
||||||
is_count_dead: boolean = false;
|
|
||||||
is_boss: boolean = false;
|
|
||||||
is_big_boss: boolean = false;
|
|
||||||
is_master: boolean = false;
|
|
||||||
is_friend: boolean = false;
|
|
||||||
is_kalami: boolean = false;
|
|
||||||
|
|
||||||
// ==================== 计数统计 ====================
|
|
||||||
atk_count: number = 0; // 攻击次数
|
|
||||||
atked_count: number = 0; // 被攻击次数
|
|
||||||
|
|
||||||
// ==================== 技能配置 ====================
|
|
||||||
skills: any = [];
|
|
||||||
|
|
||||||
|
|
||||||
addBuff(buffConf: BuffConf) {
|
|
||||||
// 怪物只使用临时buff
|
|
||||||
const attrIndex = buffConf.buff;
|
|
||||||
if (!this.BUFFS_TEMP[attrIndex]) this.BUFFS_TEMP[attrIndex] = [];
|
|
||||||
this.BUFFS_TEMP[attrIndex].push({ value: buffConf.value, BType: buffConf.BType, remainTime: buffConf.time });
|
|
||||||
this.recalculateSingleAttr(attrIndex);
|
|
||||||
}
|
|
||||||
|
|
||||||
recalculateSingleAttr(attrIndex: number) {
|
|
||||||
const baseValues: Record<number, number> = {
|
|
||||||
[Attrs.HP_MAX]: this.hp, [Attrs.MP_MAX]: this.mp, [Attrs.DEF]: this.def,
|
|
||||||
[Attrs.AP]: this.base_ap, [Attrs.MAP]: this.base_map, [Attrs.SPEED]: this.base_speed, [Attrs.SHIELD_MAX]: 0
|
|
||||||
};
|
|
||||||
const baseVal = baseValues[attrIndex] !== undefined ? baseValues[attrIndex] : 0;
|
|
||||||
let totalValue = baseVal, totalRatio = 0;
|
|
||||||
|
|
||||||
// 怪物只计算临时buff
|
|
||||||
if (this.BUFFS_TEMP[attrIndex]) {
|
|
||||||
for (const buff of this.BUFFS_TEMP[attrIndex]) {
|
|
||||||
if (buff.BType === BType.VALUE) totalValue += buff.value;
|
|
||||||
else totalRatio += buff.value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const attrType = AttrsType[attrIndex];
|
|
||||||
this.Attrs[attrIndex] = attrType === BType.RATIO ? totalValue + totalRatio : Math.floor(totalValue * (1 + totalRatio / 100));
|
|
||||||
this.clampSingleAttr(attrIndex);
|
|
||||||
}
|
|
||||||
|
|
||||||
private clampSingleAttr(attrIndex: number) {
|
|
||||||
switch(attrIndex) {
|
|
||||||
case Attrs.HP_MAX: case Attrs.MP_MAX: case Attrs.DEF: case Attrs.AP: case Attrs.MAP:
|
|
||||||
this.Attrs[attrIndex] = Math.max(1, this.Attrs[attrIndex]); break;
|
|
||||||
case Attrs.CRITICAL: case Attrs.DODGE: case Attrs.HIT:
|
|
||||||
this.Attrs[attrIndex] = Math.max(0, Math.min(AttrSet.ATTR_MAX, this.Attrs[attrIndex])); break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
updateTemporaryBuffsDebuffs(dt: number) {
|
|
||||||
const affectedAttrs = new Set<number>();
|
|
||||||
for (const attrIndex in this.BUFFS_TEMP) {
|
|
||||||
const buffs = this.BUFFS_TEMP[attrIndex];
|
|
||||||
buffs.forEach(buff => {
|
|
||||||
buff.remainTime -= dt;
|
|
||||||
if (buff.remainTime <= 0) buffs.splice(buffs.indexOf(buff), 1);
|
|
||||||
});
|
|
||||||
if (buffs.length === 0) {
|
|
||||||
delete this.BUFFS_TEMP[attrIndex];
|
|
||||||
affectedAttrs.add(parseInt(attrIndex));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (const key in this.NeAttrs) {
|
|
||||||
this.NeAttrs[key].remainTime -= dt;
|
|
||||||
if (this.NeAttrs[key].remainTime <= 0) this.NeAttrs[key].remainTime = 0;
|
|
||||||
}
|
|
||||||
affectedAttrs.forEach(attrIndex => this.recalculateSingleAttr(attrIndex));
|
|
||||||
}
|
|
||||||
|
|
||||||
clearBuffs(attrIndex?: number, isBuff: boolean = true): void {
|
|
||||||
if (attrIndex === undefined) {
|
|
||||||
for (const idx in this.BUFFS_TEMP) this.clearBuffsForAttr(parseInt(idx), isBuff);
|
|
||||||
} else {
|
|
||||||
this.clearBuffsForAttr(attrIndex, isBuff);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private clearBuffsForAttr(attrIndex: number, isBuff: boolean): void {
|
|
||||||
if (!this.BUFFS_TEMP[attrIndex]) return;
|
|
||||||
this.BUFFS_TEMP[attrIndex] = this.BUFFS_TEMP[attrIndex].filter(buff => {
|
|
||||||
const shouldClear = isBuff ? buff.value > 0 : buff.value < 0;
|
|
||||||
return !shouldClear;
|
|
||||||
});
|
|
||||||
if (this.BUFFS_TEMP[attrIndex].length === 0) delete this.BUFFS_TEMP[attrIndex];
|
|
||||||
this.recalculateSingleAttr(attrIndex);
|
|
||||||
}
|
|
||||||
|
|
||||||
clearNeAttr(neAttrIndex: number): void {
|
|
||||||
if (this.NeAttrs[neAttrIndex]) {
|
|
||||||
this.NeAttrs[neAttrIndex].value = 0;
|
|
||||||
this.NeAttrs[neAttrIndex].time = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
clearAllNeAttrs(): void {
|
|
||||||
for (const key in this.NeAttrs) {
|
|
||||||
this.NeAttrs[key].value = 0;
|
|
||||||
this.NeAttrs[key].time = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public isStun(): boolean {
|
|
||||||
return this.NeAttrs[NeAttrs.IN_STUN]?.time > 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
public isFrost(): boolean {
|
|
||||||
return this.NeAttrs[NeAttrs.IN_FROST]?.time > 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
reset() {
|
|
||||||
this.hero_uuid = 1001;
|
|
||||||
this.hero_name = "monster";
|
|
||||||
this.lv = 1;
|
|
||||||
this.type = 0;
|
|
||||||
this.fac = 1;
|
|
||||||
this.hp = 100;
|
|
||||||
this.mp = 100;
|
|
||||||
this.shield = 0;
|
|
||||||
this.Attrs = [];
|
|
||||||
this.NeAttrs = [];
|
|
||||||
this.BUFFS_TEMP = {}; // 只重置临时buff
|
|
||||||
this.is_dead = false;
|
|
||||||
this.is_count_dead = false;
|
|
||||||
this.is_boss = false;
|
|
||||||
this.is_big_boss = false;
|
|
||||||
this.is_master = false;
|
|
||||||
this.is_friend = false;
|
|
||||||
this.is_kalami = false;
|
|
||||||
this.atk_count = 0;
|
|
||||||
this.atked_count = 0;
|
|
||||||
this.skills = [];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* ==================== 怪物属性更新系统 ====================
|
|
||||||
*
|
|
||||||
* 与 HeroAttrSystem 类似,但针对怪物
|
|
||||||
* 可以复用相同逻辑,也可以定制不同规则
|
|
||||||
*/
|
|
||||||
export class MonAttrSystem extends ecs.ComblockSystem
|
|
||||||
implements ecs.ISystemUpdate {
|
|
||||||
|
|
||||||
filter(): ecs.IMatcher {
|
|
||||||
return ecs.allOf(MonAttrsComp);
|
|
||||||
}
|
|
||||||
|
|
||||||
update(e: ecs.Entity): void {
|
|
||||||
const model = e.get(MonAttrsComp);
|
|
||||||
if (!model || model.is_dead) return;
|
|
||||||
|
|
||||||
// 怪物的属性更新逻辑(可以与英雄不同)
|
|
||||||
model.updateTemporaryBuffsDebuffs(this.dt);
|
|
||||||
|
|
||||||
// 怪物可能没有自然回复,或者回复速度不同
|
|
||||||
// model.mp += MonUpSet.MP * this.dt;
|
|
||||||
// model.hp += MonUpSet.HP * this.dt;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
{
|
|
||||||
"ver": "4.0.24",
|
|
||||||
"importer": "typescript",
|
|
||||||
"imported": true,
|
|
||||||
"uuid": "b2b785de-2ec9-49ca-a015-b56c5fe19a50",
|
|
||||||
"files": [],
|
|
||||||
"subMetas": {},
|
|
||||||
"userData": {}
|
|
||||||
}
|
|
||||||
@@ -1,29 +0,0 @@
|
|||||||
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";
|
|
||||||
|
|
||||||
const { ccclass, property } = _decorator;
|
|
||||||
|
|
||||||
/** 视图层对象 */
|
|
||||||
@ccclass('MonViewComp')
|
|
||||||
@ecs.register('MonView', false)
|
|
||||||
export class MonViewComp extends CCComp {
|
|
||||||
/** 视图层逻辑代码分离演示 */
|
|
||||||
start() {
|
|
||||||
// var entity = this.ent as ecs.Entity; // ecs.Entity 可转为当前模块的具体实体对象
|
|
||||||
// this.on(ModuleEvent.Cmd, this.onHandler, this);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** 全局消息逻辑处理 */
|
|
||||||
// private onHandler(event: string, args: any) {
|
|
||||||
// switch (event) {
|
|
||||||
// case ModuleEvent.Cmd:
|
|
||||||
// break;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
/** 视图对象通过 ecs.Entity.remove(ModuleViewComp) 删除组件是触发组件处理自定义释放逻辑 */
|
|
||||||
reset() {
|
|
||||||
this.node.destroy();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
{
|
|
||||||
"ver": "4.0.24",
|
|
||||||
"importer": "typescript",
|
|
||||||
"imported": true,
|
|
||||||
"uuid": "413afaac-8d90-4810-8036-a5dae3f9eea8",
|
|
||||||
"files": [],
|
|
||||||
"subMetas": {},
|
|
||||||
"userData": {}
|
|
||||||
}
|
|
||||||
@@ -6,7 +6,6 @@ import { GameEvent } from '../common/config/GameEvent';
|
|||||||
import { FacSet } from '../common/config/BoxSet';
|
import { FacSet } from '../common/config/BoxSet';
|
||||||
import { smc } from '../common/SingletonModuleComp';
|
import { smc } from '../common/SingletonModuleComp';
|
||||||
import { CCComp } from 'db://oops-framework/module/common/CCComp';
|
import { CCComp } from 'db://oops-framework/module/common/CCComp';
|
||||||
import { MonAttrsComp } from './MonAttrsComp';
|
|
||||||
import { HeroAttrsComp } from './HeroAttrsComp';
|
import { HeroAttrsComp } from './HeroAttrsComp';
|
||||||
import { SkillEnt } from '../skill/SkillEnt';
|
import { SkillEnt } from '../skill/SkillEnt';
|
||||||
import { Attrs } from '../common/config/HeroAttrs';
|
import { Attrs } from '../common/config/HeroAttrs';
|
||||||
@@ -107,7 +106,7 @@ export class SkillConComp extends CCComp {
|
|||||||
|
|
||||||
check_target(){
|
check_target(){
|
||||||
if(this.HeroView.fac==FacSet.HERO){
|
if(this.HeroView.fac==FacSet.HERO){
|
||||||
return ecs.query(ecs.allOf(MonAttrsComp))
|
return ecs.query(ecs.allOf(HeroAttrsComp))
|
||||||
}else{
|
}else{
|
||||||
return ecs.query(ecs.allOf(HeroAttrsComp))
|
return ecs.query(ecs.allOf(HeroAttrsComp))
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user