3 Commits

Author SHA1 Message Date
pan
a94381b19f refactor(卡牌系统): 清理废弃的卡池等级相关代码并优化抽卡接口
1. 移除了CardSkillType枚举、废弃的CardLV枚举和相关常量定义
2. 删除了已废弃的getCardPoolByLv、getCardsByLv等兼容旧接口
3. 简化drawCardsByRule接口,移除不再生效的历史参数
4. 调整MissionCardComp中调用drawCardsByRule的传参方式
5. 格式化VictoryComp中的代码格式,统一代码风格
2026-07-27 16:11:52 +08:00
pan
9f2599e9ec refactor: 统一将 pool_lv 重命名为 card_lv 并清理废弃代码
本次提交完成了全项目范围内的术语统一重构:
1.  将所有`pool_lv`相关变量、字段、注释替换为`card_lv`,对齐卡牌等级的业务含义
2.  移除了配置中冗余的默认`pool_lv`赋值,简化数据结构
3.  删除了废弃的`HlistComp.ts`组件及其元文件
4.  修正了多处逻辑错误,确保卡牌等级正确驱动背景框切换
5.  更新了相关注释和文档,保持代码一致性
2026-07-27 15:54:53 +08:00
pan
62264deeed refactor(hero card): add card_lv background color logic
1. 新增updateBgNode方法根据card_lv切换英雄背景节点颜色
2. 为所有基础卡牌配置补充缺失的card_lv字段
3. 调整配置项字段顺序保持代码整洁
2026-07-27 15:33:46 +08:00
22 changed files with 216 additions and 599 deletions

View File

@@ -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",

View File

@@ -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))

View File

@@ -11,11 +11,11 @@
* → EquipBoxComptrigger_type=Field被动驻场→ FieldSkillHelper 全局聚合属性加成
*
* 依赖:
* - CardConfig / CardTriggerType / CardType / CKind / CardLVCardSet
* - CardConfig / CardTriggerType / CardType / CKindCardSet
* - SKILL_CARD_WAVESGameSet—— wave 档位定义
* - FieldSkillSetSkillSet—— 属性词条配置
*/
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,

View File

@@ -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,

View File

@@ -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,

View File

@@ -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→125级阈值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: [
{ 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 } }
]},
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: [
{ 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: [
{ 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 } }
]},
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: [
{ 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→125级 hit_count 1→22英雄环境=全队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→8HP 80→100→120→1506级终极追加 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/10s6级追加暴击驻场光环
// 统一复用 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: [

View File

@@ -1,4 +1,4 @@
import { instantiate, Node, Prefab, Vec3 ,v3,resources,SpriteFrame,Sprite,SpriteAtlas, BoxCollider2D, RigidBody2D, tween, Tween} from "cc";
import { instantiate, Node, Prefab, Vec3, v3, resources, SpriteFrame, Sprite, SpriteAtlas, BoxCollider2D, RigidBody2D, tween, Tween } from "cc";
import { oops } from "../../../../extensions/oops-plugin-framework/assets/core/Oops";
import { ecs } from "../../../../extensions/oops-plugin-framework/assets/libs/ecs/ECS";
import { smc } from "../common/SingletonModuleComp";
@@ -9,7 +9,7 @@ import { HeroInfo, HeroPos, resolveFormationTargetX } from "../common/config/her
import { GameEvent } from "../common/config/GameEvent";
import { SkillTriggerType } from "../common/config/heroSet";
import { SkillTriggerHelper } from "./SkillTriggerHelper";
import { Attrs} from "../common/config/HeroAttrs";
import { Attrs } from "../common/config/HeroAttrs";
import { MoveComp } from "./MoveComp";
import { mLogger } from "../common/Logger";
import { FieldSkillType } from "../common/config/SkillSet";
@@ -73,15 +73,15 @@ 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避免超配表范围
if(hero_lv>3) hero_lv=3
if (hero_lv > 3) hero_lv = 3
// 英雄尺寸随等级做轻量放大,强化成长反馈
let size=1.15
let size = 1.15
// 根据配置路径加载英雄预制体
var path = "game/heros/"+HeroInfo[uuid].path;
var path = "game/heros/" + HeroInfo[uuid].path;
var prefab: Prefab = oops.res.get(path, Prefab)!;
var node = instantiate(prefab);
var scene = smc.map.MapView.scene;
@@ -90,17 +90,17 @@ export class Hero extends ecs.Entity {
const collider = node.getComponent(BoxCollider2D);
// 入场过程暂不参与碰撞,防止半空触发战斗逻辑
if (collider) collider.enabled = false;
node.setScale(size*node.scale.x,size*node.scale.y);
node.setScale(size * node.scale.x, size * node.scale.y);
node.setPosition(pos)
// 输出节点层级信息,便于排查遮挡与渲染顺序问题
mLogger.log(this.debugMode,"hero",node.getSiblingIndex());
mLogger.log(this.debugMode, "hero", node.getSiblingIndex());
var hv = node.getComponent(HeroViewComp)!;
if(hero_lv == 3){hv.playAllTime("plus")}
if(hero_lv == 4){hv.playAllTime("plus")}
if(hero_lv == 5){hv.playAllTime("plus")}
if(hero_lv == 6){hv.playAllTime("plus2")}
if (hero_lv == 3) { hv.playAllTime("plus") }
if (hero_lv == 4) { hv.playAllTime("plus") }
if (hero_lv == 5) { hv.playAllTime("plus") }
if (hero_lv == 6) { hv.playAllTime("plus2") }
// if(hero_lv == 9){hv.playAllTime("plus3")}
// if(hero_lv == 9){hv.playAllTime("plus4")}
// if(hero_lv == 9){hv.playAllTime("plus5")}
@@ -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;
@@ -161,7 +161,7 @@ export class Hero extends ecs.Entity {
const skill = hero.skills[key];
if (!skill) continue;
// 最终技能等级 = 初始技能等级 + 英雄等级增量,且下限为 0
model.skills[skill.uuid] = { ...skill, lv: Math.max(0,skill.lv + hero_lv - 2), ccd: 0 };
model.skills[skill.uuid] = { ...skill, lv: Math.max(0, skill.lv + hero_lv - 2), ccd: 0 };
}
// 应用等级进化配置(从 lv2 开始逐级覆盖)

View File

@@ -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
// ==================== 基础属性(有初始值) ====================

View File

@@ -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;

View File

@@ -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);

View File

@@ -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);

View File

@@ -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();
});
}

View File

@@ -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 => {

View File

@@ -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 / HeroListheroSet—— 英雄静态配置与全量英雄 UUID 列表
* - SkillSet / ITypeSkillSet—— 技能配置与类型枚举
*/
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();
}
}

View File

@@ -1 +0,0 @@
{"ver":"4.0.24","importer":"typescript","imported":true,"uuid":"89bf6d65-5432-4946-9b14-3e5150dddedd","files":[],"subMetas":{},"userData":{}}

View File

@@ -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
});
}

View File

@@ -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,

View File

@@ -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);
}

View File

@@ -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
});
}

View File

@@ -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 });
}
/**

View File

@@ -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

View File

@@ -4,7 +4,7 @@
*
*/
import { _decorator, instantiate, Label ,Prefab,Node, Sprite, Animation, AnimationClip, resources, UITransform, Widget, ProgressBar, Tween, NodeEventType } from "cc";
import { _decorator, instantiate, Label, Prefab, Node, Sprite, Animation, AnimationClip, resources, UITransform, Widget, ProgressBar, Tween, NodeEventType } 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 { oops } from "../../../../extensions/oops-plugin-framework/assets/core/Oops";
@@ -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";
@@ -33,7 +33,7 @@ const { ccclass, property } = _decorator;
export class VictoryComp extends CCComp {
@property(Node)
mvp_node=null!
mvp_node = null!
// ======================== 结算 UI 绑定 ========================
@property({ type: Label, tooltip: "总分文本" })
@@ -63,16 +63,16 @@ export class VictoryComp extends CCComp {
/** 调试日志开关 */
debugMode: boolean = false;
/** 奖励等级(预留) */
reward_lv:number=1
reward_lv: number = 1
/** 奖励数量(预留) */
reward_num:number=2
reward_num: number = 2
/** 掉落奖励列表 */
rewards:any[]=[]
rewards: any[] = []
/** 累计游戏数据(经验 / 金币 / 钻石) */
game_data:any={
exp:0,
gold:0,
diamond:0
game_data: any = {
exp: 0,
gold: 0,
diamond: 0
}
// ======================== 复活相关 ========================
@@ -82,7 +82,7 @@ export class VictoryComp extends CCComp {
/** 加载时隐藏 loading 遮罩 */
protected onLoad(): void {
this.node.getChildByName("loading").active=false
this.node.getChildByName("loading").active = false
}
/**
@@ -94,14 +94,14 @@ export class VictoryComp extends CCComp {
* @param args.can_revive 是否可复活
*/
onAdded(args: any) {
this.node.getChildByName("loading").active=false
mLogger.log(this.debugMode, 'VictoryComp', "[VictoryComp] onAdded",args)
if(args.game_data){
this.game_data=args.game_data
this.node.getChildByName("loading").active = false
mLogger.log(this.debugMode, 'VictoryComp', "[VictoryComp] onAdded", args)
if (args.game_data) {
this.game_data = args.game_data
}
// 根据是否可复活决定按钮显示
this.node.getChildByName("btns").getChildByName("next").active=!args.can_revive
this.node.getChildByName("btns").getChildByName("next").active = !args.can_revive
// 计算总分
this.calculateTotalScore();
@@ -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();
@@ -404,24 +404,24 @@ export class VictoryComp extends CCComp {
// ======================== 操作入口 ========================
/** 退出战斗:清理数据 → 触发任务结束 → 关闭弹窗 */
victory_end(){
victory_end() {
this.clear_data()
oops.message.dispatchEvent(GameEvent.MissionEnd)
oops.gui.removeByNode(this.node)
}
/** 清理运行时数据:解除暂停标志 */
clear_data(){
smc.mission.pause=false
clear_data() {
smc.mission.pause = false
}
/** 看广告双倍奖励(预留) */
watch_ad(){
watch_ad() {
return true
}
/** 双倍奖励发放(预留) */
double_reward(){
double_reward() {
}
@@ -432,20 +432,20 @@ export class VictoryComp extends CCComp {
* 3. 显示 loading 遮罩,延迟 0.5 秒后触发 MissionStart。
* 4. 关闭弹窗。
*/
restart(){
restart() {
this.clear_data()
oops.message.dispatchEvent(GameEvent.MissionEnd)
this.node.getChildByName("loading").active=true
this.scheduleOnce(()=>{
this.node.getChildByName("loading").active = true
this.scheduleOnce(() => {
oops.gui.open(UIID.Mission)
this.node.getChildByName("loading").active=false
this.node.getChildByName("loading").active = false
oops.gui.removeByNode(this.node)
},0.5)
}, 0.5)
}
/** 物品展示回调(预留) */
item_show(e:any,val:any){
mLogger.log(this.debugMode, 'VictoryComp', "item_show",val)
item_show(e: any, val: any) {
mLogger.log(this.debugMode, 'VictoryComp', "item_show", val)
}
protected onDestroy(): void {