refactor(config): 拆分英雄卡池到独立配置文件
将原CardPoolList中的英雄卡池逻辑迁移至heroSet.ts,统一管理英雄抽卡配置,简化主配置文件内容,同时更新MissionCardComp以使用新的英雄卡池数据源
This commit is contained in:
@@ -91,44 +91,9 @@ export interface CardConfig {
|
|||||||
target_hero_eid?: number;
|
target_hero_eid?: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 基础卡池(英雄、技能、功能) */
|
/** 基础卡池(技能、功能卡;英雄卡池已迁移至 heroSet.ts HeroCardPoolList) */
|
||||||
export const CardPoolList: CardConfig[] = [];
|
export const CardPoolList: CardConfig[] = [];
|
||||||
|
|
||||||
// 动态生成英雄卡池:所有英雄统一生成 lv1 卡牌
|
|
||||||
function getHeroCost(cardLv: number): number {
|
|
||||||
if (cardLv === 1) return 5;
|
|
||||||
if (cardLv === 2) return 10;
|
|
||||||
return 15;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 英雄卡按 card_lv 分配抽取权重(几何递减,高等级越稀有)。
|
|
||||||
* 梯度:lv1=40, lv2=25, lv3=15, lv4=8, lv5=3
|
|
||||||
*/
|
|
||||||
const HERO_WEIGHT_BY_LV: Record<number, number> = {
|
|
||||||
1: 40, 2: 25, 3: 15, 4: 8, 5: 3,
|
|
||||||
};
|
|
||||||
function getHeroWeight(cardLv: number): number {
|
|
||||||
return HERO_WEIGHT_BY_LV[cardLv] ?? HERO_WEIGHT_BY_LV[1];
|
|
||||||
}
|
|
||||||
|
|
||||||
HeroList.forEach(uuid => {
|
|
||||||
const hero = HeroInfo[uuid];
|
|
||||||
if (!hero) return;
|
|
||||||
|
|
||||||
CardPoolList.push({
|
|
||||||
uuid: hero.uuid,
|
|
||||||
type: CardType.Hero,
|
|
||||||
cost: getHeroCost(hero.card_lv ?? 1),
|
|
||||||
weight: getHeroWeight(hero.card_lv ?? 1),
|
|
||||||
card_lv: hero.card_lv ?? 1,
|
|
||||||
kind: CKind.Hero,
|
|
||||||
hero_lv: 1,
|
|
||||||
base_card_lv: hero.card_lv ?? 1,
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
export enum SpecialRefreshHeroType {
|
export enum SpecialRefreshHeroType {
|
||||||
Any = 0,
|
Any = 0,
|
||||||
Melee = 1,
|
Melee = 1,
|
||||||
|
|||||||
@@ -339,6 +339,19 @@ export interface HeroCardConfig {
|
|||||||
base_card_lv?: number;
|
base_card_lv?: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 英雄卡池条目(含费用和权重,用于 MissionCardComp 抽卡)
|
||||||
|
*/
|
||||||
|
export interface HeroCardPoolEntry {
|
||||||
|
uuid: number;
|
||||||
|
cost: number;
|
||||||
|
weight: number;
|
||||||
|
card_lv: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 英雄卡池:由 HeroList 动态生成(见文件末尾初始化代码) */
|
||||||
|
export const HeroCardPoolList: HeroCardPoolEntry[] = [];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 技能基础信息接口
|
* 技能基础信息接口
|
||||||
*/
|
*/
|
||||||
@@ -940,6 +953,41 @@ export const HeroComboSet: Record<number, HeroComboInfo> = {
|
|||||||
/** 推荐阵容 id 列表(按品质/成型难度排序,供 UI 顺序展示) */
|
/** 推荐阵容 id 列表(按品质/成型难度排序,供 UI 顺序展示) */
|
||||||
export const HeroComboList: number[] = [8001, 8002, 8003, 8004, 8005, 8006];
|
export const HeroComboList: number[] = [8001, 8002, 8003, 8004, 8005, 8006];
|
||||||
|
|
||||||
|
// ==================== 英雄卡池初始化(必须在 HeroList 定义之后执行) ====================
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 英雄卡费用规则
|
||||||
|
* lv1=5, lv2=10, lv3+=15
|
||||||
|
*/
|
||||||
|
function getHeroCost(cardLv: number): number {
|
||||||
|
if (cardLv === 1) return 5;
|
||||||
|
if (cardLv === 2) return 10;
|
||||||
|
return 15;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 英雄卡按 card_lv 分配抽取权重(几何递减,高等级越稀有)
|
||||||
|
* 梯度:lv1=40, lv2=25, lv3=15, lv4=8, lv5=3
|
||||||
|
*/
|
||||||
|
const HERO_WEIGHT_BY_LV: Record<number, number> = {
|
||||||
|
1: 40, 2: 25, 3: 15, 4: 8, 5: 3,
|
||||||
|
};
|
||||||
|
function getHeroWeight(cardLv: number): number {
|
||||||
|
return HERO_WEIGHT_BY_LV[cardLv] ?? HERO_WEIGHT_BY_LV[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
// 动态生成英雄卡池:所有英雄统一生成 lv1 卡牌
|
||||||
|
HeroList.forEach(uuid => {
|
||||||
|
const hero = HeroInfo[uuid];
|
||||||
|
if (!hero) return;
|
||||||
|
HeroCardPoolList.push({
|
||||||
|
uuid: hero.uuid,
|
||||||
|
cost: getHeroCost(hero.card_lv ?? 1),
|
||||||
|
weight: getHeroWeight(hero.card_lv ?? 1),
|
||||||
|
card_lv: hero.card_lv ?? 1,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
// ==================== 英雄强度评分公式 ====================
|
// ==================== 英雄强度评分公式 ====================
|
||||||
|
|
||||||
/** 英雄强度公式调参权重(可在编辑器或运行时热调)
|
/** 英雄强度公式调参权重(可在编辑器或运行时热调)
|
||||||
|
|||||||
@@ -44,6 +44,7 @@ import { ecs } from "../../../../extensions/oops-plugin-framework/assets/libs/ec
|
|||||||
import { CCComp } from "../../../../extensions/oops-plugin-framework/assets/module/common/CCComp";
|
import { CCComp } from "../../../../extensions/oops-plugin-framework/assets/module/common/CCComp";
|
||||||
import { GameEvent } from "../common/config/GameEvent";
|
import { GameEvent } from "../common/config/GameEvent";
|
||||||
import { CardConfig, CardPoolList, CardType, SpecialRefreshCardList, SpecialRefreshHeroType } from "../common/config/CardSet";
|
import { CardConfig, CardPoolList, CardType, SpecialRefreshCardList, SpecialRefreshHeroType } from "../common/config/CardSet";
|
||||||
|
import { HeroCardPoolList, HeroCardPoolEntry } from "../common/config/heroSet";
|
||||||
import { drawEquipCards } from "../common/config/EquipSet";
|
import { drawEquipCards } from "../common/config/EquipSet";
|
||||||
import { drawItemCards } from "../common/config/ICardSet";
|
import { drawItemCards } from "../common/config/ICardSet";
|
||||||
import { drawSkillCards } from "../common/config/SCardSet";
|
import { drawSkillCards } from "../common/config/SCardSet";
|
||||||
@@ -344,7 +345,7 @@ export class MissionCardComp extends CCComp {
|
|||||||
const cards = this.buildDrawCards();
|
const cards = this.buildDrawCards();
|
||||||
mLogger.log(this.debugMode, "MissionCardComp", "onMissionStart buildDrawCards", {
|
mLogger.log(this.debugMode, "MissionCardComp", "onMissionStart buildDrawCards", {
|
||||||
cardsLength: cards.length,
|
cardsLength: cards.length,
|
||||||
cards: cards.map(c => ({ uuid: c.uuid, type: c.type, name: c.name }))
|
cards: cards.map(c => ({ uuid: c.uuid }))
|
||||||
});
|
});
|
||||||
this.dispatchCardsToSlots(cards);
|
this.dispatchCardsToSlots(cards);
|
||||||
|
|
||||||
@@ -1723,8 +1724,8 @@ export class MissionCardComp extends CCComp {
|
|||||||
* 构建随机召唤卡池:全英雄卡。
|
* 构建随机召唤卡池:全英雄卡。
|
||||||
* @returns 卡配置数组
|
* @returns 卡配置数组
|
||||||
*/
|
*/
|
||||||
private buildRandomSummonPool(): CardConfig[] {
|
private buildRandomSummonPool(): HeroCardPoolEntry[] {
|
||||||
return CardPoolList.filter(c => c.type === CardType.Hero);
|
return HeroCardPoolList;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ======================== 阶段切换 ========================
|
// ======================== 阶段切换 ========================
|
||||||
@@ -1797,8 +1798,8 @@ export class MissionCardComp extends CCComp {
|
|||||||
*
|
*
|
||||||
* 注:升级卡机制已移除,英雄卡池只出普通英雄卡。
|
* 注:升级卡机制已移除,英雄卡池只出普通英雄卡。
|
||||||
*/
|
*/
|
||||||
private buildDrawCards(): CardConfig[] {
|
private buildDrawCards(): HeroCardPoolEntry[] {
|
||||||
const allHeroCards = CardPoolList.filter(c => c.type === CardType.Hero);
|
const allHeroCards = HeroCardPoolList;
|
||||||
if (allHeroCards.length === 0) return [];
|
if (allHeroCards.length === 0) return [];
|
||||||
|
|
||||||
// 优先从“未上场英雄”子池抽取;子池不足 3 张时回退到全量池,避免凑不齐 3 张
|
// 优先从“未上场英雄”子池抽取;子池不足 3 张时回退到全量池,避免凑不齐 3 张
|
||||||
@@ -1810,7 +1811,7 @@ export class MissionCardComp extends CCComp {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** 单次按权重抽取一张卡 */
|
/** 单次按权重抽取一张卡 */
|
||||||
private weightedPick(cards: CardConfig[]): CardConfig | null {
|
private weightedPick(cards: HeroCardPoolEntry[]): HeroCardPoolEntry | null {
|
||||||
if (cards.length === 0) return null;
|
if (cards.length === 0) return null;
|
||||||
const totalWeight = cards.reduce((total, card) => total + (card.weight ?? 0), 0);
|
const totalWeight = cards.reduce((total, card) => total + (card.weight ?? 0), 0);
|
||||||
let random = Math.random() * totalWeight;
|
let random = Math.random() * totalWeight;
|
||||||
@@ -1829,8 +1830,8 @@ export class MissionCardComp extends CCComp {
|
|||||||
* @param count 目标张数
|
* @param count 目标张数
|
||||||
* @returns 不重复的卡配置数组(0 ~ count 张)
|
* @returns 不重复的卡配置数组(0 ~ count 张)
|
||||||
*/
|
*/
|
||||||
private pickUniqueHeroCards(pool: CardConfig[], count: number): CardConfig[] {
|
private pickUniqueHeroCards(pool: HeroCardPoolEntry[], count: number): HeroCardPoolEntry[] {
|
||||||
const result: CardConfig[] = [];
|
const result: HeroCardPoolEntry[] = [];
|
||||||
const usedUuids = new Set<number>();
|
const usedUuids = new Set<number>();
|
||||||
while (result.length < count) {
|
while (result.length < count) {
|
||||||
const rest = pool.filter(c => !usedUuids.has(c.uuid));
|
const rest = pool.filter(c => !usedUuids.has(c.uuid));
|
||||||
@@ -1849,7 +1850,7 @@ export class MissionCardComp extends CCComp {
|
|||||||
* 子池不足 3 张时回退到该类型的全量池,仍抽不齐则如实返回(不重复补位)。
|
* 子池不足 3 张时回退到该类型的全量池,仍抽不齐则如实返回(不重复补位)。
|
||||||
*/
|
*/
|
||||||
private tryRefreshHeroCards(heroType?: HType): boolean {
|
private tryRefreshHeroCards(heroType?: HType): boolean {
|
||||||
let pool = CardPoolList.filter(c => c.type === CardType.Hero);
|
let pool = HeroCardPoolList;
|
||||||
if (heroType !== undefined) {
|
if (heroType !== undefined) {
|
||||||
pool = pool.filter(c => HeroInfo[c.uuid]?.type === heroType);
|
pool = pool.filter(c => HeroInfo[c.uuid]?.type === heroType);
|
||||||
}
|
}
|
||||||
@@ -1878,7 +1879,7 @@ export class MissionCardComp extends CCComp {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** 全量分发给 3 槽;每个槽位是否接收由 CHeroComp 自己判断(锁定可跳过) */
|
/** 全量分发给 3 槽;每个槽位是否接收由 CHeroComp 自己判断(锁定可跳过) */
|
||||||
private dispatchCardsToSlots(cards: CardConfig[]) {
|
private dispatchCardsToSlots(cards: HeroCardPoolEntry[]) {
|
||||||
if (!this.cardComps) return;
|
if (!this.cardComps) return;
|
||||||
for (let i = 0; i < this.cardComps.length; i++) {
|
for (let i = 0; i < this.cardComps.length; i++) {
|
||||||
if (this.cardComps[i]) {
|
if (this.cardComps[i]) {
|
||||||
|
|||||||
Reference in New Issue
Block a user