Compare commits
2 Commits
53fa0d7dc0
...
67c2a53211
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
67c2a53211 | ||
|
|
401a5daf77 |
@@ -16,7 +16,9 @@
|
||||
"Bash(git add *)",
|
||||
"Bash(git commit *)",
|
||||
"Bash(npm install *)",
|
||||
"Bash(npx tsc *)"
|
||||
"Bash(npx tsc *)",
|
||||
"Bash(d:/game/pixelheros/extensions/pixelhero-config-editor/node_modules/.bin/tsx --version)",
|
||||
"Bash(d:/game/pixelheros/extensions/pixelhero-config-editor/node_modules/.bin/tsx --tsconfig scripts/tsconfig.eval.json scripts/eval-heroes.ts --lv=1 --base=5011)"
|
||||
],
|
||||
"deny": [
|
||||
"Bash(rm -rf *)",
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -59,40 +59,47 @@ export interface WindowPromptParams {
|
||||
@ccclass("CommonPrompt")
|
||||
export class CommonPrompt extends Component {
|
||||
/** 窗口标题 */
|
||||
@property(Label)
|
||||
@property({ type: Label, displayName: "标题文本" })
|
||||
private lab_title: Label | null = null;
|
||||
|
||||
/** 窗口内容(富文本,需在 prefab 中将 Label 换为 RichText 后重新拖入) */
|
||||
@property(RichText)
|
||||
@property({ type: RichText, displayName: "内容富文本" })
|
||||
private lab_content: RichText | null = null;
|
||||
|
||||
/** 确定按钮文本 */
|
||||
@property(Label)
|
||||
@property({ type: Label, displayName: "确定按钮文本" })
|
||||
private lab_ok: Label | null = null;
|
||||
|
||||
/** 取消按钮文本 */
|
||||
@property(Label)
|
||||
@property({ type: Label, displayName: "取消按钮文本" })
|
||||
private lab_cancel: Label | null = null;
|
||||
|
||||
/** 确定按钮节点 */
|
||||
@property({ type: Node, displayName: "确定按钮" })
|
||||
private btn_ok: Node | null = null;
|
||||
|
||||
/** 取消按钮节点 */
|
||||
@property({ type: Node, displayName: "取消按钮" })
|
||||
private btn_cancel: Node | null = null;
|
||||
|
||||
/** 运行时参数 */
|
||||
private config: WindowPromptParams = {};
|
||||
|
||||
/** 弹窗打开动画已播放标记(防止 onAdded 重复触发) */
|
||||
private animPlayed: boolean = false;
|
||||
|
||||
/** 代码动态绑定的确定按钮(prefab clickEvents 失效时的兜底) */
|
||||
private btnOk: Node | null = null;
|
||||
/** 代码动态绑定的取消按钮 */
|
||||
private btnCancel: Node | null = null;
|
||||
|
||||
onLoad() {
|
||||
// 兜底:prefab 中 clickEvents 引用的旧插件脚本被移除后,代码动态绑定保证按钮可用
|
||||
this.btnOk = this.node.getChildByName("Node")?.getChildByName("btn_ok") ?? null;
|
||||
this.btnCancel = this.node.getChildByName("Node")?.getChildByName("btn_cancel") ?? null;
|
||||
this.btnOk?.on(Button.EventType.CLICK, this.onOk, this);
|
||||
this.btnCancel?.on(Button.EventType.CLICK, this.onCancel, this);
|
||||
// 优先使用编辑器绑定的按钮节点;未绑定时按节点名查找兜底
|
||||
if (!this.btn_ok) {
|
||||
this.btn_ok = this.node.getChildByName("Node")?.getChildByName("btn_ok") ?? null;
|
||||
}
|
||||
if (!this.btn_cancel) {
|
||||
this.btn_cancel = this.node.getChildByName("Node")?.getChildByName("btn_cancel") ?? null;
|
||||
}
|
||||
this.btn_ok?.on(Button.EventType.CLICK, this.onOk, this);
|
||||
this.btn_cancel?.on(Button.EventType.CLICK, this.onCancel, this);
|
||||
// 遮罩点击关闭(btn_sky 为 btn_ok 内嵌子节点,无 Button 组件,直接监听触摸事件)
|
||||
this.btnOk?.getChildByName("btn_sky")?.on(NodeEventType.TOUCH_END, this.onMaskClick, this);
|
||||
this.btn_ok?.getChildByName("btn_sky")?.on(NodeEventType.TOUCH_END, this.onMaskClick, this);
|
||||
|
||||
// 序列化属性槽引用的是旧插件 LanguageLabel 组件实例,脚本替换后已失效;
|
||||
// 这里按节点名查找 Label/RichText 作为兜底,保证文字一定写入
|
||||
@@ -100,10 +107,10 @@ export class CommonPrompt extends Component {
|
||||
this.lab_title = this.node.getChildByName("lab_title")?.getComponent(Label) ?? null;
|
||||
}
|
||||
if (!this.lab_ok) {
|
||||
this.lab_ok = this.btnOk?.getChildByName("lab_ok")?.getComponent(Label) ?? null;
|
||||
this.lab_ok = this.btn_ok?.getChildByName("lab_ok")?.getComponent(Label) ?? null;
|
||||
}
|
||||
if (!this.lab_cancel) {
|
||||
this.lab_cancel = this.btnCancel?.getChildByName("lab_cancel")?.getComponent(Label) ?? null;
|
||||
this.lab_cancel = this.btn_cancel?.getChildByName("lab_cancel")?.getComponent(Label) ?? null;
|
||||
}
|
||||
if (!this.lab_content) {
|
||||
this.lab_content = this.node.getChildByName("lab_content")?.getComponent(RichText) ?? null;
|
||||
@@ -127,8 +134,8 @@ export class CommonPrompt extends Component {
|
||||
}
|
||||
|
||||
onDestroy() {
|
||||
this.btnOk?.off(Button.EventType.CLICK, this.onOk, this);
|
||||
this.btnCancel?.off(Button.EventType.CLICK, this.onCancel, this);
|
||||
this.btn_ok?.off(Button.EventType.CLICK, this.onOk, this);
|
||||
this.btn_cancel?.off(Button.EventType.CLICK, this.onCancel, this);
|
||||
Tween.stopAllByTarget(this.node);
|
||||
this.config = {};
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@ import { GameEvent } from "../common/config/GameEvent";
|
||||
import { HeroInfo } from "../common/config/heroSet";
|
||||
import { HeroAttrsComp } from "../hero/HeroAttrsComp";
|
||||
import { Hero } from "../hero/Hero";
|
||||
import { getLvColor } from "../common/config/GameSet";
|
||||
import { FacSet, getLvColor } from "../common/config/GameSet";
|
||||
import { buildSkillDescRich } from "../common/config/HeroSkillDesc";
|
||||
import { MissionEconomy } from "./MissionEconomy";
|
||||
import { UIID } from "../common/config/GameUIConfig";
|
||||
@@ -189,6 +189,11 @@ export class HeroBoxComp extends CCComp {
|
||||
*/
|
||||
private onSellHeroClick() {
|
||||
if (!this.eid || !this.model) return;
|
||||
// 场上仅剩 1 个英雄时不允许出售:复用英雄栏 smalltip 气泡提示(与满员同一挂载点)
|
||||
if (HeroBoxComp.getAliveHeroCount() <= 1) {
|
||||
oops.message.dispatchEvent(GameEvent.ShowSmallTip, { type: "hero_full", text: "至少保留 1 个英雄" });
|
||||
return;
|
||||
}
|
||||
oops.audio.playEffect("music/button");
|
||||
|
||||
const heroName = this.model.hero_name ?? "";
|
||||
@@ -453,6 +458,20 @@ export class HeroBoxComp extends CCComp {
|
||||
|
||||
// ======================== 内部工具 ========================
|
||||
|
||||
/**
|
||||
* 统计场上存活英雄数量(与 MissionCardComp.getAliveHeroCount 口径一致)。
|
||||
*/
|
||||
private static getAliveHeroCount(): number {
|
||||
let count = 0;
|
||||
ecs.query(ecs.allOf(HeroAttrsComp)).forEach((entity: ecs.Entity) => {
|
||||
const model = entity.get(HeroAttrsComp);
|
||||
if (model && model.fac === FacSet.HERO) {
|
||||
count++;
|
||||
}
|
||||
});
|
||||
return count;
|
||||
}
|
||||
|
||||
/**
|
||||
* 写入一行战斗信息(总值 + 附加值)。
|
||||
* 总值始终显示(0 不隐藏);附加值为 0 时隐藏,正/负分别显示 (+x) / (x)。
|
||||
|
||||
@@ -455,11 +455,17 @@ export class MissionCardComp extends CCComp {
|
||||
}
|
||||
|
||||
private onShowSmallTip(event: string, args: any) {
|
||||
const type = args as string;
|
||||
this.showSmallTip(type as any);
|
||||
// 支持字符串(仅类型)或 { type, text }(类型 + 自定义文案)两种负载
|
||||
const payload = typeof args === "string" ? { type: args } : (args ?? {});
|
||||
this.showSmallTip(payload.type, payload.text);
|
||||
}
|
||||
|
||||
public showSmallTip(type: "refresh_coin" | "buy_coin" | "hero_full") {
|
||||
/**
|
||||
* 在目标节点上弹出 smalltip 气泡(缩放动画)。
|
||||
* @param type 提示类型(决定挂载到哪个节点)
|
||||
* @param text 可选:覆盖气泡文字(默认读 prefab 中配置的文本)
|
||||
*/
|
||||
public showSmallTip(type: "refresh_coin" | "buy_coin" | "hero_full", text?: string) {
|
||||
let targetNode: Node | null = null;
|
||||
switch (type) {
|
||||
case "refresh_coin":
|
||||
@@ -475,6 +481,11 @@ export class MissionCardComp extends CCComp {
|
||||
if (targetNode && targetNode.isValid) {
|
||||
const tipNode = targetNode.getChildByName("smalltip");
|
||||
if (tipNode) {
|
||||
// 动态覆盖气泡文字(box/Label),用于同节点多文案场景(如英雄满员 / 至少保留 1 人)
|
||||
if (text) {
|
||||
const label = tipNode.getComponentInChildren(Label);
|
||||
if (label) label.string = text;
|
||||
}
|
||||
tipNode.active = true;
|
||||
Tween.stopAllByTarget(tipNode);
|
||||
|
||||
@@ -740,7 +751,7 @@ export class MissionCardComp extends CCComp {
|
||||
if (current >= heroMax) {
|
||||
payload.cancel = true;
|
||||
payload.reason = "hero_limit";
|
||||
this.showSmallTip("hero_full");
|
||||
this.showSmallTip("hero_full", "英雄队伍已满");
|
||||
this.playHeroNumDeniedAnim();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user