feat: 新增装备商店系统,调整英雄站位与抽卡逻辑
1. 重构抽卡函数,新增排除装备卡参数,装备卡改为商店直购 2. 添加装备商店面板,支持装备浏览与购买,跨波次保留购买记录 3. 调整英雄出场点位坐标,优化战场布局 4. 扩展技能卡槽位,新增两行技能槽位置 5. 重构EquipListComp组件,适配装备商店UI逻辑 6. 删除废弃的melist预制件与相关元文件 7. 调整hnode预制件布局参数
This commit is contained in:
@@ -35,13 +35,14 @@
|
||||
* - smc.vmdata.mission_data —— 局内数据(coin / hero_num / hero_max_num)
|
||||
*/
|
||||
import { mLogger } from "../common/Logger";
|
||||
import { _decorator, Label, Node, NodeEventType, Prefab, Tween, tween, Vec3 } from "cc";
|
||||
import { _decorator, instantiate, Label, Node, NodeEventType, Prefab, Tween, tween, Vec3 } 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 { GameEvent } from "../common/config/GameEvent";
|
||||
import { CardConfig, CardPoolList, CardType, drawCardsByRule, SpecialRefreshCardList, SpecialRefreshHeroType, SpecialUpgradeCardList } from "../common/config/CardSet";
|
||||
import { CardConfig, CardPoolList, CardType, drawCardsByRule, isEquipmentCard, SpecialRefreshCardList, SpecialRefreshHeroType, SpecialUpgradeCardList } from "../common/config/CardSet";
|
||||
import { CardComp } from "./CardComp";
|
||||
import { SCardComp } from "./SCardComp";
|
||||
import { EquipListComp } from "./EquipListComp";
|
||||
import { oops } from "db://oops-framework/core/Oops";
|
||||
import { HeroAttrsComp } from "../hero/HeroAttrsComp";
|
||||
import { smc } from "../common/SingletonModuleComp";
|
||||
@@ -165,6 +166,8 @@ export class MissionCardComp extends CCComp {
|
||||
private cardComps: CardComp[] = [];
|
||||
/** 技能卡槽控制器缓存 */
|
||||
private skillCardComps: SCardComp[] = [];
|
||||
/** 已购买装备的 UUID 集合(跨波次保持,防止重复购买) */
|
||||
private purchasedEquipUuids: Set<number> = new Set();
|
||||
/** 是否已缓存卡牌面板基准缩放 */
|
||||
private hasCachedCardsBaseScale: boolean = false;
|
||||
/** 卡牌面板基准缩放(从场景读取) */
|
||||
@@ -214,6 +217,12 @@ export class MissionCardComp extends CCComp {
|
||||
if (this.closeHeros && this.closeHeros.isValid) {
|
||||
this.closeHeros.off(NodeEventType.TOUCH_END, this.onCloseHerosClick, this);
|
||||
}
|
||||
if (this.showEquips && this.showEquips.isValid) {
|
||||
this.showEquips.off(NodeEventType.TOUCH_END, this.onShowEquipsClick, this);
|
||||
}
|
||||
if (this.closeEquips && this.closeEquips.isValid) {
|
||||
this.closeEquips.off(NodeEventType.TOUCH_END, this.onCloseEquipsClick, this);
|
||||
}
|
||||
this.unbindEvents();
|
||||
}
|
||||
|
||||
@@ -256,12 +265,17 @@ export class MissionCardComp extends CCComp {
|
||||
const cards = this.buildDrawCards();
|
||||
this.dispatchCardsToSlots(cards);
|
||||
|
||||
// 重置购买记录并填充装备商店
|
||||
this.purchasedEquipUuids.clear();
|
||||
this.populateEquipments();
|
||||
|
||||
mLogger.log(this.debugMode, "MissionCardComp", "mission start");
|
||||
}
|
||||
|
||||
/** 任务结束:清空 3 槽 + 英雄面板并隐藏整个节点 */
|
||||
/** 任务结束:清空 3 槽 + 装备商店 + 英雄面板并隐藏整个节点 */
|
||||
onMissionEnd() {
|
||||
this.clearAllCards();
|
||||
this.clearEquipments();
|
||||
if (this.node && this.node.isValid) {
|
||||
this.node.active = false;
|
||||
}
|
||||
@@ -319,6 +333,11 @@ export class MissionCardComp extends CCComp {
|
||||
/** 关闭英雄卡池按钮 */
|
||||
this.closeHeros?.on(NodeEventType.TOUCH_END, this.onCloseHerosClick, this);
|
||||
|
||||
/** 装备商店显示/隐藏切换按钮 */
|
||||
this.showEquips?.on(NodeEventType.TOUCH_END, this.onShowEquipsClick, this);
|
||||
/** 关闭装备商店按钮 */
|
||||
this.closeEquips?.on(NodeEventType.TOUCH_END, this.onCloseEquipsClick, this);
|
||||
|
||||
/** 技能卡刷新按钮 */
|
||||
this.skill_refresh?.on(NodeEventType.TOUCH_START, this.onSkillDrawTouchStart, this);
|
||||
this.skill_refresh?.on(NodeEventType.TOUCH_END, this.onSkillDrawTouchEnd, this);
|
||||
@@ -456,6 +475,12 @@ export class MissionCardComp extends CCComp {
|
||||
// 由 onCardUsed 立即向被使用的槽位补充一张新技能卡。
|
||||
// 弹窗由外部(按钮/阶段切换)控制显隐。
|
||||
|
||||
// 追踪装备购买记录(EquipListComp 购买后也会派发此事件)
|
||||
const usedCard = args as CardConfig;
|
||||
if (usedCard && isEquipmentCard(usedCard)) {
|
||||
this.purchasedEquipUuids.add(usedCard.uuid);
|
||||
}
|
||||
|
||||
// 修复:独立判断 guide2 的关闭 和 guide3 的开启
|
||||
if (!smc.finish_guides.includes(2)) {
|
||||
smc.finish_guides.push(2);
|
||||
@@ -492,6 +517,12 @@ export class MissionCardComp extends CCComp {
|
||||
if (this.closeHeros && this.closeHeros.isValid) {
|
||||
this.closeHeros.off(NodeEventType.TOUCH_END, this.onCloseHerosClick, this);
|
||||
}
|
||||
if (this.showEquips && this.showEquips.isValid) {
|
||||
this.showEquips.off(NodeEventType.TOUCH_END, this.onShowEquipsClick, this);
|
||||
}
|
||||
if (this.closeEquips && this.closeEquips.isValid) {
|
||||
this.closeEquips.off(NodeEventType.TOUCH_END, this.onCloseEquipsClick, this);
|
||||
}
|
||||
if (this.skill_refresh && this.skill_refresh.isValid) {
|
||||
this.skill_refresh.off(NodeEventType.TOUCH_START, this.onSkillDrawTouchStart, this);
|
||||
this.skill_refresh.off(NodeEventType.TOUCH_END, this.onSkillDrawTouchEnd, this);
|
||||
@@ -680,6 +711,71 @@ export class MissionCardComp extends CCComp {
|
||||
oops.gui.remove(UIID.HInfo);
|
||||
}
|
||||
|
||||
// ======================== 装备商店面板 ========================
|
||||
|
||||
/**
|
||||
* 装备商店显隐切换按钮回调:
|
||||
* 切换 equipsPanNode 的 active 状态。
|
||||
*/
|
||||
private onShowEquipsClick() {
|
||||
if (!this.equipsPanNode || !this.equipsPanNode.isValid) return;
|
||||
oops.audio.playEffect("music/button");
|
||||
this.equipsPanNode.active = !this.equipsPanNode.active;
|
||||
}
|
||||
|
||||
/** 关闭装备商店按钮回调 */
|
||||
private onCloseEquipsClick() {
|
||||
if (!this.equipsPanNode || !this.equipsPanNode.isValid) return;
|
||||
oops.audio.playEffect("music/button");
|
||||
this.equipsPanNode.active = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 填充装备列表:
|
||||
* 从 CardPoolList 获取所有装备卡(trigger_type=Field),
|
||||
* 实例化 equipPrefab 到 equipsBoxNode,
|
||||
* 每个装备项由 EquipListComp 渲染并处理购买。
|
||||
*
|
||||
* 已购买的装备会标记为已购状态(隐藏购买按钮)。
|
||||
*/
|
||||
private populateEquipments() {
|
||||
if (!this.equipsBoxNode || !this.equipPrefab) return;
|
||||
|
||||
// 清空旧列表
|
||||
this.equipsBoxNode.removeAllChildren();
|
||||
|
||||
// 获取所有装备卡
|
||||
const equipments = CardPoolList.filter(c => isEquipmentCard(c));
|
||||
|
||||
for (const equip of equipments) {
|
||||
const node = instantiate(this.equipPrefab);
|
||||
this.equipsBoxNode.addChild(node);
|
||||
const comp = node.getComponent(EquipListComp) || node.addComponent(EquipListComp);
|
||||
comp.applyCardData(equip);
|
||||
|
||||
// 已购买的装备标记为已购
|
||||
if (this.purchasedEquipUuids.has(equip.uuid)) {
|
||||
comp.setPurchased();
|
||||
}
|
||||
}
|
||||
|
||||
// 默认显示装备面板
|
||||
if (this.equipsPanNode) {
|
||||
this.equipsPanNode.active = true;
|
||||
}
|
||||
|
||||
mLogger.log(this.debugMode, "MissionCardComp", "populate equipments", {
|
||||
count: equipments.length
|
||||
});
|
||||
}
|
||||
|
||||
/** 清空装备列表 */
|
||||
private clearEquipments() {
|
||||
if (this.equipsBoxNode && this.equipsBoxNode.isValid) {
|
||||
this.equipsBoxNode.removeAllChildren();
|
||||
}
|
||||
}
|
||||
|
||||
// ======================== 技能抽卡按钮回调 ========================
|
||||
private onSkillDrawTouchStart() {
|
||||
this.playButtonPressAnim(this.skill_refresh);
|
||||
@@ -986,11 +1082,13 @@ export class MissionCardComp extends CCComp {
|
||||
private buildSkillDrawCards(): CardConfig[] {
|
||||
const currentWave = this.getCurrentWave();
|
||||
// 使用明确规则的 drawCardsByRule,指定只要 3 张技能卡,并且过滤对应 wave
|
||||
// 装备卡已改为商店直购,不再参与抽卡
|
||||
const cards = drawCardsByRule(1, {
|
||||
count: 3,
|
||||
type: CardType.Skill,
|
||||
wave: currentWave,
|
||||
unique: true // 保证技能牌不重复
|
||||
unique: true, // 保证技能牌不重复
|
||||
excludeEquipment: true, // 排除装备卡
|
||||
});
|
||||
|
||||
if (cards.length >= 3) return cards.slice(0, 3);
|
||||
@@ -1000,7 +1098,8 @@ export class MissionCardComp extends CCComp {
|
||||
count: 3,
|
||||
type: CardType.Skill,
|
||||
wave: currentWave,
|
||||
unique: true
|
||||
unique: true,
|
||||
excludeEquipment: true,
|
||||
});
|
||||
if (fallback.length === 0) break;
|
||||
|
||||
@@ -1345,6 +1444,7 @@ export class MissionCardComp extends CCComp {
|
||||
// 关键:在 reset/销毁 时将 Map 置空,彻底切断引用
|
||||
this.cardComps = [] as any;
|
||||
this.skillCardComps = [] as any;
|
||||
this.purchasedEquipUuids.clear();
|
||||
|
||||
if (this.node && this.node.isValid) {
|
||||
this.node.destroy();
|
||||
|
||||
Reference in New Issue
Block a user