refactor(skill): 重构技能配置加载逻辑,将参数下沉至prefab配置
1. 新增SkillView组件属性runType/endType/speed/time,替换原配置表字段 2. 批量同步所有技能prefab的配置参数 3. 优化技能运行逻辑,优先使用prefab配置,配置表仅作兜底 4. 新增同步脚本用于批量迁移技能配置
This commit is contained in:
@@ -250,7 +250,11 @@
|
|||||||
},
|
},
|
||||||
"atk_x": 10,
|
"atk_x": 10,
|
||||||
"atk_y": 15,
|
"atk_y": 15,
|
||||||
"_id": ""
|
"_id": "",
|
||||||
|
"runType": 1,
|
||||||
|
"endType": 2,
|
||||||
|
"speed": 720,
|
||||||
|
"time": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"__type__": "cc.CompPrefabInfo",
|
"__type__": "cc.CompPrefabInfo",
|
||||||
@@ -336,4 +340,4 @@
|
|||||||
"instance": null,
|
"instance": null,
|
||||||
"targetOverrides": null
|
"targetOverrides": null
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -250,7 +250,11 @@
|
|||||||
},
|
},
|
||||||
"atk_x": 10,
|
"atk_x": 10,
|
||||||
"atk_y": 15,
|
"atk_y": 15,
|
||||||
"_id": ""
|
"_id": "",
|
||||||
|
"runType": 1,
|
||||||
|
"endType": 2,
|
||||||
|
"speed": 720,
|
||||||
|
"time": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"__type__": "cc.CompPrefabInfo",
|
"__type__": "cc.CompPrefabInfo",
|
||||||
@@ -336,4 +340,4 @@
|
|||||||
"instance": null,
|
"instance": null,
|
||||||
"targetOverrides": null
|
"targetOverrides": null
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -250,7 +250,11 @@
|
|||||||
},
|
},
|
||||||
"atk_x": 10,
|
"atk_x": 10,
|
||||||
"atk_y": 15,
|
"atk_y": 15,
|
||||||
"_id": ""
|
"_id": "",
|
||||||
|
"runType": 1,
|
||||||
|
"endType": 2,
|
||||||
|
"speed": 720,
|
||||||
|
"time": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"__type__": "cc.CompPrefabInfo",
|
"__type__": "cc.CompPrefabInfo",
|
||||||
@@ -336,4 +340,4 @@
|
|||||||
"instance": null,
|
"instance": null,
|
||||||
"targetOverrides": null
|
"targetOverrides": null
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -250,7 +250,11 @@
|
|||||||
},
|
},
|
||||||
"atk_x": 10,
|
"atk_x": 10,
|
||||||
"atk_y": 15,
|
"atk_y": 15,
|
||||||
"_id": ""
|
"_id": "",
|
||||||
|
"runType": 1,
|
||||||
|
"endType": 2,
|
||||||
|
"speed": 720,
|
||||||
|
"time": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"__type__": "cc.CompPrefabInfo",
|
"__type__": "cc.CompPrefabInfo",
|
||||||
@@ -336,4 +340,4 @@
|
|||||||
"instance": null,
|
"instance": null,
|
||||||
"targetOverrides": null
|
"targetOverrides": null
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -250,7 +250,11 @@
|
|||||||
},
|
},
|
||||||
"atk_x": 10,
|
"atk_x": 10,
|
||||||
"atk_y": 15,
|
"atk_y": 15,
|
||||||
"_id": ""
|
"_id": "",
|
||||||
|
"runType": 1,
|
||||||
|
"endType": 2,
|
||||||
|
"speed": 720,
|
||||||
|
"time": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"__type__": "cc.CompPrefabInfo",
|
"__type__": "cc.CompPrefabInfo",
|
||||||
@@ -336,4 +340,4 @@
|
|||||||
"instance": null,
|
"instance": null,
|
||||||
"targetOverrides": null
|
"targetOverrides": null
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -108,8 +108,8 @@
|
|||||||
},
|
},
|
||||||
"_lscale": {
|
"_lscale": {
|
||||||
"__type__": "cc.Vec3",
|
"__type__": "cc.Vec3",
|
||||||
"x": 1.6,
|
"x": 1.3,
|
||||||
"y": 1.4,
|
"y": 1.1,
|
||||||
"z": 1
|
"z": 1
|
||||||
},
|
},
|
||||||
"_mobility": 0,
|
"_mobility": 0,
|
||||||
@@ -252,7 +252,11 @@
|
|||||||
"__id__": 11
|
"__id__": 11
|
||||||
},
|
},
|
||||||
"atk_x": 20,
|
"atk_x": 20,
|
||||||
"atk_y": 30,
|
"atk_y": 40,
|
||||||
|
"runType": 2,
|
||||||
|
"endType": 2,
|
||||||
|
"speed": 720,
|
||||||
|
"time": 0,
|
||||||
"_id": ""
|
"_id": ""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -282,7 +282,11 @@
|
|||||||
},
|
},
|
||||||
"atk_x": 10,
|
"atk_x": 10,
|
||||||
"atk_y": 25,
|
"atk_y": 25,
|
||||||
"_id": ""
|
"_id": "",
|
||||||
|
"runType": 1,
|
||||||
|
"endType": 2,
|
||||||
|
"speed": 720,
|
||||||
|
"time": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"__type__": "cc.CompPrefabInfo",
|
"__type__": "cc.CompPrefabInfo",
|
||||||
@@ -368,4 +372,4 @@
|
|||||||
"instance": null,
|
"instance": null,
|
||||||
"targetOverrides": null
|
"targetOverrides": null
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -282,7 +282,11 @@
|
|||||||
},
|
},
|
||||||
"atk_x": 10,
|
"atk_x": 10,
|
||||||
"atk_y": 25,
|
"atk_y": 25,
|
||||||
"_id": ""
|
"_id": "",
|
||||||
|
"runType": 1,
|
||||||
|
"endType": 2,
|
||||||
|
"speed": 720,
|
||||||
|
"time": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"__type__": "cc.CompPrefabInfo",
|
"__type__": "cc.CompPrefabInfo",
|
||||||
@@ -368,4 +372,4 @@
|
|||||||
"instance": null,
|
"instance": null,
|
||||||
"targetOverrides": null
|
"targetOverrides": null
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -282,7 +282,11 @@
|
|||||||
},
|
},
|
||||||
"atk_x": 10,
|
"atk_x": 10,
|
||||||
"atk_y": 25,
|
"atk_y": 25,
|
||||||
"_id": ""
|
"_id": "",
|
||||||
|
"runType": 1,
|
||||||
|
"endType": 2,
|
||||||
|
"speed": 720,
|
||||||
|
"time": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"__type__": "cc.CompPrefabInfo",
|
"__type__": "cc.CompPrefabInfo",
|
||||||
@@ -368,4 +372,4 @@
|
|||||||
"instance": null,
|
"instance": null,
|
||||||
"targetOverrides": null
|
"targetOverrides": null
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -250,7 +250,11 @@
|
|||||||
},
|
},
|
||||||
"atk_x": 10,
|
"atk_x": 10,
|
||||||
"atk_y": 15,
|
"atk_y": 15,
|
||||||
"_id": ""
|
"_id": "",
|
||||||
|
"runType": 1,
|
||||||
|
"endType": 2,
|
||||||
|
"speed": 720,
|
||||||
|
"time": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"__type__": "cc.CompPrefabInfo",
|
"__type__": "cc.CompPrefabInfo",
|
||||||
@@ -336,4 +340,4 @@
|
|||||||
"instance": null,
|
"instance": null,
|
||||||
"targetOverrides": null
|
"targetOverrides": null
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -250,7 +250,11 @@
|
|||||||
},
|
},
|
||||||
"atk_x": 10,
|
"atk_x": 10,
|
||||||
"atk_y": 15,
|
"atk_y": 15,
|
||||||
"_id": ""
|
"_id": "",
|
||||||
|
"runType": 1,
|
||||||
|
"endType": 2,
|
||||||
|
"speed": 720,
|
||||||
|
"time": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"__type__": "cc.CompPrefabInfo",
|
"__type__": "cc.CompPrefabInfo",
|
||||||
@@ -336,4 +340,4 @@
|
|||||||
"instance": null,
|
"instance": null,
|
||||||
"targetOverrides": null
|
"targetOverrides": null
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -253,7 +253,11 @@
|
|||||||
},
|
},
|
||||||
"atk_x": 0,
|
"atk_x": 0,
|
||||||
"atk_y": 0,
|
"atk_y": 0,
|
||||||
"_id": ""
|
"_id": "",
|
||||||
|
"runType": 1,
|
||||||
|
"endType": 2,
|
||||||
|
"speed": 720,
|
||||||
|
"time": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"__type__": "cc.CompPrefabInfo",
|
"__type__": "cc.CompPrefabInfo",
|
||||||
@@ -368,4 +372,4 @@
|
|||||||
"instance": null,
|
"instance": null,
|
||||||
"targetOverrides": null
|
"targetOverrides": null
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -389,7 +389,11 @@
|
|||||||
},
|
},
|
||||||
"atk_x": 0,
|
"atk_x": 0,
|
||||||
"atk_y": 0,
|
"atk_y": 0,
|
||||||
"_id": ""
|
"_id": "",
|
||||||
|
"runType": 0,
|
||||||
|
"endType": 2,
|
||||||
|
"speed": 720,
|
||||||
|
"time": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"__type__": "cc.CompPrefabInfo",
|
"__type__": "cc.CompPrefabInfo",
|
||||||
@@ -504,4 +508,4 @@
|
|||||||
"instance": null,
|
"instance": null,
|
||||||
"targetOverrides": null
|
"targetOverrides": null
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -250,7 +250,11 @@
|
|||||||
},
|
},
|
||||||
"atk_x": 10,
|
"atk_x": 10,
|
||||||
"atk_y": 15,
|
"atk_y": 15,
|
||||||
"_id": ""
|
"_id": "",
|
||||||
|
"runType": 1,
|
||||||
|
"endType": 2,
|
||||||
|
"speed": 720,
|
||||||
|
"time": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"__type__": "cc.CompPrefabInfo",
|
"__type__": "cc.CompPrefabInfo",
|
||||||
@@ -336,4 +340,4 @@
|
|||||||
"instance": null,
|
"instance": null,
|
||||||
"targetOverrides": null
|
"targetOverrides": null
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -250,7 +250,11 @@
|
|||||||
},
|
},
|
||||||
"atk_x": 10,
|
"atk_x": 10,
|
||||||
"atk_y": 15,
|
"atk_y": 15,
|
||||||
"_id": ""
|
"_id": "",
|
||||||
|
"runType": 1,
|
||||||
|
"endType": 2,
|
||||||
|
"speed": 720,
|
||||||
|
"time": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"__type__": "cc.CompPrefabInfo",
|
"__type__": "cc.CompPrefabInfo",
|
||||||
@@ -336,4 +340,4 @@
|
|||||||
"instance": null,
|
"instance": null,
|
||||||
"targetOverrides": null
|
"targetOverrides": null
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -250,7 +250,11 @@
|
|||||||
},
|
},
|
||||||
"atk_x": 10,
|
"atk_x": 10,
|
||||||
"atk_y": 15,
|
"atk_y": 15,
|
||||||
"_id": ""
|
"_id": "",
|
||||||
|
"runType": 1,
|
||||||
|
"endType": 2,
|
||||||
|
"speed": 720,
|
||||||
|
"time": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"__type__": "cc.CompPrefabInfo",
|
"__type__": "cc.CompPrefabInfo",
|
||||||
@@ -336,4 +340,4 @@
|
|||||||
"instance": null,
|
"instance": null,
|
||||||
"targetOverrides": null
|
"targetOverrides": null
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -250,7 +250,11 @@
|
|||||||
},
|
},
|
||||||
"atk_x": 10,
|
"atk_x": 10,
|
||||||
"atk_y": 15,
|
"atk_y": 15,
|
||||||
"_id": ""
|
"_id": "",
|
||||||
|
"runType": 1,
|
||||||
|
"endType": 2,
|
||||||
|
"speed": 720,
|
||||||
|
"time": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"__type__": "cc.CompPrefabInfo",
|
"__type__": "cc.CompPrefabInfo",
|
||||||
@@ -336,4 +340,4 @@
|
|||||||
"instance": null,
|
"instance": null,
|
||||||
"targetOverrides": null
|
"targetOverrides": null
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
// ========== 从 HeroAttrs.ts 导入属性相关定义 ==========
|
// ========== 从 HeroAttrs.ts 导入属性相关定义 ==========
|
||||||
import { Attrs } from "./HeroAttrs";
|
import { Attrs } from "./HeroAttrs";
|
||||||
|
|
||||||
export enum HSSet {
|
export enum HSSet {
|
||||||
@@ -134,6 +134,7 @@ export interface SkillConfig {
|
|||||||
gold?: number, // 获取金币技能的金币值
|
gold?: number, // 获取金币技能的金币值
|
||||||
hit_count: number, // 可命中次数
|
hit_count: number, // 可命中次数
|
||||||
hitcd: number, // 持续伤害的伤害间隔(秒)
|
hitcd: number, // 持续伤害的伤害间隔(秒)
|
||||||
|
/** @deprecated 已下沉到 SkillView @property(prefab 配置),此处仅作兜底 */
|
||||||
speed: number, // 移动速度
|
speed: number, // 移动速度
|
||||||
with: number, // 宽度(暂时无用)
|
with: number, // 宽度(暂时无用)
|
||||||
ready: number, // 前摇时间
|
ready: number, // 前摇时间
|
||||||
@@ -142,11 +143,14 @@ export interface SkillConfig {
|
|||||||
EAnm: number, // 结束动画ID
|
EAnm: number, // 结束动画ID
|
||||||
DAnm: string, // 命中后动画ID
|
DAnm: string, // 命中后动画ID
|
||||||
IType: IType, // 技能类型(近战/远程/辅助)
|
IType: IType, // 技能类型(近战/远程/辅助)
|
||||||
|
/** @deprecated 已下沉到 SkillView @property(prefab 配置),此处仅作兜底 */
|
||||||
RType: RType, // 技能运行类型(直线/贝塞尔/固定起点/固定终点)
|
RType: RType, // 技能运行类型(直线/贝塞尔/固定起点/固定终点)
|
||||||
|
/** @deprecated 已下沉到 SkillView @property(prefab 配置),此处仅作兜底 */
|
||||||
EType: EType, // 结束条件(动画结束/时间结束/距离结束/碰撞/次数结束)
|
EType: EType, // 结束条件(动画结束/时间结束/距离结束/碰撞/次数结束)
|
||||||
bezier_start_y?: number, // 贝塞尔起始抬升高度
|
bezier_start_y?: number, // 贝塞尔起始抬升高度
|
||||||
bezier_mid_y?: number, // 贝塞尔中间高度增量
|
bezier_mid_y?: number, // 贝塞尔中间高度增量
|
||||||
bezier_arc?: number, // 贝塞尔弧度系数
|
bezier_arc?: number, // 贝塞尔弧度系数
|
||||||
|
/** @deprecated 已下沉到 SkillView @property(prefab 配置),此处仅作兜底 */
|
||||||
time?: number, // timeEnd 持续时间(秒)
|
time?: number, // timeEnd 持续时间(秒)
|
||||||
kind?: SkillKind, // 主效果类型
|
kind?: SkillKind, // 主效果类型
|
||||||
crt?: number, // 额外暴击率
|
crt?: number, // 额外暴击率
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { v3, Vec3 ,Node} from "cc";
|
import { v3, Vec3, 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 { EType, RType, SkillSet } from "../common/config/SkillSet";
|
import { EType, RType, SkillSet } from "../common/config/SkillSet";
|
||||||
import { SMoveDataComp } from "./SMoveComp";
|
import { SMoveDataComp } from "./SMoveComp";
|
||||||
@@ -26,46 +26,46 @@ export class SMoveSystem extends ecs.ComblockSystem implements ecs.ISystemUpdate
|
|||||||
filter(): ecs.IMatcher {
|
filter(): ecs.IMatcher {
|
||||||
return ecs.allOf(SMoveDataComp, SkillView);
|
return ecs.allOf(SMoveDataComp, SkillView);
|
||||||
}
|
}
|
||||||
|
|
||||||
entityEnter(entity: ecs.Entity): void {
|
entityEnter(entity: ecs.Entity): void {
|
||||||
const moveComp = entity.get(SMoveDataComp);
|
const moveComp = entity.get(SMoveDataComp);
|
||||||
const skillView = entity.get(SkillView);
|
const skillView = entity.get(SkillView);
|
||||||
|
|
||||||
if (!moveComp || !skillView || !skillView.node) return;
|
if (!moveComp || !skillView || !skillView.node) return;
|
||||||
|
|
||||||
// 获取技能配置
|
// 获取技能配置
|
||||||
const skillConfig = SkillSet[moveComp.s_uuid];
|
const skillConfig = SkillSet[moveComp.s_uuid];
|
||||||
if (!skillConfig) {
|
if (!skillConfig) {
|
||||||
mLogger.warn(this.debugMode, 'SMoveSystem', `[SMoveSystem] 技能配置不存在: ${moveComp.s_uuid}`);
|
mLogger.warn(this.debugMode, 'SMoveSystem', `[SMoveSystem] 技能配置不存在: ${moveComp.s_uuid}`);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 根据配置设置移动速度与加速度
|
// 移动参数由 prefab 的 SkillView @property 决定(speed<=0 时 Skill.load 已回退配置表值)
|
||||||
if (skillConfig.speed > 0) {
|
if (moveComp.speed <= 0) {
|
||||||
moveComp.speed = skillConfig.speed;
|
moveComp.speed = skillConfig.speed;
|
||||||
}
|
}
|
||||||
if (skillConfig.is_accel) {
|
if (skillConfig.is_accel) {
|
||||||
moveComp.isAccelerate = true;
|
moveComp.isAccelerate = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 根据runType设置初始位置
|
// 根据runType设置初始位置
|
||||||
this.initializePosition(moveComp, skillView);
|
this.initializePosition(moveComp, skillView);
|
||||||
|
|
||||||
// 开始移动(除了固定位置类型)
|
// 开始移动(除了固定位置类型)
|
||||||
if (moveComp.runType !== RType.fixed && moveComp.runType !== RType.fixedEnd) {
|
if (moveComp.runType !== RType.fixed && moveComp.runType !== RType.fixedEnd) {
|
||||||
moveComp.startMove();
|
moveComp.startMove();
|
||||||
}
|
}
|
||||||
|
|
||||||
mLogger.log(this.debugMode, 'SMoveSystem', `[SMoveSystem] 技能 ${skillConfig.name} 开始移动,类型: ${moveComp.runType}`);
|
mLogger.log(this.debugMode, 'SMoveSystem', `[SMoveSystem] 技能 ${skillConfig.name} 开始移动,类型: ${moveComp.runType}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 根据runType初始化技能位置
|
* 根据runType初始化技能位置
|
||||||
*/
|
*/
|
||||||
private initializePosition(moveComp: SMoveDataComp, skillView: SkillView): void {
|
private initializePosition(moveComp: SMoveDataComp, skillView: SkillView): void {
|
||||||
const node = skillView.node;
|
const node = skillView.node;
|
||||||
|
|
||||||
switch(moveComp.runType) {
|
switch (moveComp.runType) {
|
||||||
case RType.linear:
|
case RType.linear:
|
||||||
// linear类型:根据atk_x和atk_y调整起始位置
|
// linear类型:根据atk_x和atk_y调整起始位置
|
||||||
const adjustedStartPos = v3(
|
const adjustedStartPos = v3(
|
||||||
@@ -73,35 +73,35 @@ export class SMoveSystem extends ecs.ComblockSystem implements ecs.ISystemUpdate
|
|||||||
moveComp.startPos.y + moveComp.atk_y,
|
moveComp.startPos.y + moveComp.atk_y,
|
||||||
moveComp.startPos.z
|
moveComp.startPos.z
|
||||||
);
|
);
|
||||||
|
|
||||||
const originTargetPos = v3(
|
const originTargetPos = v3(
|
||||||
moveComp.targetPos.x,
|
moveComp.targetPos.x,
|
||||||
moveComp.targetPos.y,
|
moveComp.targetPos.y,
|
||||||
moveComp.targetPos.z
|
moveComp.targetPos.z
|
||||||
);
|
);
|
||||||
|
|
||||||
const direction = new Vec3();
|
const direction = new Vec3();
|
||||||
Vec3.subtract(direction, originTargetPos, adjustedStartPos);
|
Vec3.subtract(direction, originTargetPos, adjustedStartPos);
|
||||||
|
|
||||||
// 延长终止点,统一消亡点的x坐标为 +-500
|
// 延长终止点,统一消亡点的x坐标为 +-500
|
||||||
const targetX = moveComp.scale > 0 ? 500 : -500;
|
const targetX = moveComp.scale > 0 ? 500 : -500;
|
||||||
let targetY = originTargetPos.y;
|
let targetY = originTargetPos.y;
|
||||||
|
|
||||||
if (Math.abs(direction.x) > 0.01) {
|
if (Math.abs(direction.x) > 0.01) {
|
||||||
const slope = direction.y / direction.x;
|
const slope = direction.y / direction.x;
|
||||||
targetY = adjustedStartPos.y + slope * (targetX - adjustedStartPos.x);
|
targetY = adjustedStartPos.y + slope * (targetX - adjustedStartPos.x);
|
||||||
}
|
}
|
||||||
|
|
||||||
const adjustedTargetPos = v3(
|
const adjustedTargetPos = v3(
|
||||||
targetX,
|
targetX,
|
||||||
targetY,
|
targetY,
|
||||||
originTargetPos.z
|
originTargetPos.z
|
||||||
);
|
);
|
||||||
|
|
||||||
moveComp.startPos.set(adjustedStartPos);
|
moveComp.startPos.set(adjustedStartPos);
|
||||||
moveComp.targetPos.set(adjustedTargetPos);
|
moveComp.targetPos.set(adjustedTargetPos);
|
||||||
node.setPosition(adjustedStartPos);
|
node.setPosition(adjustedStartPos);
|
||||||
|
|
||||||
// 设置旋转角度
|
// 设置旋转角度
|
||||||
const dirForAngle = new Vec3();
|
const dirForAngle = new Vec3();
|
||||||
Vec3.subtract(dirForAngle, adjustedTargetPos, adjustedStartPos);
|
Vec3.subtract(dirForAngle, adjustedTargetPos, adjustedStartPos);
|
||||||
@@ -113,12 +113,12 @@ export class SMoveSystem extends ecs.ComblockSystem implements ecs.ISystemUpdate
|
|||||||
node.angle = angle;
|
node.angle = angle;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case RType.fixed:
|
case RType.fixed:
|
||||||
// 固定起始位置
|
// 固定起始位置
|
||||||
node.setPosition(moveComp.startPos.x, node.position.y, 0);
|
node.setPosition(moveComp.startPos.x, node.position.y, 0);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case RType.fixedEnd:
|
case RType.fixedEnd:
|
||||||
// 固定结束位置
|
// 固定结束位置
|
||||||
node.setPosition(moveComp.targetPos.x > 360 ? 300 : moveComp.targetPos.x, moveComp.targetPos.y, 0);
|
node.setPosition(moveComp.targetPos.x > 360 ? 300 : moveComp.targetPos.x, moveComp.targetPos.y, 0);
|
||||||
@@ -154,26 +154,26 @@ export class SMoveSystem extends ecs.ComblockSystem implements ecs.ISystemUpdate
|
|||||||
}
|
}
|
||||||
|
|
||||||
update(entity: ecs.Entity): void {
|
update(entity: ecs.Entity): void {
|
||||||
if(!smc.mission.play ) return;
|
if (!smc.mission.play) return;
|
||||||
if(smc.mission.pause) return
|
if (smc.mission.pause) return
|
||||||
const moveComp = entity.get(SMoveDataComp);
|
const moveComp = entity.get(SMoveDataComp);
|
||||||
const skillView = entity.get(SkillView);
|
const skillView = entity.get(SkillView);
|
||||||
|
|
||||||
if (!moveComp || !skillView || !skillView.node) return;
|
if (!moveComp || !skillView || !skillView.node) return;
|
||||||
|
|
||||||
// 更新移动进度
|
// 更新移动进度
|
||||||
const isMoving = moveComp.updateProgress(this.dt);
|
const isMoving = moveComp.updateProgress(this.dt);
|
||||||
|
|
||||||
if (isMoving) {
|
if (isMoving) {
|
||||||
// 更新节点位置
|
// 更新节点位置
|
||||||
skillView.node.setPosition(moveComp.currentPos);
|
skillView.node.setPosition(moveComp.currentPos);
|
||||||
|
|
||||||
// 处理自动旋转(贝塞尔移动)
|
// 处理自动旋转(贝塞尔移动)
|
||||||
if (moveComp.runType === RType.bezier) {
|
if (moveComp.runType === RType.bezier) {
|
||||||
this.updateRotation(skillView.node, moveComp);
|
this.updateRotation(skillView.node, moveComp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 检查移动完成
|
// 检查移动完成
|
||||||
if (moveComp.isCompleted && moveComp.autoDestroy) {
|
if (moveComp.isCompleted && moveComp.autoDestroy) {
|
||||||
// 根据结束类型决定是否销毁
|
// 根据结束类型决定是否销毁
|
||||||
@@ -185,7 +185,7 @@ export class SMoveSystem extends ecs.ComblockSystem implements ecs.ISystemUpdate
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 更新节点旋转(用于贝塞尔移动)
|
* 更新节点旋转(用于贝塞尔移动)
|
||||||
*/
|
*/
|
||||||
@@ -193,29 +193,29 @@ export class SMoveSystem extends ecs.ComblockSystem implements ecs.ISystemUpdate
|
|||||||
if (moveComp.progress < 1) {
|
if (moveComp.progress < 1) {
|
||||||
// 计算下一帧的位置来确定方向
|
// 计算下一帧的位置来确定方向
|
||||||
const nextProgress = Math.min(moveComp.progress + 0.01, 1);
|
const nextProgress = Math.min(moveComp.progress + 0.01, 1);
|
||||||
const t = moveComp.isAccelerate ?
|
const t = moveComp.isAccelerate ?
|
||||||
(nextProgress * nextProgress * 0.7 + nextProgress * 0.3) :
|
(nextProgress * nextProgress * 0.7 + nextProgress * 0.3) :
|
||||||
nextProgress;
|
nextProgress;
|
||||||
const nextPos = v3(0, 0, 0);
|
const nextPos = v3(0, 0, 0);
|
||||||
|
|
||||||
// 计算下一个位置
|
// 计算下一个位置
|
||||||
const oneMinusT = 1 - t;
|
const oneMinusT = 1 - t;
|
||||||
const oneMinusTSquared = oneMinusT * oneMinusT;
|
const oneMinusTSquared = oneMinusT * oneMinusT;
|
||||||
const tSquared = t * t;
|
const tSquared = t * t;
|
||||||
const twoOneMinusTt = 2 * oneMinusT * t;
|
const twoOneMinusTt = 2 * oneMinusT * t;
|
||||||
|
|
||||||
nextPos.x = oneMinusTSquared * moveComp.startPos.x +
|
nextPos.x = oneMinusTSquared * moveComp.startPos.x +
|
||||||
twoOneMinusTt * moveComp.controlPoint.x +
|
twoOneMinusTt * moveComp.controlPoint.x +
|
||||||
tSquared * moveComp.targetPos.x;
|
tSquared * moveComp.targetPos.x;
|
||||||
|
|
||||||
nextPos.y = oneMinusTSquared * moveComp.startPos.y +
|
nextPos.y = oneMinusTSquared * moveComp.startPos.y +
|
||||||
twoOneMinusTt * moveComp.controlPoint.y +
|
twoOneMinusTt * moveComp.controlPoint.y +
|
||||||
tSquared * moveComp.targetPos.y;
|
tSquared * moveComp.targetPos.y;
|
||||||
|
|
||||||
// 计算方向角度
|
// 计算方向角度
|
||||||
const direction = new Vec3();
|
const direction = new Vec3();
|
||||||
Vec3.subtract(direction, nextPos, moveComp.currentPos);
|
Vec3.subtract(direction, nextPos, moveComp.currentPos);
|
||||||
|
|
||||||
if (direction.length() > 0.01) {
|
if (direction.length() > 0.01) {
|
||||||
let angle = Math.atan2(direction.y, direction.x) * (180 / Math.PI);
|
let angle = Math.atan2(direction.y, direction.x) * (180 / Math.PI);
|
||||||
if (moveComp.scale < 0) {
|
if (moveComp.scale < 0) {
|
||||||
@@ -236,15 +236,15 @@ export class SMoveHelper {
|
|||||||
*/
|
*/
|
||||||
static setupMoveForSkill(entity: ecs.Entity, startPos: Vec3, targetPos: Vec3, s_uuid: number): void {
|
static setupMoveForSkill(entity: ecs.Entity, startPos: Vec3, targetPos: Vec3, s_uuid: number): void {
|
||||||
let moveComp = entity.get(SMoveDataComp);
|
let moveComp = entity.get(SMoveDataComp);
|
||||||
|
|
||||||
if (!moveComp) {
|
if (!moveComp) {
|
||||||
moveComp = entity.add(SMoveDataComp);
|
moveComp = entity.add(SMoveDataComp);
|
||||||
}
|
}
|
||||||
|
|
||||||
moveComp.startPos.set(startPos);
|
moveComp.startPos.set(startPos);
|
||||||
moveComp.targetPos.set(targetPos);
|
moveComp.targetPos.set(targetPos);
|
||||||
moveComp.s_uuid = s_uuid;
|
moveComp.s_uuid = s_uuid;
|
||||||
|
|
||||||
// 从技能配置获取默认参数
|
// 从技能配置获取默认参数
|
||||||
const skillConfig = SkillSet[s_uuid];
|
const skillConfig = SkillSet[s_uuid];
|
||||||
if (skillConfig) {
|
if (skillConfig) {
|
||||||
@@ -253,7 +253,7 @@ export class SMoveHelper {
|
|||||||
if (skillConfig.is_accel) moveComp.isAccelerate = true;
|
if (skillConfig.is_accel) moveComp.isAccelerate = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 检查技能是否正在移动
|
* 检查技能是否正在移动
|
||||||
*/
|
*/
|
||||||
@@ -261,7 +261,7 @@ export class SMoveHelper {
|
|||||||
const moveComp = entity.get(SMoveDataComp);
|
const moveComp = entity.get(SMoveDataComp);
|
||||||
return moveComp ? moveComp.isMoving : false;
|
return moveComp ? moveComp.isMoving : false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取技能移动统计信息
|
* 获取技能移动统计信息
|
||||||
*/
|
*/
|
||||||
@@ -269,7 +269,7 @@ export class SMoveHelper {
|
|||||||
const moveComp = entity.get(SMoveDataComp);
|
const moveComp = entity.get(SMoveDataComp);
|
||||||
return moveComp ? moveComp.getMoveStats() : null;
|
return moveComp ? moveComp.getMoveStats() : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 停止技能移动
|
* 停止技能移动
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -146,7 +146,7 @@ export class Skill extends ecs.Entity {
|
|||||||
if (node.isValid) node.destroy();
|
if (node.isValid) node.destroy();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (config.EType != EType.collision) {
|
if (SView.endType != EType.collision) {
|
||||||
const collider = node.getComponent(BoxCollider2D);
|
const collider = node.getComponent(BoxCollider2D);
|
||||||
if (collider) {
|
if (collider) {
|
||||||
collider.enabled = false
|
collider.enabled = false
|
||||||
@@ -174,8 +174,10 @@ export class Skill extends ecs.Entity {
|
|||||||
sMoveCom.targetPos.set(targetPos);
|
sMoveCom.targetPos.set(targetPos);
|
||||||
sMoveCom.s_uuid = s_uuid;
|
sMoveCom.s_uuid = s_uuid;
|
||||||
sMoveCom.scale = caster.node.scale.x < 0 ? -1 : 1;
|
sMoveCom.scale = caster.node.scale.x < 0 ? -1 : 1;
|
||||||
sMoveCom.runType = config.RType;
|
// runType/endType/speed/time 由 prefab 的 SkillView @property 决定,配置表同名字段仅作兜底
|
||||||
sMoveCom.endType = config.EType;
|
sMoveCom.runType = SView.runType;
|
||||||
|
sMoveCom.endType = SView.endType;
|
||||||
|
sMoveCom.speed = SView.speed > 0 ? SView.speed : config.speed;
|
||||||
sMoveCom.bezierStartHeight = config.bezier_start_y ?? sMoveCom.bezierStartHeight;
|
sMoveCom.bezierStartHeight = config.bezier_start_y ?? sMoveCom.bezierStartHeight;
|
||||||
sMoveCom.bezierMidHeight = config.bezier_mid_y ?? sMoveCom.bezierMidHeight;
|
sMoveCom.bezierMidHeight = config.bezier_mid_y ?? sMoveCom.bezierMidHeight;
|
||||||
sMoveCom.bezierArc = config.bezier_arc ?? sMoveCom.bezierArc;
|
sMoveCom.bezierArc = config.bezier_arc ?? sMoveCom.bezierArc;
|
||||||
@@ -183,12 +185,12 @@ export class Skill extends ecs.Entity {
|
|||||||
sMoveCom.atk_x = SView.atk_x;
|
sMoveCom.atk_x = SView.atk_x;
|
||||||
sMoveCom.atk_y = SView.atk_y;
|
sMoveCom.atk_y = SView.atk_y;
|
||||||
|
|
||||||
if (config.EType === EType.timeEnd) {
|
if (SView.endType === EType.timeEnd) {
|
||||||
let sTimeCom = this.get(StimeDataComp);
|
let sTimeCom = this.get(StimeDataComp);
|
||||||
if (!sTimeCom) sTimeCom = this.add(StimeDataComp);
|
if (!sTimeCom) sTimeCom = this.add(StimeDataComp);
|
||||||
sTimeCom.reset();
|
sTimeCom.reset();
|
||||||
sTimeCom.s_uuid = s_uuid;
|
sTimeCom.s_uuid = s_uuid;
|
||||||
sTimeCom.totalTime = Math.max(1, config.time ?? 0);
|
sTimeCom.totalTime = Math.max(1, SView.time > 0 ? SView.time : (config.time ?? 0));
|
||||||
sTimeCom.hitInterval = Math.max(0.5, config.hitcd || 0);
|
sTimeCom.hitInterval = Math.max(0.5, config.hitcd || 0);
|
||||||
} else {
|
} else {
|
||||||
const sTimeCom = this.get(StimeDataComp);
|
const sTimeCom = this.get(StimeDataComp);
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { _decorator, Animation, CCInteger, Collider2D, Contact2DType, UITransform, v3, Vec3 } from "cc";
|
import { _decorator, Animation, CCFloat, CCInteger, Collider2D, Contact2DType, Enum, UITransform, v3, Vec3 } 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 { HeroViewComp } from "../hero/HeroViewComp";
|
import { HeroViewComp } from "../hero/HeroViewComp";
|
||||||
@@ -22,6 +22,22 @@ export class SkillView extends CCComp {
|
|||||||
@property({ type: CCInteger })
|
@property({ type: CCInteger })
|
||||||
atk_y: number = 0
|
atk_y: number = 0
|
||||||
|
|
||||||
|
/** 运动类型:直线/贝塞尔/固定起点/固定终点(由 prefab 配置,优先级高于 SkillSet) */
|
||||||
|
@property({ type: Enum(RType), tooltip: "技能特效运动类型" })
|
||||||
|
runType: RType = RType.linear;
|
||||||
|
|
||||||
|
/** 消亡条件:动画结束/计时结束/碰撞次数结束(由 prefab 配置,优先级高于 SkillSet) */
|
||||||
|
@property({ type: Enum(EType), tooltip: "技能特效消亡条件" })
|
||||||
|
endType: EType = EType.collision;
|
||||||
|
|
||||||
|
/** 移动速度(由 prefab 配置,<=0 时回退 SkillSet.speed) */
|
||||||
|
@property({ type: CCFloat, slide: true, range: [0, 2000, 10], tooltip: "技能特效移动速度" })
|
||||||
|
speed: number = 0;
|
||||||
|
|
||||||
|
/** timeEnd 持续时间(秒),仅 endType=timeEnd 时生效(由 prefab 配置,<=0 时回退 SkillSet.time) */
|
||||||
|
@property({ type: CCFloat, slide: true, range: [0, 30, 0.1], tooltip: "timeEnd 持续时间(秒)" })
|
||||||
|
time: number = 0;
|
||||||
|
|
||||||
private debugMode: boolean = false;
|
private debugMode: boolean = false;
|
||||||
|
|
||||||
anim: Animation = null;
|
anim: Animation = null;
|
||||||
@@ -45,7 +61,7 @@ export class SkillView extends CCComp {
|
|||||||
this.collider.group = this.group;
|
this.collider.group = this.group;
|
||||||
this.collider.off(Contact2DType.BEGIN_CONTACT, this.onBeginContact, this);
|
this.collider.off(Contact2DType.BEGIN_CONTACT, this.onBeginContact, this);
|
||||||
this.collider.on(Contact2DType.BEGIN_CONTACT, this.onBeginContact, this);
|
this.collider.on(Contact2DType.BEGIN_CONTACT, this.onBeginContact, this);
|
||||||
this.collider.enabled = this.SConf?.EType === EType.collision;
|
this.collider.enabled = this.endType === EType.collision;
|
||||||
}
|
}
|
||||||
if (this.node.getComponent(Animation)) {
|
if (this.node.getComponent(Animation)) {
|
||||||
let anim = this.node.getComponent(Animation);
|
let anim = this.node.getComponent(Animation);
|
||||||
@@ -128,13 +144,13 @@ export class SkillView extends CCComp {
|
|||||||
|
|
||||||
onAnimationFinished() {
|
onAnimationFinished() {
|
||||||
// animationEnd 类型:动画结束后再关闭碰撞并销毁
|
// animationEnd 类型:动画结束后再关闭碰撞并销毁
|
||||||
if (this.SConf.EType == EType.animationEnd) {
|
if (this.endType == EType.animationEnd) {
|
||||||
this.disable_collider_now();
|
this.disable_collider_now();
|
||||||
this.ent.destroy()
|
this.ent.destroy()
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// fixed 类型不移动,无法通过移动完成销毁;动画播完作为兜底销毁时机
|
// fixed 类型不移动,无法通过移动完成销毁;动画播完作为兜底销毁时机
|
||||||
if (this.SConf.RType == RType.fixed) {
|
if (this.runType == RType.fixed) {
|
||||||
this.disable_collider_now();
|
this.disable_collider_now();
|
||||||
this.ent.destroy()
|
this.ent.destroy()
|
||||||
}
|
}
|
||||||
@@ -142,7 +158,7 @@ export class SkillView extends CCComp {
|
|||||||
// 动画帧事件 atk:仅负责开启一帧碰撞窗口,不负责伤害与计数
|
// 动画帧事件 atk:仅负责开启一帧碰撞窗口,不负责伤害与计数
|
||||||
public atk(args: any) {
|
public atk(args: any) {
|
||||||
if (!this.SConf) return;
|
if (!this.SConf) return;
|
||||||
if (this.SConf.EType == EType.collision) return
|
if (this.endType == EType.collision) return
|
||||||
if (this.enable_collider_safely()) {
|
if (this.enable_collider_safely()) {
|
||||||
mLogger.log(this.debugMode, 'SkillView', `[SkillView] [${this.SConf?.name}] 开启碰撞检测`);
|
mLogger.log(this.debugMode, 'SkillView', `[SkillView] [${this.SConf?.name}] 开启碰撞检测`);
|
||||||
this.scheduleOnce(() => {
|
this.scheduleOnce(() => {
|
||||||
|
|||||||
83
tools/sync-skill-prefab.js
Normal file
83
tools/sync-skill-prefab.js
Normal file
@@ -0,0 +1,83 @@
|
|||||||
|
/**
|
||||||
|
* 一次性迁移脚本:把 SkillSet 中的 RType/EType/speed/time 刷入各技能 prefab 的 SkillView 序列化字段。
|
||||||
|
* 用法: node tools/sync-skill-prefab.js
|
||||||
|
* 注意: 直接改写 prefab JSON,运行前请保证工作区已提交。
|
||||||
|
*/
|
||||||
|
const fs = require('fs');
|
||||||
|
const path = require('path');
|
||||||
|
|
||||||
|
const ROOT = path.resolve(__dirname, '..');
|
||||||
|
const SKILL_SET = path.join(ROOT, 'assets/script/game/common/config/SkillSet.ts');
|
||||||
|
const PREFAB_DIR = path.join(ROOT, 'assets/resources/game/skill/atk');
|
||||||
|
// SkillView 组件在 prefab 中的脚本类 cid
|
||||||
|
const SKILL_VIEW_CID = '57aabs7TE1J5obTAZczc+64';
|
||||||
|
|
||||||
|
const RTYPE = { linear: 0, bezier: 1, fixed: 2, fixedEnd: 3 };
|
||||||
|
const ETYPE = { animationEnd: 0, timeEnd: 1, collision: 2 };
|
||||||
|
|
||||||
|
/** 从 SkillSet.ts 解析 sp_name -> {runType, endType, speed, time} */
|
||||||
|
function parseSkillSet(src) {
|
||||||
|
const map = new Map();
|
||||||
|
// 匹配每个技能条目块
|
||||||
|
const entryRe = /\d+:\s*\{([\s\S]*?)\n\s*\},/g;
|
||||||
|
let m;
|
||||||
|
while ((m = entryRe.exec(src)) !== null) {
|
||||||
|
const body = m[1];
|
||||||
|
const sp = body.match(/sp_name:\s*"([^"]+)"/);
|
||||||
|
if (!sp) continue;
|
||||||
|
const spName = sp[1];
|
||||||
|
|
||||||
|
const rt = body.match(/RType:\s*RType\.(\w+)/);
|
||||||
|
const et = body.match(/EType:\s*EType\.(\w+)/);
|
||||||
|
const speed = body.match(/speed:\s*([\d.]+)/);
|
||||||
|
const time = body.match(/\btime:\s*([\d.]+)/);
|
||||||
|
|
||||||
|
const entry = {
|
||||||
|
runType: rt ? RTYPE[rt[1]] : undefined,
|
||||||
|
endType: et ? ETYPE[et[1]] : undefined,
|
||||||
|
speed: speed ? Number(speed[1]) : undefined,
|
||||||
|
time: time ? Number(time[1]) : 0,
|
||||||
|
};
|
||||||
|
// 多个技能可共用同一 sp_name,保留首个非 undefined 组合
|
||||||
|
if (!map.has(spName)) map.set(spName, entry);
|
||||||
|
}
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
|
||||||
|
function main() {
|
||||||
|
const src = fs.readFileSync(SKILL_SET, 'utf8');
|
||||||
|
const confMap = parseSkillSet(src);
|
||||||
|
|
||||||
|
const files = fs.readdirSync(PREFAB_DIR).filter(f => f.endsWith('.prefab'));
|
||||||
|
const report = { updated: [], skipped: [], noConf: [] };
|
||||||
|
|
||||||
|
for (const file of files) {
|
||||||
|
const spName = path.basename(file, '.prefab');
|
||||||
|
const conf = confMap.get(spName);
|
||||||
|
const fp = path.join(PREFAB_DIR, file);
|
||||||
|
const json = JSON.parse(fs.readFileSync(fp, 'utf8'));
|
||||||
|
|
||||||
|
// 定位 SkillView 组件
|
||||||
|
const comp = json.find(o => o && o.__type__ === SKILL_VIEW_CID);
|
||||||
|
if (!comp) { report.skipped.push(file + ' (no SkillView)'); continue; }
|
||||||
|
|
||||||
|
if (!conf) { report.noConf.push(file); continue; }
|
||||||
|
|
||||||
|
if (conf.runType !== undefined) comp.runType = conf.runType;
|
||||||
|
if (conf.endType !== undefined) comp.endType = conf.endType;
|
||||||
|
if (conf.speed !== undefined) comp.speed = conf.speed;
|
||||||
|
comp.time = conf.time ?? 0;
|
||||||
|
|
||||||
|
fs.writeFileSync(fp, JSON.stringify(json, null, 2) + '\n', 'utf8');
|
||||||
|
report.updated.push(`${file} -> runType=${comp.runType} endType=${comp.endType} speed=${comp.speed} time=${comp.time}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log('=== updated ===');
|
||||||
|
report.updated.forEach(s => console.log(' ' + s));
|
||||||
|
console.log('=== no config matched ===');
|
||||||
|
report.noConf.forEach(s => console.log(' ' + s));
|
||||||
|
console.log('=== skipped ===');
|
||||||
|
report.skipped.forEach(s => console.log(' ' + s));
|
||||||
|
}
|
||||||
|
|
||||||
|
main();
|
||||||
Reference in New Issue
Block a user