Compare commits
2 Commits
d759689269
...
e1c37eb510
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e1c37eb510 | ||
|
|
2d11246838 |
@@ -46,7 +46,6 @@ export enum CardTriggerType {
|
|||||||
Interval = 2, // 定时循环:战斗中按 t_inv 间隔重复触发
|
Interval = 2, // 定时循环:战斗中按 t_inv 间隔重复触发
|
||||||
Field = 3, // 驻场光环(俗称「装备」):被动生效,由 field 数组驱动,支持单卡多词条
|
Field = 3, // 驻场光环(俗称「装备」):被动生效,由 field 数组驱动,支持单卡多词条
|
||||||
FightStart = 4, // 战斗开始时触发
|
FightStart = 4, // 战斗开始时触发
|
||||||
FightEnd = 5, // 战斗结束时触发(每回合结束)
|
|
||||||
HeroDead = 6, // 场上己方英雄死亡时触发
|
HeroDead = 6, // 场上己方英雄死亡时触发
|
||||||
HeroCall = 7, // 英雄上场时触发(主角召唤 + 技能召唤 + 复活)
|
HeroCall = 7, // 英雄上场时触发(主角召唤 + 技能召唤 + 复活)
|
||||||
}
|
}
|
||||||
@@ -78,7 +77,7 @@ export interface CardConfig {
|
|||||||
/** 触发类型(必填,技能卡专用;功能卡/英雄卡可缺省) */
|
/** 触发类型(必填,技能卡专用;功能卡/英雄卡可缺省) */
|
||||||
trigger_type?: CardTriggerType;
|
trigger_type?: CardTriggerType;
|
||||||
/**
|
/**
|
||||||
* 事件型触发的全局次数上限(仅 FightStart/FightEnd/HeroDead/HeroCall 有效)
|
* 事件型触发的全局次数上限(仅 FightStart/HeroDead/HeroCall 有效)
|
||||||
* 默认 Infinity;达到上限后销毁节点
|
* 默认 Infinity;达到上限后销毁节点
|
||||||
* 注意:与 t_times 语义不同——t_times 控制每回合内 Interval 的次数
|
* 注意:与 t_times 语义不同——t_times 控制每回合内 Interval 的次数
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -79,7 +79,6 @@ const EquipRawList: EquipRawData[] = [
|
|||||||
{ uuid: 8811, card_lv: 3, icon: "Wand-FA_WP_Main_Wand_004_WoodGold", name: "召唤强化", info: "召唤触发技能次数+1", field: [{ uuid: 7014, value: 1 }] },
|
{ uuid: 8811, card_lv: 3, icon: "Wand-FA_WP_Main_Wand_004_WoodGold", name: "召唤强化", info: "召唤触发技能次数+1", field: [{ uuid: 7014, value: 1 }] },
|
||||||
{ uuid: 8812, card_lv: 3, icon: "Staff-FA_WP_Main_Staff_005_WoodGold", name: "死亡强化", info: "死亡触发技能次数+1", field: [{ uuid: 7015, value: 1 }] },
|
{ uuid: 8812, card_lv: 3, icon: "Staff-FA_WP_Main_Staff_005_WoodGold", name: "死亡强化", info: "死亡触发技能次数+1", field: [{ uuid: 7015, value: 1 }] },
|
||||||
{ uuid: 8813, card_lv: 3, icon: "Spear-FA_WP_Main_Spear_008_GrayGold", name: "开场强化", info: "战斗开始触发技能次数+1", field: [{ uuid: 7016, value: 1 }] },
|
{ uuid: 8813, card_lv: 3, icon: "Spear-FA_WP_Main_Spear_008_GrayGold", name: "开场强化", info: "战斗开始触发技能次数+1", field: [{ uuid: 7016, value: 1 }] },
|
||||||
{ uuid: 8814, card_lv: 3, icon: "Blunt-FA_WP_Main_Blunt_006_OrangeGray", name: "结束强化", info: "战斗结束触发技能次数+1", field: [{ uuid: 7017, value: 1 }] },
|
|
||||||
{ uuid: 8815, card_lv: 3, icon: "Sword-FA_WP_Main_Sword_001_Gold", name: "攻击强化", info: "攻击触发技能次数+1", field: [{ uuid: 7018, value: 1 }] },
|
{ uuid: 8815, card_lv: 3, icon: "Sword-FA_WP_Main_Sword_001_Gold", name: "攻击强化", info: "攻击触发技能次数+1", field: [{ uuid: 7018, value: 1 }] },
|
||||||
{ uuid: 8816, card_lv: 3, icon: "Shield-FA_WP_Sub_Shield_009_RedGold", name: "受击强化", info: "被攻击触发技能次数+1", field: [{ uuid: 7019, value: 1 }] },
|
{ uuid: 8816, card_lv: 3, icon: "Shield-FA_WP_Sub_Shield_009_RedGold", name: "受击强化", info: "被攻击触发技能次数+1", field: [{ uuid: 7019, value: 1 }] },
|
||||||
// 多词条装备
|
// 多词条装备
|
||||||
|
|||||||
@@ -36,7 +36,6 @@ export enum GameEvent {
|
|||||||
FightStart = "FightStart",
|
FightStart = "FightStart",
|
||||||
FightPause = "FightPause",
|
FightPause = "FightPause",
|
||||||
FightResume = "FightResume",
|
FightResume = "FightResume",
|
||||||
FightEnd = "FightEnd",
|
|
||||||
MissionEnd = "MissionEnd",
|
MissionEnd = "MissionEnd",
|
||||||
MissionComplete = "MissionComplete",//战斗结算完成
|
MissionComplete = "MissionComplete",//战斗结算完成
|
||||||
HeroSkillSelect = "HeroSkillSelect",
|
HeroSkillSelect = "HeroSkillSelect",
|
||||||
|
|||||||
@@ -45,7 +45,6 @@ export interface ISkillDescSource {
|
|||||||
call?: TriggerGrouped;
|
call?: TriggerGrouped;
|
||||||
dead?: TriggerGrouped;
|
dead?: TriggerGrouped;
|
||||||
fstart?: TriggerGrouped;
|
fstart?: TriggerGrouped;
|
||||||
fend?: TriggerGrouped;
|
|
||||||
atking?: TriggerGrouped;
|
atking?: TriggerGrouped;
|
||||||
atked?: TriggerGrouped;
|
atked?: TriggerGrouped;
|
||||||
field?: LvFieldEntry[];
|
field?: LvFieldEntry[];
|
||||||
@@ -85,7 +84,6 @@ const TRIGGER_KEYS: SkillTriggerType[] = [
|
|||||||
SkillTriggerType.Call,
|
SkillTriggerType.Call,
|
||||||
SkillTriggerType.Dead,
|
SkillTriggerType.Dead,
|
||||||
SkillTriggerType.FStart,
|
SkillTriggerType.FStart,
|
||||||
SkillTriggerType.FEnd,
|
|
||||||
SkillTriggerType.Atking,
|
SkillTriggerType.Atking,
|
||||||
SkillTriggerType.Atked,
|
SkillTriggerType.Atked,
|
||||||
];
|
];
|
||||||
|
|||||||
@@ -287,7 +287,6 @@ export const FieldDescSet: Record<number, FieldDescConfig> = {
|
|||||||
[FieldSkillType.SummonCount]: { verb: "召唤触发技能次数", fmt: FieldValueFmt.Int },
|
[FieldSkillType.SummonCount]: { verb: "召唤触发技能次数", fmt: FieldValueFmt.Int },
|
||||||
[FieldSkillType.DeadCount]: { verb: "死亡触发技能次数", fmt: FieldValueFmt.Int },
|
[FieldSkillType.DeadCount]: { verb: "死亡触发技能次数", fmt: FieldValueFmt.Int },
|
||||||
[FieldSkillType.StartCount]: { verb: "战斗开始触发技能次数", fmt: FieldValueFmt.Int },
|
[FieldSkillType.StartCount]: { verb: "战斗开始触发技能次数", fmt: FieldValueFmt.Int },
|
||||||
[FieldSkillType.EndCount]: { verb: "战斗结束触发技能次数", fmt: FieldValueFmt.Int },
|
|
||||||
[FieldSkillType.WaveGold]: { verb: "每回合金币收益", fmt: FieldValueFmt.Int },
|
[FieldSkillType.WaveGold]: { verb: "每回合金币收益", fmt: FieldValueFmt.Int },
|
||||||
[FieldSkillType.SellGold]: { verb: "卖出英雄金币", fmt: FieldValueFmt.Int },
|
[FieldSkillType.SellGold]: { verb: "卖出英雄金币", fmt: FieldValueFmt.Int },
|
||||||
[FieldSkillType.WaveHeal]: { verb: "战斗结束生命回复量", fmt: FieldValueFmt.Percent },
|
[FieldSkillType.WaveHeal]: { verb: "战斗结束生命回复量", fmt: FieldValueFmt.Percent },
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
// ========== 从 HeroAttrs.ts 导入属性相关定义 ==========
|
// ========== 从 HeroAttrs.ts 导入属性相关定义 ==========
|
||||||
import { Attrs } from "./HeroAttrs";
|
import { Attrs } from "./HeroAttrs";
|
||||||
|
|
||||||
export enum HSSet {
|
export enum HSSet {
|
||||||
@@ -460,7 +460,6 @@ export enum FieldSkillType {
|
|||||||
SummonCount = 1, // 召唤触发技能次数提升
|
SummonCount = 1, // 召唤触发技能次数提升
|
||||||
DeadCount = 2, // 死亡触发技能次数提升
|
DeadCount = 2, // 死亡触发技能次数提升
|
||||||
StartCount = 3, // 战斗开始触发技能次数提升
|
StartCount = 3, // 战斗开始触发技能次数提升
|
||||||
EndCount = 4, // 战斗结束触发技能次数提升
|
|
||||||
WaveGold = 5, // 每回合金币收益提升
|
WaveGold = 5, // 每回合金币收益提升
|
||||||
SellGold = 6, // 卖出英雄金币提升
|
SellGold = 6, // 卖出英雄金币提升
|
||||||
WaveHeal = 7, // 战斗结束生命回复量提升
|
WaveHeal = 7, // 战斗结束生命回复量提升
|
||||||
@@ -515,7 +514,6 @@ export const FieldSkillSet: Record<number, FieldSkillConfig> = {
|
|||||||
7014: { uuid: 7014, name: "召唤强化", icon: "Stat_UnitSummonIncrease_02", type: FieldSkillType.SummonCount, info: "召唤触发技能次数提升" },
|
7014: { uuid: 7014, name: "召唤强化", icon: "Stat_UnitSummonIncrease_02", type: FieldSkillType.SummonCount, info: "召唤触发技能次数提升" },
|
||||||
7015: { uuid: 7015, name: "死亡强化", icon: "Stat_PoisonChanceIncrease", type: FieldSkillType.DeadCount, info: "死亡触发技能次数提升" },
|
7015: { uuid: 7015, name: "死亡强化", icon: "Stat_PoisonChanceIncrease", type: FieldSkillType.DeadCount, info: "死亡触发技能次数提升" },
|
||||||
7016: { uuid: 7016, name: "开场强化", icon: "Stat_AttackRangeIncrease_01", type: FieldSkillType.StartCount, info: "战斗开始触发技能次数提升" },
|
7016: { uuid: 7016, name: "开场强化", icon: "Stat_AttackRangeIncrease_01", type: FieldSkillType.StartCount, info: "战斗开始触发技能次数提升" },
|
||||||
7017: { uuid: 7017, name: "结束强化", icon: "Stat_UnitSummonIncrease_01", type: FieldSkillType.EndCount, info: "战斗结束触发技能次数提升" },
|
|
||||||
7018: { uuid: 7018, name: "攻击强化", icon: "Stat_Attack_03", type: FieldSkillType.AtkCount, info: "攻击触发技能次数提升" },
|
7018: { uuid: 7018, name: "攻击强化", icon: "Stat_Attack_03", type: FieldSkillType.AtkCount, info: "攻击触发技能次数提升" },
|
||||||
7019: { uuid: 7019, name: "受击强化", icon: "Stat_Armor_01", type: FieldSkillType.BeAtkCount, info: "被攻击触发技能次数提升" },
|
7019: { uuid: 7019, name: "受击强化", icon: "Stat_Armor_01", type: FieldSkillType.BeAtkCount, info: "被攻击触发技能次数提升" },
|
||||||
7020: { uuid: 7020, name: "穿透强化", icon: "Stat_Tripleshot", type: FieldSkillType.HeroPunctureDmg, info: "英雄穿透后伤害提升(百分点)" },
|
7020: { uuid: 7020, name: "穿透强化", icon: "Stat_Tripleshot", type: FieldSkillType.HeroPunctureDmg, info: "英雄穿透后伤害提升(百分点)" },
|
||||||
|
|||||||
@@ -164,7 +164,6 @@ export enum SkillTriggerType {
|
|||||||
Call = "call", // 召唤后触发 降临
|
Call = "call", // 召唤后触发 降临
|
||||||
Dead = "dead", // 死亡后触发 遗志
|
Dead = "dead", // 死亡后触发 遗志
|
||||||
FStart = "fstart", // 战斗开始 先手
|
FStart = "fstart", // 战斗开始 先手
|
||||||
FEnd = "fend", // 战斗结束 终战
|
|
||||||
Field = "field", // 驻场 光环
|
Field = "field", // 驻场 光环
|
||||||
Atking = "atking", // 攻击后触发 追击
|
Atking = "atking", // 攻击后触发 追击
|
||||||
Atked = "atked", // 受击后触发 反击
|
Atked = "atked", // 受击后触发 反击
|
||||||
@@ -175,7 +174,6 @@ export const SkillTriggerName = {
|
|||||||
[SkillTriggerType.Call]: "召唤",
|
[SkillTriggerType.Call]: "召唤",
|
||||||
[SkillTriggerType.Dead]: "死亡后",
|
[SkillTriggerType.Dead]: "死亡后",
|
||||||
[SkillTriggerType.FStart]: "回合开始",
|
[SkillTriggerType.FStart]: "回合开始",
|
||||||
[SkillTriggerType.FEnd]: "回合结束",
|
|
||||||
[SkillTriggerType.Field]: "光环",
|
[SkillTriggerType.Field]: "光环",
|
||||||
[SkillTriggerType.Atking]: "攻击",
|
[SkillTriggerType.Atking]: "攻击",
|
||||||
[SkillTriggerType.Atked]: "受伤",
|
[SkillTriggerType.Atked]: "受伤",
|
||||||
@@ -186,7 +184,6 @@ export const SkillTriggerDesc = {
|
|||||||
[SkillTriggerType.Call]: "召唤时",
|
[SkillTriggerType.Call]: "召唤时",
|
||||||
[SkillTriggerType.Dead]: "死亡时",
|
[SkillTriggerType.Dead]: "死亡时",
|
||||||
[SkillTriggerType.FStart]: "战斗开始时",
|
[SkillTriggerType.FStart]: "战斗开始时",
|
||||||
[SkillTriggerType.FEnd]: "战斗结束时",
|
|
||||||
[SkillTriggerType.Field]: "光环",
|
[SkillTriggerType.Field]: "光环",
|
||||||
[SkillTriggerType.Atking]: "攻击n次",
|
[SkillTriggerType.Atking]: "攻击n次",
|
||||||
[SkillTriggerType.Atked]: "受伤n次",
|
[SkillTriggerType.Atked]: "受伤n次",
|
||||||
@@ -298,7 +295,6 @@ export interface heroInfo {
|
|||||||
[SkillTriggerType.Call]?: TriggerGrouped; // 召唤后触发的技能配置(按 s_uuid 分组,每组按 lv 升序)
|
[SkillTriggerType.Call]?: TriggerGrouped; // 召唤后触发的技能配置(按 s_uuid 分组,每组按 lv 升序)
|
||||||
[SkillTriggerType.Dead]?: TriggerGrouped; // 死亡后触发的技能配置
|
[SkillTriggerType.Dead]?: TriggerGrouped; // 死亡后触发的技能配置
|
||||||
[SkillTriggerType.FStart]?: TriggerGrouped; // 战斗开始时释放的技能配置
|
[SkillTriggerType.FStart]?: TriggerGrouped; // 战斗开始时释放的技能配置
|
||||||
[SkillTriggerType.FEnd]?: TriggerGrouped; // 战斗结束时释放的技能配置
|
|
||||||
[SkillTriggerType.Field]?: LvFieldEntry[]; // 驻场光环(按 lv 升序,运行时取 ≤英雄等级 的最大档)
|
[SkillTriggerType.Field]?: LvFieldEntry[]; // 驻场光环(按 lv 升序,运行时取 ≤英雄等级 的最大档)
|
||||||
[SkillTriggerType.Atking]?: TriggerGrouped; // 普通攻击后触发的技能配置,s_uuid: 技能id, t_num: 触发所需的普攻次数
|
[SkillTriggerType.Atking]?: TriggerGrouped; // 普通攻击后触发的技能配置,s_uuid: 技能id, t_num: 触发所需的普攻次数
|
||||||
[SkillTriggerType.Atked]?: TriggerGrouped; // 受击后触发的技能配置,s_uuid: 技能id, t_num: 触发所需的受击次数
|
[SkillTriggerType.Atked]?: TriggerGrouped; // 受击后触发的技能配置,s_uuid: 技能id, t_num: 触发所需的受击次数
|
||||||
@@ -938,7 +934,7 @@ export const HeroComboList: number[] = [8001, 8002, 8003, 8004, 8005, 8006];
|
|||||||
* - W_HP: 每 1 点生命值折算 1 分(生命值不随时间变化)
|
* - W_HP: 每 1 点生命值折算 1 分(生命值不随时间变化)
|
||||||
* - W_DPS_PER_SEC: 每 1 点 DPS 持续 1 秒折算 0.5 分
|
* - W_DPS_PER_SEC: 每 1 点 DPS 持续 1 秒折算 0.5 分
|
||||||
* (默认 60 秒评估窗下,1 DPS ≈ 30 分,与旧版 W_DPS=30 等效)
|
* (默认 60 秒评估窗下,1 DPS ≈ 30 分,与旧版 W_DPS=30 等效)
|
||||||
* - WAVE_DURATION / HITS_PER_WAVE: 回合参数,用于估算 atked/fstart/fend/dead 触发次数
|
* - WAVE_DURATION / HITS_PER_WAVE: 回合参数,用于估算 atked/fstart/dead 触发次数
|
||||||
* - DEFAULT_EVAL_SECONDS: calcHeroPower 默认使用的评估时间窗
|
* - DEFAULT_EVAL_SECONDS: calcHeroPower 默认使用的评估时间窗
|
||||||
*/
|
*/
|
||||||
export const HERO_POWER_WEIGHTS = {
|
export const HERO_POWER_WEIGHTS = {
|
||||||
@@ -947,7 +943,6 @@ export const HERO_POWER_WEIGHTS = {
|
|||||||
W_atking: 1.0,
|
W_atking: 1.0,
|
||||||
W_atked: 0.8,
|
W_atked: 0.8,
|
||||||
W_fstart: 1.0,
|
W_fstart: 1.0,
|
||||||
W_fend: 1.2,
|
|
||||||
W_dead: 0.6,
|
W_dead: 0.6,
|
||||||
W_field_alive: 1.0,
|
W_field_alive: 1.0,
|
||||||
W_revive: 1.0,
|
W_revive: 1.0,
|
||||||
@@ -1071,7 +1066,6 @@ function getTriggerCount(
|
|||||||
case SkillTriggerType.Atked:
|
case SkillTriggerType.Atked:
|
||||||
return getHitCount(seconds) / t_num;
|
return getHitCount(seconds) / t_num;
|
||||||
case SkillTriggerType.FStart:
|
case SkillTriggerType.FStart:
|
||||||
case SkillTriggerType.FEnd:
|
|
||||||
return getWaveCount(seconds);
|
return getWaveCount(seconds);
|
||||||
case SkillTriggerType.Dead:
|
case SkillTriggerType.Dead:
|
||||||
return getWaveCount(seconds) * (1 + (resolveReviveByLv(hero.revive, FightSet.HERO_MAX_LV)?.r_num || 0));
|
return getWaveCount(seconds) * (1 + (resolveReviveByLv(hero.revive, FightSet.HERO_MAX_LV)?.r_num || 0));
|
||||||
@@ -1203,7 +1197,6 @@ export interface HeroPowerBreakdown {
|
|||||||
atking: number;
|
atking: number;
|
||||||
atked: number;
|
atked: number;
|
||||||
fstart: number;
|
fstart: number;
|
||||||
fend: number;
|
|
||||||
dead: number;
|
dead: number;
|
||||||
field: number;
|
field: number;
|
||||||
revive: number;
|
revive: number;
|
||||||
@@ -1218,7 +1211,7 @@ export interface HeroPowerDetailed {
|
|||||||
normalAttack: { s_uuid: number, name: string, cd: number, dps: number, value: number };
|
normalAttack: { s_uuid: number, name: string, cd: number, dps: number, value: number };
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 计算普通触发类技能(atking/atked/fstart/fend/dead)的详细价值 */
|
/** 计算普通触发类技能(atking/atked/fstart/dead)的详细价值 */
|
||||||
function calcTriggerPowerDetailed(
|
function calcTriggerPowerDetailed(
|
||||||
triggerConfigs: { s_uuid: number, t_num?: number, overrides?: SkillOverrides }[],
|
triggerConfigs: { s_uuid: number, t_num?: number, overrides?: SkillOverrides }[],
|
||||||
hero: heroInfo,
|
hero: heroInfo,
|
||||||
@@ -1252,9 +1245,6 @@ function calcTriggerPowerDetailed(
|
|||||||
case SkillTriggerType.FStart:
|
case SkillTriggerType.FStart:
|
||||||
weight = weights.W_fstart;
|
weight = weights.W_fstart;
|
||||||
break;
|
break;
|
||||||
case SkillTriggerType.FEnd:
|
|
||||||
weight = weights.W_fend;
|
|
||||||
break;
|
|
||||||
case SkillTriggerType.Dead:
|
case SkillTriggerType.Dead:
|
||||||
weight = weights.W_dead;
|
weight = weights.W_dead;
|
||||||
break;
|
break;
|
||||||
@@ -1351,7 +1341,6 @@ export function calcHeroPowerDetailed(hero: heroInfo, targetLv: number = 1, seco
|
|||||||
const atking = hero.atking ? calcTriggerPowerDetailed(resolveTriggerByLv(hero.atking, targetLv), hero, targetLv, SkillTriggerType.Atking, seconds) : { total: 0, items: [] as TriggerSkillEval[] };
|
const atking = hero.atking ? calcTriggerPowerDetailed(resolveTriggerByLv(hero.atking, targetLv), hero, targetLv, SkillTriggerType.Atking, seconds) : { total: 0, items: [] as TriggerSkillEval[] };
|
||||||
const atked = hero.atked ? calcTriggerPowerDetailed(resolveTriggerByLv(hero.atked, targetLv), hero, targetLv, SkillTriggerType.Atked, seconds) : { total: 0, items: [] as TriggerSkillEval[] };
|
const atked = hero.atked ? calcTriggerPowerDetailed(resolveTriggerByLv(hero.atked, targetLv), hero, targetLv, SkillTriggerType.Atked, seconds) : { total: 0, items: [] as TriggerSkillEval[] };
|
||||||
const fstart = hero.fstart ? calcTriggerPowerDetailed(resolveTriggerByLv(hero.fstart, targetLv), hero, targetLv, SkillTriggerType.FStart, seconds) : { total: 0, items: [] as TriggerSkillEval[] };
|
const fstart = hero.fstart ? calcTriggerPowerDetailed(resolveTriggerByLv(hero.fstart, targetLv), hero, targetLv, SkillTriggerType.FStart, seconds) : { total: 0, items: [] as TriggerSkillEval[] };
|
||||||
const fend = hero.fend ? calcTriggerPowerDetailed(resolveTriggerByLv(hero.fend, targetLv), hero, targetLv, SkillTriggerType.FEnd, seconds) : { total: 0, items: [] as TriggerSkillEval[] };
|
|
||||||
const dead = hero.dead ? calcTriggerPowerDetailed(resolveTriggerByLv(hero.dead, targetLv), hero, targetLv, SkillTriggerType.Dead, seconds) : { total: 0, items: [] as TriggerSkillEval[] };
|
const dead = hero.dead ? calcTriggerPowerDetailed(resolveTriggerByLv(hero.dead, targetLv), hero, targetLv, SkillTriggerType.Dead, seconds) : { total: 0, items: [] as TriggerSkillEval[] };
|
||||||
const fieldEntries = resolveFieldByLv(hero.field, targetLv);
|
const fieldEntries = resolveFieldByLv(hero.field, targetLv);
|
||||||
const field = fieldEntries.length > 0 ? calcFieldPowerDetailed(fieldEntries, hero, targetLv, seconds) : { total: 0, items: [] as FieldSkillEval[] };
|
const field = fieldEntries.length > 0 ? calcFieldPowerDetailed(fieldEntries, hero, targetLv, seconds) : { total: 0, items: [] as FieldSkillEval[] };
|
||||||
@@ -1362,7 +1351,7 @@ export function calcHeroPowerDetailed(hero: heroInfo, targetLv: number = 1, seco
|
|||||||
reviveValue = hpEff * revive.upr * revive.r_num * weights.W_revive * getWaveCount(seconds);
|
reviveValue = hpEff * revive.upr * revive.r_num * weights.W_revive * getWaveCount(seconds);
|
||||||
}
|
}
|
||||||
|
|
||||||
const total = hpValue + dpsValue + atking.total + atked.total + fstart.total + fend.total + dead.total + field.total + reviveValue;
|
const total = hpValue + dpsValue + atking.total + atked.total + fstart.total + dead.total + field.total + reviveValue;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
total,
|
total,
|
||||||
@@ -1372,12 +1361,11 @@ export function calcHeroPowerDetailed(hero: heroInfo, targetLv: number = 1, seco
|
|||||||
atking: atking.total,
|
atking: atking.total,
|
||||||
atked: atked.total,
|
atked: atked.total,
|
||||||
fstart: fstart.total,
|
fstart: fstart.total,
|
||||||
fend: fend.total,
|
|
||||||
dead: dead.total,
|
dead: dead.total,
|
||||||
field: field.total,
|
field: field.total,
|
||||||
revive: reviveValue,
|
revive: reviveValue,
|
||||||
},
|
},
|
||||||
triggerSkills: [...atking.items, ...atked.items, ...fstart.items, ...fend.items, ...dead.items],
|
triggerSkills: [...atking.items, ...atked.items, ...fstart.items, ...dead.items],
|
||||||
fieldSkills: field.items,
|
fieldSkills: field.items,
|
||||||
normalAttack,
|
normalAttack,
|
||||||
};
|
};
|
||||||
|
|||||||
361
assets/script/game/common/config/几何王国技能复刻方案.md
Normal file
361
assets/script/game/common/config/几何王国技能复刻方案.md
Normal file
@@ -0,0 +1,361 @@
|
|||||||
|
# 几何王国技能复刻设计文档
|
||||||
|
|
||||||
|
> **目的**:基于《几何王国》热门英雄技能,分析哪些可以**零代码改动**或**最小改动**复刻到本系统(1 回合定生死机制)。
|
||||||
|
>
|
||||||
|
> **前置约束**(已确认的设计原则):
|
||||||
|
> - 局内固定 lv=1,等级成长移交局外
|
||||||
|
> - 单场战斗 30 秒
|
||||||
|
> - card_lv 纯技能数量差异(1~5 个技能槽)
|
||||||
|
> - 技能触发极简(`t_num=1`),高频高数值
|
||||||
|
> - 无相同能力英雄,无阵容限制
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 一、本系统可复用的"触发骨架"
|
||||||
|
|
||||||
|
| 触发类型 | 枚举 | 语义 | 几何王国对应场景 |
|
||||||
|
|---|---|---|---|
|
||||||
|
| 战斗开始 | `SkillTriggerType.FStart` | 入场时触发 1 次 | 战吼、入场护盾 |
|
||||||
|
| 战斗结束 | `SkillTriggerType.FEnd` | 战斗胜利后触发 | (30s 短局意义弱) |
|
||||||
|
| 召唤入场 | `SkillTriggerType.Call` | 落地触发 1 次 | 登场技 |
|
||||||
|
| 死亡触发 | `SkillTriggerType.Dead` | 死亡时触发 1 次 | 亡语、遗志 |
|
||||||
|
| 攻击触发 | `SkillTriggerType.Atking` | 普攻 N 次触发 | 概率普攻特效(t_num 模拟概率) |
|
||||||
|
| 受击触发 | `SkillTriggerType.Atked` | 被击 N 次触发 | 受击反击、叠甲 |
|
||||||
|
| 驻场光环 | `SkillTriggerType.Field` | 存活期间全局生效 | 光环类(移速/攻击/回血) |
|
||||||
|
| 复活 | `SkillTriggerType.Revive` | 死亡后复活 | 凤凰涅槃、尸骸存活 |
|
||||||
|
|
||||||
|
> **概率模拟技巧**:本系统无"概率触发"概念,用 `t_num` 计数模拟。
|
||||||
|
> - `t_num=1`:每次普攻都触发(最高频)
|
||||||
|
> - `t_num=3`:≈33% 概率
|
||||||
|
> - `t_num=4`:≈25% 概率(对应几何王国的"30% 概率")
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 二、本系统可复用的"效果骨架"
|
||||||
|
|
||||||
|
### 2.1 SkillKind(技能主效果)
|
||||||
|
|
||||||
|
| 类型 | 字段 | 几何王国对应 |
|
||||||
|
|---|---|---|
|
||||||
|
| `SkillKind.Damage` | `ap` 百分比伤害 | 大招、战技伤害 |
|
||||||
|
| `SkillKind.Heal` | `ap` 治疗量 | 治疗、吸血 |
|
||||||
|
| `SkillKind.Shield` | `ap` 护盾层数(数值减免) | 暗光之盾、守护壁垒 |
|
||||||
|
| `SkillKind.Support` | `buff_type` + `timed_buff_id` | 属性强化、限时增益 |
|
||||||
|
| `SkillKind.Gold` | `gold` 金币数 | (本局不适用) |
|
||||||
|
|
||||||
|
### 2.2 击杀特效字段
|
||||||
|
|
||||||
|
| 字段 | 含义 | 几何王国对应 |
|
||||||
|
|---|---|---|
|
||||||
|
| `crt` | 额外暴击率 | 致命一击 |
|
||||||
|
| `frz` | 额外冰冻概率 | 寒冰攻击 |
|
||||||
|
| `stun` | 额外击晕概率 | 眩晕 |
|
||||||
|
| `bck` | 击退距离增量 | 击退(雷霆一击、剑刃风暴) |
|
||||||
|
| `hit_count` | 命中目标数 | 多段攻击(乱棍、剑刃风暴) |
|
||||||
|
| `puncture_chance` | 穿透概率 | 穿透(暗器大师) |
|
||||||
|
|
||||||
|
### 2.3 BuffList 已有 DoT / HoT / 控制
|
||||||
|
|
||||||
|
| Buff ID | 名称 | 类型 | 几何王国对应 |
|
||||||
|
|---|---|---|---|
|
||||||
|
| 7002 | 灼烧 | Debuff DoT(-10 伤害/0.5s,吃 30% 攻击加成) | 剧毒利刃、火系持续伤害 |
|
||||||
|
| 7003 | 冰冻 | Control(2s) | 冰冻 |
|
||||||
|
| 7004 | 击晕 | Control(2s) | 眩晕、沉默(替代) |
|
||||||
|
| 7010 | 再生 | Buff HoT(+10 治疗/0.5s) | 持续回血 |
|
||||||
|
| 7011 | 攻击爆发 | Buff(+50% 攻击 5s) | 大圣归来、剑圣 1 觉 |
|
||||||
|
| 7012 | 暴击爆发 | Buff(+30% 暴击 5s) | 暴击强化 |
|
||||||
|
| 7017 | 击晕爆发 | Buff(+30% 击晕 5s) | 群体眩晕强化 |
|
||||||
|
| 7111 | 战前强攻 | Buff(+30 攻击 5s) | 开场增益 |
|
||||||
|
|
||||||
|
### 2.4 FieldSkillType 已有光环
|
||||||
|
|
||||||
|
| 类型 | 几何王国对应 |
|
||||||
|
|---|---|
|
||||||
|
| `HeroAtk` | 攻击光环(人鱼公主、邪恶光环) |
|
||||||
|
| `HeroCrit` / `HeroCritDamage` | 暴击光环 |
|
||||||
|
| `HeroSpeed` | 攻速光环 |
|
||||||
|
| `HeroHp` | 生命光环 |
|
||||||
|
| `HeroStun` / `HeroWindFury` / `HeroPuncture` | 特殊光环 |
|
||||||
|
| `WaveHeal` | 战后回血(30s 短局可改为局内 HoT) |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 三、可直接复刻(零代码改动)
|
||||||
|
|
||||||
|
> 仅通过 `heroSet.ts` 配置 + 复用现有 SkillSet / BuffList 即可实现。
|
||||||
|
|
||||||
|
### 3.1 剧毒女王(Mage,复刻"深渊女王·剧毒利刃")
|
||||||
|
|
||||||
|
**核心机制**:普攻触发灼烧 DoT,叠加毒伤害。
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
[SkillTriggerType.Atking]: {
|
||||||
|
// 每次普攻上灼烧 DoT(已存在 BuffList 7002)
|
||||||
|
6101: [{ lv: 1, t_num: 1, overrides: { timed_buff_id: 7002, buff_duration: 5 } }],
|
||||||
|
},
|
||||||
|
```
|
||||||
|
|
||||||
|
**复刻自**:深渊女王·剧毒利刃(普攻 30% 概率 200% 法伤 + 减益)。
|
||||||
|
**适配调整**:30s 战斗节奏快,`t_num=1` 100% 触发,但单层 DoT 数值调低以平衡。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 3.2 猴王·乱棍(Assassin,复刻"至尊宝·大圣归来")
|
||||||
|
|
||||||
|
**核心机制**:普攻触发多段伤害+击晕。
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
[SkillTriggerType.Atking]: {
|
||||||
|
// 每次普攻触发 4 段 30% 伤害 + 高击晕
|
||||||
|
6006: [{ lv: 1, t_num: 1, overrides: { ap: 30, hit_count: 4, stun: 30 } }],
|
||||||
|
},
|
||||||
|
```
|
||||||
|
|
||||||
|
**复刻自**:至尊宝·大圣归来(乱棍 4 次 ×30% 物伤 + 眩晕)。
|
||||||
|
**适配调整**:去除"召唤虚影+攻击+25%"(与本系统能量体系冲突),保留多段+击晕核心。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 3.3 剑圣·疾风(Warrior,复刻"剑圣·剑刃风暴+吸血面罩")
|
||||||
|
|
||||||
|
**核心机制**:高伤范围 + 击退 + 普攻吸血。
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
[SkillTriggerType.Atking]: {
|
||||||
|
// 普攻触发 360% 范围伤害 + 击退
|
||||||
|
6201: [{ lv: 1, t_num: 1, overrides: { ap: 150, bck: 30 } }],
|
||||||
|
// 普攻吸血 35%
|
||||||
|
6302: [{ lv: 1, t_num: 1, overrides: { TGroup: TGroup.Self, ap: 35 } }],
|
||||||
|
},
|
||||||
|
```
|
||||||
|
|
||||||
|
**复刻自**:剑圣·剑刃风暴(360% 物伤 + 击退) + 吸血面罩(普攻 35% 吸血)。
|
||||||
|
**适配调整**:`t_num=1` 高频触发,单场 30s 内吸血量需调平衡。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 3.4 壁垒贤者(Support,复刻"哀木涕·守护壁垒")
|
||||||
|
|
||||||
|
**核心机制**:开场全队护盾 + 驻场生命光环。
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
[SkillTriggerType.FStart]: {
|
||||||
|
// 开场全队护盾(数值减免型)
|
||||||
|
6301: [{ lv: 1, t_num: 1, overrides: { TGroup: TGroup.Team, ap: 5 } }],
|
||||||
|
},
|
||||||
|
[SkillTriggerType.Field]: [
|
||||||
|
// 驻场生命光环
|
||||||
|
{ lv: 1, s_uuid: 7007, value: 15 }, // +15% 最大生命
|
||||||
|
],
|
||||||
|
```
|
||||||
|
|
||||||
|
**复刻自**:哀木涕·守护壁垒(开场 10% 最大生命护盾 + 防御光环)。
|
||||||
|
**适配调整**:本系统护盾是"数值减免"非"层数",ap 字段意义不同,需重新校准数值。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 3.5 凤凰祭司(Warrior,复刻"死亡守护 + 复活")
|
||||||
|
|
||||||
|
**核心机制**:死亡时为最低血友军回血 + 自身可复活。
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
[SkillTriggerType.Dead]: {
|
||||||
|
// 死亡守护:死亡时为最低血友军回血
|
||||||
|
6302: [{ lv: 1, t_num: 1, overrides: { ap: 50 } }],
|
||||||
|
},
|
||||||
|
[SkillTriggerType.Revive]: [
|
||||||
|
// 复活:死亡后 1 次 50% 血复活
|
||||||
|
{ lv: 1, s_uuid: 6501, r_num: 1, upr: 50 },
|
||||||
|
],
|
||||||
|
```
|
||||||
|
|
||||||
|
**复刻自**:通用觉醒·死亡守护(10% 最大生命回血) + 黑暗骑士 3 觉(尸骸存活)。
|
||||||
|
**适配调整**:30s 战斗中复活价值高,`r_num=1` 限定 1 次。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 3.6 暗影骑士(Tank,复刻"黑暗骑士·死亡缠绕")
|
||||||
|
|
||||||
|
**核心机制**:普攻治疗血少友军 + 受击反击自盾。
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
[SkillTriggerType.Atking]: {
|
||||||
|
// 普攻触发治疗(自动选血量最低友方,引擎已支持)
|
||||||
|
6302: [{ lv: 1, t_num: 1, overrides: { ap: 220 } }],
|
||||||
|
},
|
||||||
|
[SkillTriggerType.Atked]: {
|
||||||
|
// 受击触发自身护盾
|
||||||
|
6301: [{ lv: 1, t_num: 1, overrides: { TGroup: TGroup.Self, ap: 3 } }],
|
||||||
|
},
|
||||||
|
```
|
||||||
|
|
||||||
|
**复刻自**:黑暗骑士·死亡缠绕(普攻 25% 概率 220% 真伤/治疗友方)。
|
||||||
|
**适配调整**:本系统暂无"真伤",用高治疗量替代。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 3.7 风暴歌者(Mage,复刻"深渊女王·超声波")
|
||||||
|
|
||||||
|
**核心机制**:范围伤害 + 群体击退。
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
[SkillTriggerType.Atking]: {
|
||||||
|
// 范围伤害 + 群体击退
|
||||||
|
6201: [{ lv: 1, t_num: 1, overrides: { ap: 200, bck: 50, hit_count: 6 } }],
|
||||||
|
},
|
||||||
|
```
|
||||||
|
|
||||||
|
**复刻自**:深渊女王·超声波(伤害 + 击退控制)。
|
||||||
|
**适配调整**:`bck` 字段直接对应击退距离增量,无需新增机制。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 3.8 战吼先锋(Warrior,复刻"光明骑士·光明守护")
|
||||||
|
|
||||||
|
**核心机制**:开场全队增益 + 持续回血。
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
[SkillTriggerType.FStart]: {
|
||||||
|
// 开场全队攻击强化
|
||||||
|
6401: [{ lv: 1, t_num: 1, overrides: { ap: 30 } }],
|
||||||
|
// 开场全队持续回血
|
||||||
|
6502: [{ lv: 1, t_num: 1, overrides: { timed_buff_id: 7010, buff_duration: 10 } }],
|
||||||
|
},
|
||||||
|
```
|
||||||
|
|
||||||
|
**复刻自**:光明骑士·光明守护(清异常 + 加防 + 持续治疗)。
|
||||||
|
**适配调整**:本系统无"解控"概念,30s 战斗也不需要,改为纯增益 + HoT。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 四、需要小幅扩展即可复刻
|
||||||
|
|
||||||
|
### 4.1 反伤罗刹(Tank,复刻"剑豪·罗生门")
|
||||||
|
|
||||||
|
**缺失机制**:本系统无"反伤"属性。
|
||||||
|
|
||||||
|
**扩展方案**:
|
||||||
|
1. `HeroAttrs.ts` 的 `Attrs` 枚举新增 `thorns = "thorns"`(反伤数值)
|
||||||
|
2. `HeroAttrsComp.ts` 新增字段 `thorns: number = 0`
|
||||||
|
3. 战斗结算时,受击方对攻击者造成 `thorns` 点固定伤害
|
||||||
|
4. `SkillConfig` 新增 `thorns?: number` 用于 Support 技能附加反伤 buff
|
||||||
|
|
||||||
|
**复刻配置**:
|
||||||
|
```typescript
|
||||||
|
[SkillTriggerType.Atked]: {
|
||||||
|
// 受击触发护盾 + 反伤 buff(5s 内反伤 30 点)
|
||||||
|
6301: [{ lv: 1, t_num: 1, overrides: { ap: 5 } }],
|
||||||
|
6401: [{ lv: 1, t_num: 1, overrides: { buff_type: Attrs.thorns, timed_buff_id: 7030 } }],
|
||||||
|
},
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 4.2 真伤刺客(Assassin,复刻"玉面狐妖·真伤")
|
||||||
|
|
||||||
|
**缺失机制**:本系统伤害公式只支持 `ap × 系数`,无"按目标最大生命百分比伤害"。
|
||||||
|
|
||||||
|
**扩展方案**:
|
||||||
|
1. `SkillConfig` 新增 `target_hp_pct?: number`(按目标最大生命百分比扣血)
|
||||||
|
2. 伤害结算时,若技能含此字段,额外造成 `target.hp_max × target_hp_pct / 100` 伤害
|
||||||
|
|
||||||
|
**复刻配置**:
|
||||||
|
```typescript
|
||||||
|
[SkillTriggerType.Atking]: {
|
||||||
|
// 普攻附带 3% 目标最大生命真伤
|
||||||
|
6001: [{ lv: 1, t_num: 1, overrides: { ap: 100, /* 需新增 target_hp_pct: 3 */ } }],
|
||||||
|
},
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 4.3 重伤诅咒(Mage,复刻"巫妖王·重伤")
|
||||||
|
|
||||||
|
**缺失机制**:本系统无"降低治疗效果"属性。
|
||||||
|
|
||||||
|
**扩展方案**:
|
||||||
|
1. `Attrs` 新增 `heal_reduce = "heal_reduce"`(百分比降低受治疗)
|
||||||
|
2. 治疗结算时,实际治疗量 = 原治疗量 × (1 - heal_reduce/100)
|
||||||
|
|
||||||
|
**复刻配置**:
|
||||||
|
```typescript
|
||||||
|
[SkillTriggerType.Atking]: {
|
||||||
|
// 普攻附带重伤 debuff(敌方受治疗 -50%)
|
||||||
|
6101: [{ lv: 1, t_num: 1, overrides: { /* 需新增 heal_reduce 机制 */ } }],
|
||||||
|
},
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 五、不建议复刻
|
||||||
|
|
||||||
|
| 类型 | 代表技能 | 原因 |
|
||||||
|
|---|---|---|
|
||||||
|
| **能量/大招系统** | 所有英雄的"大招" | 本系统无能量条,技能全靠触发器,无法承载"释放大招"概念 |
|
||||||
|
| **解控** | 光明洗礼、暗黑盾解控 | 30s 战斗节奏快,控制时间仅 2~3s,解控价值极低 |
|
||||||
|
| **多段位移/分身** | 炼狱鬼斩、大圣虚影 | 视觉表现层复杂,ECS 弹道模型难承载"幻影穿梭" |
|
||||||
|
| **沉默 / 减能** | 潮壮壮、海拉 | 本系统无主动技能,沉默无目标可作用 |
|
||||||
|
| **长期叠层** | 剑圣 1 觉(30% 防御转攻击,永久) | 30s 战斗内永久叠层易失衡 |
|
||||||
|
| **按当前生命%伤害** | 女王尖啸(18% 当前生命) | 与"按最大生命%"相比,30s 短局内波动过大,难平衡 |
|
||||||
|
| **击退抗性 / 减速抗性** | 剑豪红武、酒仙 | 本系统已有 `knockback_res`,但减速概念不存在 |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 六、复刻优先级矩阵
|
||||||
|
|
||||||
|
| 优先级 | 英雄 | 复刻难度 | 设计价值 |
|
||||||
|
|---|---|---|---|
|
||||||
|
| **P0(必做)** | 剧毒女王 | ✅ 零代码 | 引入 DoT 体系,丰富伤害维度 |
|
||||||
|
| **P0** | 猴王·乱棍 | ✅ 零代码 | 多段伤害+击晕,近战核心 |
|
||||||
|
| **P0** | 剑圣·疾风 | ✅ 零代码 | 范围+击退+吸血,全能战士 |
|
||||||
|
| **P1(推荐)** | 壁垒贤者 | ✅ 零代码 | 团队防御核心 |
|
||||||
|
| **P1** | 凤凰祭司 | ✅ 零代码 | 复活机制已有,强化死亡触发 |
|
||||||
|
| **P1** | 暗影骑士 | ✅ 零代码 | 治疗型坦克,差异化定位 |
|
||||||
|
| **P2(可选)** | 风暴歌者 | ✅ 零代码 | 范围控制,与剧毒女王互补 |
|
||||||
|
| **P2** | 战吼先锋 | ✅ 零代码 | 开场增益,节奏型辅助 |
|
||||||
|
| **P3(扩展后做)** | 反伤罗刹 | ⚙️ 需新增 thorns | 反伤 META,针对高攻速敌人 |
|
||||||
|
| **P3** | 真伤刺客 | ⚙️ 需新增 target_hp_pct | 针对高血量 Boss |
|
||||||
|
| **P3** | 重伤诅咒 | ⚙️ 需新增 heal_reduce | 针对治疗队 |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 七、新增机制工作量评估
|
||||||
|
|
||||||
|
| 机制 | 改动文件 | 改动量 | 风险 |
|
||||||
|
|---|---|---|---|
|
||||||
|
| **反伤 thorns** | HeroAttrs.ts + HeroAttrsComp.ts + 战斗结算 | ~50 行 | 低(独立属性) |
|
||||||
|
| **按最大生命%伤害** | SkillSet.ts + 伤害结算 | ~30 行 | 低(额外乘区) |
|
||||||
|
| **减疗 heal_reduce** | HeroAttrs.ts + HeroAttrsComp.ts + 治疗结算 | ~40 行 | 低(独立乘区) |
|
||||||
|
| **敌方 Support 技能** | SCastSystem.ts | ~20 行 | 中(需测试目标选择) |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 八、与原"20 回合制"的兼容性
|
||||||
|
|
||||||
|
本设计文档基于 **1 回合定生死** 机制,所有数值均按 **30 秒战斗窗口** 校准:
|
||||||
|
|
||||||
|
- `t_num=1` 触发:30s 内普攻 30~50 次,技能触发 30~50 次
|
||||||
|
- DoT/HoT 持续 5s:覆盖 1/6 战斗时长,效果显著但不至于"挂上就赢"
|
||||||
|
- 复活 `r_num=1`:单场战斗最多 1 次,价值极高但可控
|
||||||
|
- 驻场光环 `value=15%`:30s 内持续生效,等价于"永久"(单场)
|
||||||
|
|
||||||
|
若未来回归多回合制,需重新校准:
|
||||||
|
- `t_num` 提高到 2~4(降低触发频率)
|
||||||
|
- DoT/HoT 持续时间延长至 10~15s
|
||||||
|
- 复活次数可放开到 2~3 次
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 九、下一步行动
|
||||||
|
|
||||||
|
1. **确认 P0 英雄清单**:是否按本方案复刻 8 个英雄?
|
||||||
|
2. **数值校准**:是否需要先用 `calcHeroPower` 公式推导每个英雄的目标强度锚点?
|
||||||
|
3. **新增机制决策**:是否在第 1 阶段引入反伤/真伤/减疗?还是先纯配置复刻?
|
||||||
|
4. **编写 heroSet.ts 配置**:确认后我可以直接输出可粘贴的 TypeScript 配置代码。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**文档版本**:v1.0
|
||||||
|
**创建日期**:2026-08-14
|
||||||
|
**作者**:AI Assistant
|
||||||
|
**关联文档**:[heroSet.ts](./heroSet.ts) / [SkillSet.ts](./SkillSet.ts) / [BuffSet.ts](./BuffSet.ts) / [几何王国英雄技能汇总.md](./几何王国英雄技能汇总.md)
|
||||||
11
assets/script/game/common/config/几何王国技能复刻方案.md.meta
Normal file
11
assets/script/game/common/config/几何王国技能复刻方案.md.meta
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
{
|
||||||
|
"ver": "1.0.1",
|
||||||
|
"importer": "text",
|
||||||
|
"imported": true,
|
||||||
|
"uuid": "4b91da8c-0510-4f36-a3f7-b78ec260c1f9",
|
||||||
|
"files": [
|
||||||
|
".json"
|
||||||
|
],
|
||||||
|
"subMetas": {},
|
||||||
|
"userData": {}
|
||||||
|
}
|
||||||
11
assets/script/game/common/config/几何王国英雄技能汇总.md.meta
Normal file
11
assets/script/game/common/config/几何王国英雄技能汇总.md.meta
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
{
|
||||||
|
"ver": "1.0.1",
|
||||||
|
"importer": "text",
|
||||||
|
"imported": true,
|
||||||
|
"uuid": "3ec17428-df2e-40bc-a707-4de99ee79b10",
|
||||||
|
"files": [
|
||||||
|
".json"
|
||||||
|
],
|
||||||
|
"subMetas": {},
|
||||||
|
"userData": {}
|
||||||
|
}
|
||||||
@@ -133,7 +133,6 @@ export class Hero extends ecs.Entity {
|
|||||||
model.call = hero.call;
|
model.call = hero.call;
|
||||||
model.dead = hero.dead;
|
model.dead = hero.dead;
|
||||||
model.fstart = hero.fstart;
|
model.fstart = hero.fstart;
|
||||||
model.fend = hero.fend;
|
|
||||||
model.atking = hero.atking;
|
model.atking = hero.atking;
|
||||||
model.atked = hero.atked;
|
model.atked = hero.atked;
|
||||||
model.field = hero.field;
|
model.field = hero.field;
|
||||||
@@ -172,7 +171,6 @@ export class Hero extends ecs.Entity {
|
|||||||
model.runtime_call = resolveTriggerByLv(model.call, hero_lv);
|
model.runtime_call = resolveTriggerByLv(model.call, hero_lv);
|
||||||
model.runtime_dead = resolveTriggerByLv(model.dead, hero_lv);
|
model.runtime_dead = resolveTriggerByLv(model.dead, hero_lv);
|
||||||
model.runtime_fstart = resolveTriggerByLv(model.fstart, hero_lv);
|
model.runtime_fstart = resolveTriggerByLv(model.fstart, hero_lv);
|
||||||
model.runtime_fend = resolveTriggerByLv(model.fend, hero_lv);
|
|
||||||
model.runtime_atking = resolveTriggerByLv(model.atking, hero_lv);
|
model.runtime_atking = resolveTriggerByLv(model.atking, hero_lv);
|
||||||
model.runtime_atked = resolveTriggerByLv(model.atked, hero_lv);
|
model.runtime_atked = resolveTriggerByLv(model.atked, hero_lv);
|
||||||
model.runtime_field = resolveFieldByLv(model.field, hero_lv);
|
model.runtime_field = resolveFieldByLv(model.field, hero_lv);
|
||||||
|
|||||||
@@ -47,7 +47,6 @@ export class HeroAttrsComp extends ecs.Comp {
|
|||||||
[SkillTriggerType.Call]?: TriggerGrouped;
|
[SkillTriggerType.Call]?: TriggerGrouped;
|
||||||
[SkillTriggerType.Dead]?: TriggerGrouped;
|
[SkillTriggerType.Dead]?: TriggerGrouped;
|
||||||
[SkillTriggerType.FStart]?: TriggerGrouped;
|
[SkillTriggerType.FStart]?: TriggerGrouped;
|
||||||
[SkillTriggerType.FEnd]?: TriggerGrouped;
|
|
||||||
[SkillTriggerType.Atking]?: TriggerGrouped;
|
[SkillTriggerType.Atking]?: TriggerGrouped;
|
||||||
[SkillTriggerType.Atked]?: TriggerGrouped;
|
[SkillTriggerType.Atked]?: TriggerGrouped;
|
||||||
/** 驻场光环(按 lv 解锁,存活期间全局生效) */
|
/** 驻场光环(按 lv 解锁,存活期间全局生效) */
|
||||||
@@ -68,8 +67,6 @@ export class HeroAttrsComp extends ecs.Comp {
|
|||||||
runtime_dead?: { s_uuid: number; t_num: number; overrides?: SkillOverrides }[];
|
runtime_dead?: { s_uuid: number; t_num: number; overrides?: SkillOverrides }[];
|
||||||
/** 当前等级下生效的战前触发条目 */
|
/** 当前等级下生效的战前触发条目 */
|
||||||
runtime_fstart?: { s_uuid: number; t_num: number; overrides?: SkillOverrides }[];
|
runtime_fstart?: { s_uuid: number; t_num: number; overrides?: SkillOverrides }[];
|
||||||
/** 当前等级下生效的战后触发条目 */
|
|
||||||
runtime_fend?: { s_uuid: number; t_num: number; overrides?: SkillOverrides }[];
|
|
||||||
/** 当前等级下生效的驻场光环词条列表 */
|
/** 当前等级下生效的驻场光环词条列表 */
|
||||||
runtime_field?: FieldEntry[];
|
runtime_field?: FieldEntry[];
|
||||||
/** 当前等级下生效的复活配置 */
|
/** 当前等级下生效的复活配置 */
|
||||||
@@ -580,7 +577,6 @@ export class HeroAttrsComp extends ecs.Comp {
|
|||||||
this.call = undefined;
|
this.call = undefined;
|
||||||
this.dead = undefined;
|
this.dead = undefined;
|
||||||
this.fstart = undefined;
|
this.fstart = undefined;
|
||||||
this.fend = undefined;
|
|
||||||
this.atking = undefined;
|
this.atking = undefined;
|
||||||
this.atked = undefined;
|
this.atked = undefined;
|
||||||
this.field = undefined;
|
this.field = undefined;
|
||||||
@@ -592,7 +588,6 @@ export class HeroAttrsComp extends ecs.Comp {
|
|||||||
this.runtime_call = undefined;
|
this.runtime_call = undefined;
|
||||||
this.runtime_dead = undefined;
|
this.runtime_dead = undefined;
|
||||||
this.runtime_fstart = undefined;
|
this.runtime_fstart = undefined;
|
||||||
this.runtime_fend = undefined;
|
|
||||||
this.runtime_field = undefined;
|
this.runtime_field = undefined;
|
||||||
this.runtime_revive = undefined;
|
this.runtime_revive = undefined;
|
||||||
this.critical = 0;
|
this.critical = 0;
|
||||||
|
|||||||
@@ -186,7 +186,6 @@ export class Monster extends ecs.Entity {
|
|||||||
model.call = hero.call;
|
model.call = hero.call;
|
||||||
model.dead = hero.dead;
|
model.dead = hero.dead;
|
||||||
model.fstart = hero.fstart;
|
model.fstart = hero.fstart;
|
||||||
model.fend = hero.fend;
|
|
||||||
model.atking = hero.atking;
|
model.atking = hero.atking;
|
||||||
model.atked = hero.atked;
|
model.atked = hero.atked;
|
||||||
model.revive = hero.revive;
|
model.revive = hero.revive;
|
||||||
@@ -225,7 +224,6 @@ export class Monster extends ecs.Entity {
|
|||||||
if (testSkills.atked !== undefined) model.atked = testSkills.atked;
|
if (testSkills.atked !== undefined) model.atked = testSkills.atked;
|
||||||
if (testSkills.dead !== undefined) model.dead = testSkills.dead;
|
if (testSkills.dead !== undefined) model.dead = testSkills.dead;
|
||||||
if (testSkills.fstart !== undefined) model.fstart = testSkills.fstart;
|
if (testSkills.fstart !== undefined) model.fstart = testSkills.fstart;
|
||||||
if (testSkills.fend !== undefined) model.fend = testSkills.fend;
|
|
||||||
if (testSkills.call !== undefined) model.call = testSkills.call;
|
if (testSkills.call !== undefined) model.call = testSkills.call;
|
||||||
if (testSkills.revive !== undefined) model.revive = testSkills.revive;
|
if (testSkills.revive !== undefined) model.revive = testSkills.revive;
|
||||||
}
|
}
|
||||||
@@ -234,7 +232,6 @@ export class Monster extends ecs.Entity {
|
|||||||
model.runtime_call = resolveTriggerByLv(model.call, mon_lv);
|
model.runtime_call = resolveTriggerByLv(model.call, mon_lv);
|
||||||
model.runtime_dead = resolveTriggerByLv(model.dead, mon_lv);
|
model.runtime_dead = resolveTriggerByLv(model.dead, mon_lv);
|
||||||
model.runtime_fstart = resolveTriggerByLv(model.fstart, 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_atking = resolveTriggerByLv(model.atking, mon_lv);
|
||||||
model.runtime_atked = resolveTriggerByLv(model.atked, mon_lv);
|
model.runtime_atked = resolveTriggerByLv(model.atked, mon_lv);
|
||||||
model.runtime_revive = resolveReviveByLv(model.revive, mon_lv);
|
model.runtime_revive = resolveReviveByLv(model.revive, mon_lv);
|
||||||
|
|||||||
@@ -44,9 +44,6 @@ export class SkillTriggerHelper {
|
|||||||
case SkillTriggerType.FStart:
|
case SkillTriggerType.FStart:
|
||||||
this.handleArrayTrigger(model.runtime_fstart, model, view, type);
|
this.handleArrayTrigger(model.runtime_fstart, model, view, type);
|
||||||
break;
|
break;
|
||||||
case SkillTriggerType.FEnd:
|
|
||||||
this.handleArrayTrigger(model.runtime_fend, model, view, type);
|
|
||||||
break;
|
|
||||||
case SkillTriggerType.Atking:
|
case SkillTriggerType.Atking:
|
||||||
this.handleAtking(model, view);
|
this.handleAtking(model, view);
|
||||||
break;
|
break;
|
||||||
@@ -142,7 +139,7 @@ export class SkillTriggerHelper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 通用的数组型触发器处理(适用于 FStart / FEnd 等无需额外判定的简单列表触发)
|
* 通用的数组型触发器处理(适用于 FStart 等无需额外判定的简单列表触发)
|
||||||
*/
|
*/
|
||||||
private static handleArrayTrigger(configs: { s_uuid: number, t_num: number, overrides?: SkillOverrides }[] | undefined, model: HeroAttrsComp, view: HeroViewComp, type: SkillTriggerType) {
|
private static handleArrayTrigger(configs: { s_uuid: number, t_num: number, overrides?: SkillOverrides }[] | undefined, model: HeroAttrsComp, view: HeroViewComp, type: SkillTriggerType) {
|
||||||
if (!configs || configs.length === 0) return;
|
if (!configs || configs.length === 0) return;
|
||||||
|
|||||||
@@ -478,7 +478,6 @@ export class CHeroComp extends CCComp {
|
|||||||
call: hero.call,
|
call: hero.call,
|
||||||
dead: hero.dead,
|
dead: hero.dead,
|
||||||
fstart: hero.fstart,
|
fstart: hero.fstart,
|
||||||
fend: hero.fend,
|
|
||||||
atking: hero.atking,
|
atking: hero.atking,
|
||||||
atked: hero.atked,
|
atked: hero.atked,
|
||||||
field: hero.field,
|
field: hero.field,
|
||||||
|
|||||||
@@ -13,7 +13,6 @@
|
|||||||
* - Interval (2):监听 FightStart → update 帧驱动按 t_inv 间隔重复触发(按 t_times 控制每回合次数)
|
* - Interval (2):监听 FightStart → update 帧驱动按 t_inv 间隔重复触发(按 t_times 控制每回合次数)
|
||||||
* - Field (3):被动生效,不主动施法(实际由 FieldSkillSet 处理)
|
* - Field (3):被动生效,不主动施法(实际由 FieldSkillSet 处理)
|
||||||
* - FightStart (4):监听 FightStart 事件,按 trigger_limit 全局累计上限
|
* - FightStart (4):监听 FightStart 事件,按 trigger_limit 全局累计上限
|
||||||
* - FightEnd (5):监听 FightEnd 事件(每回合结束派发),按 trigger_limit 全局累计上限
|
|
||||||
* - HeroDead (6):监听 HeroDead 事件(仅英雄阵营派发,怪物死亡不触发)
|
* - HeroDead (6):监听 HeroDead 事件(仅英雄阵营派发,怪物死亡不触发)
|
||||||
* - HeroCall (7):监听 MasterCalled(主角/技能召唤)+ ReviveSuccess(复活)
|
* - HeroCall (7):监听 MasterCalled(主角/技能召唤)+ ReviveSuccess(复活)
|
||||||
*
|
*
|
||||||
@@ -145,7 +144,6 @@ export class EquipBoxComp extends CCComp {
|
|||||||
oops.message.off(GameEvent.MissionEnd, this.onMissionEnd, this);
|
oops.message.off(GameEvent.MissionEnd, this.onMissionEnd, this);
|
||||||
oops.message.off(GameEvent.FightStart, this.onFightStart, this);
|
oops.message.off(GameEvent.FightStart, this.onFightStart, this);
|
||||||
oops.message.off(GameEvent.FightStart, this.onEventTrigger, this);
|
oops.message.off(GameEvent.FightStart, this.onEventTrigger, this);
|
||||||
oops.message.off(GameEvent.FightEnd, this.onEventTrigger, this);
|
|
||||||
oops.message.off(GameEvent.HeroDead, this.onEventTrigger, this);
|
oops.message.off(GameEvent.HeroDead, this.onEventTrigger, this);
|
||||||
oops.message.off(GameEvent.MasterCalled, this.onEventTrigger, this);
|
oops.message.off(GameEvent.MasterCalled, this.onEventTrigger, this);
|
||||||
oops.message.off(GameEvent.ReviveSuccess, this.onEventTrigger, this);
|
oops.message.off(GameEvent.ReviveSuccess, this.onEventTrigger, this);
|
||||||
@@ -287,7 +285,6 @@ export class EquipBoxComp extends CCComp {
|
|||||||
* - Interval: 监听 FightStart,进入战斗后由 update 帧驱动计时
|
* - Interval: 监听 FightStart,进入战斗后由 update 帧驱动计时
|
||||||
* - Field: 不主动施法(实际生效由 FieldSkillSet 处理)
|
* - Field: 不主动施法(实际生效由 FieldSkillSet 处理)
|
||||||
* - FightStart: 监听 FightStart 事件
|
* - FightStart: 监听 FightStart 事件
|
||||||
* - FightEnd: 监听 FightEnd 事件
|
|
||||||
* - HeroDead: 监听 HeroDead 事件(已在派发处做阵营过滤)
|
* - HeroDead: 监听 HeroDead 事件(已在派发处做阵营过滤)
|
||||||
* - HeroCall: 监听 MasterCalled(主角/技能召唤)+ ReviveSuccess(复活)
|
* - HeroCall: 监听 MasterCalled(主角/技能召唤)+ ReviveSuccess(复活)
|
||||||
*
|
*
|
||||||
@@ -313,10 +310,6 @@ export class EquipBoxComp extends CCComp {
|
|||||||
oops.message.on(GameEvent.FightStart, this.onEventTrigger, this);
|
oops.message.on(GameEvent.FightStart, this.onEventTrigger, this);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CardTriggerType.FightEnd:
|
|
||||||
oops.message.on(GameEvent.FightEnd, this.onEventTrigger, this);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case CardTriggerType.HeroDead:
|
case CardTriggerType.HeroDead:
|
||||||
oops.message.on(GameEvent.HeroDead, this.onEventTrigger, this);
|
oops.message.on(GameEvent.HeroDead, this.onEventTrigger, this);
|
||||||
break;
|
break;
|
||||||
@@ -338,7 +331,7 @@ export class EquipBoxComp extends CCComp {
|
|||||||
* 事件型触发的统一入口:
|
* 事件型触发的统一入口:
|
||||||
* - Instant 类型:按 trigger_times 上限判定,复用 current_trigger_times 跟踪
|
* - Instant 类型:按 trigger_times 上限判定,复用 current_trigger_times 跟踪
|
||||||
* (保持与原 is_instant 行为一致,且 NewWave 中也用 current_trigger_times)
|
* (保持与原 is_instant 行为一致,且 NewWave 中也用 current_trigger_times)
|
||||||
* - 事件型(FightStart/FightEnd/HeroDead/HeroCall):按 trigger_limit 上限判定,使用 trigger_count 跟踪
|
* - 事件型(FightStart/HeroDead/HeroCall):按 trigger_limit 上限判定,使用 trigger_count 跟踪
|
||||||
*
|
*
|
||||||
* 注意:本方法不读取事件 payload,仅作触发信号使用(避免 MasterCalled 不同 payload 字段引发的兼容问题)。
|
* 注意:本方法不读取事件 payload,仅作触发信号使用(避免 MasterCalled 不同 payload 字段引发的兼容问题)。
|
||||||
*/
|
*/
|
||||||
@@ -445,7 +438,6 @@ export class EquipBoxComp extends CCComp {
|
|||||||
const showRemainCount =
|
const showRemainCount =
|
||||||
this.trigger_type === CardTriggerType.Interval ||
|
this.trigger_type === CardTriggerType.Interval ||
|
||||||
this.trigger_type === CardTriggerType.FightStart ||
|
this.trigger_type === CardTriggerType.FightStart ||
|
||||||
this.trigger_type === CardTriggerType.FightEnd ||
|
|
||||||
this.trigger_type === CardTriggerType.HeroDead ||
|
this.trigger_type === CardTriggerType.HeroDead ||
|
||||||
this.trigger_type === CardTriggerType.HeroCall;
|
this.trigger_type === CardTriggerType.HeroCall;
|
||||||
|
|
||||||
@@ -454,7 +446,6 @@ export class EquipBoxComp extends CCComp {
|
|||||||
// 事件型按 trigger_limit;Interval 按 t_times
|
// 事件型按 trigger_limit;Interval 按 t_times
|
||||||
const isEvent =
|
const isEvent =
|
||||||
this.trigger_type === CardTriggerType.FightStart ||
|
this.trigger_type === CardTriggerType.FightStart ||
|
||||||
this.trigger_type === CardTriggerType.FightEnd ||
|
|
||||||
this.trigger_type === CardTriggerType.HeroDead ||
|
this.trigger_type === CardTriggerType.HeroDead ||
|
||||||
this.trigger_type === CardTriggerType.HeroCall;
|
this.trigger_type === CardTriggerType.HeroCall;
|
||||||
const used = isEvent ? this.trigger_count : this.current_trigger_times;
|
const used = isEvent ? this.trigger_count : this.current_trigger_times;
|
||||||
@@ -514,7 +505,7 @@ export class EquipBoxComp extends CCComp {
|
|||||||
* 处理维持回合逻辑:递减剩余回合,或者重置触发次数。
|
* 处理维持回合逻辑:递减剩余回合,或者重置触发次数。
|
||||||
*
|
*
|
||||||
* 各类型在新一回合的行为:
|
* 各类型在新一回合的行为:
|
||||||
* - Instant/Interval/FightStart/FightEnd:按 keep_waves 决定维持/销毁,并在新一回合开始时重置本地计数
|
* - Instant/Interval/FightStart:按 keep_waves 决定维持/销毁,并在新一回合开始时重置本地计数
|
||||||
* - Field:被动生效,跟随 keep_waves 决定存活
|
* - Field:被动生效,跟随 keep_waves 决定存活
|
||||||
* - HeroDead/HeroCall:跨回合触发的事件型,trigger_count(全局)不重置,仅 keep_waves 控制存活
|
* - HeroDead/HeroCall:跨回合触发的事件型,trigger_count(全局)不重置,仅 keep_waves 控制存活
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -217,7 +217,6 @@ export class HeroBoxComp extends CCComp {
|
|||||||
call: hero.call,
|
call: hero.call,
|
||||||
dead: hero.dead,
|
dead: hero.dead,
|
||||||
fstart: hero.fstart,
|
fstart: hero.fstart,
|
||||||
fend: hero.fend,
|
|
||||||
atking: hero.atking,
|
atking: hero.atking,
|
||||||
atked: hero.atked,
|
atked: hero.atked,
|
||||||
field: hero.field,
|
field: hero.field,
|
||||||
|
|||||||
@@ -2264,7 +2264,6 @@ export class MissionCardComp extends CCComp {
|
|||||||
model.runtime_call = resolveTriggerByLv(model.call, nextLv);
|
model.runtime_call = resolveTriggerByLv(model.call, nextLv);
|
||||||
model.runtime_dead = resolveTriggerByLv(model.dead, nextLv);
|
model.runtime_dead = resolveTriggerByLv(model.dead, nextLv);
|
||||||
model.runtime_fstart = resolveTriggerByLv(model.fstart, nextLv);
|
model.runtime_fstart = resolveTriggerByLv(model.fstart, nextLv);
|
||||||
model.runtime_fend = resolveTriggerByLv(model.fend, nextLv);
|
|
||||||
model.runtime_atking = resolveTriggerByLv(model.atking, nextLv);
|
model.runtime_atking = resolveTriggerByLv(model.atking, nextLv);
|
||||||
model.runtime_atked = resolveTriggerByLv(model.atked, nextLv);
|
model.runtime_atked = resolveTriggerByLv(model.atked, nextLv);
|
||||||
model.runtime_field = resolveFieldByLv(model.field, nextLv);
|
model.runtime_field = resolveFieldByLv(model.field, nextLv);
|
||||||
|
|||||||
@@ -225,7 +225,7 @@ export class MissionComp extends CCComp {
|
|||||||
protected update(dt: number): void {
|
protected update(dt: number): void {
|
||||||
if (!smc.mission.play) return
|
if (!smc.mission.play) return
|
||||||
|
|
||||||
// 如果是暂停状态,且不在 BattleEnd 阶段(全灭时需要播放完 fend 技能动画并自动流转),才真正停止 update 逻辑
|
// 如果是暂停状态,且不在 BattleEnd 阶段(全灭时需要自动流转),才真正停止 update 逻辑
|
||||||
if (smc.mission.pause && this.currentPhase !== MissionPhase.BattleEnd) return
|
if (smc.mission.pause && this.currentPhase !== MissionPhase.BattleEnd) return
|
||||||
|
|
||||||
// 回合间倒计时:PrepareStart 复用为倒计时阶段,5 秒后自动进入下一回合
|
// 回合间倒计时:PrepareStart 复用为倒计时阶段,5 秒后自动进入下一回合
|
||||||
@@ -515,7 +515,7 @@ export class MissionComp extends CCComp {
|
|||||||
|
|
||||||
case MissionPhase.BattleStart:
|
case MissionPhase.BattleStart:
|
||||||
// 触发战斗开始技能(fstart)
|
// 触发战斗开始技能(fstart)
|
||||||
this.triggerHeroBattleSkills(true);
|
this.triggerHeroBattleSkills();
|
||||||
// Boss 预警:Boss 同步场立即登场(eta=0)
|
// Boss 预警:Boss 同步场立即登场(eta=0)
|
||||||
if (this.isBossWave) {
|
if (this.isBossWave) {
|
||||||
oops.message.dispatchEvent(GameEvent.BossWarning, {
|
oops.message.dispatchEvent(GameEvent.BossWarning, {
|
||||||
@@ -576,14 +576,9 @@ export class MissionComp extends CCComp {
|
|||||||
smc.vmdata.scores.passed_wave_20 = true;
|
smc.vmdata.scores.passed_wave_20 = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 触发战斗结束技能(fend)
|
|
||||||
this.triggerHeroBattleSkills(false);
|
|
||||||
|
|
||||||
// 战斗结束阶段,按 FightSet.WAVE_HEAL_RATE 恢复所有英雄血量
|
// 战斗结束阶段,按 FightSet.WAVE_HEAL_RATE 恢复所有英雄血量
|
||||||
this.healAllHeroes();
|
this.healAllHeroes();
|
||||||
|
|
||||||
// 【新增】派发每回合战斗结束事件,供卡牌技能监听(区别于整局结束的 MissionEnd)
|
|
||||||
oops.message.dispatchEvent(GameEvent.FightEnd);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MissionPhase.Settle:
|
case MissionPhase.Settle:
|
||||||
@@ -669,32 +664,26 @@ export class MissionComp extends CCComp {
|
|||||||
* - 标记非战斗
|
* - 标记非战斗
|
||||||
* - 暂停刷怪
|
* - 暂停刷怪
|
||||||
* - 显示开始按钮
|
* - 显示开始按钮
|
||||||
* - 触发英雄战斗结束技能
|
|
||||||
*/
|
*/
|
||||||
private enterPreparePhase() {
|
private enterPreparePhase() {
|
||||||
this.changePhase(MissionPhase.PrepareStart);
|
this.changePhase(MissionPhase.PrepareStart);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 触发英雄的战斗开始/结束技能
|
* 触发英雄的战斗开始技能
|
||||||
* @param isStart 是否为战斗开始
|
|
||||||
*/
|
*/
|
||||||
private triggerHeroBattleSkills(isStart: boolean) {
|
private triggerHeroBattleSkills() {
|
||||||
let triggerCount = 1;
|
let triggerCount = 1;
|
||||||
if (isStart) {
|
|
||||||
triggerCount += FieldSkillHelper.getFieldSkillTotalValue(FieldSkillType.StartCount);
|
triggerCount += FieldSkillHelper.getFieldSkillTotalValue(FieldSkillType.StartCount);
|
||||||
} else {
|
|
||||||
triggerCount += FieldSkillHelper.getFieldSkillTotalValue(FieldSkillType.EndCount);
|
|
||||||
}
|
|
||||||
triggerCount = Math.max(1, Math.floor(triggerCount));
|
triggerCount = Math.max(1, Math.floor(triggerCount));
|
||||||
|
|
||||||
ecs.query(this.heroAttrsMatcher).forEach(entity => {
|
ecs.query(this.heroAttrsMatcher).forEach(entity => {
|
||||||
const attrs = entity.get(HeroAttrsComp);
|
const attrs = entity.get(HeroAttrsComp);
|
||||||
const view = entity.get(HeroViewComp);
|
const view = entity.get(HeroViewComp);
|
||||||
if (!attrs || !view || attrs.is_dead || attrs.fac !== FacSet.HERO) return;
|
if (!attrs || !view || attrs.is_dead || attrs.fac !== FacSet.HERO) return;
|
||||||
// 触发战斗开始/结束技能
|
// 触发战斗开始技能
|
||||||
for (let i = 0; i < triggerCount; i++) {
|
for (let i = 0; i < triggerCount; i++) {
|
||||||
SkillTriggerHelper.trigger(isStart ? SkillTriggerType.FStart : SkillTriggerType.FEnd, attrs, view);
|
SkillTriggerHelper.trigger(SkillTriggerType.FStart, attrs, view);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -755,8 +744,7 @@ export class MissionComp extends CCComp {
|
|||||||
open_Victory(e: any, is_hero_dead: boolean = false) {
|
open_Victory(e: any, is_hero_dead: boolean = false) {
|
||||||
// 战斗失败或胜利,标记暂停状态以切断回合流转逻辑
|
// 战斗失败或胜利,标记暂停状态以切断回合流转逻辑
|
||||||
smc.mission.pause = true;
|
smc.mission.pause = true;
|
||||||
// 直接切入 BattleEnd,触发 fend 表现
|
// 直接切入 BattleEnd,2s 后由 autoNextPhase 自动流转弹窗结算
|
||||||
// 倒计时逻辑已在 update 中由 PhaseTime 接管,2s 后将触发 autoNextPhase 弹窗结算
|
|
||||||
this.changePhase(MissionPhase.BattleEnd);
|
this.changePhase(MissionPhase.BattleEnd);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -859,7 +847,7 @@ export class MissionComp extends CCComp {
|
|||||||
this.isBossWave = true; // 单场 Boss 战,恒为 Boss 战(超时阈值/预警走 Boss 档)
|
this.isBossWave = true; // 单场 Boss 战,恒为 Boss 战(超时阈值/预警走 Boss 档)
|
||||||
|
|
||||||
if (wave > 1) {
|
if (wave > 1) {
|
||||||
// 在新一回合到来时,先进入 BattleEnd,触发上一回合的战斗结束技能 (fend),2秒后自动进入下一回合的准备阶段
|
// 在新一回合到来时,先进入 BattleEnd,2秒后自动进入下一回合的准备阶段
|
||||||
this.changePhase(MissionPhase.BattleEnd);
|
this.changePhase(MissionPhase.BattleEnd);
|
||||||
} else {
|
} else {
|
||||||
// 第1回合不需要结束上一回合,延迟一点播放提示,避免被开始游戏的loading遮挡
|
// 第1回合不需要结束上一回合,延迟一点播放提示,避免被开始游戏的loading遮挡
|
||||||
|
|||||||
@@ -171,7 +171,7 @@ export function pickBossCombo(): BossComboConfig | null {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 怪物技能套装(一套完整的触发技能配置)
|
* 怪物技能套装(一套完整的触发技能配置)
|
||||||
* 覆盖触发时机:call / atking / atked / dead / fstart / fend / revive
|
* 覆盖触发时机:call / atking / atked / dead / fstart / revive
|
||||||
*/
|
*/
|
||||||
export interface MonSkillSet {
|
export interface MonSkillSet {
|
||||||
id: string;
|
id: string;
|
||||||
@@ -188,8 +188,6 @@ export interface MonSkillSet {
|
|||||||
dead?: TriggerGrouped;
|
dead?: TriggerGrouped;
|
||||||
/** 战斗开始触发 */
|
/** 战斗开始触发 */
|
||||||
fstart?: TriggerGrouped;
|
fstart?: TriggerGrouped;
|
||||||
/** 战斗结束触发 */
|
|
||||||
fend?: TriggerGrouped;
|
|
||||||
/** 复活 */
|
/** 复活 */
|
||||||
revive?: LvReviveEntry[];
|
revive?: LvReviveEntry[];
|
||||||
/** 在技能池中的抽取权重 */
|
/** 在技能池中的抽取权重 */
|
||||||
@@ -343,7 +341,6 @@ export interface GeneratedMonster {
|
|||||||
atked?: TriggerGrouped;
|
atked?: TriggerGrouped;
|
||||||
dead?: TriggerGrouped;
|
dead?: TriggerGrouped;
|
||||||
fstart?: TriggerGrouped;
|
fstart?: TriggerGrouped;
|
||||||
fend?: TriggerGrouped;
|
|
||||||
revive?: LvReviveEntry[];
|
revive?: LvReviveEntry[];
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -363,7 +360,6 @@ export const TestModeConfig = {
|
|||||||
atked: undefined as TriggerGrouped | undefined,
|
atked: undefined as TriggerGrouped | undefined,
|
||||||
dead: undefined as TriggerGrouped | undefined,
|
dead: undefined as TriggerGrouped | undefined,
|
||||||
fstart: undefined as TriggerGrouped | undefined,
|
fstart: undefined as TriggerGrouped | undefined,
|
||||||
fend: undefined as TriggerGrouped | undefined,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// ======================== 8. 生成引擎 ========================
|
// ======================== 8. 生成引擎 ========================
|
||||||
@@ -452,7 +448,6 @@ export class RogueSpawningEngine {
|
|||||||
atked: TestModeConfig.atked,
|
atked: TestModeConfig.atked,
|
||||||
dead: TestModeConfig.dead,
|
dead: TestModeConfig.dead,
|
||||||
fstart: TestModeConfig.fstart,
|
fstart: TestModeConfig.fstart,
|
||||||
fend: TestModeConfig.fend,
|
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -519,7 +514,6 @@ export class RogueSpawningEngine {
|
|||||||
atked: picked.atked,
|
atked: picked.atked,
|
||||||
dead: picked.dead,
|
dead: picked.dead,
|
||||||
fstart: picked.fstart,
|
fstart: picked.fstart,
|
||||||
fend: picked.fend,
|
|
||||||
revive: picked.revive,
|
revive: picked.revive,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,7 +13,6 @@
|
|||||||
* - Interval (2):监听 FightStart → update 帧驱动按 t_inv 间隔重复触发(按 t_times 控制每回合次数)
|
* - Interval (2):监听 FightStart → update 帧驱动按 t_inv 间隔重复触发(按 t_times 控制每回合次数)
|
||||||
* - Field (3):被动生效,不主动施法(实际由 FieldSkillSet 处理)
|
* - Field (3):被动生效,不主动施法(实际由 FieldSkillSet 处理)
|
||||||
* - FightStart (4):监听 FightStart 事件,按 trigger_limit 全局累计上限
|
* - FightStart (4):监听 FightStart 事件,按 trigger_limit 全局累计上限
|
||||||
* - FightEnd (5):监听 FightEnd 事件(每回合结束派发),按 trigger_limit 全局累计上限
|
|
||||||
* - HeroDead (6):监听 HeroDead 事件(仅英雄阵营派发,怪物死亡不触发)
|
* - HeroDead (6):监听 HeroDead 事件(仅英雄阵营派发,怪物死亡不触发)
|
||||||
* - HeroCall (7):监听 MasterCalled(主角/技能召唤)+ ReviveSuccess(复活)
|
* - HeroCall (7):监听 MasterCalled(主角/技能召唤)+ ReviveSuccess(复活)
|
||||||
*
|
*
|
||||||
@@ -145,7 +144,6 @@ export class SkillBoxComp extends CCComp {
|
|||||||
oops.message.off(GameEvent.MissionEnd, this.onMissionEnd, this);
|
oops.message.off(GameEvent.MissionEnd, this.onMissionEnd, this);
|
||||||
oops.message.off(GameEvent.FightStart, this.onFightStart, this);
|
oops.message.off(GameEvent.FightStart, this.onFightStart, this);
|
||||||
oops.message.off(GameEvent.FightStart, this.onEventTrigger, this);
|
oops.message.off(GameEvent.FightStart, this.onEventTrigger, this);
|
||||||
oops.message.off(GameEvent.FightEnd, this.onEventTrigger, this);
|
|
||||||
oops.message.off(GameEvent.HeroDead, this.onEventTrigger, this);
|
oops.message.off(GameEvent.HeroDead, this.onEventTrigger, this);
|
||||||
oops.message.off(GameEvent.MasterCalled, this.onEventTrigger, this);
|
oops.message.off(GameEvent.MasterCalled, this.onEventTrigger, this);
|
||||||
oops.message.off(GameEvent.ReviveSuccess, this.onEventTrigger, this);
|
oops.message.off(GameEvent.ReviveSuccess, this.onEventTrigger, this);
|
||||||
@@ -289,7 +287,6 @@ export class SkillBoxComp extends CCComp {
|
|||||||
* - Interval: 监听 FightStart,进入战斗后由 update 帧驱动计时
|
* - Interval: 监听 FightStart,进入战斗后由 update 帧驱动计时
|
||||||
* - Field: 不主动施法(实际生效由 FieldSkillSet 处理)
|
* - Field: 不主动施法(实际生效由 FieldSkillSet 处理)
|
||||||
* - FightStart: 监听 FightStart 事件
|
* - FightStart: 监听 FightStart 事件
|
||||||
* - FightEnd: 监听 FightEnd 事件
|
|
||||||
* - HeroDead: 监听 HeroDead 事件(已在派发处做阵营过滤)
|
* - HeroDead: 监听 HeroDead 事件(已在派发处做阵营过滤)
|
||||||
* - HeroCall: 监听 MasterCalled(主角/技能召唤)+ ReviveSuccess(复活)
|
* - HeroCall: 监听 MasterCalled(主角/技能召唤)+ ReviveSuccess(复活)
|
||||||
*
|
*
|
||||||
@@ -320,10 +317,6 @@ export class SkillBoxComp extends CCComp {
|
|||||||
oops.message.on(GameEvent.FightStart, this.onEventTrigger, this);
|
oops.message.on(GameEvent.FightStart, this.onEventTrigger, this);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CardTriggerType.FightEnd:
|
|
||||||
oops.message.on(GameEvent.FightEnd, this.onEventTrigger, this);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case CardTriggerType.HeroDead:
|
case CardTriggerType.HeroDead:
|
||||||
oops.message.on(GameEvent.HeroDead, this.onEventTrigger, this);
|
oops.message.on(GameEvent.HeroDead, this.onEventTrigger, this);
|
||||||
break;
|
break;
|
||||||
@@ -345,7 +338,7 @@ export class SkillBoxComp extends CCComp {
|
|||||||
* 事件型触发的统一入口:
|
* 事件型触发的统一入口:
|
||||||
* - Instant 类型:按 trigger_times 上限判定,复用 current_trigger_times 跟踪
|
* - Instant 类型:按 trigger_times 上限判定,复用 current_trigger_times 跟踪
|
||||||
* (保持与原 is_instant 行为一致,且 NewWave 中也用 current_trigger_times)
|
* (保持与原 is_instant 行为一致,且 NewWave 中也用 current_trigger_times)
|
||||||
* - 事件型(FightStart/FightEnd/HeroDead/HeroCall):按 trigger_limit 上限判定,使用 trigger_count 跟踪
|
* - 事件型(FightStart/HeroDead/HeroCall):按 trigger_limit 上限判定,使用 trigger_count 跟踪
|
||||||
*
|
*
|
||||||
* 注意:本方法不读取事件 payload,仅作触发信号使用(避免 MasterCalled 不同 payload 字段引发的兼容问题)。
|
* 注意:本方法不读取事件 payload,仅作触发信号使用(避免 MasterCalled 不同 payload 字段引发的兼容问题)。
|
||||||
*/
|
*/
|
||||||
@@ -441,7 +434,6 @@ export class SkillBoxComp extends CCComp {
|
|||||||
const showRemainCount =
|
const showRemainCount =
|
||||||
this.trigger_type === CardTriggerType.Interval ||
|
this.trigger_type === CardTriggerType.Interval ||
|
||||||
this.trigger_type === CardTriggerType.FightStart ||
|
this.trigger_type === CardTriggerType.FightStart ||
|
||||||
this.trigger_type === CardTriggerType.FightEnd ||
|
|
||||||
this.trigger_type === CardTriggerType.HeroDead ||
|
this.trigger_type === CardTriggerType.HeroDead ||
|
||||||
this.trigger_type === CardTriggerType.HeroCall;
|
this.trigger_type === CardTriggerType.HeroCall;
|
||||||
|
|
||||||
@@ -450,7 +442,6 @@ export class SkillBoxComp extends CCComp {
|
|||||||
// 事件型按 trigger_limit;Interval 按 t_times
|
// 事件型按 trigger_limit;Interval 按 t_times
|
||||||
const isEvent =
|
const isEvent =
|
||||||
this.trigger_type === CardTriggerType.FightStart ||
|
this.trigger_type === CardTriggerType.FightStart ||
|
||||||
this.trigger_type === CardTriggerType.FightEnd ||
|
|
||||||
this.trigger_type === CardTriggerType.HeroDead ||
|
this.trigger_type === CardTriggerType.HeroDead ||
|
||||||
this.trigger_type === CardTriggerType.HeroCall;
|
this.trigger_type === CardTriggerType.HeroCall;
|
||||||
const used = isEvent ? this.trigger_count : this.current_trigger_times;
|
const used = isEvent ? this.trigger_count : this.current_trigger_times;
|
||||||
@@ -520,7 +511,7 @@ export class SkillBoxComp extends CCComp {
|
|||||||
* 处理维持回合逻辑:递减剩余回合,或者重置触发次数。
|
* 处理维持回合逻辑:递减剩余回合,或者重置触发次数。
|
||||||
*
|
*
|
||||||
* 各类型在新一回合的行为:
|
* 各类型在新一回合的行为:
|
||||||
* - Instant/Interval/FightStart/FightEnd:按 keep_waves 决定维持/销毁,并在新一回合开始时重置本地计数
|
* - Instant/Interval/FightStart:按 keep_waves 决定维持/销毁,并在新一回合开始时重置本地计数
|
||||||
* - Field:被动生效,跟随 keep_waves 决定存活
|
* - Field:被动生效,跟随 keep_waves 决定存活
|
||||||
* - HeroDead/HeroCall:跨回合触发的事件型,trigger_count(全局)不重置,仅 keep_waves 控制存活
|
* - HeroDead/HeroCall:跨回合触发的事件型,trigger_count(全局)不重置,仅 keep_waves 控制存活
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -19,8 +19,6 @@ export class TooltipCom extends CCComp {
|
|||||||
@property(Node)
|
@property(Node)
|
||||||
fstart_bg: Node = null;
|
fstart_bg: Node = null;
|
||||||
@property(Node)
|
@property(Node)
|
||||||
fend_bg: Node = null;
|
|
||||||
@property(Node)
|
|
||||||
dead_bg: Node = null;
|
dead_bg: Node = null;
|
||||||
@property(Node)
|
@property(Node)
|
||||||
revive_bg: Node = null;
|
revive_bg: Node = null;
|
||||||
@@ -176,7 +174,6 @@ export class TooltipCom extends CCComp {
|
|||||||
this.atking_bg && (this.atking_bg.active = false);
|
this.atking_bg && (this.atking_bg.active = false);
|
||||||
this.atked_bg && (this.atked_bg.active = false);
|
this.atked_bg && (this.atked_bg.active = false);
|
||||||
this.fstart_bg && (this.fstart_bg.active = false);
|
this.fstart_bg && (this.fstart_bg.active = false);
|
||||||
this.fend_bg && (this.fend_bg.active = false);
|
|
||||||
this.dead_bg && (this.dead_bg.active = false);
|
this.dead_bg && (this.dead_bg.active = false);
|
||||||
this.revive_bg && (this.revive_bg.active = false);
|
this.revive_bg && (this.revive_bg.active = false);
|
||||||
|
|
||||||
@@ -186,7 +183,6 @@ export class TooltipCom extends CCComp {
|
|||||||
[SkillTriggerType.Atking]: this.atking_bg,
|
[SkillTriggerType.Atking]: this.atking_bg,
|
||||||
[SkillTriggerType.Atked]: this.atked_bg,
|
[SkillTriggerType.Atked]: this.atked_bg,
|
||||||
[SkillTriggerType.FStart]: this.fstart_bg,
|
[SkillTriggerType.FStart]: this.fstart_bg,
|
||||||
[SkillTriggerType.FEnd]: this.fend_bg,
|
|
||||||
[SkillTriggerType.Dead]: this.dead_bg,
|
[SkillTriggerType.Dead]: this.dead_bg,
|
||||||
[SkillTriggerType.Revive]: this.revive_bg,
|
[SkillTriggerType.Revive]: this.revive_bg,
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user