refactor(hero): 重构技能触发与属性系统,使用运行时解析缓存
1. 重构英雄属性组件,将静态配置与运行时缓存分离,新增runtime_前缀的运行时解析字段 2. 移除旧的evolve进化配置处理逻辑,改为通过等级解析器动态获取当前等级生效的技能与属性 3. 统一怪物与英雄的技能触发逻辑,均使用运行时缓存字段 4. 更新测试模式配置结构,适配新的分组+等级数组配置格式 5. 优化技能描述生成逻辑,支持新的等级配置结构
This commit is contained in:
@@ -1,9 +1,9 @@
|
||||
import { instantiate, Node, Prefab, Vec3 ,v3,resources,SpriteFrame,Sprite,SpriteAtlas, BoxCollider2D, NodePool, tween, Tween} from "cc";
|
||||
import { instantiate, Node, Prefab, Vec3, v3, resources, SpriteFrame, Sprite, SpriteAtlas, BoxCollider2D, NodePool, tween, Tween } from "cc";
|
||||
import { oops } from "../../../../extensions/oops-plugin-framework/assets/core/Oops";
|
||||
import { ecs } from "../../../../extensions/oops-plugin-framework/assets/libs/ecs/ECS";
|
||||
import { smc } from "../common/SingletonModuleComp";
|
||||
import { BoxSet, FacSet, FightSet, IndexSet } from "../common/config/GameSet";
|
||||
import { HeroInfo } from "../common/config/heroSet";
|
||||
import { HeroInfo, resolveTriggerByLv, resolveReviveByLv } from "../common/config/heroSet";
|
||||
import { HeroAttrsComp } from "./HeroAttrsComp";
|
||||
import { HeroViewComp } from "./HeroViewComp";
|
||||
import { MoveComp } from "./MoveComp";
|
||||
@@ -109,10 +109,10 @@ export class Monster extends ecs.Entity {
|
||||
const model = this.get(HeroAttrsComp);
|
||||
const view = this.get(HeroViewComp);
|
||||
if (model && view && view.node && view.node.isValid) {
|
||||
const path = "game/heros/" + HeroInfo[model.hero_uuid].path;
|
||||
Monster.putToPool(path, view.node);
|
||||
const path = "game/heros/" + HeroInfo[model.hero_uuid].path;
|
||||
Monster.putToPool(path, view.node);
|
||||
}
|
||||
|
||||
|
||||
if (model && model.posIndex >= 0) {
|
||||
if (smc.mission.monGrid[model.posIndex] === this.eid) {
|
||||
smc.mission.monGrid[model.posIndex] = -1;
|
||||
@@ -131,15 +131,15 @@ export class Monster extends ecs.Entity {
|
||||
* 2) 初始化表现、属性、技能与阵营
|
||||
* 3) 播放下落入场并在落地后启用碰撞与移动
|
||||
*/
|
||||
load(pos: Vec3 = Vec3.ZERO,scale:number = 1,uuid:number=1001, is_boss:boolean=false, dropToY:number = pos.y,mon_lv:number=1, laneIndex:number = 0) {
|
||||
load(pos: Vec3 = Vec3.ZERO, scale: number = 1, uuid: number = 1001, is_boss: boolean = false, dropToY: number = pos.y, mon_lv: number = 1, laneIndex: number = 0) {
|
||||
// 怪物默认朝左,表现缩放固定为负向
|
||||
scale=-1
|
||||
scale = -1
|
||||
// 当前怪物尺寸固定,保留变量便于后续扩展
|
||||
let size=1.15
|
||||
let size = 1.15
|
||||
var scene = smc.map.MapView.scene;
|
||||
// 根据配置读取怪物预制体路径
|
||||
var path = "game/heros/"+HeroInfo[uuid].path;
|
||||
|
||||
var path = "game/heros/" + HeroInfo[uuid].path;
|
||||
|
||||
// 优先从对象池取节点,未命中时再实例化
|
||||
let node = Monster.getFromPool(path);
|
||||
if (!node) {
|
||||
@@ -157,7 +157,7 @@ export class Monster extends ecs.Entity {
|
||||
if (collider) {
|
||||
collider.enabled = false;
|
||||
}
|
||||
|
||||
|
||||
let baseScale = (node as any)._baseScale || v3(1, 1, 1);
|
||||
node.setScale(size * baseScale.x, size * baseScale.y);
|
||||
node.setPosition(pos)
|
||||
@@ -191,8 +191,8 @@ export class Monster extends ecs.Entity {
|
||||
model.revive = hero.revive;
|
||||
|
||||
// 标记是否 Boss,非 Boss 默认记作杂兵
|
||||
model.is_boss =is_boss
|
||||
if(!model.is_boss){
|
||||
model.is_boss = is_boss
|
||||
if (!model.is_boss) {
|
||||
model.is_kalami = true;
|
||||
}
|
||||
|
||||
@@ -202,7 +202,7 @@ export class Monster extends ecs.Entity {
|
||||
const skill = hero.skills[key];
|
||||
if (!skill) continue;
|
||||
// 最终技能等级 = 初始技能等级 + 怪物等级增量,且下限为 0
|
||||
model.skills[skill.uuid] = { ...skill, lv: Math.max(0,skill.lv + mon_lv - 2), ccd: 0 };
|
||||
model.skills[skill.uuid] = { ...skill, lv: Math.max(0, skill.lv + mon_lv - 2), ccd: 0 };
|
||||
}
|
||||
// 【测试模式专属】如果有覆盖技能配置则应用
|
||||
const testSkills = (this as any)._testSkills;
|
||||
@@ -227,15 +227,24 @@ export class Monster extends ecs.Entity {
|
||||
if (testSkills.fend !== undefined) model.fend = testSkills.fend;
|
||||
}
|
||||
|
||||
// 按怪物等级 resolve 触发技能/复活到运行时缓存(怪物无 lv 成长,恒用 mon_lv)
|
||||
model.runtime_call = resolveTriggerByLv(model.call, mon_lv);
|
||||
model.runtime_dead = resolveTriggerByLv(model.dead, mon_lv);
|
||||
model.runtime_fstart = resolveTriggerByLv(model.fstart, mon_lv);
|
||||
model.runtime_fend = resolveTriggerByLv(model.fend, mon_lv);
|
||||
model.runtime_atking = resolveTriggerByLv(model.atking, mon_lv);
|
||||
model.runtime_atked = resolveTriggerByLv(model.atked, mon_lv);
|
||||
model.runtime_revive = resolveReviveByLv(model.revive, mon_lv);
|
||||
|
||||
// 缓存技能射程等派生数据,减少战斗帧内重复计算
|
||||
model.updateSkillDistanceCache();
|
||||
|
||||
|
||||
// 注册视图组件并重置对象池复用状态
|
||||
this.add(view);
|
||||
view.init();
|
||||
view.as.idle();
|
||||
// 广播怪物加载事件,供刷怪与战斗系统联动
|
||||
oops.message.dispatchEvent("monster_load",this)
|
||||
oops.message.dispatchEvent("monster_load", this)
|
||||
// 初始化移动参数:方向、目标 X、站位基准 Y
|
||||
const move = this.get(MonMoveComp);
|
||||
move.reset();
|
||||
@@ -246,7 +255,7 @@ export class Monster extends ecs.Entity {
|
||||
|
||||
// 依据下落距离自适应入场时长,确保观感一致
|
||||
const dropDistance = Math.abs(pos.y - dropToY);
|
||||
|
||||
|
||||
const onDropComplete = () => {
|
||||
if (!node || !node.isValid) return;
|
||||
// 落地后锁定最终位置,切换到落地完成状态
|
||||
@@ -271,7 +280,7 @@ export class Monster extends ecs.Entity {
|
||||
|
||||
// 停止旧动画后执行下落 tween,避免复用节点时动画叠加
|
||||
Tween.stopAllByTarget(node);
|
||||
|
||||
|
||||
if (dropDistance > 0) {
|
||||
const dropDuration = Math.max(0.18, Math.min(0.38, dropDistance / 1200));
|
||||
tween(node)
|
||||
@@ -287,10 +296,10 @@ export class Monster extends ecs.Entity {
|
||||
smc.vmdata.mission_data.mon_num++
|
||||
}
|
||||
|
||||
|
||||
|
||||
/** 重置入口:复用 destroy 的释放流程 */
|
||||
reset() {
|
||||
super.destroy();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user