Files
pixelheros/assets/script/game/common/config/CardSet.ts
panw 588c935c18 feat(卡牌): 添加卡牌大类标识并更新UI显示
- 在CardSet中新增CKind枚举,区分英雄、技能、卡牌、药水等大类
- 在卡牌配置中增加kind字段,并更新所有卡牌配置
- 在CardComp组件中添加Ckind_node属性,用于显示卡牌大类图标
- 重构card.prefab,将大类图标节点重命名为更具语义的名称(如lv1-lv5),并调整节点激活状态
- 在卡牌初始化和重置时,根据cardData.kind动态显示对应的大类图标
2026-04-02 15:39:08 +08:00

229 lines
8.3 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import * as exp from "constants"
import { HeroInfo, HType } from "./heroSet"
/** 卡牌大类定义 */
export enum CardType {
Hero = 1,
Skill = 2,
SpecialUpgrade = 3,
SpecialRefresh = 4,
}
/** 卡牌大类定义 */
export enum CKind {
Hero = 1, //英雄
Skill = 2, //技能
Card = 3, //卡牌
Potion = 4, //药水
}
/** 卡池等级定义 */
export enum CardKind {
LV1 = 1,
LV2 = 2,
LV3 = 3,
LV4 = 4,
LV5 = 5,
LV6 = 6,
}
/** 通用卡牌配置 */
export interface CardConfig {
uuid: number
type: CardType
cost: number
weight: number
kind: CKind
lv: CardKind
hero_lv?: number
}
export const CardsUpSet: Record<number, number> = {
1: 50,
2: 100,
3: 150,
4: 200,
5: 250,
}
/**初始coin数 */
export const CardInitCoins = 4
/** 卡池升级每波减免金额 */
export const CARD_POOL_UPGRADE_DISCOUNT_PER_WAVE = 10
/** 卡池默认初始等级 */
export const CARD_POOL_INIT_LEVEL = CardKind.LV1
/** 卡池等级上限 */
export const CARD_POOL_MAX_LEVEL = CardKind.LV6
/** 英雄最高等级限制 */
export const CARD_HERO_MAX_LEVEL = 3
/** 基础卡池(英雄、技能、功能) */
export const CardPoolList: CardConfig[] = [
{ uuid: 5001, type: CardType.Hero, cost: 3, weight: 25, lv: 1, kind: CKind.Hero, hero_lv: 1 },
{ uuid: 5101, type: CardType.Hero, cost: 3, weight: 25, lv: 1, kind: CKind.Hero, hero_lv: 1 },
{ uuid: 5201, type: CardType.Hero, cost: 3, weight: 25, lv: 1, kind: CKind.Hero, hero_lv: 1 },
{ uuid: 5301, type: CardType.Hero, cost: 3, weight: 25, lv: 1, kind: CKind.Hero, hero_lv: 1 },
{ uuid: 5003, type: CardType.Hero, cost: 3, weight: 25, lv: 2, kind: CKind.Hero, hero_lv: 1 },
{ uuid: 5102, type: CardType.Hero, cost: 3, weight: 25, lv: 2, kind: CKind.Hero, hero_lv: 1 },
{ uuid: 5302, type: CardType.Hero, cost: 3, weight: 25, lv: 2, kind: CKind.Hero, hero_lv: 1 },
{ uuid: 5002, type: CardType.Hero, cost: 3, weight: 25, lv: 3, kind: CKind.Hero, hero_lv: 1 },
{ uuid: 5103, type: CardType.Hero, cost: 3, weight: 25, lv: 3, kind: CKind.Hero, hero_lv: 1 },
{ uuid: 5202, type: CardType.Hero, cost: 3, weight: 25, lv: 3, kind: CKind.Hero, hero_lv: 1 },
{ uuid: 5004, type: CardType.Hero, cost: 3, weight: 25, lv: 4, kind: CKind.Hero, hero_lv: 1 },
{ uuid: 5104, type: CardType.Hero, cost: 3, weight: 25, lv: 4, kind: CKind.Hero, hero_lv: 1 },
{ uuid: 5303, type: CardType.Hero, cost: 3, weight: 25, lv: 4, kind: CKind.Hero, hero_lv: 1 },
{ uuid: 5105, type: CardType.Hero, cost: 3, weight: 25, lv: 5, kind: CKind.Hero, hero_lv: 1 },
{ uuid: 5304, type: CardType.Hero, cost: 3, weight: 25, lv: 5, kind: CKind.Hero, hero_lv: 1 },
{ uuid: 7001, type: CardType.SpecialUpgrade, cost: 6, weight: 16, lv: 1 ,kind: CKind.Card },
{ uuid: 7002, type: CardType.SpecialUpgrade, cost: 6, weight: 14, lv: 2 ,kind: CKind.Card },
{ uuid: 7101, type: CardType.SpecialRefresh, cost: 4, weight: 14, lv: 1 ,kind: CKind.Card },
{ uuid: 7102, type: CardType.SpecialRefresh, cost: 4, weight: 14, lv: 1 ,kind: CKind.Card },
{ uuid: 7103, type: CardType.SpecialRefresh, cost: 5, weight: 12, lv: 2 ,kind: CKind.Card },
]
export enum SpecialRefreshHeroType {
Any = 0,
Melee = 1,
Ranged = 2,
}
/** 升级功能卡完整配置 */
export interface SpecialUpgradeCardConfig extends CardConfig {
name: string
info: string
currentLv: number
targetLv: number
}
/** 刷新功能卡完整配置 */
export interface SpecialRefreshCardConfig extends CardConfig {
name: string
info: string
refreshLv: number
refreshHeroType: SpecialRefreshHeroType
}
/** 功能卡定义表 */
export const SpecialUpgradeCardList: Record<number, SpecialUpgradeCardConfig> = {
7001: { uuid: 7001,type: CardType.SpecialUpgrade,cost: 6,weight: 16,lv: CardKind.LV1,kind:CKind.Card,name:"战术晋升",info: "升级场上随机1个1级英雄到2级",
currentLv: 1, targetLv: 2,
},
7002: { uuid: 7002,type: CardType.SpecialUpgrade,cost: 6,weight: 14,lv: CardKind.LV2,kind:CKind.Card,name:"进阶战术",info: "升级场上随机1个2级英雄到3级",
currentLv: 2, targetLv: 3,
},
}
export const SpecialRefreshCardList: Record<number, SpecialRefreshCardConfig> = {
7101: { uuid: 7101,type: CardType.SpecialRefresh,cost: 4,weight: 14,lv: CardKind.LV1,kind:CKind.Card,name:"近战征召",info: "刷新卡池,都是近战英雄",
refreshLv: 0, refreshHeroType: SpecialRefreshHeroType.Melee,
},
7102: { uuid: 7102,type: CardType.SpecialRefresh,cost: 4,weight: 14,lv: CardKind.LV1,kind:CKind.Card,name:"远程征召",info: "刷新卡池,都是远程英雄",
refreshLv: 0, refreshHeroType: SpecialRefreshHeroType.Ranged,
},
7103: { uuid: 7103,type: CardType.SpecialRefresh,cost: 5,weight: 12,lv: CardKind.LV2,kind:CKind.Card,name:"精英筛选",info: "刷新卡池都是3级卡池等级英雄",
refreshLv: 3, refreshHeroType: SpecialRefreshHeroType.Any,
},
}
/** 规范等级到合法区间 [LV1, LV6] */
const clampCardLv = (lv: number): CardKind => {
const value = Math.floor(lv)
if (value < CARD_POOL_INIT_LEVEL) return CARD_POOL_INIT_LEVEL
if (value > CARD_POOL_MAX_LEVEL) return CARD_POOL_MAX_LEVEL
return value as CardKind
}
/** 单次按权重抽取一张卡 */
const weightedPick = (cards: CardConfig[]): CardConfig | null => {
if (cards.length === 0) return null
const totalWeight = cards.reduce((total, card) => total + card.weight, 0)
let random = Math.random() * totalWeight
for (const card of cards) {
random -= card.weight
if (random <= 0) return card
}
return cards[cards.length - 1]
}
/** 连续抽取 count 张卡,允许重复 */
const pickCards = (cards: CardConfig[], count: number): CardConfig[] => {
if (cards.length === 0 || count <= 0) return []
const selected: CardConfig[] = []
while (selected.length < count) {
const pick = weightedPick(cards)
if (!pick) break
selected.push(pick)
}
return selected
}
/** 获取指定等级可出现的基础卡池 */
export const getCardPoolByLv = (lv: number, onlyCurrentLv: boolean = false): CardConfig[] => {
const cardLv = clampCardLv(lv)
if (onlyCurrentLv) {
return CardPoolList.filter(card => card.lv === cardLv)
}
return CardPoolList.filter(card => card.lv <= cardLv)
}
const normalizeTypeFilter = (type: CardType | CardType[]): Set<CardType> => {
const list = Array.isArray(type) ? type : [type]
return new Set<CardType>(list)
}
/** 常规发牌:前 2 英雄 + 后 2 其他;支持按类型和等级模式过滤 */
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, 2)
const others = pickCards(otherPool, 2)
return [...heroes, ...others]
}
export const drawCardsByRule = (
lv: number,
options: {
count?: number
onlyCurrentLv?: boolean
type?: CardType | CardType[]
heroType?: HType
heroLv?: number
} = {}
): CardConfig[] => {
const count = Math.max(0, Math.floor(options.count ?? 4))
const onlyCurrentLv = options.onlyCurrentLv ?? false
let pool = getCardPoolByLv(lv, onlyCurrentLv)
if (options.type !== undefined) {
const typeSet = normalizeTypeFilter(options.type)
pool = pool.filter(card => typeSet.has(card.type))
}
if (options.heroType !== undefined || options.heroLv !== undefined) {
pool = pool.filter(card => {
if (card.type !== CardType.Hero) return false
const hero = HeroInfo[card.uuid]
if (!hero) return false
if (options.heroType !== undefined && hero.type !== options.heroType) return false
if (options.heroLv !== undefined && card.hero_lv !== options.heroLv) return false
return true
})
}
return pickCards(pool, count)
}