去掉伤害系统
This commit is contained in:
@@ -1,6 +1,5 @@
|
|||||||
import { ecs } from "../../../../extensions/oops-plugin-framework/assets/libs/ecs/ECS";
|
import { ecs } from "../../../../extensions/oops-plugin-framework/assets/libs/ecs/ECS";
|
||||||
import { BattleStateComp } from "./BattleStateComp";
|
import { BattleStateComp } from "./BattleStateComp";
|
||||||
import { DamageResult } from "../damage/DamageComp";
|
|
||||||
import { HeroViewComp } from "../hero/HeroViewComp";
|
import { HeroViewComp } from "../hero/HeroViewComp";
|
||||||
import { HeroSkillsComp } from "../skill/heroSkillsComp";
|
import { HeroSkillsComp } from "../skill/heroSkillsComp";
|
||||||
import { HCardComp } from "../map/HCardComp";
|
import { HCardComp } from "../map/HCardComp";
|
||||||
@@ -25,11 +24,9 @@ export class BattleEndSystem extends ecs.ComblockSystem {
|
|||||||
|
|
||||||
private cleanComponents() {
|
private cleanComponents() {
|
||||||
console.log("cleanComponents");
|
console.log("cleanComponents");
|
||||||
console.log("DamageResult",ecs.query(ecs.allOf(DamageResult)));
|
|
||||||
console.log("HCardComp",ecs.query(ecs.allOf(HCardComp)));
|
console.log("HCardComp",ecs.query(ecs.allOf(HCardComp)));
|
||||||
console.log("HeroSkillsComp",ecs.query(ecs.allOf(HeroSkillsComp)));
|
console.log("HeroSkillsComp",ecs.query(ecs.allOf(HeroSkillsComp)));
|
||||||
console.log("HeroViewComp",ecs.query(ecs.allOf(HeroViewComp)));
|
console.log("HeroViewComp",ecs.query(ecs.allOf(HeroViewComp)));
|
||||||
ecs.query(ecs.allOf(DamageResult)).forEach(entity => entity.remove(DamageResult));
|
|
||||||
ecs.query(ecs.allOf(HCardComp)).forEach(entity => entity.remove(HCardComp));
|
ecs.query(ecs.allOf(HCardComp)).forEach(entity => entity.remove(HCardComp));
|
||||||
ecs.query(ecs.allOf(HeroSkillsComp)).forEach(entity => entity.remove(HeroSkillsComp));
|
ecs.query(ecs.allOf(HeroSkillsComp)).forEach(entity => entity.remove(HeroSkillsComp));
|
||||||
ecs.query(ecs.allOf(HeroViewComp)).forEach(entity => entity.remove(HeroViewComp));
|
ecs.query(ecs.allOf(HeroViewComp)).forEach(entity => entity.remove(HeroViewComp));
|
||||||
|
|||||||
@@ -1,9 +0,0 @@
|
|||||||
{
|
|
||||||
"ver": "1.2.0",
|
|
||||||
"importer": "directory",
|
|
||||||
"imported": true,
|
|
||||||
"uuid": "d2e9b2e7-c86a-4c47-b030-bb7ae1d38fad",
|
|
||||||
"files": [],
|
|
||||||
"subMetas": {},
|
|
||||||
"userData": {}
|
|
||||||
}
|
|
||||||
@@ -1,48 +0,0 @@
|
|||||||
import { Vec3 } from "cc";
|
|
||||||
import { ecs } from "../../../../extensions/oops-plugin-framework/assets/libs/ecs/ECS";
|
|
||||||
|
|
||||||
export enum DamageType {
|
|
||||||
Physical = 1,
|
|
||||||
Magic = 2,
|
|
||||||
True = 3
|
|
||||||
}
|
|
||||||
|
|
||||||
/** 伤害请求组件 */
|
|
||||||
@ecs.register('DamageRequest')
|
|
||||||
export class DamageRequest extends ecs.Comp {
|
|
||||||
source!: ecs.Entity; // 伤害来源
|
|
||||||
target!: ecs.Entity; // 伤害目标
|
|
||||||
baseValue!: number; // 基础伤害值
|
|
||||||
damageType: number = 1; // 伤害类型
|
|
||||||
canCrit: boolean = true; // 是否可暴击
|
|
||||||
ignoreDefense: boolean = false; // 是否忽略防御
|
|
||||||
delay: number = 0; // 新增延迟时间属性
|
|
||||||
|
|
||||||
reset() {
|
|
||||||
this.source = null!;
|
|
||||||
this.target = null!;
|
|
||||||
this.baseValue = 0;
|
|
||||||
this.damageType = 1;
|
|
||||||
this.canCrit = true;
|
|
||||||
this.ignoreDefense = false;
|
|
||||||
this.delay = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/** 伤害结果组件 */
|
|
||||||
@ecs.register('DamageResult')
|
|
||||||
export class DamageResult extends ecs.Comp {
|
|
||||||
value: number = 0; // 伤害数值
|
|
||||||
isCrit: boolean = false; // 是否暴击
|
|
||||||
isDodged: boolean = false; // 是否闪避
|
|
||||||
delay: number = 0; // 显示延迟(秒)
|
|
||||||
position: Vec3 = new Vec3();// 显示位置
|
|
||||||
|
|
||||||
reset() {
|
|
||||||
this.value = 0;
|
|
||||||
this.isCrit = false;
|
|
||||||
this.isDodged = false;
|
|
||||||
this.delay = 0;
|
|
||||||
this.position.set(0, 0, 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
{
|
|
||||||
"ver": "4.0.23",
|
|
||||||
"importer": "typescript",
|
|
||||||
"imported": true,
|
|
||||||
"uuid": "5dc13d0b-967b-4378-89d0-35322998b506",
|
|
||||||
"files": [],
|
|
||||||
"subMetas": {},
|
|
||||||
"userData": {}
|
|
||||||
}
|
|
||||||
@@ -1,114 +0,0 @@
|
|||||||
import { oops } from "db://oops-framework/core/Oops";
|
|
||||||
import { ecs } from "../../../../extensions/oops-plugin-framework/assets/libs/ecs/ECS";
|
|
||||||
import { HeroViewComp } from "../hero/HeroViewComp";
|
|
||||||
import { DamageRequest, DamageResult } from "./DamageComp";
|
|
||||||
|
|
||||||
@ecs.register('DamageSystem')
|
|
||||||
export class DamageSystem extends ecs.ComblockSystem implements ecs.ISystemUpdate {
|
|
||||||
private _timers: { [key: string]: number } = {};
|
|
||||||
|
|
||||||
filter(): ecs.IMatcher {
|
|
||||||
return ecs.allOf(DamageRequest);
|
|
||||||
}
|
|
||||||
|
|
||||||
update(e: ecs.Entity) {
|
|
||||||
const req = e.get(DamageRequest);
|
|
||||||
const result = this.calculateDamage(req);
|
|
||||||
this.applyDamage(req.target, result);
|
|
||||||
e.remove(DamageRequest);
|
|
||||||
}
|
|
||||||
|
|
||||||
private calculateDamage(req: DamageRequest): DamageResult {
|
|
||||||
const targetView = req.target.get(HeroViewComp);
|
|
||||||
const sourceView = req.source.get(HeroViewComp);
|
|
||||||
let final = req.baseValue;
|
|
||||||
|
|
||||||
// 伤害浮动(±10%)
|
|
||||||
const damageFloat = 0.9 + Math.random() * 0.2; // 0.9~1.1
|
|
||||||
final *= damageFloat;
|
|
||||||
final = Math.round(final);
|
|
||||||
|
|
||||||
// 闪避判定
|
|
||||||
if (Math.random()*100 < targetView.dodge) {
|
|
||||||
const result = new DamageResult();
|
|
||||||
result.isDodged = true;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 护甲减伤
|
|
||||||
if (!req.ignoreDefense) {
|
|
||||||
const effectiveArmor = Math.min(targetView.def, 300); // 最大减伤75%
|
|
||||||
const damageReduction = effectiveArmor / (effectiveArmor + 100);
|
|
||||||
final *= (1 - damageReduction);
|
|
||||||
final = Math.round(final); // 四舍五入取整
|
|
||||||
}
|
|
||||||
|
|
||||||
// 暴击判定
|
|
||||||
let isCrit = false;
|
|
||||||
if (req.canCrit) {
|
|
||||||
const critRate = sourceView.crit;
|
|
||||||
if (Math.random() * 100 < critRate) {
|
|
||||||
final *= 1.5;
|
|
||||||
isCrit = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const result = new DamageResult();
|
|
||||||
result.value = Math.max(1, final); // 确保最小伤害为1
|
|
||||||
result.isCrit = isCrit;
|
|
||||||
result.position = req.target.get(HeroViewComp).node.position;
|
|
||||||
result.delay = req.delay;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
private applyDamage(target: ecs.Entity, result: DamageResult) {
|
|
||||||
const view = target.get(HeroViewComp);
|
|
||||||
if (!view.ent.has(HeroViewComp)) return;
|
|
||||||
this.scheduleOnce(()=>{
|
|
||||||
// 护盾优先吸收伤害
|
|
||||||
let remainingDamage = result.value;
|
|
||||||
if(result.isDodged){
|
|
||||||
view.BUFFCOMP.tooltip(5,"*闪避*");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (view.shield > 0) {
|
|
||||||
const shieldAbsorb = Math.min(view.shield, remainingDamage);
|
|
||||||
view.shield -= shieldAbsorb;
|
|
||||||
remainingDamage -= shieldAbsorb;
|
|
||||||
|
|
||||||
if (view.shield <= 0) {
|
|
||||||
view.BUFFCOMP.show_shield(false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 剩余伤害扣除血量
|
|
||||||
if (remainingDamage > 0) {
|
|
||||||
view.hp -= remainingDamage;
|
|
||||||
view.showDamage(result.value, result.isCrit);
|
|
||||||
}else{
|
|
||||||
view.BUFFCOMP.tooltip(5,"*吸收*");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}, result.delay)
|
|
||||||
|
|
||||||
// 直接触发事件
|
|
||||||
oops.message.dispatchEvent("OnDamage", {
|
|
||||||
target,
|
|
||||||
damage: result.value,
|
|
||||||
isCrit: result.isCrit
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private scheduleOnce(callback: () => void, delay: number) {
|
|
||||||
const timer = setTimeout(() => {
|
|
||||||
callback();
|
|
||||||
delete this._timers[timer];
|
|
||||||
}, delay * 1000);
|
|
||||||
this._timers[timer] = timer;
|
|
||||||
}
|
|
||||||
|
|
||||||
onDestroy() {
|
|
||||||
Object.values(this._timers).forEach(clearTimeout);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
{
|
|
||||||
"ver": "4.0.23",
|
|
||||||
"importer": "typescript",
|
|
||||||
"imported": true,
|
|
||||||
"uuid": "5e0fcfaa-f9b3-43b6-8584-5a55940c89e0",
|
|
||||||
"files": [],
|
|
||||||
"subMetas": {},
|
|
||||||
"userData": {}
|
|
||||||
}
|
|
||||||
@@ -1,6 +1,5 @@
|
|||||||
import { ecs } from "../../../../extensions/oops-plugin-framework/assets/libs/ecs/ECS";
|
import { ecs } from "../../../../extensions/oops-plugin-framework/assets/libs/ecs/ECS";
|
||||||
import { HeroSkillSystem } from "./HeroSkillSystem";
|
import { HeroSkillSystem } from "./HeroSkillSystem";
|
||||||
import { DamageSystem } from "../damage/DamageSystem";
|
|
||||||
import { BattleEndSystem } from "../battle/BattleEndSystem";
|
import { BattleEndSystem } from "../battle/BattleEndSystem";
|
||||||
import { BattleStartSystem } from "../battle/BattleStartSystem";
|
import { BattleStartSystem } from "../battle/BattleStartSystem";
|
||||||
import { BattlePhaseSystem } from "../battle/BattlePhaseSystem";
|
import { BattlePhaseSystem } from "../battle/BattlePhaseSystem";
|
||||||
@@ -8,7 +7,6 @@ export class EcsSkillSystem extends ecs.System {
|
|||||||
constructor() {
|
constructor() {
|
||||||
super();
|
super();
|
||||||
this.add(new HeroSkillSystem());
|
this.add(new HeroSkillSystem());
|
||||||
this.add(new DamageSystem());
|
|
||||||
this.add(new BattleStartSystem());
|
this.add(new BattleStartSystem());
|
||||||
this.add(new BattlePhaseSystem());
|
this.add(new BattlePhaseSystem());
|
||||||
this.add(new BattleEndSystem());
|
this.add(new BattleEndSystem());
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import { HeroViewComp } from "../hero/HeroViewComp";
|
|||||||
import { HeroSkillsComp } from "./heroSkillsComp";
|
import { HeroSkillsComp } from "./heroSkillsComp";
|
||||||
import { SkillSet, TargetGroup, TargetType } from "../common/config/SkillSet";
|
import { SkillSet, TargetGroup, TargetType } from "../common/config/SkillSet";
|
||||||
import { CdType } from "../common/config/SkillSet";
|
import { CdType } from "../common/config/SkillSet";
|
||||||
import { DamageRequest, DamageType } from "../../game/damage/DamageComp";
|
import { oops } from "db://oops-framework/core/Oops";
|
||||||
|
|
||||||
|
|
||||||
/** 技能系统 */
|
/** 技能系统 */
|
||||||
@@ -12,6 +12,7 @@ import { DamageRequest, DamageType } from "../../game/damage/DamageComp";
|
|||||||
export class HeroSkillSystem extends ecs.ComblockSystem implements ecs.ISystemUpdate {
|
export class HeroSkillSystem extends ecs.ComblockSystem implements ecs.ISystemUpdate {
|
||||||
private updateInterval: number = 0.1; // 每0.1秒更新一次
|
private updateInterval: number = 0.1; // 每0.1秒更新一次
|
||||||
private accumulator: number = 0;
|
private accumulator: number = 0;
|
||||||
|
private _timers: { [key: string]: number } = {};
|
||||||
|
|
||||||
filter(): ecs.IMatcher {
|
filter(): ecs.IMatcher {
|
||||||
return ecs.allOf(HeroSkillsComp, HeroViewComp);
|
return ecs.allOf(HeroSkillsComp, HeroViewComp);
|
||||||
@@ -32,7 +33,6 @@ export class HeroSkillSystem extends ecs.ComblockSystem implements ecs.ISystemUp
|
|||||||
skills.skills.forEach(skillId => {
|
skills.skills.forEach(skillId => {
|
||||||
this.updateCooldown(skills, skillId);
|
this.updateCooldown(skills, skillId);
|
||||||
});
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 处理所有技能逻辑 */
|
/** 处理所有技能逻辑 */
|
||||||
@@ -197,17 +197,117 @@ export class HeroSkillSystem extends ecs.ComblockSystem implements ecs.ISystemUp
|
|||||||
|
|
||||||
/** 应用技能效果 */
|
/** 应用技能效果 */
|
||||||
private applySkillEffect(caster: ecs.Entity, target: ecs.Entity, config: typeof SkillSet[keyof typeof SkillSet]) {
|
private applySkillEffect(caster: ecs.Entity, target: ecs.Entity, config: typeof SkillSet[keyof typeof SkillSet]) {
|
||||||
// 创建伤害请求实体
|
const casterView = caster.get(HeroViewComp);
|
||||||
const damageEntity = new ecs.Entity();
|
const targetView = target.get(HeroViewComp);
|
||||||
const req = damageEntity.add(DamageRequest);
|
|
||||||
req.source = caster;
|
// 直接计算伤害(包含防御减免)
|
||||||
req.target = target;
|
const damageResult = this.calculateDamage(caster, target, config);
|
||||||
req.baseValue = caster.get(HeroViewComp).ap * (config.ap / 100);
|
this.applyDamage(target, damageResult);
|
||||||
req.delay = config.hited; // 添加命中延迟时间(秒)用于同步动画与伤害
|
|
||||||
|
|
||||||
// 播放技能特效
|
// 播放技能特效
|
||||||
caster.get(HeroViewComp).playSkillEffect(config.uuid);
|
casterView.playSkillEffect(config.uuid);
|
||||||
console.log(caster.get(HeroViewComp).hero_name+"技能反馈"+"=>"+req.target.get(HeroViewComp).hero_name+":"+req.baseValue)
|
console.log(`${casterView.hero_name} 对 ${targetView.hero_name} 造成 ${damageResult.value}伤害`);
|
||||||
|
}
|
||||||
|
|
||||||
|
private calculateDamage(caster: ecs.Entity, target: ecs.Entity, config: typeof SkillSet[keyof typeof SkillSet]) {
|
||||||
|
const result = {
|
||||||
|
value :0, // 确保最小伤害为1
|
||||||
|
isCrit : false,
|
||||||
|
isDodged : false,
|
||||||
|
delay : 0.3,
|
||||||
|
ignoreDefense : false,
|
||||||
|
canCrit : true,
|
||||||
|
}
|
||||||
|
|
||||||
|
const targetView =target.get(HeroViewComp);
|
||||||
|
const sourceView =caster.get(HeroViewComp);
|
||||||
|
let final = sourceView.ap*config.ap/100;
|
||||||
|
|
||||||
|
// 伤害浮动(±10%)
|
||||||
|
const damageFloat = 0.9 + Math.random() * 0.2; // 0.9~1.1
|
||||||
|
final *= damageFloat;
|
||||||
|
final = Math.round(final);
|
||||||
|
|
||||||
|
|
||||||
|
// 闪避判定
|
||||||
|
if (Math.random()*100 < targetView.dodge) {
|
||||||
|
result.isDodged = true
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
// 护甲减伤
|
||||||
|
if (!result.ignoreDefense) {
|
||||||
|
const effectiveArmor = Math.min(targetView.def, 300); // 最大减伤75%
|
||||||
|
const damageReduction = effectiveArmor / (effectiveArmor + 100);
|
||||||
|
final *= (1 - damageReduction);
|
||||||
|
final = Math.round(final); // 四舍五入取整
|
||||||
|
}
|
||||||
|
|
||||||
|
// 暴击判定
|
||||||
|
let isCrit = false;
|
||||||
|
if (result.canCrit) {
|
||||||
|
const critRate = sourceView.crit;
|
||||||
|
if (Math.random() * 100 < critRate) {
|
||||||
|
final *= 1.5;
|
||||||
|
isCrit = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
result.value = Math.max(1, final); // 确保最小伤害为1
|
||||||
|
result.isCrit = isCrit;
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private applyDamage(target: ecs.Entity, result:any) {
|
||||||
|
const view = target.get(HeroViewComp);
|
||||||
|
if (!view.ent.has(HeroViewComp)) return;
|
||||||
|
this.scheduleOnce(()=>{
|
||||||
|
// 护盾优先吸收伤害
|
||||||
|
let remainingDamage = result.value;
|
||||||
|
if(result.isDodged){
|
||||||
|
view.BUFFCOMP.tooltip(5,"*闪避*");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (view.shield > 0) {
|
||||||
|
const shieldAbsorb = Math.min(view.shield, remainingDamage);
|
||||||
|
view.shield -= shieldAbsorb;
|
||||||
|
remainingDamage -= shieldAbsorb;
|
||||||
|
|
||||||
|
if (view.shield <= 0) {
|
||||||
|
view.BUFFCOMP.show_shield(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 剩余伤害扣除血量
|
||||||
|
if (remainingDamage > 0) {
|
||||||
|
view.hp -= remainingDamage;
|
||||||
|
view.showDamage(result.value, result.isCrit);
|
||||||
|
}else{
|
||||||
|
view.BUFFCOMP.tooltip(5,"*吸收*");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}, result.delay)
|
||||||
|
|
||||||
|
// 直接触发事件
|
||||||
|
oops.message.dispatchEvent("OnDamage", {
|
||||||
|
target,
|
||||||
|
damage: result.value,
|
||||||
|
isCrit: result.isCrit
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private scheduleOnce(callback: () => void, delay: number) {
|
||||||
|
const timer = setTimeout(() => {
|
||||||
|
callback();
|
||||||
|
delete this._timers[timer];
|
||||||
|
}, delay * 1000);
|
||||||
|
this._timers[timer] = timer;
|
||||||
|
}
|
||||||
|
|
||||||
|
onDestroy() {
|
||||||
|
Object.values(this._timers).forEach(clearTimeout);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 应用负面状态 */
|
/** 应用负面状态 */
|
||||||
|
|||||||
Reference in New Issue
Block a user