Compare commits
3 Commits
2234b9021d
...
fb299f6328
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
fb299f6328 | ||
|
|
4f95accfbf | ||
|
|
5d55f3bdb1 |
@@ -859,7 +859,7 @@
|
|||||||
"_contentSize": {
|
"_contentSize": {
|
||||||
"__type__": "cc.Size",
|
"__type__": "cc.Size",
|
||||||
"width": 40,
|
"width": 40,
|
||||||
"height": 7
|
"height": 11
|
||||||
},
|
},
|
||||||
"_anchorPoint": {
|
"_anchorPoint": {
|
||||||
"__type__": "cc.Vec2",
|
"__type__": "cc.Vec2",
|
||||||
@@ -1037,7 +1037,7 @@
|
|||||||
"_contentSize": {
|
"_contentSize": {
|
||||||
"__type__": "cc.Size",
|
"__type__": "cc.Size",
|
||||||
"width": 140,
|
"width": 140,
|
||||||
"height": 30
|
"height": 43.333333333333336
|
||||||
},
|
},
|
||||||
"_anchorPoint": {
|
"_anchorPoint": {
|
||||||
"__type__": "cc.Vec2",
|
"__type__": "cc.Vec2",
|
||||||
@@ -1162,7 +1162,7 @@
|
|||||||
"_contentSize": {
|
"_contentSize": {
|
||||||
"__type__": "cc.Size",
|
"__type__": "cc.Size",
|
||||||
"width": 40,
|
"width": 40,
|
||||||
"height": 7
|
"height": 11
|
||||||
},
|
},
|
||||||
"_anchorPoint": {
|
"_anchorPoint": {
|
||||||
"__type__": "cc.Vec2",
|
"__type__": "cc.Vec2",
|
||||||
@@ -1912,8 +1912,8 @@
|
|||||||
},
|
},
|
||||||
"_contentSize": {
|
"_contentSize": {
|
||||||
"__type__": "cc.Size",
|
"__type__": "cc.Size",
|
||||||
"width": 52,
|
"width": 80,
|
||||||
"height": 75
|
"height": 100
|
||||||
},
|
},
|
||||||
"_anchorPoint": {
|
"_anchorPoint": {
|
||||||
"__type__": "cc.Vec2",
|
"__type__": "cc.Vec2",
|
||||||
@@ -1943,18 +1943,18 @@
|
|||||||
"_dstBlendFactor": 4,
|
"_dstBlendFactor": 4,
|
||||||
"_color": {
|
"_color": {
|
||||||
"__type__": "cc.Color",
|
"__type__": "cc.Color",
|
||||||
"r": 255,
|
"r": 253,
|
||||||
"g": 255,
|
"g": 213,
|
||||||
"b": 255,
|
"b": 0,
|
||||||
"a": 255
|
"a": 255
|
||||||
},
|
},
|
||||||
"_spriteFrame": {
|
"_spriteFrame": {
|
||||||
"__uuid__": "cb93c900-b440-4571-91d1-7da1636e3d73@5c7a0",
|
"__uuid__": "cb93c900-b440-4571-91d1-7da1636e3d73@79d6f",
|
||||||
"__expectedType__": "cc.SpriteFrame"
|
"__expectedType__": "cc.SpriteFrame"
|
||||||
},
|
},
|
||||||
"_type": 0,
|
"_type": 0,
|
||||||
"_fillType": 0,
|
"_fillType": 0,
|
||||||
"_sizeMode": 1,
|
"_sizeMode": 0,
|
||||||
"_fillCenter": {
|
"_fillCenter": {
|
||||||
"__type__": "cc.Vec2",
|
"__type__": "cc.Vec2",
|
||||||
"x": 0,
|
"x": 0,
|
||||||
@@ -1964,7 +1964,10 @@
|
|||||||
"_fillRange": 0,
|
"_fillRange": 0,
|
||||||
"_isTrimmedMode": true,
|
"_isTrimmedMode": true,
|
||||||
"_useGrayscale": false,
|
"_useGrayscale": false,
|
||||||
"_atlas": null,
|
"_atlas": {
|
||||||
|
"__uuid__": "cb93c900-b440-4571-91d1-7da1636e3d73",
|
||||||
|
"__expectedType__": "cc.SpriteAtlas"
|
||||||
|
},
|
||||||
"_id": ""
|
"_id": ""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -2007,8 +2010,8 @@
|
|||||||
},
|
},
|
||||||
"_lpos": {
|
"_lpos": {
|
||||||
"__type__": "cc.Vec3",
|
"__type__": "cc.Vec3",
|
||||||
"x": 0,
|
"x": -0.103,
|
||||||
"y": 0,
|
"y": -0.601,
|
||||||
"z": 0
|
"z": 0
|
||||||
},
|
},
|
||||||
"_lrot": {
|
"_lrot": {
|
||||||
@@ -2048,7 +2051,7 @@
|
|||||||
},
|
},
|
||||||
"_contentSize": {
|
"_contentSize": {
|
||||||
"__type__": "cc.Size",
|
"__type__": "cc.Size",
|
||||||
"width": 4.38,
|
"width": 7.29,
|
||||||
"height": 40
|
"height": 40
|
||||||
},
|
},
|
||||||
"_anchorPoint": {
|
"_anchorPoint": {
|
||||||
@@ -2087,8 +2090,8 @@
|
|||||||
"_string": "1",
|
"_string": "1",
|
||||||
"_horizontalAlign": 1,
|
"_horizontalAlign": 1,
|
||||||
"_verticalAlign": 1,
|
"_verticalAlign": 1,
|
||||||
"_actualFontSize": 15,
|
"_actualFontSize": 25,
|
||||||
"_fontSize": 15,
|
"_fontSize": 25,
|
||||||
"_fontFamily": "Arial",
|
"_fontFamily": "Arial",
|
||||||
"_lineHeight": 40,
|
"_lineHeight": 40,
|
||||||
"_overflow": 0,
|
"_overflow": 0,
|
||||||
@@ -2100,7 +2103,7 @@
|
|||||||
"_isSystemFontUsed": false,
|
"_isSystemFontUsed": false,
|
||||||
"_spacingX": 0,
|
"_spacingX": 0,
|
||||||
"_isItalic": false,
|
"_isItalic": false,
|
||||||
"_isBold": false,
|
"_isBold": true,
|
||||||
"_isUnderline": false,
|
"_isUnderline": false,
|
||||||
"_underlineHeight": 2,
|
"_underlineHeight": 2,
|
||||||
"_cacheMode": 0,
|
"_cacheMode": 0,
|
||||||
@@ -2161,7 +2164,7 @@
|
|||||||
"_contentSize": {
|
"_contentSize": {
|
||||||
"__type__": "cc.Size",
|
"__type__": "cc.Size",
|
||||||
"width": 10,
|
"width": 10,
|
||||||
"height": 10
|
"height": 13
|
||||||
},
|
},
|
||||||
"_anchorPoint": {
|
"_anchorPoint": {
|
||||||
"__type__": "cc.Vec2",
|
"__type__": "cc.Vec2",
|
||||||
|
|||||||
@@ -22,6 +22,8 @@ export enum GameEvent {
|
|||||||
CardRefresh = "CardRefresh",
|
CardRefresh = "CardRefresh",
|
||||||
/** 单张卡牌被点击选中(payload 为被点击的 CardComp 实例,用于其他卡牌联动隐藏 call_btn) */
|
/** 单张卡牌被点击选中(payload 为被点击的 CardComp 实例,用于其他卡牌联动隐藏 call_btn) */
|
||||||
CardSelected = "CardSelected",
|
CardSelected = "CardSelected",
|
||||||
|
/** 单张卡牌被成功使用(payload 为该卡槽组件实例 CardComp / SCardComp,用于 MissionCardComp 补卡) */
|
||||||
|
CardUsed = "CardUsed",
|
||||||
UseHeroCard = "UseHeroCard",
|
UseHeroCard = "UseHeroCard",
|
||||||
UseSkillCard = "UseSkillCard",
|
UseSkillCard = "UseSkillCard",
|
||||||
UseSpecialCard = "UseSpecialCard",
|
UseSpecialCard = "UseSpecialCard",
|
||||||
|
|||||||
@@ -70,6 +70,7 @@ export class HeroAttrsComp extends ecs.Comp {
|
|||||||
// ==================== 脏标签标记 ====================
|
// ==================== 脏标签标记 ====================
|
||||||
dirty_hp: boolean = false; // 血量变更标记
|
dirty_hp: boolean = false; // 血量变更标记
|
||||||
dirty_shield: boolean = false; // 护盾变更标记
|
dirty_shield: boolean = false; // 护盾变更标记
|
||||||
|
dirty_lv: boolean = false; // 等级变更标记
|
||||||
|
|
||||||
// ==================== 技能距离缓存 ====================
|
// ==================== 技能距离缓存 ====================
|
||||||
maxSkillDistance: number = 0; // 最远技能攻击距离(缓存,受MP影响)
|
maxSkillDistance: number = 0; // 最远技能攻击距离(缓存,受MP影响)
|
||||||
@@ -429,6 +430,7 @@ export class HeroAttrsComp extends ecs.Comp {
|
|||||||
// 重置脏标签
|
// 重置脏标签
|
||||||
this.dirty_hp = false;
|
this.dirty_hp = false;
|
||||||
this.dirty_shield = false;
|
this.dirty_shield = false;
|
||||||
|
this.dirty_lv = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -38,14 +38,15 @@ export class HeroViewComp extends CCComp {
|
|||||||
realDeadTime: number = 0.1
|
realDeadTime: number = 0.1
|
||||||
deadCD: number = 0
|
deadCD: number = 0
|
||||||
monDeadTime: number = 0.1
|
monDeadTime: number = 0.1
|
||||||
hp_height:number=70
|
hp_height: number = 90
|
||||||
boss_hp_height:number=120
|
boss_hp_height: number = 160
|
||||||
// 血条显示相关
|
// 血条显示相关
|
||||||
lastBarUpdateTime: number = 0; // 最后一次血条/蓝条/护盾更新时间
|
lastBarUpdateTime: number = 0; // 最后一次血条/蓝条/护盾更新时间
|
||||||
// ==================== UI 节点引用 ====================
|
// ==================== UI 节点引用 ====================
|
||||||
private top_node: Node = null!;
|
private top_node: Node = null!;
|
||||||
private topOpacity: UIOpacity = null!;
|
private topOpacity: UIOpacity = null!;
|
||||||
private topBasePos: Vec3 = v3();
|
private topBasePos: Vec3 = v3();
|
||||||
|
private lvLabel: Label | null = null; // 等级显示文本
|
||||||
private readonly barIdleOpacity: number = 153;
|
private readonly barIdleOpacity: number = 153;
|
||||||
private readonly barActiveOpacity: number = 255;
|
private readonly barActiveOpacity: number = 255;
|
||||||
private readonly idleOpacityDelay: number = 0.25;
|
private readonly idleOpacityDelay: number = 0.25;
|
||||||
@@ -116,15 +117,19 @@ export class HeroViewComp extends CCComp {
|
|||||||
|
|
||||||
/** 方向 */
|
/** 方向 */
|
||||||
this.node.setScale(this.scale * Math.abs(this.node.scale.x), 1 * this.node.scale.y); // 确保 scale.x 为正后再乘方向
|
this.node.setScale(this.scale * Math.abs(this.node.scale.x), 1 * this.node.scale.y); // 确保 scale.x 为正后再乘方向
|
||||||
this.top_node.setScale(this.scale*this.top_node.scale.x,1*this.top_node.scale.y);
|
// top_node 取 abs 避免对象池复用时 scale 累乘导致血条方向反转
|
||||||
|
this.top_node.setScale(this.scale * Math.abs(this.top_node.scale.x), 1 * this.top_node.scale.y);
|
||||||
/* 显示角色血*/
|
/* 显示角色血*/
|
||||||
this.top_node.getChildByName("hp").active = true;
|
this.top_node.getChildByName("hp").active = true;
|
||||||
this.top_node.getChildByName("cd").active = false;
|
this.top_node.getChildByName("cd").active = false;
|
||||||
this.top_node.getChildByName("shield").active = false;
|
this.top_node.getChildByName("shield").active = false;
|
||||||
this.top_node.getChildByName("lv").active = false;
|
this.top_node.getChildByName("lv").active = true;
|
||||||
this.top_node.active = true;
|
this.top_node.active = true;
|
||||||
this.setTopBarOpacity(false);
|
this.setTopBarOpacity(false);
|
||||||
|
|
||||||
|
// 初始化等级显示
|
||||||
|
this.lv_show();
|
||||||
|
|
||||||
// 🔥 重置血条 UI 显示状态
|
// 🔥 重置血条 UI 显示状态
|
||||||
if (this.model) {
|
if (this.model) {
|
||||||
this.hp_show();
|
this.hp_show();
|
||||||
@@ -157,6 +162,12 @@ export class HeroViewComp extends CCComp {
|
|||||||
|
|
||||||
// 确保血条等UI始终在最上层显示
|
// 确保血条等UI始终在最上层显示
|
||||||
this.top_node.setSiblingIndex(999);
|
this.top_node.setSiblingIndex(999);
|
||||||
|
|
||||||
|
// 缓存等级显示 Label(lv 节点下的 Label 子节点)
|
||||||
|
const lvNode = this.top_node.getChildByName("lv");
|
||||||
|
if (lvNode) {
|
||||||
|
this.lvLabel = lvNode.getChildByName("Label")?.getComponent(Label) ?? null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -195,6 +206,11 @@ export class HeroViewComp extends CCComp {
|
|||||||
this.show_shield(this.model.shield);
|
this.show_shield(this.model.shield);
|
||||||
this.model.dirty_shield = false;
|
this.model.dirty_shield = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (this.model.dirty_lv) {
|
||||||
|
this.lv_show();
|
||||||
|
this.model.dirty_lv = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public cd_show() {
|
public cd_show() {
|
||||||
@@ -237,6 +253,12 @@ export class HeroViewComp extends CCComp {
|
|||||||
return this.model.hp >= this.model.hp_max;
|
return this.model.hp >= this.model.hp_max;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** 更新等级显示 */
|
||||||
|
private lv_show() {
|
||||||
|
if (!this.lvLabel || !this.model) return;
|
||||||
|
this.lvLabel.string = String(this.model.lv);
|
||||||
|
}
|
||||||
|
|
||||||
private setTopBarOpacity(isActive: boolean) {
|
private setTopBarOpacity(isActive: boolean) {
|
||||||
if (!this.top_node || !this.top_node.isValid) return;
|
if (!this.top_node || !this.top_node.isValid) return;
|
||||||
if (this.topOpacity) {
|
if (this.topOpacity) {
|
||||||
|
|||||||
@@ -347,18 +347,26 @@ export class CardComp extends CCComp {
|
|||||||
/**
|
/**
|
||||||
* 根据卡牌类型分发对应的游戏效果事件。
|
* 根据卡牌类型分发对应的游戏效果事件。
|
||||||
* - 英雄卡 → CallHero
|
* - 英雄卡 → CallHero
|
||||||
* - 技能卡 → UseSkillCard
|
|
||||||
* - 特殊升级 / 特殊刷新 → UseSpecialCard
|
* - 特殊升级 / 特殊刷新 → UseSpecialCard
|
||||||
*
|
*
|
||||||
|
* 卡牌使用成功后会派发 CardUsed 事件(携带本卡槽组件),
|
||||||
|
* 由 MissionCardComp 接收并立即补充一张新卡到该槽位。
|
||||||
|
* SpecialRefresh 例外:其效果本身会重填所有槽位,无需重复补卡。
|
||||||
|
*
|
||||||
* @param payload 被使用的卡牌数据
|
* @param payload 被使用的卡牌数据
|
||||||
*/
|
*/
|
||||||
private executeCardEffectEntry(payload: CardConfig) {
|
private executeCardEffectEntry(payload: CardConfig) {
|
||||||
switch (payload.type) {
|
switch (payload.type) {
|
||||||
case CardType.Hero:
|
case CardType.Hero:
|
||||||
oops.message.dispatchEvent(GameEvent.CallHero, payload);
|
oops.message.dispatchEvent(GameEvent.CallHero, payload);
|
||||||
|
oops.message.dispatchEvent(GameEvent.CardUsed, this);
|
||||||
break;
|
break;
|
||||||
case CardType.SpecialUpgrade:
|
case CardType.SpecialUpgrade:
|
||||||
|
oops.message.dispatchEvent(GameEvent.UseSpecialCard, payload);
|
||||||
|
oops.message.dispatchEvent(GameEvent.CardUsed, this);
|
||||||
|
break;
|
||||||
case CardType.SpecialRefresh:
|
case CardType.SpecialRefresh:
|
||||||
|
// 刷新卡效果(tryRefreshHeroCards)会重填全部 3 槽,此处不再补卡
|
||||||
oops.message.dispatchEvent(GameEvent.UseSpecialCard, payload);
|
oops.message.dispatchEvent(GameEvent.UseSpecialCard, payload);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -287,6 +287,7 @@ export class MissionCardComp extends CCComp {
|
|||||||
oops.message.on(GameEvent.UseSkillCard, this.onUseSkillCard, this);
|
oops.message.on(GameEvent.UseSkillCard, this.onUseSkillCard, this);
|
||||||
oops.message.on(GameEvent.UseSpecialCard, this.onUseSpecialCard, this);
|
oops.message.on(GameEvent.UseSpecialCard, this.onUseSpecialCard, this);
|
||||||
oops.message.on(GameEvent.ShowSmallTip, this.onShowSmallTip, this);
|
oops.message.on(GameEvent.ShowSmallTip, this.onShowSmallTip, this);
|
||||||
|
oops.message.on(GameEvent.CardUsed, this.onCardUsed, this);
|
||||||
|
|
||||||
/** 按钮触控事件:抽卡 */
|
/** 按钮触控事件:抽卡 */
|
||||||
this.cards_chou?.on(NodeEventType.TOUCH_START, this.onDrawTouchStart, this);
|
this.cards_chou?.on(NodeEventType.TOUCH_START, this.onDrawTouchStart, this);
|
||||||
@@ -431,10 +432,9 @@ export class MissionCardComp extends CCComp {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private onUseSkillCard(event: string, args: any) {
|
private onUseSkillCard(event: string, args: any) {
|
||||||
// 选择技能后关闭弹窗
|
// 购买技能卡后不再关闭弹窗:技能卡池与英雄卡池保持一致,
|
||||||
if (this.skill_card_node && this.skill_card_node.isValid) {
|
// 由 onCardUsed 立即向被使用的槽位补充一张新技能卡。
|
||||||
this.skill_card_node.active = false;
|
// 弹窗由外部(按钮/阶段切换)控制显隐。
|
||||||
}
|
|
||||||
|
|
||||||
// 修复:独立判断 guide2 的关闭 和 guide3 的开启
|
// 修复:独立判断 guide2 的关闭 和 guide3 的开启
|
||||||
if (!smc.finish_guides.includes(2)) {
|
if (!smc.finish_guides.includes(2)) {
|
||||||
@@ -460,6 +460,7 @@ export class MissionCardComp extends CCComp {
|
|||||||
oops.message.off(GameEvent.UseSkillCard, this.onUseSkillCard, this);
|
oops.message.off(GameEvent.UseSkillCard, this.onUseSkillCard, this);
|
||||||
oops.message.off(GameEvent.UseSpecialCard, this.onUseSpecialCard, this);
|
oops.message.off(GameEvent.UseSpecialCard, this.onUseSpecialCard, this);
|
||||||
oops.message.off(GameEvent.ShowSmallTip, this.onShowSmallTip, this);
|
oops.message.off(GameEvent.ShowSmallTip, this.onShowSmallTip, this);
|
||||||
|
oops.message.off(GameEvent.CardUsed, this.onCardUsed, this);
|
||||||
if (this.cards_chou && this.cards_chou.isValid) {
|
if (this.cards_chou && this.cards_chou.isValid) {
|
||||||
this.cards_chou.off(NodeEventType.TOUCH_START, this.onDrawTouchStart, this);
|
this.cards_chou.off(NodeEventType.TOUCH_START, this.onDrawTouchStart, this);
|
||||||
this.cards_chou.off(NodeEventType.TOUCH_END, this.onDrawTouchEnd, this);
|
this.cards_chou.off(NodeEventType.TOUCH_END, this.onDrawTouchEnd, this);
|
||||||
@@ -572,6 +573,47 @@ export class MissionCardComp extends CCComp {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 单张卡牌被成功使用后的补卡回调:
|
||||||
|
* - payload 为该卡槽组件实例(CardComp 或 SCardComp)。
|
||||||
|
* - 命中英雄卡槽 → 调用 buildSingleHeroCard 补一张英雄/升级卡。
|
||||||
|
* - 命中技能卡槽 → 调用 buildSingleSkillCard 补一张技能卡。
|
||||||
|
* - 未命中任何槽位(如已销毁/未缓存)→ 忽略。
|
||||||
|
*
|
||||||
|
* Why: 购买一张卡后立即补充新卡,避免出现空槽,提升抽卡体验;
|
||||||
|
* 英雄卡池与技能卡池遵循同一逻辑。
|
||||||
|
*/
|
||||||
|
private onCardUsed(event: string, args: any) {
|
||||||
|
const source = args;
|
||||||
|
if (!source) return;
|
||||||
|
|
||||||
|
const heroIdx = this.cardComps.findIndex(c => c === source);
|
||||||
|
if (heroIdx >= 0) {
|
||||||
|
const card = this.buildSingleHeroCard();
|
||||||
|
if (card) {
|
||||||
|
this.cardComps[heroIdx].applyDrawCard(card);
|
||||||
|
}
|
||||||
|
mLogger.log(this.debugMode, "MissionCardComp", "refill hero slot", {
|
||||||
|
index: heroIdx,
|
||||||
|
uuid: card?.uuid ?? 0
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const skillIdx = this.skillCardComps.findIndex(c => c === source);
|
||||||
|
if (skillIdx >= 0) {
|
||||||
|
const card = this.buildSingleSkillCard();
|
||||||
|
if (card) {
|
||||||
|
this.skillCardComps[skillIdx].applyDrawCard(card);
|
||||||
|
}
|
||||||
|
mLogger.log(this.debugMode, "MissionCardComp", "refill skill slot", {
|
||||||
|
index: skillIdx,
|
||||||
|
uuid: card?.uuid ?? 0
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// ======================== 按钮触控回调 ========================
|
// ======================== 按钮触控回调 ========================
|
||||||
|
|
||||||
/** 抽卡按钮按下反馈 */
|
/** 抽卡按钮按下反馈 */
|
||||||
@@ -957,6 +999,58 @@ export class MissionCardComp extends CCComp {
|
|||||||
return filled;
|
return filled;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 构建单张英雄池卡牌,用于购买后补卡。
|
||||||
|
*
|
||||||
|
* 规则与 buildDrawCards 保持一致(不含"必出轮询"逻辑):
|
||||||
|
* 1. 满员且有可升级英雄 → 仅从升级卡池按权重抽 1 张。
|
||||||
|
* 2. 否则从 升级卡 + 未召唤英雄卡 的混合池按权重抽 1 张。
|
||||||
|
*
|
||||||
|
* @returns 卡牌数据;池为空时返回 null
|
||||||
|
*/
|
||||||
|
private buildSingleHeroCard(): CardConfig | null {
|
||||||
|
const upgradeCards = this.buildHeroUpgradeCards();
|
||||||
|
const aliveHeroCount = this.getAliveHeroCount();
|
||||||
|
const heroMax = this.getMissionHeroMaxNum();
|
||||||
|
|
||||||
|
if (aliveHeroCount >= heroMax && upgradeCards.length > 0) {
|
||||||
|
return this.weightedPick(upgradeCards);
|
||||||
|
}
|
||||||
|
|
||||||
|
const heroCards = CardPoolList.filter(c => c.type === CardType.Hero);
|
||||||
|
const aliveHeroUuids = this.getAliveHeroUuids();
|
||||||
|
const availableHeroCards = heroCards.filter(c => !aliveHeroUuids.has(c.uuid));
|
||||||
|
|
||||||
|
const mixedPool: CardConfig[] = [...upgradeCards, ...availableHeroCards];
|
||||||
|
if (mixedPool.length === 0) return null;
|
||||||
|
return this.weightedPick(mixedPool);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 构建单张技能卡,用于购买后补卡。
|
||||||
|
* 规则与 buildSkillDrawCards 对齐(按当前 wave 过滤)。
|
||||||
|
*
|
||||||
|
* @returns 卡牌数据;池为空时返回 null
|
||||||
|
*/
|
||||||
|
private buildSingleSkillCard(): CardConfig | null {
|
||||||
|
const currentWave = this.getCurrentWave();
|
||||||
|
const cards = drawCardsByRule(1, {
|
||||||
|
count: 1,
|
||||||
|
type: CardType.Skill,
|
||||||
|
wave: currentWave,
|
||||||
|
unique: true
|
||||||
|
});
|
||||||
|
if (cards.length > 0) return cards[0];
|
||||||
|
|
||||||
|
// 兜底:放宽 wave 限制再尝试
|
||||||
|
const fallback = drawCardsByRule(1, {
|
||||||
|
count: 1,
|
||||||
|
type: CardType.Skill,
|
||||||
|
unique: true
|
||||||
|
});
|
||||||
|
return fallback[0] ?? null;
|
||||||
|
}
|
||||||
|
|
||||||
private tryRefreshHeroCards(heroType?: HType): boolean {
|
private tryRefreshHeroCards(heroType?: HType): boolean {
|
||||||
const cards = drawCardsByRule(1, {
|
const cards = drawCardsByRule(1, {
|
||||||
count: 3,
|
count: 3,
|
||||||
@@ -1199,6 +1293,7 @@ export class MissionCardComp extends CCComp {
|
|||||||
}
|
}
|
||||||
model.updateSkillDistanceCache();
|
model.updateSkillDistanceCache();
|
||||||
model.dirty_hp = true;
|
model.dirty_hp = true;
|
||||||
|
model.dirty_lv = true;
|
||||||
oops.message.dispatchEvent(GameEvent.HeroLvUp, {
|
oops.message.dispatchEvent(GameEvent.HeroLvUp, {
|
||||||
uuid: model.hero_uuid,
|
uuid: model.hero_uuid,
|
||||||
lv: nextLv
|
lv: nextLv
|
||||||
|
|||||||
@@ -109,6 +109,8 @@ export class SCardComp extends CCComp {
|
|||||||
this.clearAfterUse();
|
this.clearAfterUse();
|
||||||
this.isUsing = false;
|
this.isUsing = false;
|
||||||
oops.message.dispatchEvent(GameEvent.UseSkillCard, used);
|
oops.message.dispatchEvent(GameEvent.UseSkillCard, used);
|
||||||
|
// 派发 CardUsed 让 MissionCardComp 立即补一张新技能卡到本槽位
|
||||||
|
oops.message.dispatchEvent(GameEvent.CardUsed, this);
|
||||||
});
|
});
|
||||||
return used;
|
return used;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user