去掉伤害系统
This commit is contained in:
@@ -1,6 +1,5 @@
|
||||
import { ecs } from "../../../../extensions/oops-plugin-framework/assets/libs/ecs/ECS";
|
||||
import { BattleStateComp } from "./BattleStateComp";
|
||||
import { DamageResult } from "../damage/DamageComp";
|
||||
import { HeroViewComp } from "../hero/HeroViewComp";
|
||||
import { HeroSkillsComp } from "../skill/heroSkillsComp";
|
||||
import { HCardComp } from "../map/HCardComp";
|
||||
@@ -25,11 +24,9 @@ export class BattleEndSystem extends ecs.ComblockSystem {
|
||||
|
||||
private cleanComponents() {
|
||||
console.log("cleanComponents");
|
||||
console.log("DamageResult",ecs.query(ecs.allOf(DamageResult)));
|
||||
console.log("HCardComp",ecs.query(ecs.allOf(HCardComp)));
|
||||
console.log("HeroSkillsComp",ecs.query(ecs.allOf(HeroSkillsComp)));
|
||||
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(HeroSkillsComp)).forEach(entity => entity.remove(HeroSkillsComp));
|
||||
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 { HeroSkillSystem } from "./HeroSkillSystem";
|
||||
import { DamageSystem } from "../damage/DamageSystem";
|
||||
import { BattleEndSystem } from "../battle/BattleEndSystem";
|
||||
import { BattleStartSystem } from "../battle/BattleStartSystem";
|
||||
import { BattlePhaseSystem } from "../battle/BattlePhaseSystem";
|
||||
@@ -8,7 +7,6 @@ export class EcsSkillSystem extends ecs.System {
|
||||
constructor() {
|
||||
super();
|
||||
this.add(new HeroSkillSystem());
|
||||
this.add(new DamageSystem());
|
||||
this.add(new BattleStartSystem());
|
||||
this.add(new BattlePhaseSystem());
|
||||
this.add(new BattleEndSystem());
|
||||
|
||||
@@ -4,7 +4,7 @@ import { HeroViewComp } from "../hero/HeroViewComp";
|
||||
import { HeroSkillsComp } from "./heroSkillsComp";
|
||||
import { SkillSet, TargetGroup, TargetType } 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 {
|
||||
private updateInterval: number = 0.1; // 每0.1秒更新一次
|
||||
private accumulator: number = 0;
|
||||
private _timers: { [key: string]: number } = {};
|
||||
|
||||
filter(): ecs.IMatcher {
|
||||
return ecs.allOf(HeroSkillsComp, HeroViewComp);
|
||||
@@ -32,7 +33,6 @@ export class HeroSkillSystem extends ecs.ComblockSystem implements ecs.ISystemUp
|
||||
skills.skills.forEach(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]) {
|
||||
// 创建伤害请求实体
|
||||
const damageEntity = new ecs.Entity();
|
||||
const req = damageEntity.add(DamageRequest);
|
||||
req.source = caster;
|
||||
req.target = target;
|
||||
req.baseValue = caster.get(HeroViewComp).ap * (config.ap / 100);
|
||||
req.delay = config.hited; // 添加命中延迟时间(秒)用于同步动画与伤害
|
||||
const casterView = caster.get(HeroViewComp);
|
||||
const targetView = target.get(HeroViewComp);
|
||||
|
||||
// 直接计算伤害(包含防御减免)
|
||||
const damageResult = this.calculateDamage(caster, target, config);
|
||||
this.applyDamage(target, damageResult);
|
||||
|
||||
// 播放技能特效
|
||||
caster.get(HeroViewComp).playSkillEffect(config.uuid);
|
||||
console.log(caster.get(HeroViewComp).hero_name+"技能反馈"+"=>"+req.target.get(HeroViewComp).hero_name+":"+req.baseValue)
|
||||
casterView.playSkillEffect(config.uuid);
|
||||
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