feat(英雄属性): 新增暴击伤害属性并支持驻场技能加成
- 在 HeroAttrs 枚举中添加 critical_damage 属性 - 修改 HeroAtkSystem 的暴击伤害计算逻辑,支持基础暴伤和英雄额外暴伤叠加 - 在 Skill 类中设置技能属性时,使用 HeroAttrsComp 的运行时属性获取方法 - 为 FieldSkillSet 添加 HeroFrost、HeroCrit、HeroCritDamage 和 HeroSpeed 驻场技能配置 - 在 HeroAttrsComp 中新增 crit_damage 字段和相关运行时属性计算方法 - 实现驻场技能百分比值统一换算逻辑,支持 0.2 和 20 两种配置写法 - 添加攻速加成机制,通过缩短技能 CD 实现攻击速度提升
This commit is contained in:
@@ -23,6 +23,7 @@ export enum Attrs {
|
||||
|
||||
// ==================== 暴击与命中属性 ====================
|
||||
critical = "critical", // 暴击率
|
||||
critical_damage = "critical_damage", // 暴击伤害
|
||||
|
||||
// ==================== 特殊效果属性 ====================
|
||||
freeze_chance = "freeze_chance", // 冰冻概率
|
||||
|
||||
@@ -325,7 +325,7 @@ export const SkillSet: Record<number, SkillConfig> = {
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
//***************驻场技能配置***************
|
||||
export enum FieldSkillType {
|
||||
SummonCount = 1, // 召唤触发技能次数提升
|
||||
DeadCount = 2, // 死亡触发技能次数提升
|
||||
@@ -338,7 +338,7 @@ export enum FieldSkillType {
|
||||
HeroFrost = 9, // 英雄冰冻加成
|
||||
HeroCrit = 10, // 英雄暴击加成
|
||||
HeroCritDamage = 11, // 英雄暴击伤害加成
|
||||
HeroSpeed = 12, // 英雄移动速度加成
|
||||
HeroSpeed = 12, // 英雄攻击速度加成
|
||||
}
|
||||
|
||||
export interface FieldSkillConfig {
|
||||
@@ -358,5 +358,8 @@ export const FieldSkillSet: Record<number, FieldSkillConfig> = {
|
||||
7006: { uuid: 7006, name: t("fskill_name_7006"), type: FieldSkillType.SellGold, value: 5, info: t("fskill_info_7006", 5) },
|
||||
7007: { uuid: 7007, name: t("fskill_name_7007"), type: FieldSkillType.WaveHeal, value: 0.3, info: t("fskill_info_7007", 30) },
|
||||
7008: { uuid: 7008, name: t("fskill_name_7008"), type: FieldSkillType.HeroAtk, value: 0.2, info: t("fskill_info_7008", 20) },
|
||||
7009: { uuid: 7009, name: t("fskill_name_7009"), type: FieldSkillType.HeroFrost, value: 0.1, info: t("fskill_info_7009", 10) },
|
||||
7010: { uuid: 7010, name: t("fskill_name_7010"), type: FieldSkillType.HeroCrit, value: 0.1, info: t("fskill_info_7010", 10) },
|
||||
7011: { uuid: 7011, name: t("fskill_name_7011"), type: FieldSkillType.HeroCritDamage, value: 0.5, info: t("fskill_info_7011", 50) },
|
||||
7012: { uuid: 7012, name: t("fskill_name_7012"), type: FieldSkillType.HeroSpeed, value: 0.2, info: t("fskill_info_7012", 20) },
|
||||
};
|
||||
|
||||
|
||||
@@ -142,7 +142,8 @@ export class HeroAtkSystem extends ecs.ComblockSystem implements ecs.ISystemUpd
|
||||
|
||||
mLogger.log(this.debugMode, 'HeroAtkSystem', " dmgCount",damage)
|
||||
if (isCrit) {
|
||||
damage = Math.floor(damage * (1 + FightSet.CRIT_DAMAGE / 100));
|
||||
const critDamageBonus = damageEvent.Attrs[Attrs.critical_damage] || 0;
|
||||
damage = Math.floor(damage * (1 + (FightSet.CRIT_DAMAGE + critDamageBonus) / 100));
|
||||
reDate.isCrit=true;
|
||||
if (damageEvent.Attrs.fac === FacSet.HERO) {
|
||||
// 【评分系统 - 输出分】统计暴击次数与暴击造成的总伤害
|
||||
|
||||
@@ -9,6 +9,8 @@ import { TalentConfig, TalentType } from "../common/config/TalentSet";
|
||||
@ecs.register('HeroAttrs')
|
||||
export class HeroAttrsComp extends ecs.Comp {
|
||||
public debugMode: boolean = false;
|
||||
private static readonly percentRateThreshold = 1;
|
||||
private static readonly minAttackCd = 0.05;
|
||||
|
||||
Ebus:any=null!
|
||||
// ==================== 角色基础信息 ====================
|
||||
@@ -41,6 +43,7 @@ export class HeroAttrsComp extends ecs.Comp {
|
||||
// ==================== 特殊属性 ====================
|
||||
critical: number = 0; // 暴击率
|
||||
freeze_chance: number = 0; // 冰冻概率
|
||||
crit_damage: number = 0; // 额外暴击伤害
|
||||
puncture: number = 0; // 穿刺次数
|
||||
wfuny: number = 0; // 风怒
|
||||
|
||||
@@ -137,15 +140,16 @@ export class HeroAttrsComp extends ecs.Comp {
|
||||
for (const key in this.skills) {
|
||||
const skill = this.skills[key];
|
||||
if (!skill) continue;
|
||||
if (skill.cd <= 0) {
|
||||
const actualCd = this.getEffectiveSkillCd(skill.uuid);
|
||||
if (actualCd <= 0) {
|
||||
skill.ccd = 0;
|
||||
continue;
|
||||
}
|
||||
if (skill.ccd >= skill.cd) {
|
||||
skill.ccd = skill.cd;
|
||||
if (skill.ccd >= actualCd) {
|
||||
skill.ccd = actualCd;
|
||||
continue;
|
||||
}
|
||||
skill.ccd = Math.min(skill.cd, skill.ccd + dt);
|
||||
skill.ccd = Math.min(actualCd, skill.ccd + dt);
|
||||
}
|
||||
}
|
||||
isFrost(): boolean {
|
||||
@@ -164,8 +168,9 @@ export class HeroAttrsComp extends ecs.Comp {
|
||||
if (!skillId) return false;
|
||||
const skill = this.skills[skillId];
|
||||
if (!skill) return false;
|
||||
if (skill.cd <= 0) return true;
|
||||
return skill.ccd >= skill.cd;
|
||||
const actualCd = this.getEffectiveSkillCd(skillId);
|
||||
if (actualCd <= 0) return true;
|
||||
return skill.ccd >= actualCd;
|
||||
}
|
||||
|
||||
triggerSkillCD(skillId: number) {
|
||||
@@ -178,8 +183,9 @@ export class HeroAttrsComp extends ecs.Comp {
|
||||
getSkillCdProgress(skillId: number): number {
|
||||
if (!skillId) return 1;
|
||||
const skill = this.skills[skillId];
|
||||
if (!skill || skill.cd <= 0) return 1;
|
||||
return Math.max(0, Math.min(1, skill.ccd / skill.cd));
|
||||
const actualCd = this.getEffectiveSkillCd(skillId);
|
||||
if (!skill || actualCd <= 0) return 1;
|
||||
return Math.max(0, Math.min(1, skill.ccd / actualCd));
|
||||
}
|
||||
|
||||
getDisplaySkillCdProgress(): number {
|
||||
@@ -188,6 +194,50 @@ export class HeroAttrsComp extends ecs.Comp {
|
||||
return this.getSkillCdProgress(displaySkillId);
|
||||
}
|
||||
|
||||
/** 将驻场配置值统一换算成百分比数值,兼容 0.2 和 20 两种写法。 */
|
||||
private getFieldPercentValue(type: FieldSkillType): number {
|
||||
const rawValue = HeroAttrsComp.getFieldSkillTotalValue(type);
|
||||
if (Math.abs(rawValue) <= HeroAttrsComp.percentRateThreshold) {
|
||||
return rawValue * 100;
|
||||
}
|
||||
return rawValue;
|
||||
}
|
||||
|
||||
/** 英雄实时暴击率 = 基础暴击率 + 驻场暴击率。 */
|
||||
public getRuntimeCritical(): number {
|
||||
if (this.fac !== FacSet.HERO) return this.critical;
|
||||
return this.critical + this.getFieldPercentValue(FieldSkillType.HeroCrit);
|
||||
}
|
||||
|
||||
/** 英雄实时冰冻率 = 基础冰冻率 + 驻场冰冻率。 */
|
||||
public getRuntimeFreezeChance(): number {
|
||||
if (this.fac !== FacSet.HERO) return this.freeze_chance;
|
||||
return this.freeze_chance + this.getFieldPercentValue(FieldSkillType.HeroFrost);
|
||||
}
|
||||
|
||||
/** 英雄实时暴击伤害 = 基础额外暴伤 + 驻场暴伤。 */
|
||||
public getRuntimeCritDamageBonus(): number {
|
||||
if (this.fac !== FacSet.HERO) return this.crit_damage;
|
||||
return this.crit_damage + this.getFieldPercentValue(FieldSkillType.HeroCritDamage);
|
||||
}
|
||||
|
||||
/** 攻速加成通过缩短普通攻击技能 CD 生效,正值越高,攻击越快。 */
|
||||
public getRuntimeAttackSpeedBonus(): number {
|
||||
if (this.fac !== FacSet.HERO) return 0;
|
||||
return this.getFieldPercentValue(FieldSkillType.HeroSpeed);
|
||||
}
|
||||
|
||||
/** 根据攻速加成换算实际攻击间隔,避免直接改写配置里的基础 CD。 */
|
||||
public getEffectiveSkillCd(skillId: number): number {
|
||||
const skill = this.skills[skillId];
|
||||
if (!skill) return 0;
|
||||
if (skill.cd <= 0) return 0;
|
||||
const speedBonus = this.getRuntimeAttackSpeedBonus();
|
||||
if (speedBonus <= 0) return skill.cd;
|
||||
const speedRate = 1 + speedBonus / 100;
|
||||
return Math.max(HeroAttrsComp.minAttackCd, skill.cd / speedRate);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// ==================== 技能距离缓存管理 ====================
|
||||
@@ -245,6 +295,7 @@ export class HeroAttrsComp extends ecs.Comp {
|
||||
this.revive = undefined;
|
||||
this.critical = 0;
|
||||
this.freeze_chance = 0;
|
||||
this.crit_damage = 0;
|
||||
this.revived_count = 0;
|
||||
this.invincible_time = 0;
|
||||
this.puncture = 0;
|
||||
|
||||
@@ -213,8 +213,9 @@ export class Skill extends ecs.Entity {
|
||||
const sAp =config.ap+(SUp.ap*skill_lv);
|
||||
const sHit=config.hit_count+(SUp.hit_count*skill_lv) + cAttrsComp.puncture
|
||||
sDataCom.Attrs[Attrs.ap] = Math.floor(cAttrsComp.ap*sAp/100); //技能的ap是百分值 需要/100 而且需要再最终计算总ap时再/100,不然会出现ap为90%变0
|
||||
sDataCom.Attrs[Attrs.critical] = cAttrsComp.critical + sCrt;
|
||||
sDataCom.Attrs[Attrs.freeze_chance] = cAttrsComp.freeze_chance + sFrz;
|
||||
sDataCom.Attrs[Attrs.critical] = cAttrsComp.getRuntimeCritical() + sCrt;
|
||||
sDataCom.Attrs[Attrs.critical_damage] = cAttrsComp.getRuntimeCritDamageBonus();
|
||||
sDataCom.Attrs[Attrs.freeze_chance] = cAttrsComp.getRuntimeFreezeChance() + sFrz;
|
||||
sDataCom.s_uuid=s_uuid
|
||||
sDataCom.skill_lv = Math.max(0, skill_lv);
|
||||
sDataCom.fac=cAttrsComp.fac
|
||||
|
||||
Reference in New Issue
Block a user