Compare commits
3 Commits
354a2894e4
...
a94381b19f
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a94381b19f | ||
|
|
9f2599e9ec | ||
|
|
62264deeed |
@@ -4764,8 +4764,8 @@
|
||||
},
|
||||
"_contentSize": {
|
||||
"__type__": "cc.Size",
|
||||
"width": 233,
|
||||
"height": 233
|
||||
"width": 193,
|
||||
"height": 193
|
||||
},
|
||||
"_anchorPoint": {
|
||||
"__type__": "cc.Vec2",
|
||||
@@ -4889,8 +4889,8 @@
|
||||
},
|
||||
"_contentSize": {
|
||||
"__type__": "cc.Size",
|
||||
"width": 450,
|
||||
"height": 450
|
||||
"width": 370,
|
||||
"height": 370
|
||||
},
|
||||
"_anchorPoint": {
|
||||
"__type__": "cc.Vec2",
|
||||
|
||||
@@ -37,16 +37,6 @@ export enum CKind {
|
||||
Potion = 4, //药水
|
||||
}
|
||||
|
||||
/** 技能卡触发类型 */
|
||||
export enum CardSkillType {
|
||||
Interval = 1, // 间隔定时触发 (战斗中每隔N秒执行)
|
||||
Field = 2, // 驻场技能 (被动光环)
|
||||
BattleStart = 3, // 战斗开始时触发一次
|
||||
BattleEnd = 4, // 战斗结束时触发一次
|
||||
HeroDead = 5, // 场上己方英雄死亡时触发
|
||||
HeroCall = 6, // 场上己方英雄召唤上场时触发
|
||||
}
|
||||
|
||||
/**
|
||||
* 卡牌技能触发类型
|
||||
* - 命名对齐英雄侧 SkillTriggerType,便于跨模块认知统一
|
||||
@@ -62,19 +52,6 @@ export enum CardTriggerType {
|
||||
HeroCall = 7, // 英雄上场时触发(主角召唤 + 技能召唤 + 复活)
|
||||
}
|
||||
|
||||
/**
|
||||
* 卡池等级占位枚举(已废弃分层语义)。
|
||||
* 新机制下所有英雄卡均属 LV1,不再使用卡池升级。
|
||||
* 保留枚举仅为兼容历史代码引用。
|
||||
*/
|
||||
export enum CardLV {
|
||||
LV1 = 1,
|
||||
LV2 = 2,
|
||||
LV3 = 3,
|
||||
LV4 = 4,
|
||||
LV5 = 5,
|
||||
}
|
||||
|
||||
/** 通用卡牌配置 */
|
||||
export interface CardConfig {
|
||||
uuid: number
|
||||
@@ -82,11 +59,10 @@ export interface CardConfig {
|
||||
cost: number
|
||||
weight: number
|
||||
kind: CKind
|
||||
pool_lv: CardLV
|
||||
card_lv: number // 卡牌等级(驱动 bg_node 颜色:1=green 2=blue 3=purple 4=red 5=yellow)
|
||||
wave?: number // 针对技能卡:仅在指定波次(wave)才能抽到
|
||||
hero_lv?: number
|
||||
card_lv?: number
|
||||
base_pool_lv?: number
|
||||
base_card_lv?: number
|
||||
|
||||
// 技能卡扩展属性
|
||||
skill?: number // 关联的技能 UUID
|
||||
@@ -117,24 +93,6 @@ export interface CardConfig {
|
||||
target_hero_eid?: number;
|
||||
}
|
||||
|
||||
/** 升级卡折扣表(已废弃,保留以兼容历史引用) */
|
||||
export const CardsUpSet: Record<number, number> = {
|
||||
1: 50,
|
||||
2: 100,
|
||||
3: 150,
|
||||
4: 200,
|
||||
5: 250,
|
||||
}
|
||||
|
||||
/** 卡池升级每波减免金额(已废弃,保留以兼容历史引用) */
|
||||
export const CARD_POOL_UPGRADE_DISCOUNT_PER_WAVE = 10
|
||||
/** 卡池默认初始等级(已废弃,所有卡牌统一 LV1) */
|
||||
export const CARD_POOL_INIT_LEVEL = CardLV.LV1
|
||||
/** 卡池等级上限(已废弃,所有卡牌统一 LV1) */
|
||||
export const CARD_POOL_MAX_LEVEL = CardLV.LV1
|
||||
/** 英雄最高等级限制(已废弃,统一由 FightSet.HERO_MAX_LV 控制) */
|
||||
export const CARD_HERO_MAX_LEVEL = 1
|
||||
|
||||
/** 基础卡池(英雄、技能、功能) */
|
||||
export const CardPoolList: CardConfig[] = [];
|
||||
|
||||
@@ -151,10 +109,10 @@ HeroList.forEach(uuid => {
|
||||
type: CardType.Hero,
|
||||
cost: baseCost,
|
||||
weight: baseWeight,
|
||||
pool_lv: CardLV.LV1,
|
||||
card_lv: hero.card_lv ?? 1,
|
||||
kind: CKind.Hero,
|
||||
hero_lv: 1,
|
||||
base_pool_lv: 1,
|
||||
base_card_lv: hero.card_lv ?? 1,
|
||||
});
|
||||
});
|
||||
|
||||
@@ -191,32 +149,27 @@ export interface SpecialRefreshCardConfig extends CardConfig {
|
||||
*/
|
||||
export const SpecialUpgradeCardList: Record<number, SpecialUpgradeCardConfig> = {
|
||||
7001: {
|
||||
uuid: 7001, type: CardType.SpecialUpgrade, cost: 10, weight: 18, pool_lv: CardLV.LV1, kind: CKind.Card, name: t("scard_name_7001"), info: t("scard_info_7001"),
|
||||
uuid: 7001, type: CardType.SpecialUpgrade, cost: 10, weight: 18, card_lv: 1, kind: CKind.Card, name: t("scard_name_7001"), info: t("scard_info_7001"),
|
||||
currentLv: 0, targetLv: 0,
|
||||
},
|
||||
}
|
||||
|
||||
export const SpecialRefreshCardList: Record<number, SpecialRefreshCardConfig> = {
|
||||
7101: {
|
||||
uuid: 7101, type: CardType.SpecialRefresh, cost: 3, weight: 14, pool_lv: CardLV.LV1, kind: CKind.Card, name: t("scard_name_7101"), info: t("scard_info_7101"),
|
||||
uuid: 7101, type: CardType.SpecialRefresh, cost: 3, weight: 14, card_lv: 1, kind: CKind.Card, name: t("scard_name_7101"), info: t("scard_info_7101"),
|
||||
refreshLv: 0, refreshHeroType: SpecialRefreshHeroType.Melee,
|
||||
},
|
||||
7102: {
|
||||
uuid: 7102, type: CardType.SpecialRefresh, cost: 3, weight: 14, pool_lv: CardLV.LV1, kind: CKind.Card, name: t("scard_name_7102"), info: t("scard_info_7102"),
|
||||
uuid: 7102, type: CardType.SpecialRefresh, cost: 3, weight: 14, card_lv: 1, kind: CKind.Card, name: t("scard_name_7102"), info: t("scard_info_7102"),
|
||||
refreshLv: 0, refreshHeroType: SpecialRefreshHeroType.Ranged,
|
||||
},
|
||||
7103: {
|
||||
uuid: 7103, type: CardType.SpecialRefresh, cost: 4, weight: 12, pool_lv: CardLV.LV1, kind: CKind.Card, name: t("scard_name_7103"), info: t("scard_info_7103"),
|
||||
uuid: 7103, type: CardType.SpecialRefresh, cost: 4, weight: 12, card_lv: 1, kind: CKind.Card, name: t("scard_name_7103"), info: t("scard_info_7103"),
|
||||
refreshLv: 0, refreshHeroType: SpecialRefreshHeroType.Any,
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
/** 规范等级到合法区间(保留以兼容历史调用,新机制下统一返回 LV1) */
|
||||
const clampCardLv = (lv: number): CardLV => {
|
||||
return CardLV.LV1;
|
||||
}
|
||||
|
||||
// ============ 装备相关语义已迁移至 EquipSet.ts ============
|
||||
// 装备卡池(EquipPoolList)独立管理,不再混入 CardPoolList
|
||||
|
||||
@@ -249,62 +202,27 @@ const pickCards = (cards: CardConfig[], count: number, unique: boolean = false):
|
||||
return selected
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取基础卡池(已废弃 lv 参数,新机制下返回完整卡池)。
|
||||
* @param lv 历史遗留参数,不再生效
|
||||
* @param onlyCurrentLv 历史遗留参数,不再生效
|
||||
*/
|
||||
export const getCardPoolByLv = (lv: number, onlyCurrentLv: boolean = false): CardConfig[] => {
|
||||
return CardPoolList;
|
||||
}
|
||||
|
||||
const normalizeTypeFilter = (type: CardType | CardType[]): Set<CardType> => {
|
||||
const list = Array.isArray(type) ? type : [type]
|
||||
return new Set<CardType>(list)
|
||||
}
|
||||
|
||||
/**
|
||||
* 常规发牌:前 3 英雄 + 后 1 其他;支持按类型过滤。
|
||||
* @param lv 历史遗留参数,不再生效
|
||||
* @param type 限定卡牌类型
|
||||
* @param onlyCurrentLv 历史遗留参数,不再生效
|
||||
*/
|
||||
export const getCardsByLv = (
|
||||
lv: number,
|
||||
type?: CardType | CardType[],
|
||||
onlyCurrentLv: boolean = false
|
||||
): CardConfig[] => {
|
||||
const pool = getCardPoolByLv(lv, onlyCurrentLv)
|
||||
if (type !== undefined) {
|
||||
const typeSet = normalizeTypeFilter(type)
|
||||
const filteredPool = pool.filter(card => typeSet.has(card.type))
|
||||
return pickCards(filteredPool, 4)
|
||||
}
|
||||
const heroPool = pool.filter(card => card.type === CardType.Hero)
|
||||
const otherPool = pool.filter(card => card.type !== CardType.Hero)
|
||||
const heroes = pickCards(heroPool, 3)
|
||||
const others = pickCards(otherPool, 1)
|
||||
return [...heroes, ...others]
|
||||
}
|
||||
|
||||
/**
|
||||
* 通用按规则抽卡(已废弃 lv/targetPoolLv/onlyCurrentLv 参数,仅为兼容保留)。
|
||||
* 通用按规则抽卡。
|
||||
* @param options 抽卡选项
|
||||
*/
|
||||
export const drawCardsByRule = (
|
||||
lv: number,
|
||||
options: {
|
||||
count?: number
|
||||
onlyCurrentLv?: boolean
|
||||
type?: CardType | CardType[]
|
||||
heroType?: HType
|
||||
heroLv?: number
|
||||
targetPoolLv?: number
|
||||
wave?: number
|
||||
unique?: boolean
|
||||
} = {}
|
||||
): CardConfig[] => {
|
||||
const count = Math.max(0, Math.floor(options.count ?? 4))
|
||||
let pool = getCardPoolByLv(lv, options.onlyCurrentLv ?? false)
|
||||
let pool = CardPoolList
|
||||
if (options.type !== undefined) {
|
||||
const typeSet = normalizeTypeFilter(options.type)
|
||||
pool = pool.filter(card => typeSet.has(card.type))
|
||||
|
||||
@@ -11,11 +11,11 @@
|
||||
* → EquipBoxComp(trigger_type=Field,被动驻场)→ FieldSkillHelper 全局聚合属性加成
|
||||
*
|
||||
* 依赖:
|
||||
* - CardConfig / CardTriggerType / CardType / CKind / CardLV(CardSet)
|
||||
* - CardConfig / CardTriggerType / CardType / CKind(CardSet)
|
||||
* - SKILL_CARD_WAVES(GameSet)—— wave 档位定义
|
||||
* - FieldSkillSet(SkillSet)—— 属性词条配置
|
||||
*/
|
||||
import { CardConfig, CardType, CardLV, CKind, CardTriggerType } from "./CardSet";
|
||||
import { CardConfig, CardType, CKind, CardTriggerType } from "./CardSet";
|
||||
import { SKILL_CARD_WAVES } from "./GameSet";
|
||||
|
||||
/** wave → card_lv 映射(wave 1→lv1, wave 5→lv2, wave 8→lv3) */
|
||||
@@ -103,7 +103,6 @@ export const EquipPoolList: CardConfig[] = EquipRawList.map(data => ({
|
||||
type: CardType.Skill,
|
||||
cost: data.cost ?? 0,
|
||||
weight: 10,
|
||||
pool_lv: CardLV.LV1,
|
||||
wave: data.wave,
|
||||
kind: CKind.Skill,
|
||||
card_lv: waveToCardLv[data.wave] ?? 1,
|
||||
|
||||
@@ -13,10 +13,10 @@
|
||||
* - kind 为 CKind.Potion(药水类)。
|
||||
*
|
||||
* 依赖:
|
||||
* - CardSet —— CardConfig / CardType / CKind / CardLV / CardTriggerType
|
||||
* - CardSet —— CardConfig / CardType / CKind / CardTriggerType
|
||||
* - SkillSet —— SkillOverrides
|
||||
*/
|
||||
import { CardConfig, CardType, CardLV, CKind, CardTriggerType } from "./CardSet";
|
||||
import { CardConfig, CardType, CKind, CardTriggerType } from "./CardSet";
|
||||
import { SkillOverrides } from "./SkillSet";
|
||||
|
||||
/** 商品/药品卡原始数据(平铺字段,构建后转为 CardConfig) */
|
||||
@@ -68,7 +68,6 @@ export const ItemCardList: CardConfig[] = ItemCardData.map(data => ({
|
||||
type: CardType.Skill,
|
||||
cost: data.cost,
|
||||
weight: data.weight,
|
||||
pool_lv: CardLV.LV1,
|
||||
kind: CKind.Potion,
|
||||
card_lv: 1,
|
||||
icon: data.icon,
|
||||
|
||||
@@ -11,10 +11,10 @@
|
||||
* - card_lv 直接显式配置,不再依赖 wave 推导。
|
||||
*
|
||||
* 依赖:
|
||||
* - CardSet —— CardConfig / CardType / CKind / CardLV / CardTriggerType
|
||||
* - CardSet —— CardConfig / CardType / CKind / CardTriggerType
|
||||
* - SkillSet —— SkillOverrides
|
||||
*/
|
||||
import { CardConfig, CardType, CardLV, CKind, CardTriggerType } from "./CardSet";
|
||||
import { CardConfig, CardType, CKind, CardTriggerType } from "./CardSet";
|
||||
import { SkillOverrides } from "./SkillSet";
|
||||
|
||||
/** 技能卡原始数据(平铺字段,构建后转为 CardConfig) */
|
||||
@@ -65,7 +65,6 @@ export const SkillCardList: CardConfig[] = SkillCardData.map(data => {
|
||||
type: CardType.Skill,
|
||||
cost: 0,
|
||||
weight: 10,
|
||||
pool_lv: CardLV.LV1,
|
||||
kind: CKind.Skill,
|
||||
card_lv: data.card_lv,
|
||||
icon: data.icon,
|
||||
|
||||
@@ -154,7 +154,7 @@ export interface heroInfo {
|
||||
fac: FacSet; // 阵营(FacSet.HERO 或 FacSet.MON)
|
||||
kind?: number; // 未使用
|
||||
lv: number; // 英雄等级
|
||||
pool_lv?: number; // 卡片等级
|
||||
card_lv?: number; // 卡牌等级(驱动 bg_node 颜色:1=green 2=blue 3=purple 4=red 5=yellow)
|
||||
type: HType; // 攻击定位(近战/中程/远程)
|
||||
monType?: MonType; // 怪物专属类型
|
||||
hp: number; // 生命值上限
|
||||
@@ -224,7 +224,7 @@ export interface HeroEvolve {
|
||||
export const HeroInfo: Record<number, heroInfo> = {
|
||||
// ========== atked 类(战士 · 自身强化) ==========
|
||||
5011: {
|
||||
uuid: 5011, name: "小铁卫", path: "hk1", fac: FacSet.HERO, pool_lv: 1, lv: 1, type: HType.Melee, hp: 300, ap: 28,
|
||||
uuid: 5011, name: "小铁卫", path: "hk1", fac: FacSet.HERO, card_lv: 1, lv: 1, type: HType.Melee, hp: 300, ap: 28,
|
||||
skills: { 6001: { uuid: 6001, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.Slow3].cd, ccd: 0 } },
|
||||
atked: [{ s_uuid: 6301, t_num: 3, overrides: { TGroup: TGroup.Self, ap: 4 } }],
|
||||
// 成长主线:护盾层数 4→5→6(等效减伤 57%→67%),6 级追加治疗形成“盾挡+回血”双循环
|
||||
@@ -252,7 +252,7 @@ export const HeroInfo: Record<number, heroInfo> = {
|
||||
]
|
||||
},
|
||||
5012: {
|
||||
uuid: 5012, name: "不死小强", path: "hk2", fac: FacSet.HERO, pool_lv: 2, lv: 1, type: HType.Melee, hp: 600, ap: 57,
|
||||
uuid: 5012, name: "不死小强", path: "hk2", fac: FacSet.HERO, card_lv: 2, lv: 1, type: HType.Melee, hp: 600, ap: 57,
|
||||
skills: { 6001: { uuid: 6001, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.Slow3].cd, ccd: 0 } },
|
||||
atked: [{ s_uuid: 6302, t_num: 3, overrides: { TGroup: TGroup.Self, ap: 250 } }],
|
||||
evolve: {
|
||||
@@ -278,26 +278,26 @@ export const HeroInfo: Record<number, heroInfo> = {
|
||||
]
|
||||
},
|
||||
// 以下英雄暂时注释,保留待后续扩展
|
||||
// 5012:{uuid:5012,name:"不死小强",path:"hk2", fac:FacSet.HERO,pool_lv:2,lv:1,type:HType.Melee,hp:600,ap:57,
|
||||
// 5012:{uuid:5012,name:"不死小强",path:"hk2", fac:FacSet.HERO,card_lv:2,lv:1,type:HType.Melee,hp:600,ap:57,
|
||||
// skills:{6001:{uuid:6001,lv:1,cd:AtkSpeedSet[AtkSpeedLv.Slow3].cd,ccd:0}},
|
||||
// atked:[{s_uuid:6302,t_num:3,overrides:{TGroup:TGroup.Self,ap:250}}],
|
||||
// info:"每受击3次为自身回复攻击力250%的生命值"},
|
||||
// 5013:{uuid:5013,name:"铁骨头",path:"hk3", fac:FacSet.HERO,pool_lv:2,lv:1,type:HType.Melee,hp:600,ap:57,
|
||||
// 5013:{uuid:5013,name:"铁骨头",path:"hk3", fac:FacSet.HERO,card_lv:2,lv:1,type:HType.Melee,hp:600,ap:57,
|
||||
// skills:{6001:{uuid:6001,lv:1,cd:AtkSpeedSet[AtkSpeedLv.Slow3].cd,ccd:0}},
|
||||
// atked:[{s_uuid:6402,t_num:5,overrides:{TGroup:TGroup.Self,ap:100}}],
|
||||
// info:"每受击5次永久提升自身最大生命值100点"},
|
||||
// 5014:{uuid:5014,name:"怒火武者",path:"hk4", fac:FacSet.HERO,pool_lv:3,lv:1,type:HType.Melee,hp:900,ap:85,
|
||||
// 5014:{uuid:5014,name:"怒火武者",path:"hk4", fac:FacSet.HERO,card_lv:3,lv:1,type:HType.Melee,hp:900,ap:85,
|
||||
// skills:{6001:{uuid:6001,lv:1,cd:AtkSpeedSet[AtkSpeedLv.Slow1].cd,ccd:0}},
|
||||
// atked:[{s_uuid:6401,t_num:3,overrides:{TGroup:TGroup.Self,ap:12}}],
|
||||
// info:"每受击3次永久提升自身攻击力12点"},
|
||||
// 5015:{uuid:5015,name:"血刃武者",path:"hk5", fac:FacSet.HERO,pool_lv:4,lv:1,type:HType.Melee,hp:1200,ap:113,
|
||||
// 5015:{uuid:5015,name:"血刃武者",path:"hk5", fac:FacSet.HERO,card_lv:4,lv:1,type:HType.Melee,hp:1200,ap:113,
|
||||
// skills:{6001:{uuid:6001,lv:1,cd:AtkSpeedSet[AtkSpeedLv.Slow3].cd,ccd:0}},
|
||||
// atked:[
|
||||
// {s_uuid:6301,t_num:3,overrides:{TGroup:TGroup.Self,ap:3}},
|
||||
// {s_uuid:6401,t_num:5,overrides:{TGroup:TGroup.Self,ap:15}}
|
||||
// ],
|
||||
// info:"每受击3次加3层护盾,每受击5次永久+15攻击力"},
|
||||
// 5016:{uuid:5016,name:"狂血战士",path:"hc1", fac:FacSet.HERO,pool_lv:5,lv:1,type:HType.Melee,hp:1500,ap:142,
|
||||
// 5016:{uuid:5016,name:"狂血战士",path:"hc1", fac:FacSet.HERO,card_lv:5,lv:1,type:HType.Melee,hp:1500,ap:142,
|
||||
// skills:{6001:{uuid:6001,lv:1,cd:AtkSpeedSet[AtkSpeedLv.Slow3].cd,ccd:0}},
|
||||
// atked:[
|
||||
// {s_uuid:6401,t_num:3,overrides:{TGroup:TGroup.Self,ap:10}},
|
||||
@@ -307,7 +307,7 @@ export const HeroInfo: Record<number, heroInfo> = {
|
||||
|
||||
// ========== atking 类 — 刺客(自身强化) ==========
|
||||
5021: {
|
||||
uuid: 5021, name: "小刺客", path: "hc1", fac: FacSet.HERO, pool_lv: 1, lv: 1, type: HType.Melee, hp: 300, ap: 28,
|
||||
uuid: 5021, name: "小刺客", path: "hc1", fac: FacSet.HERO, card_lv: 1, lv: 1, type: HType.Melee, hp: 300, ap: 28,
|
||||
skills: { 6001: { uuid: 6001, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.Fast2].cd, ccd: 0 } },
|
||||
atking: [{ s_uuid: 6401, t_num: 5, overrides: { TGroup: TGroup.Self, ap: 8 } }],
|
||||
// 成长主线:滚雪球(AP增量8→10→12,5级阈值5→4刀);6级追加暴伤强化(永久叠加无100%上限,与高AP叠乘)
|
||||
@@ -335,26 +335,32 @@ export const HeroInfo: Record<number, heroInfo> = {
|
||||
]
|
||||
},
|
||||
5022: {
|
||||
uuid: 5022, name: "嗜血剑客", path: "hc2", fac: FacSet.HERO, pool_lv: 3, lv: 1, type: HType.Melee, hp: 900, ap: 85,
|
||||
uuid: 5022, name: "嗜血剑客", path: "hc2", fac: FacSet.HERO, card_lv: 3, lv: 1, type: HType.Melee, hp: 900, ap: 85,
|
||||
skills: { 6001: { uuid: 6001, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.Fast2].cd, ccd: 0 } },
|
||||
atking: [
|
||||
{ s_uuid: 6403, t_num: 5, overrides: { TGroup: TGroup.Self, hit_count: 1, timed_buff_id: 7012, buff_value: 15, buff_duration: 5 } },
|
||||
{ s_uuid: 6401, t_num: 7, overrides: { TGroup: TGroup.Self, ap: 12 } }
|
||||
],
|
||||
evolve: {
|
||||
2: { atking: [
|
||||
2: {
|
||||
atking: [
|
||||
{ s_uuid: 6403, t_num: 5, overrides: { TGroup: TGroup.Self, hit_count: 1, timed_buff_id: 7012, buff_value: 20, buff_duration: 5 } },
|
||||
{ s_uuid: 6401, t_num: 7, overrides: { TGroup: TGroup.Self, ap: 12 } }
|
||||
]},
|
||||
]
|
||||
},
|
||||
3: { ap_bonus: 20, hp_bonus: 80 },
|
||||
4: { atking: [
|
||||
4: {
|
||||
atking: [
|
||||
{ s_uuid: 6403, t_num: 5, overrides: { TGroup: TGroup.Self, hit_count: 1, timed_buff_id: 7012, buff_value: 20, buff_duration: 6 } },
|
||||
{ s_uuid: 6401, t_num: 7, overrides: { TGroup: TGroup.Self, ap: 15 } }
|
||||
]},
|
||||
5: { atking: [
|
||||
]
|
||||
},
|
||||
5: {
|
||||
atking: [
|
||||
{ s_uuid: 6403, t_num: 4, overrides: { TGroup: TGroup.Self, hit_count: 1, timed_buff_id: 7012, buff_value: 20, buff_duration: 6 } },
|
||||
{ s_uuid: 6401, t_num: 7, overrides: { TGroup: TGroup.Self, ap: 15 } }
|
||||
]},
|
||||
]
|
||||
},
|
||||
6: {
|
||||
atking: [
|
||||
{ s_uuid: 6403, t_num: 4, overrides: { TGroup: TGroup.Self, hit_count: 1, timed_buff_id: 7012, buff_value: 20, buff_duration: 6 } },
|
||||
@@ -374,7 +380,7 @@ export const HeroInfo: Record<number, heroInfo> = {
|
||||
]
|
||||
},
|
||||
// 5022: {
|
||||
// uuid: 5022, name: "嗜血剑客", path: "hc2", fac: FacSet.HERO, pool_lv: 3, lv: 1, type: HType.Melee, hp: 900, ap: 85,
|
||||
// uuid: 5022, name: "嗜血剑客", path: "hc2", fac: FacSet.HERO, card_lv: 3, lv: 1, type: HType.Melee, hp: 900, ap: 85,
|
||||
// skills: { 6001: { uuid: 6001, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.Fast2].cd, ccd: 0 } },
|
||||
// atking: [
|
||||
// { s_uuid: 6403, t_num: 5, overrides: { TGroup: TGroup.Self, ap: 10 } },
|
||||
@@ -383,7 +389,7 @@ export const HeroInfo: Record<number, heroInfo> = {
|
||||
// info: "每攻击5次永久+10%暴击率,每攻击7次永久+12攻击力"
|
||||
// },
|
||||
// 5023: {
|
||||
// uuid: 5023, name: "暗影杀手", path: "hc3", fac: FacSet.HERO, pool_lv: 5, lv: 1, type: HType.Melee, hp: 1500, ap: 142,
|
||||
// uuid: 5023, name: "暗影杀手", path: "hc3", fac: FacSet.HERO, card_lv: 5, lv: 1, type: HType.Melee, hp: 1500, ap: 142,
|
||||
// skills: { 6001: { uuid: 6001, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.Fast1].cd, ccd: 0 } },
|
||||
// atking: [
|
||||
// { s_uuid: 6403, t_num: 5, overrides: { TGroup: TGroup.Self, ap: 10 } },
|
||||
@@ -394,7 +400,7 @@ export const HeroInfo: Record<number, heroInfo> = {
|
||||
|
||||
// ========== atking 类 — 射手(队友强化,hit_count 控制目标数) ==========
|
||||
5031: {
|
||||
uuid: 5031, name: "援护弓手", path: "ha1", fac: FacSet.HERO, pool_lv: 1, lv: 1, type: HType.Long, hp: 143, ap: 40,
|
||||
uuid: 5031, name: "援护弓手", path: "ha1", fac: FacSet.HERO, card_lv: 1, lv: 1, type: HType.Long, hp: 143, ap: 40,
|
||||
skills: { 6001: { uuid: 6001, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.Normal2].cd, ccd: 0 } },
|
||||
atking: [{ s_uuid: 6401, t_num: 5, overrides: { TGroup: TGroup.Team, hit_count: 1, ap: 8 } }],
|
||||
// 成长主线:AP增益 8→10→12,5级 hit_count 1→2(2英雄环境=全队);6级追加全队攻速光环
|
||||
@@ -417,7 +423,7 @@ export const HeroInfo: Record<number, heroInfo> = {
|
||||
]
|
||||
},
|
||||
5032: {
|
||||
uuid: 5032, name: "战术弓手", path: "ha2", fac: FacSet.HERO, pool_lv: 3, lv: 1, type: HType.Long, hp: 430, ap: 120,
|
||||
uuid: 5032, name: "战术弓手", path: "ha2", fac: FacSet.HERO, card_lv: 3, lv: 1, type: HType.Long, hp: 430, ap: 120,
|
||||
skills: { 6008: { uuid: 6008, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.Normal1].cd, ccd: 0 } },
|
||||
atking: [{ s_uuid: 6403, t_num: 5, overrides: { TGroup: TGroup.Team, hit_count: 3, timed_buff_id: 7012, buff_value: 10, buff_duration: 5 } }],
|
||||
evolve: {
|
||||
@@ -443,13 +449,13 @@ export const HeroInfo: Record<number, heroInfo> = {
|
||||
]
|
||||
},
|
||||
// 5032: {
|
||||
// uuid: 5032, name: "战术弓手", path: "ha2", fac: FacSet.HERO, pool_lv: 3, lv: 1, type: HType.Long, hp: 430, ap: 120,
|
||||
// uuid: 5032, name: "战术弓手", path: "ha2", fac: FacSet.HERO, card_lv: 3, lv: 1, type: HType.Long, hp: 430, ap: 120,
|
||||
// skills: { 6001: { uuid: 6001, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.Normal1].cd, ccd: 0 } },
|
||||
// atking: [{ s_uuid: 6403, t_num: 5, overrides: { TGroup: TGroup.Team, hit_count: 3, ap: 10 } }],
|
||||
// info: "每攻击5次为随机3名队友永久提升暴击率10%"
|
||||
// },
|
||||
// 5033: {
|
||||
// uuid: 5033, name: "鹰眼弓将", path: "ha3", fac: FacSet.HERO, pool_lv: 5, lv: 1, type: HType.Long, hp: 717, ap: 200,
|
||||
// uuid: 5033, name: "鹰眼弓将", path: "ha3", fac: FacSet.HERO, card_lv: 5, lv: 1, type: HType.Long, hp: 717, ap: 200,
|
||||
// skills: { 6001: { uuid: 6001, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.Fast3].cd, ccd: 0 } },
|
||||
// atking: [
|
||||
// { s_uuid: 6401, t_num: 5, overrides: { TGroup: TGroup.Team, hit_count: 6, ap: 8 } },
|
||||
@@ -460,13 +466,13 @@ export const HeroInfo: Record<number, heroInfo> = {
|
||||
|
||||
// ========== dead 类(战士+刺客 · 死亡遗产) ==========
|
||||
// 5041: {
|
||||
// uuid: 5041, name: "殉道卫士", path: "hk1", fac: FacSet.HERO, pool_lv: 1, lv: 1, type: HType.Melee, hp: 300, ap: 28,
|
||||
// uuid: 5041, name: "殉道卫士", path: "hk1", fac: FacSet.HERO, card_lv: 1, lv: 1, type: HType.Melee, hp: 300, ap: 28,
|
||||
// skills: { 6001: { uuid: 6001, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.Slow3].cd, ccd: 0 } },
|
||||
// dead: [{ s_uuid: 6301, t_num: 1, overrides: { TGroup: TGroup.Team, ap: 3 } }],
|
||||
// info: "死亡时为全队添加3层护盾"
|
||||
// },
|
||||
// 5042: {
|
||||
// uuid: 5042, name: "遗志将军", path: "hk2", fac: FacSet.HERO, pool_lv: 2, lv: 1, type: HType.Melee, hp: 600, ap: 57,
|
||||
// uuid: 5042, name: "遗志将军", path: "hk2", fac: FacSet.HERO, card_lv: 2, lv: 1, type: HType.Melee, hp: 600, ap: 57,
|
||||
// skills: { 6001: { uuid: 6001, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.Slow3].cd, ccd: 0 } },
|
||||
// dead: [
|
||||
// { s_uuid: 6401, t_num: 1, overrides: { TGroup: TGroup.Team, ap: 20 } },
|
||||
@@ -476,13 +482,13 @@ export const HeroInfo: Record<number, heroInfo> = {
|
||||
// info: "死亡时全队永久+20攻击力、+80最大生命值,死后复活一次"
|
||||
// },
|
||||
// 5043: {
|
||||
// uuid: 5043, name: "亡魂刺客", path: "hc1", fac: FacSet.HERO, pool_lv: 3, lv: 1, type: HType.Melee, hp: 900, ap: 85,
|
||||
// uuid: 5043, name: "亡魂刺客", path: "hc1", fac: FacSet.HERO, card_lv: 3, lv: 1, type: HType.Melee, hp: 900, ap: 85,
|
||||
// skills: { 6001: { uuid: 6001, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.Normal1].cd, ccd: 0 } },
|
||||
// dead: [{ s_uuid: 6405, t_num: 1, overrides: { TGroup: TGroup.Team, ap: 15 } }],
|
||||
// info: "死亡时全队永久提升击晕概率15%"
|
||||
// },
|
||||
// 5044: {
|
||||
// uuid: 5044, name: "血誓剑客", path: "hc2", fac: FacSet.HERO, pool_lv: 4, lv: 1, type: HType.Melee, hp: 1200, ap: 113,
|
||||
// uuid: 5044, name: "血誓剑客", path: "hc2", fac: FacSet.HERO, card_lv: 4, lv: 1, type: HType.Melee, hp: 1200, ap: 113,
|
||||
// skills: { 6001: { uuid: 6001, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.Fast3].cd, ccd: 0 } },
|
||||
// dead: [
|
||||
// { s_uuid: 6403, t_num: 1, overrides: { TGroup: TGroup.Team, ap: 15 } },
|
||||
@@ -491,7 +497,7 @@ export const HeroInfo: Record<number, heroInfo> = {
|
||||
// info: "死亡时全队永久+15%暴击率、+20%暴伤"
|
||||
// },
|
||||
// 5045: {
|
||||
// uuid: 5045, name: "不灭战魂", path: "hk3", fac: FacSet.HERO, pool_lv: 5, lv: 1, type: HType.Melee, hp: 1500, ap: 142,
|
||||
// uuid: 5045, name: "不灭战魂", path: "hk3", fac: FacSet.HERO, card_lv: 5, lv: 1, type: HType.Melee, hp: 1500, ap: 142,
|
||||
// skills: { 6001: { uuid: 6001, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.Slow3].cd, ccd: 0 } },
|
||||
// dead: [
|
||||
// { s_uuid: 6301, t_num: 1, overrides: { TGroup: TGroup.Team, ap: 5 } },
|
||||
@@ -505,7 +511,7 @@ export const HeroInfo: Record<number, heroInfo> = {
|
||||
// 遗志双核心:死亡一次释放【盾+HP】双遗产;6级追加【AP】,并解锁第2次复活
|
||||
// 数值节奏:盾 5→6→7→8,HP 80→100→120→150,6级终极追加 AP+30 且复活次数 1→2
|
||||
5045: {
|
||||
uuid: 5045, name: "不灭战魂", path: "hk3", fac: FacSet.HERO, pool_lv: 5, lv: 1, type: HType.Melee, hp: 1500, ap: 60,
|
||||
uuid: 5045, name: "不灭战魂", path: "hk3", fac: FacSet.HERO, card_lv: 5, lv: 1, type: HType.Melee, hp: 1500, ap: 60,
|
||||
skills: { 6001: { uuid: 6001, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.Slow3].cd, ccd: 0 } },
|
||||
// 死亡释放:5 层护盾 + 全队 +80 HP;复活 1 次血量 50%
|
||||
dead: [{ s_uuid: 6301, t_num: 1, overrides: { TGroup: TGroup.Team, ap: 5 } }, { s_uuid: 6402, t_num: 1, overrides: { TGroup: TGroup.Team, ap: 80 } }],
|
||||
@@ -531,7 +537,7 @@ export const HeroInfo: Record<number, heroInfo> = {
|
||||
|
||||
// ========== fstart 类(法师 · 战前增益) ==========
|
||||
5051: {
|
||||
uuid: 5051, name: "占卜师", path: "hm1", fac: FacSet.HERO, pool_lv: 1, lv: 1, type: HType.Long, hp: 143, ap: 40,
|
||||
uuid: 5051, name: "占卜师", path: "hm1", fac: FacSet.HERO, card_lv: 1, lv: 1, type: HType.Long, hp: 143, ap: 40,
|
||||
skills: { 6001: { uuid: 6001, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.Mid3].cd, ccd: 0 } },
|
||||
// 战前计时 buff:每波开始全队 AP 限时提升(+30/5s → +60/7s → +90/10s),6级追加暴击驻场光环
|
||||
// 统一复用 7111 基础配置,通过 buff_value/buff_duration 覆写实现三档成长
|
||||
@@ -554,7 +560,7 @@ export const HeroInfo: Record<number, heroInfo> = {
|
||||
]
|
||||
},
|
||||
5052: {
|
||||
uuid: 5052, name: "护盾牧师", path: "hm2", fac: FacSet.HERO, pool_lv: 2, lv: 1, type: HType.Long, hp: 287, ap: 80,
|
||||
uuid: 5052, name: "护盾牧师", path: "hm2", fac: FacSet.HERO, card_lv: 2, lv: 1, type: HType.Long, hp: 287, ap: 80,
|
||||
skills: { 6001: { uuid: 6001, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.Slow1].cd, ccd: 0 } },
|
||||
fstart: [{ s_uuid: 6301, t_num: 1, overrides: { TGroup: TGroup.Team, ap: 3 } }],
|
||||
evolve: {
|
||||
@@ -575,25 +581,25 @@ export const HeroInfo: Record<number, heroInfo> = {
|
||||
]
|
||||
},
|
||||
// 5052: {
|
||||
// uuid: 5052, name: "护盾牧师", path: "hm2", fac: FacSet.HERO, pool_lv: 2, lv: 1, type: HType.Long, hp: 287, ap: 80,
|
||||
// uuid: 5052, name: "护盾牧师", path: "hm2", fac: FacSet.HERO, card_lv: 2, lv: 1, type: HType.Long, hp: 287, ap: 80,
|
||||
// skills: { 6001: { uuid: 6001, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.Slow1].cd, ccd: 0 } },
|
||||
// fstart: [{ s_uuid: 6301, t_num: 1, overrides: { TGroup: TGroup.Team, ap: 2 } }],
|
||||
// info: "战斗开始时为全队添加2层护盾"
|
||||
// },
|
||||
// 5053: {
|
||||
// uuid: 5053, name: "血盟法师", path: "hm3", fac: FacSet.HERO, pool_lv: 2, lv: 1, type: HType.Long, hp: 287, ap: 80,
|
||||
// uuid: 5053, name: "血盟法师", path: "hm3", fac: FacSet.HERO, card_lv: 2, lv: 1, type: HType.Long, hp: 287, ap: 80,
|
||||
// skills: { 6001: { uuid: 6001, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.Mid2].cd, ccd: 0 } },
|
||||
// fstart: [{ s_uuid: 6402, t_num: 1, overrides: { TGroup: TGroup.Team, ap: 100 } }],
|
||||
// info: "战斗开始时为全队永久提升最大生命值100点"
|
||||
// },
|
||||
// 5054: {
|
||||
// uuid: 5054, name: "暴击法师", path: "hm4", fac: FacSet.HERO, pool_lv: 3, lv: 1, type: HType.Long, hp: 430, ap: 120,
|
||||
// uuid: 5054, name: "暴击法师", path: "hm4", fac: FacSet.HERO, card_lv: 3, lv: 1, type: HType.Long, hp: 430, ap: 120,
|
||||
// skills: { 6001: { uuid: 6001, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.Mid3].cd, ccd: 0 } },
|
||||
// fstart: [{ s_uuid: 6403, t_num: 1, overrides: { TGroup: TGroup.Team, ap: 20 } }],
|
||||
// info: "战斗开始时为全队永久提升暴击率20%"
|
||||
// },
|
||||
// 5055: {
|
||||
// uuid: 5055, name: "毁灭法师", path: "hm5", fac: FacSet.HERO, pool_lv: 4, lv: 1, type: HType.Long, hp: 573, ap: 160,
|
||||
// uuid: 5055, name: "毁灭法师", path: "hm5", fac: FacSet.HERO, card_lv: 4, lv: 1, type: HType.Long, hp: 573, ap: 160,
|
||||
// skills: { 6001: { uuid: 6001, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.Mid1].cd, ccd: 0 } },
|
||||
// fstart: [
|
||||
// { s_uuid: 6404, t_num: 1, overrides: { TGroup: TGroup.Team, ap: 25 } },
|
||||
@@ -602,7 +608,7 @@ export const HeroInfo: Record<number, heroInfo> = {
|
||||
// info: "战斗开始时为全队永久+25%暴伤、+20攻击力"
|
||||
// },
|
||||
// 5056: {
|
||||
// uuid: 5056, name: "预言法师", path: "hm6", fac: FacSet.HERO, pool_lv: 5, lv: 1, type: HType.Long, hp: 717, ap: 200,
|
||||
// uuid: 5056, name: "预言法师", path: "hm6", fac: FacSet.HERO, card_lv: 5, lv: 1, type: HType.Long, hp: 717, ap: 200,
|
||||
// skills: { 6001: { uuid: 6001, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.Normal3].cd, ccd: 0 } },
|
||||
// fstart: [
|
||||
// { s_uuid: 6405, t_num: 1, overrides: { TGroup: TGroup.Team, ap: 20 } },
|
||||
@@ -614,13 +620,13 @@ export const HeroInfo: Record<number, heroInfo> = {
|
||||
|
||||
// ========== field 类(法师 · 驻场光环) ==========
|
||||
// 5061: {
|
||||
// uuid: 5061, name: "亡语法师", path: "hm1", fac: FacSet.HERO, pool_lv: 3, lv: 1, type: HType.Long, hp: 430, ap: 120,
|
||||
// uuid: 5061, name: "亡语法师", path: "hm1", fac: FacSet.HERO, card_lv: 3, lv: 1, type: HType.Long, hp: 430, ap: 120,
|
||||
// skills: { 6001: { uuid: 6001, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.Mid2].cd, ccd: 0 } },
|
||||
// field: [7015],
|
||||
// info: "驻场期间全队死亡触发技能次数+1,死亡后光环消失"
|
||||
// },
|
||||
5061: {
|
||||
uuid: 5061, name: "战歌法师", path: "hm3", fac: FacSet.HERO, pool_lv: 3, lv: 1, type: HType.Long, hp: 430, ap: 120,
|
||||
uuid: 5061, name: "战歌法师", path: "hm3", fac: FacSet.HERO, card_lv: 3, lv: 1, type: HType.Long, hp: 430, ap: 120,
|
||||
skills: { 6001: { uuid: 6001, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.Mid2].cd, ccd: 0 } },
|
||||
field: [7002],
|
||||
evolve: {
|
||||
@@ -643,7 +649,7 @@ export const HeroInfo: Record<number, heroInfo> = {
|
||||
|
||||
// ========== fend + atking 类(辅助 · 治疗续航 + 波次增益) ==========
|
||||
5071: {
|
||||
uuid: 5071, name: "治愈牧师", path: "hh1", fac: FacSet.HERO, pool_lv: 1, lv: 1, type: HType.Long, hp: 143, ap: 40,
|
||||
uuid: 5071, name: "治愈牧师", path: "hh1", fac: FacSet.HERO, card_lv: 1, lv: 1, type: HType.Long, hp: 143, ap: 40,
|
||||
skills: { 6001: { uuid: 6001, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.Normal3].cd, ccd: 0 } },
|
||||
atking: [{ s_uuid: 6302, t_num: 5, overrides: { TGroup: TGroup.Team, ap: 200 } }],
|
||||
// 成长主线:治疗量 200→250→300%,5级 hit_count 1→2(全队);6级追加护盾 atking,攻防一体
|
||||
@@ -671,28 +677,28 @@ export const HeroInfo: Record<number, heroInfo> = {
|
||||
]
|
||||
},
|
||||
// 5072: {
|
||||
// uuid: 5072, name: "小金库", path: "hh2", fac: FacSet.HERO, pool_lv: 2, lv: 1, type: HType.Long, hp: 287, ap: 80,
|
||||
// uuid: 5072, name: "小金库", path: "hh2", fac: FacSet.HERO, card_lv: 2, lv: 1, type: HType.Long, hp: 287, ap: 80,
|
||||
// skills: { 6001: { uuid: 6001, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.Mid1].cd, ccd: 0 } },
|
||||
// atking: [{ s_uuid: 6302, t_num: 5, overrides: { TGroup: TGroup.Team, ap: 200 } }],
|
||||
// fend: [{ s_uuid: 6303, t_num: 1, overrides: { gold: 1 } }],
|
||||
// info: "每攻击5次治疗全队,每波结束获得1金币"
|
||||
// },
|
||||
// 5073: {
|
||||
// uuid: 5073, name: "强化牧师", path: "hh3", fac: FacSet.HERO, pool_lv: 3, lv: 1, type: HType.Long, hp: 430, ap: 120,
|
||||
// uuid: 5073, name: "强化牧师", path: "hh3", fac: FacSet.HERO, card_lv: 3, lv: 1, type: HType.Long, hp: 430, ap: 120,
|
||||
// skills: { 6001: { uuid: 6001, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.Normal3].cd, ccd: 0 } },
|
||||
// atking: [{ s_uuid: 6302, t_num: 5, overrides: { TGroup: TGroup.Team, ap: 250 } }],
|
||||
// fend: [{ s_uuid: 6401, t_num: 1, overrides: { TGroup: TGroup.Team, ap: 10 } }],
|
||||
// info: "每攻击5次治疗全队,每波结束全队永久+10攻击力"
|
||||
// },
|
||||
// 5074: {
|
||||
// uuid: 5074, name: "生命牧师", path: "hh4", fac: FacSet.HERO, pool_lv: 4, lv: 1, type: HType.Long, hp: 573, ap: 160,
|
||||
// uuid: 5074, name: "生命牧师", path: "hh4", fac: FacSet.HERO, card_lv: 4, lv: 1, type: HType.Long, hp: 573, ap: 160,
|
||||
// skills: { 6001: { uuid: 6001, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.Normal3].cd, ccd: 0 } },
|
||||
// atking: [{ s_uuid: 6302, t_num: 5, overrides: { TGroup: TGroup.Team, ap: 250 } }],
|
||||
// fend: [{ s_uuid: 6402, t_num: 1, overrides: { TGroup: TGroup.Team, ap: 80 } }],
|
||||
// info: "每攻击5次治疗全队,每波结束全队永久+80最大生命值"
|
||||
// },
|
||||
// 5075: {
|
||||
// uuid: 5075, name: "全能牧师", path: "hh5", fac: FacSet.HERO, pool_lv: 5, lv: 1, type: HType.Long, hp: 717, ap: 200,
|
||||
// uuid: 5075, name: "全能牧师", path: "hh5", fac: FacSet.HERO, card_lv: 5, lv: 1, type: HType.Long, hp: 717, ap: 200,
|
||||
// skills: { 6001: { uuid: 6001, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.Normal2].cd, ccd: 0 } },
|
||||
// atking: [{ s_uuid: 6302, t_num: 5, overrides: { TGroup: TGroup.Team, ap: 300 } }],
|
||||
// fend: [
|
||||
|
||||
@@ -73,7 +73,7 @@ export class Hero extends ecs.Entity {
|
||||
* 2) 初始化表现与属性数据
|
||||
* 3) 播放下落入场并在落地后启用碰撞与移动
|
||||
*/
|
||||
load(pos: Vec3 = Vec3.ZERO,scale:number = 1,uuid:number=1001, dropToY:number = pos.y,hero_lv:number=1, pool_lv:number=1, posIndex: number = -1) {
|
||||
load(pos: Vec3 = Vec3.ZERO, scale: number = 1, uuid: number = 1001, dropToY: number = pos.y, hero_lv: number = 1, card_lv: number = 1, posIndex: number = -1) {
|
||||
// 英雄始终朝右,表现缩放固定为正向
|
||||
scale = 1
|
||||
// 英雄等级在当前规则下上限为 3,避免超配表范围
|
||||
@@ -116,8 +116,8 @@ export class Hero extends ecs.Entity {
|
||||
model.hero_uuid = uuid;
|
||||
model.hero_name = hero.name;
|
||||
model.lv = hero_lv;
|
||||
model.pool_lv = pool_lv;
|
||||
model.base_pool_lv = hero.pool_lv ?? 1;
|
||||
model.card_lv = card_lv;
|
||||
model.base_card_lv = hero.card_lv ?? 1;
|
||||
model.type = hero.type;
|
||||
model.fac = FacSet.HERO;
|
||||
model.dis = hero.dis ?? 720;
|
||||
|
||||
@@ -24,8 +24,8 @@ export class HeroAttrsComp extends ecs.Comp {
|
||||
hero_uuid: number = 1001;
|
||||
hero_name: string = "hero";
|
||||
lv: number = 1;
|
||||
pool_lv: number = 1;
|
||||
base_pool_lv: number = 1;
|
||||
card_lv: number = 1;
|
||||
base_card_lv: number = 1;
|
||||
type: number = 0; // 0近战 1远程 2辅助
|
||||
fac: number = 0; // 0:hero 1:monster
|
||||
// ==================== 基础属性(有初始值) ====================
|
||||
|
||||
@@ -292,6 +292,9 @@ export class CHeroComp extends CCComp {
|
||||
}
|
||||
}
|
||||
|
||||
// 背景:按 card_lv 激活对应颜色子节点(1→green 2→blue 3→purple 4→red 5→yellow)
|
||||
this.updateBgNode();
|
||||
|
||||
// 描述词条(最多显示 3 条,对应 fied1/fied2/fied3)
|
||||
const fieldLabels = [this.fied1, this.fied2, this.fied3];
|
||||
const desc = hero?.info || this.cardData.info || "";
|
||||
@@ -321,6 +324,30 @@ export class CHeroComp extends CCComp {
|
||||
this.playEnterAnim();
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据 card_lv 切换 bg_node 下的颜色子节点显示。
|
||||
* 等级与颜色对应关系:
|
||||
* card_lv 1 → green
|
||||
* card_lv 2 → blue
|
||||
* card_lv 3 → purple
|
||||
* card_lv 4 → red
|
||||
* card_lv 5 → yellow
|
||||
*/
|
||||
private updateBgNode() {
|
||||
if (!this.bg_node || !this.cardData) return;
|
||||
const lvToColor: Record<number, string> = {
|
||||
1: "green",
|
||||
2: "blue",
|
||||
3: "purple",
|
||||
4: "red",
|
||||
5: "yellow",
|
||||
};
|
||||
const targetColor = lvToColor[this.cardData.card_lv ?? 1];
|
||||
this.bg_node.children.forEach(child => {
|
||||
child.active = (child.name === targetColor);
|
||||
});
|
||||
}
|
||||
|
||||
// ======================== 动画效果 ========================
|
||||
|
||||
/** 入场动画时长(秒) */
|
||||
@@ -552,7 +579,7 @@ export class CHeroComp extends CCComp {
|
||||
? (this.queryHeroUuidByEid(this.cardData.target_hero_eid as number) ?? this.cardData.uuid)
|
||||
: this.cardData.uuid;
|
||||
const heroLv = Math.max(1, this.cardData.hero_lv ?? 1);
|
||||
const poolLv = Math.max(1, this.cardData.base_pool_lv ?? this.cardData.pool_lv ?? 1);
|
||||
const poolLv = Math.max(1, this.cardData.base_card_lv ?? this.cardData.card_lv ?? 1);
|
||||
|
||||
// oops.gui 打开 HInfo 英雄卡预览
|
||||
oops.gui.remove(UIID.HInfo);
|
||||
@@ -585,7 +612,7 @@ export class CHeroComp extends CCComp {
|
||||
reason: "",
|
||||
uuid: this.cardData.uuid,
|
||||
hero_lv: this.cardData.hero_lv ?? 1,
|
||||
card_lv: this.cardData.base_pool_lv ?? this.cardData.pool_lv ?? 1
|
||||
card_lv: this.cardData.base_card_lv ?? this.cardData.card_lv ?? 1
|
||||
};
|
||||
oops.message.dispatchEvent(GameEvent.UseHeroCard, guard);
|
||||
if (guard.cancel) return;
|
||||
|
||||
@@ -298,7 +298,7 @@ export class CardComp extends CCComp {
|
||||
reason: "",
|
||||
uuid: this.cardData.uuid,
|
||||
hero_lv: this.cardData.hero_lv ?? 1,
|
||||
card_lv: this.cardData.base_pool_lv ?? this.cardData.pool_lv ?? 1
|
||||
card_lv: this.cardData.base_card_lv ?? this.cardData.card_lv ?? 1
|
||||
};
|
||||
oops.message.dispatchEvent(GameEvent.UseHeroCard, guard);
|
||||
if (guard.cancel) {
|
||||
@@ -549,7 +549,7 @@ export class CardComp extends CCComp {
|
||||
? (this.queryHeroUuidByEid(this.cardData!.target_hero_eid as number) ?? this.card_uuid)
|
||||
: this.card_uuid;
|
||||
const heroLv = Math.max(1, this.cardData?.hero_lv ?? 1);
|
||||
const poolLv = Math.max(1, this.cardData?.base_pool_lv ?? this.cardData?.pool_lv ?? 1);
|
||||
const poolLv = Math.max(1, this.cardData?.base_card_lv ?? this.cardData?.card_lv ?? 1);
|
||||
oops.gui.remove(UIID.HInfo);
|
||||
oops.gui.open(UIID.HInfo, { heroUuid, heroLv, poolLv });
|
||||
}
|
||||
@@ -659,7 +659,7 @@ export class CardComp extends CCComp {
|
||||
* 2. 技能卡:显示技能名(带品质后缀)、描述文本、静态图标。
|
||||
* 3. 特殊卡:显示卡名(带品质后缀)、描述文本、静态图标。
|
||||
*
|
||||
* 同时根据 pool_lv 切换背景底框,根据 hero_lv / card_lv 切换普通/高级边框。
|
||||
* 同时根据 card_lv 切换背景底框,根据 hero_lv / card_lv 切换普通/高级边框。
|
||||
*/
|
||||
private applyCardUI() {
|
||||
if (!this.cardData) {
|
||||
@@ -686,7 +686,7 @@ export class CardComp extends CCComp {
|
||||
const kindName = CKind[renderKind];
|
||||
|
||||
if (this.BG_node) {
|
||||
const bgLv = this.cardData.base_pool_lv ?? this.cardData.pool_lv;
|
||||
const bgLv = this.cardData.base_card_lv ?? this.cardData.card_lv;
|
||||
this.BG_node.children.forEach(child => {
|
||||
child.active = (child.name === kindName);
|
||||
const bg = child.getComponent(CardBgComp);
|
||||
|
||||
@@ -115,10 +115,10 @@ export class CardLiteComp extends CCComp {
|
||||
* 便捷方法:通过英雄 UUID 和卡池等级直接设置英雄卡。
|
||||
* 自动从 CardPoolList 查找匹配的卡牌配置。
|
||||
* @param uuid 英雄 UUID
|
||||
* @param poolLv 卡池等级(默认 1)
|
||||
* @param cardLv 卡牌等级(默认 1)
|
||||
*/
|
||||
setHeroByUuid(uuid: number, poolLv: number = 1) {
|
||||
const card = CardPoolList.find(c => c.uuid === uuid && c.pool_lv === poolLv);
|
||||
setHeroByUuid(uuid: number, cardLv: number = 1) {
|
||||
const card = CardPoolList.find(c => c.uuid === uuid && c.card_lv === cardLv);
|
||||
if (card) {
|
||||
this.setData(card);
|
||||
return;
|
||||
@@ -130,7 +130,7 @@ export class CardLiteComp extends CCComp {
|
||||
type: CardType.Hero,
|
||||
cost: 5,
|
||||
weight: 25,
|
||||
pool_lv: poolLv as any,
|
||||
card_lv: cardLv,
|
||||
kind: CKind.Hero,
|
||||
hero_lv: hero.lv || 1
|
||||
});
|
||||
@@ -194,7 +194,7 @@ export class CardLiteComp extends CCComp {
|
||||
* 2. 技能卡:显示技能名、静态图标。
|
||||
* 3. 特殊卡:显示卡名、静态图标。
|
||||
*
|
||||
* 同时根据 pool_lv 切换背景底框,根据 kind 切换种类标识。
|
||||
* 同时根据 card_lv 切换背景底框,根据 kind 切换种类标识。
|
||||
*/
|
||||
private applyCardUI() {
|
||||
if (!this.cardData) {
|
||||
@@ -221,7 +221,7 @@ export class CardLiteComp extends CCComp {
|
||||
const kindName = CKind[this.cardData.kind];
|
||||
|
||||
if (this.BG_node) {
|
||||
const bgLv = this.cardData.base_pool_lv ?? this.cardData.pool_lv;
|
||||
const bgLv = this.cardData.base_card_lv ?? this.cardData.card_lv;
|
||||
this.BG_node.children.forEach(child => {
|
||||
child.active = (child.name === kindName);
|
||||
const bg = child.getComponent(CardBgComp);
|
||||
|
||||
@@ -333,7 +333,7 @@ export class HInfoComp extends CCComp {
|
||||
this.BG_node.children.forEach(child => {
|
||||
child.active = (child.name === kindName);
|
||||
const bg = child.getComponent(CardBgComp);
|
||||
if (bg) child.active ? bg.apply(this.model.base_pool_lv ?? this.model.pool_lv ?? 1) : bg.clear();
|
||||
if (bg) child.active ? bg.apply(this.model.base_card_lv ?? this.model.card_lv ?? 1) : bg.clear();
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -116,7 +116,7 @@ export class HerosListComp extends CCComp {
|
||||
this.cards_node.removeAllChildren()
|
||||
|
||||
const sorted = [...HeroList].sort((a, b) => {
|
||||
return (HeroInfo[a]?.pool_lv ?? 1) - (HeroInfo[b]?.pool_lv ?? 1);
|
||||
return (HeroInfo[a]?.card_lv ?? 1) - (HeroInfo[b]?.card_lv ?? 1);
|
||||
});
|
||||
|
||||
for (const uuid of sorted) {
|
||||
@@ -136,7 +136,7 @@ export class HerosListComp extends CCComp {
|
||||
})
|
||||
|
||||
const comp = cardNode.getComponent(CardLiteComp) || cardNode.addComponent(CardLiteComp)
|
||||
comp.setHeroByUuid(uuid, hero.pool_lv ?? 1)
|
||||
comp.setHeroByUuid(uuid, hero.card_lv ?? 1)
|
||||
comp.onClickCallback = (cardComp: CardLiteComp) => {
|
||||
this.onCardSelect(uuid)
|
||||
this.highlightCard(cardNode)
|
||||
@@ -209,7 +209,7 @@ export class HerosListComp extends CCComp {
|
||||
if (infoLabel) infoLabel.string = desc || hero.info || ""
|
||||
}
|
||||
|
||||
this.updatePoolLvBg(hero.pool_lv ?? 1)
|
||||
this.updatePoolLvBg(hero.card_lv ?? 1)
|
||||
this.updateLvDisplay(hero)
|
||||
this.updateTypeDisplay(hero)
|
||||
this.updateHeroAnimation(uuid)
|
||||
@@ -237,7 +237,7 @@ export class HerosListComp extends CCComp {
|
||||
|
||||
private updateLvDisplay(hero: typeof HeroInfo[number]) {
|
||||
if (!this.lv_node) return
|
||||
const cardLvStr = `lv${hero.pool_lv ?? 1}`
|
||||
const cardLvStr = `lv${hero.card_lv ?? 1}`
|
||||
this.lv_node.active = true
|
||||
this.lv_node.children.forEach(child => {
|
||||
|
||||
|
||||
@@ -1,330 +0,0 @@
|
||||
/**
|
||||
* @file HlistComp.ts
|
||||
* @description 英雄列表轮播组件(UI 视图层)
|
||||
*
|
||||
* 职责:
|
||||
* 1. 在主页界面以 **5 格轮播** 形式展示英雄图鉴。
|
||||
* 2. 支持左右切换,用 tween 动画平滑过渡节点位置。
|
||||
* 3. 点击切换时自动更新当前选中英雄的名称、AP、HP 和技能信息。
|
||||
*
|
||||
* 关键设计:
|
||||
* - carouselNodes[0..4] 对应 5 个展示位(最左-2 到最右+2),
|
||||
* 中间位 [2] 为当前选中英雄。
|
||||
* - 切换时:将即将移出屏幕的节点瞬间跳转到另一端,再用 tween 滑入。
|
||||
* - 切换完成后重排 carouselNodes 数组保持逻辑顺序。
|
||||
* - iconVisualTokens 按节点独立管理竞态令牌,防止异步动画回调错乱。
|
||||
*
|
||||
* 依赖:
|
||||
* - HeroInfo / HeroList(heroSet)—— 英雄静态配置与全量英雄 UUID 列表
|
||||
* - SkillSet / IType(SkillSet)—— 技能配置与类型枚举
|
||||
*/
|
||||
import { _decorator, Animation, AnimationClip, Button, Event, Label, Node, NodeEventType, Sprite, resources, tween, Vec3, Widget } from "cc";
|
||||
import { ecs } from "../../../../extensions/oops-plugin-framework/assets/libs/ecs/ECS";
|
||||
import { CCComp } from "../../../../extensions/oops-plugin-framework/assets/module/common/CCComp";
|
||||
import { HeroInfo, HeroList } from "../common/config/heroSet";
|
||||
import { IType, SkillSet } from "../common/config/SkillSet";
|
||||
import { oops } from "db://oops-framework/core/Oops";
|
||||
import { mLogger } from "../common/Logger";
|
||||
import { UIID } from "../common/config/GameUIConfig";
|
||||
|
||||
const {property, ccclass } = _decorator;
|
||||
|
||||
/**
|
||||
* HListComp —— 英雄图鉴轮播视图组件
|
||||
*
|
||||
* 在任务主页展示所有可用英雄,玩家可左右滑动查看:
|
||||
* - 中间位显示完整信息(名称 / AP / HP / 技能列表)
|
||||
* - 两侧位显示缩略 idle 动画
|
||||
*/
|
||||
@ccclass('HListComp')
|
||||
@ecs.register('HListComp', false)
|
||||
export class HListComp extends CCComp {
|
||||
// ======================== 编辑器绑定节点 ========================
|
||||
|
||||
/** 中间位英雄 idle 图标节点 */
|
||||
@property(Node)
|
||||
hero_icon=null!
|
||||
|
||||
/** 攻击力标签节点 */
|
||||
@property(Node)
|
||||
ap_node=null!
|
||||
/** 生命值标签节点 */
|
||||
@property(Node)
|
||||
hp_node=null!
|
||||
/** 技能信息容器节点(包含 Line1~Line5 子节点) */
|
||||
@property(Node)
|
||||
info_node=null!
|
||||
/** 英雄名称标签节点 */
|
||||
@property(Node)
|
||||
name_node=null!
|
||||
/** 向左切换按钮 */
|
||||
|
||||
@property(Node)
|
||||
lv_node=null!
|
||||
|
||||
// ======================== 运行时状态 ========================
|
||||
|
||||
/** 当前选中英雄在 HeroList 中的索引 */
|
||||
huuid:number=null!
|
||||
/** 当前选中英雄在 HeroList 数组中的下标 */
|
||||
private currentIndex: number = 0;
|
||||
/** 各图标节点的视觉令牌映射(防止异步动画竞态) */
|
||||
private iconVisualTokens: Map<Node, number> = new Map();
|
||||
/** 是否正在播放切换动画(防止快速连点) */
|
||||
private isAnimating: boolean = false;
|
||||
/** 轮播节点数组,顺序为 [左2, 左1, 中, 右1, 右2] */
|
||||
private carouselNodes: Node[] = [];
|
||||
/** 5 个固定位置坐标(从场景中读取初始值) */
|
||||
private fixedPositions: Vec3[] = [];
|
||||
/** 调试日志开关 */
|
||||
debugMode: boolean = false;
|
||||
|
||||
onLoad() {
|
||||
|
||||
}
|
||||
/** 预留:弹窗打开时接收参数 */
|
||||
onAdded(args: any) {
|
||||
|
||||
}
|
||||
/** 关闭排行榜弹窗 */
|
||||
closeHeros(){
|
||||
oops.gui.remove(UIID.Heros)
|
||||
}
|
||||
start() {
|
||||
|
||||
|
||||
// 设置初始选中并加载所有位置的英雄动画
|
||||
if (HeroList && HeroList.length > 0) {
|
||||
this.currentIndex = 0;
|
||||
this.initAllNodes();
|
||||
this.updateHeroInfo();
|
||||
}
|
||||
}
|
||||
|
||||
// ======================== 切换逻辑 ========================
|
||||
|
||||
/**
|
||||
* 向左切换(查看上一个英雄):
|
||||
* 1. currentIndex 左移。
|
||||
* 2. 最右节点 n4 瞬间跳到最左位置,加载新英雄动画。
|
||||
* 3. 所有节点 tween 向右滑动一格。
|
||||
* 4. 动画完成后重排 carouselNodes 数组。
|
||||
*/
|
||||
private onPreClick() {
|
||||
if (!HeroList || HeroList.length === 0 || this.isAnimating || this.carouselNodes.length < 5) return;
|
||||
this.isAnimating = true;
|
||||
|
||||
this.currentIndex = (this.currentIndex - 1 + HeroList.length) % HeroList.length;
|
||||
|
||||
const [n0, n1, n2, n3, n4] = this.carouselNodes;
|
||||
|
||||
// n4 瞬间跳至最左位置,准备滑入
|
||||
n4.setPosition(new Vec3(this.fixedPositions[0].x, n4.position.y, n4.position.z));
|
||||
this.updateNodeAnimationByOffset(n4, -2);
|
||||
this.updateHeroInfo();
|
||||
|
||||
// 所有节点向右滑动一格
|
||||
tween(n0).to(0.2, { position: new Vec3(this.fixedPositions[1].x, n0.position.y, n0.position.z) }).start();
|
||||
tween(n1).to(0.2, { position: new Vec3(this.fixedPositions[2].x, n1.position.y, n1.position.z) }).start();
|
||||
tween(n2).to(0.2, { position: new Vec3(this.fixedPositions[3].x, n2.position.y, n2.position.z) }).start();
|
||||
tween(n3).to(0.2, { position: new Vec3(this.fixedPositions[4].x, n3.position.y, n3.position.z) })
|
||||
.call(() => {
|
||||
// 重排数组:n4 成为新的最左节点
|
||||
this.carouselNodes = [n4, n0, n1, n2, n3];
|
||||
this.isAnimating = false;
|
||||
})
|
||||
.start();
|
||||
}
|
||||
|
||||
/**
|
||||
* 向右切换(查看下一个英雄):
|
||||
* 1. currentIndex 右移。
|
||||
* 2. 最左节点 n0 瞬间跳到最右位置,加载新英雄动画。
|
||||
* 3. 所有节点 tween 向左滑动一格。
|
||||
* 4. 动画完成后重排 carouselNodes 数组。
|
||||
*/
|
||||
private onNextClick() {
|
||||
if (!HeroList || HeroList.length === 0 || this.isAnimating || this.carouselNodes.length < 5) return;
|
||||
this.isAnimating = true;
|
||||
|
||||
this.currentIndex = (this.currentIndex + 1) % HeroList.length;
|
||||
|
||||
const [n0, n1, n2, n3, n4] = this.carouselNodes;
|
||||
|
||||
// n0 瞬间跳至最右位置,准备滑入
|
||||
n0.setPosition(new Vec3(this.fixedPositions[4].x, n0.position.y, n0.position.z));
|
||||
this.updateNodeAnimationByOffset(n0, 2);
|
||||
this.updateHeroInfo();
|
||||
|
||||
// 所有节点向左滑动一格
|
||||
tween(n1).to(0.2, { position: new Vec3(this.fixedPositions[0].x, n1.position.y, n1.position.z) }).start();
|
||||
tween(n2).to(0.2, { position: new Vec3(this.fixedPositions[1].x, n2.position.y, n2.position.z) }).start();
|
||||
tween(n3).to(0.2, { position: new Vec3(this.fixedPositions[2].x, n3.position.y, n3.position.z) }).start();
|
||||
tween(n4).to(0.2, { position: new Vec3(this.fixedPositions[3].x, n4.position.y, n4.position.z) })
|
||||
.call(() => {
|
||||
// 重排数组:n0 成为新的最右节点
|
||||
this.carouselNodes = [n1, n2, n3, n4, n0];
|
||||
this.isAnimating = false;
|
||||
})
|
||||
.start();
|
||||
}
|
||||
|
||||
// ======================== 数据查询 ========================
|
||||
|
||||
/**
|
||||
* 根据偏移量获取英雄 UUID。
|
||||
* @param offset 相对于当前选中英雄的偏移(-2, -1, 0, 1, 2)
|
||||
* @returns HeroList 中对应位置的英雄 UUID
|
||||
*/
|
||||
private getHeroUuid(offset: number): number {
|
||||
const len = HeroList.length;
|
||||
return HeroList[(this.currentIndex + offset + len * 5) % len];
|
||||
}
|
||||
|
||||
/**
|
||||
* 按偏移量更新指定节点的英雄动画。
|
||||
* @param node 目标图标节点
|
||||
* @param offset 偏移量
|
||||
*/
|
||||
private updateNodeAnimationByOffset(node: Node, offset: number) {
|
||||
const uuid = this.getHeroUuid(offset);
|
||||
this.updateHeroAnimation(node, uuid);
|
||||
}
|
||||
|
||||
/** 更新当前选中英雄的详细信息(名称、AP、HP、技能列表) */
|
||||
private updateHeroInfo() {
|
||||
this.huuid = this.getHeroUuid(0);
|
||||
const hero = HeroInfo[this.huuid];
|
||||
if (!hero) return;
|
||||
|
||||
const heroLv = Math.max(1, Math.floor(hero.lv ?? 1));
|
||||
const suffix = heroLv >= 2 ? "★".repeat(heroLv - 1) : "";
|
||||
this.setLabelText(this.name_node, `${suffix}${hero.name || ""}${suffix}`);
|
||||
|
||||
this.setLabelText(this.ap_node, `${(hero.ap ?? 0) * heroLv}`);
|
||||
this.setLabelText(this.hp_node, `${(hero.hp ?? 0) * heroLv}`);
|
||||
|
||||
if (this.info_node) {
|
||||
const infoLabel = this.info_node.getChildByName("info")?.getComponent(Label);
|
||||
if (infoLabel) infoLabel.string = `${hero.info || ""}`;
|
||||
}
|
||||
|
||||
const cardLvStr = `lv${hero.pool_lv ?? 1}`;
|
||||
if (this.lv_node) {
|
||||
this.lv_node.active = true;
|
||||
this.lv_node.children.forEach(child => {
|
||||
if (child.name === "light") {
|
||||
child.active = false;
|
||||
} else if (child.name === "bg") {
|
||||
child.active = true;
|
||||
} else {
|
||||
child.active = (child.name === cardLvStr);
|
||||
}
|
||||
});
|
||||
const widget = this.lv_node.getComponent(Widget);
|
||||
if (widget) widget.updateAlignment();
|
||||
this.lv_node.children.forEach(child => {
|
||||
const childWidget = child.getComponent(Widget);
|
||||
if (childWidget) childWidget.updateAlignment();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/** 初始化 5 个轮播位的英雄动画 */
|
||||
private initAllNodes() {
|
||||
if (this.carouselNodes.length < 5) return;
|
||||
this.updateNodeAnimationByOffset(this.carouselNodes[0], -2);
|
||||
this.updateNodeAnimationByOffset(this.carouselNodes[1], -1);
|
||||
this.updateNodeAnimationByOffset(this.carouselNodes[2], 0);
|
||||
this.updateNodeAnimationByOffset(this.carouselNodes[3], 1);
|
||||
this.updateNodeAnimationByOffset(this.carouselNodes[4], 2);
|
||||
}
|
||||
|
||||
// ======================== UI 工具 ========================
|
||||
|
||||
/**
|
||||
* 安全设置 Label 文本
|
||||
* @param node 标签所在节点
|
||||
* @param text 文本内容
|
||||
*/
|
||||
private setLabelText(node: Node, text: string) {
|
||||
if (!node) return;
|
||||
const label = node.getComponent(Label) || node.getComponentInChildren(Label);
|
||||
if (label) {
|
||||
label.string = text;
|
||||
}
|
||||
}
|
||||
|
||||
// ======================== 英雄动画 ========================
|
||||
|
||||
/**
|
||||
* 为指定节点加载并播放英雄 idle 动画。
|
||||
* 使用 iconVisualTokens 做节点级竞态保护。
|
||||
*
|
||||
* @param node 图标节点
|
||||
* @param uuid 英雄 UUID
|
||||
*/
|
||||
private updateHeroAnimation(node: Node, uuid: number) {
|
||||
if (!node) return;
|
||||
const sprite = node.getComponent(Sprite) || node.getComponentInChildren(Sprite);
|
||||
if (sprite) sprite.spriteFrame = null;
|
||||
|
||||
const hero = HeroInfo[uuid];
|
||||
if (!hero) return;
|
||||
|
||||
const anim = node.getComponent(Animation) || node.addComponent(Animation);
|
||||
this.clearAnimationClips(anim);
|
||||
|
||||
// 递增该节点的视觉令牌
|
||||
let token = (this.iconVisualTokens.get(node) || 0) + 1;
|
||||
this.iconVisualTokens.set(node, token);
|
||||
const path = `game/heros/hero/${hero.path}/idle`;
|
||||
|
||||
resources.load(path, AnimationClip, (err, clip) => {
|
||||
if (err || !clip) {
|
||||
mLogger.log(this.debugMode, "HListComp", `load hero animation failed ${uuid}`, err);
|
||||
return;
|
||||
}
|
||||
// 竞态保护:令牌不匹配则丢弃
|
||||
if (token !== this.iconVisualTokens.get(node)) {
|
||||
return;
|
||||
}
|
||||
this.clearAnimationClips(anim);
|
||||
anim.addClip(clip);
|
||||
anim.play("idle");
|
||||
});
|
||||
}
|
||||
|
||||
/** 移除 Animation 上的全部 clip(倒序遍历避免索引偏移) */
|
||||
private clearAnimationClips(anim: Animation) {
|
||||
const clips = anim.clips;
|
||||
if (clips && clips.length > 0) {
|
||||
for (let i = clips.length - 1; i >= 0; i--) {
|
||||
const clip = clips[i];
|
||||
if (clip) anim.removeClip(clip, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 递归查找子节点(按名称)
|
||||
* @param root 起始节点
|
||||
* @param name 目标节点名
|
||||
*/
|
||||
private findNodeByName(root: Node, name: string): Node | null {
|
||||
if (!root) return null;
|
||||
if (root.name === name) return root;
|
||||
for (let i = 0; i < root.children.length; i++) {
|
||||
const res = this.findNodeByName(root.children[i], name);
|
||||
if (res) return res;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/** ECS 组件移除时销毁节点 */
|
||||
reset() {
|
||||
this.node.destroy();
|
||||
}
|
||||
}
|
||||
@@ -1 +0,0 @@
|
||||
{"ver":"4.0.24","importer":"typescript","imported":true,"uuid":"89bf6d65-5432-4946-9b14-3e5150dddedd","files":[],"subMetas":{},"userData":{}}
|
||||
@@ -419,7 +419,7 @@ export class ItemListComp extends CCComp {
|
||||
oops.gui.open(UIID.HInfo, {
|
||||
heroUuid: cardUuid,
|
||||
heroLv: this.cardData.card_lv ?? 1,
|
||||
poolLv: config?.pool_lv ?? 1,
|
||||
poolLv: config?.card_lv ?? 1,
|
||||
isSkillCard: true
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1473,7 +1473,7 @@ export class MissionCardComp extends CCComp {
|
||||
}
|
||||
|
||||
private tryRefreshHeroCards(heroType?: HType): boolean {
|
||||
const cards = drawCardsByRule(1, {
|
||||
const cards = drawCardsByRule({
|
||||
count: 3,
|
||||
type: CardType.Hero,
|
||||
heroType,
|
||||
|
||||
@@ -73,7 +73,7 @@ export class MissionHeroComp extends CCComp {
|
||||
/** 是否正在消费召唤队列(防止并发) */
|
||||
is_processing_queue: boolean = false
|
||||
/** 召唤请求队列:保证召唤按顺序串行执行 */
|
||||
summon_queue: { uuid: number; hero_lv: number; pool_lv: number }[] = []
|
||||
summon_queue: { uuid: number; hero_lv: number; card_lv: number }[] = []
|
||||
/** 预留英雄列表 */
|
||||
heros: any = []
|
||||
|
||||
@@ -141,17 +141,17 @@ export class MissionHeroComp extends CCComp {
|
||||
|
||||
/**
|
||||
* 召唤请求入口:
|
||||
* 从事件参数中提取 uuid / hero_lv / pool_lv,放入串行队列。
|
||||
* 从事件参数中提取 uuid / hero_lv / card_lv,放入串行队列。
|
||||
* 防御:已召唤的英雄 uuid 拒绝重复召唤(只能通过升级卡升级)。
|
||||
*
|
||||
* @param event 事件名
|
||||
* @param args { uuid, hero_lv, pool_lv }
|
||||
* @param args { uuid, hero_lv, card_lv }
|
||||
*/
|
||||
private async call_hero(event: string, args: any) {
|
||||
const payload = args ?? event;
|
||||
const uuid = Number(payload?.uuid ?? 1001);
|
||||
const hero_lv = Math.max(1, Number(payload?.hero_lv ?? 1));
|
||||
const pool_lv = Math.max(1, Number(payload?.pool_lv ?? 1));
|
||||
const card_lv = Math.max(1, Number(payload?.card_lv ?? 1));
|
||||
|
||||
// 防御:场上已有同 uuid 的存活英雄时,拒绝重复召唤
|
||||
if (this.isHeroAlreadySummoned(uuid)) {
|
||||
@@ -159,7 +159,7 @@ export class MissionHeroComp extends CCComp {
|
||||
return;
|
||||
}
|
||||
|
||||
this.summon_queue.push({ uuid, hero_lv, pool_lv });
|
||||
this.summon_queue.push({ uuid, hero_lv, card_lv });
|
||||
this.processSummonQueue();
|
||||
}
|
||||
|
||||
@@ -216,16 +216,16 @@ export class MissionHeroComp extends CCComp {
|
||||
*
|
||||
* @param uuid 英雄 UUID
|
||||
* @param hero_lv 英雄等级
|
||||
* @param pool_lv 卡池等级(历史遗留,新机制下不再使用)
|
||||
* @param card_lv 卡牌等级(驱动 bg_node 颜色)
|
||||
* @returns 创建的 Hero 实体
|
||||
*/
|
||||
private addHero(uuid: number = 1001, hero_lv: number = 1, pool_lv: number = 1) {
|
||||
private addHero(uuid: number = 1001, hero_lv: number = 1, card_lv: number = 1) {
|
||||
let hero = ecs.getEntity<Hero>(Hero);
|
||||
let scale = 1
|
||||
const posIndex = this.pickPositionIndexForHero();
|
||||
const landingPos = MissionHeroComp.HERO_POSITIONS[posIndex];
|
||||
let spawnPos: Vec3 = v3(landingPos.x, landingPos.y + MissionHeroComp.HERO_DROP_HEIGHT, 0);
|
||||
hero.load(spawnPos, scale, uuid, landingPos.y, hero_lv, pool_lv, posIndex);
|
||||
hero.load(spawnPos, scale, uuid, landingPos.y, hero_lv, card_lv, posIndex);
|
||||
|
||||
// 召唤完成后,派发事件以更新英雄面板
|
||||
const model = hero.get(HeroAttrsComp);
|
||||
@@ -267,7 +267,7 @@ export class MissionHeroComp extends CCComp {
|
||||
while (this.summon_queue.length > 0) {
|
||||
const payload = this.summon_queue.shift();
|
||||
if (!payload) continue;
|
||||
await this.handleSingleSummon(payload.uuid, payload.hero_lv, payload.pool_lv);
|
||||
await this.handleSingleSummon(payload.uuid, payload.hero_lv, payload.card_lv);
|
||||
}
|
||||
} finally {
|
||||
this.is_processing_queue = false;
|
||||
@@ -279,10 +279,10 @@ export class MissionHeroComp extends CCComp {
|
||||
*
|
||||
* @param uuid 英雄 UUID
|
||||
* @param hero_lv 英雄等级
|
||||
* @param pool_lv 卡池等级(历史遗留)
|
||||
* @param card_lv 卡牌等级
|
||||
*/
|
||||
private async handleSingleSummon(uuid: number, hero_lv: number, pool_lv: number = 1) {
|
||||
this.addHero(uuid, hero_lv, pool_lv);
|
||||
private async handleSingleSummon(uuid: number, hero_lv: number, card_lv: number = 1) {
|
||||
this.addHero(uuid, hero_lv, card_lv);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -409,7 +409,7 @@ export class SCardComp extends CCComp {
|
||||
oops.gui.open(UIID.HInfo, {
|
||||
heroUuid: cardUuid,
|
||||
heroLv: this.cardData.card_lv ?? 1,
|
||||
poolLv: config?.pool_lv ?? 1,
|
||||
poolLv: config?.card_lv ?? 1,
|
||||
isSkillCard: true
|
||||
});
|
||||
}
|
||||
|
||||
@@ -186,7 +186,7 @@ export class SkillBoxComp extends CCComp {
|
||||
const cardUuid = config ? config.uuid : this.s_uuid;
|
||||
|
||||
oops.gui.remove(UIID.HInfo);
|
||||
oops.gui.open(UIID.HInfo, { heroUuid: cardUuid, heroLv: this.card_lv, poolLv: config?.pool_lv ?? 1, isSkillCard: true });
|
||||
oops.gui.open(UIID.HInfo, { heroUuid: cardUuid, heroLv: this.card_lv, poolLv: config?.card_lv ?? 1, isSkillCard: true });
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -49,10 +49,10 @@ export class TalentItemComp extends CCComp {
|
||||
if (this.lbl_name) this.lbl_name.string = config.name ?? "";
|
||||
if (this.lbl_info) this.lbl_info.string = config.info ?? "";
|
||||
|
||||
// 直接复用 CardSet 中已映射好的 pool_lv,保证与技能卡牌背景一致
|
||||
// CardSet 通过 waveToPoolLv[wave] 由 SKILL_CARD_WAVES 索引推导(wave 1→1, 5→2, 8→3)
|
||||
// 直接复用 CardSet 中已映射好的 card_lv,保证与技能卡牌背景一致
|
||||
// CardSet 通过 waveToCardLv[wave] 由 SKILL_CARD_WAVES 索引推导(wave 1→1, 5→2, 8→3)
|
||||
if (this.bg) {
|
||||
this.bg.apply(config.pool_lv || 1);
|
||||
this.bg.apply(config.card_lv || 1);
|
||||
}
|
||||
|
||||
// 设置图标:驻场卡(skill=undefined 但有 field)走 FieldSkillSet,否则走 SkillSet
|
||||
|
||||
@@ -13,7 +13,7 @@ import { GameEvent } from "../common/config/GameEvent";
|
||||
import { HeroAttrsComp } from "../hero/HeroAttrsComp";
|
||||
import { FacSet } from "../common/config/GameSet";
|
||||
import { HeroInfo } from "../common/config/heroSet";
|
||||
import { CKind, CardType, CardLV, CardConfig } from "../common/config/CardSet";
|
||||
import { CKind, CardType, CardConfig } from "../common/config/CardSet";
|
||||
import { CardComp } from "./CardComp";
|
||||
import { HighlightSet, HighlightType, HighlightLevel } from "../common/config/HighlightSet";
|
||||
import { LangPrefix, lang, langf } from "../common/LangUtil";
|
||||
@@ -172,9 +172,9 @@ export class VictoryComp extends CCComp {
|
||||
cost: 0,
|
||||
weight: 0,
|
||||
kind: CKind.Hero,
|
||||
pool_lv: mvp.pool_lv || CardLV.LV1,
|
||||
card_lv: mvp.card_lv || 1,
|
||||
hero_lv: mvp.lv || 1,
|
||||
base_pool_lv: mvp.base_pool_lv || mvp.pool_lv || 1,
|
||||
base_card_lv: mvp.base_card_lv || mvp.card_lv || 1,
|
||||
};
|
||||
|
||||
const originalPos = this.mvp_node.position.clone();
|
||||
|
||||
Reference in New Issue
Block a user