diff --git a/assets/resources/gui/element/reward_item_exp.prefab b/assets/resources/gui/element/reward_item_exp.prefab index f568a8d8..5c6f5191 100644 --- a/assets/resources/gui/element/reward_item_exp.prefab +++ b/assets/resources/gui/element/reward_item_exp.prefab @@ -878,7 +878,9 @@ "__prefab": { "__id__": 37 }, - "count_label": null, + "count_label": { + "__id__": 31 + }, "_id": "" }, { @@ -894,6 +896,7 @@ "__id__": 0 }, "fileId": "47Sc4S8E5EfJ3uZtG97byB", + "instance": null, "targetOverrides": null } ] \ No newline at end of file diff --git a/assets/resources/gui/element/reward_item_gold.prefab b/assets/resources/gui/element/reward_item_gold.prefab index aec697cf..54870643 100644 --- a/assets/resources/gui/element/reward_item_gold.prefab +++ b/assets/resources/gui/element/reward_item_gold.prefab @@ -713,7 +713,9 @@ "__prefab": { "__id__": 31 }, - "count_label": null, + "count_label": { + "__id__": 25 + }, "_id": "" }, { @@ -729,6 +731,7 @@ "__id__": 0 }, "fileId": "10z6GxEehAebPrefUJTgkq", + "instance": null, "targetOverrides": null } ] \ No newline at end of file diff --git a/assets/script/game/common/SingletonModuleComp.ts b/assets/script/game/common/SingletonModuleComp.ts index 961930cf..24caf35c 100644 --- a/assets/script/game/common/SingletonModuleComp.ts +++ b/assets/script/game/common/SingletonModuleComp.ts @@ -211,7 +211,8 @@ export class SingletonModuleComp extends ecs.Comp { achieved_highlights: [], } as GameScoreStats, - gold: 0, // 金币数据(MVVM绑定字段) + gold: 0, // 金币数据(MVVM绑定字段,镜像 data.gold) + diamond: 0, // 钻石数据(MVVM绑定字段,镜像 data.diamond) switch_effect: true, // 音效开关(MVVM绑定字段) switch_music: true, // 音乐开关(MVVM绑定字段) }; @@ -303,13 +304,24 @@ export class SingletonModuleComp extends ecs.Comp { Object.assign(this.data, cloudData.data); } - // 触发UI更新 + // 触发UI更新(同步镜像层 + 事件) + this.syncCurrencyToView(); oops.message.dispatchEvent(GameEvent.GOLD_UPDATE); } catch (error) { mLogger.error(this.debugMode, 'SMC', `[SMC]: 数据覆盖失败:`, error); } } + + /** + * 将 data 层的货币镜像到 vmdata 视图层(MVVM 绑定字段)。 + * Why: data 为云端持久权威源,vmdata.gold/diamond 仅供界面绑定展示; + * 登录覆盖、奖励发放后都必须调用本方法保持镜像一致。 + */ + public syncCurrencyToView(): void { + this.vmdata.gold = this.data.gold ?? 0; + this.vmdata.diamond = this.data.diamond ?? 0; + } getGameDate() { let data: GameDate = { ...this.data, @@ -318,8 +330,29 @@ export class SingletonModuleComp extends ecs.Comp { return data; } + /** + * 变更金币(正数获得 / 负数消耗),以 data 为权威源并镜像到 vmdata。 + * @param gold 变动量 + * @param is_sync 是否标记脏并触发云端/本地同步 + */ updateGold(gold: number, is_sync: boolean = true) { - this.vmdata.gold += gold; + this.data.gold = Math.max(0, (this.data.gold ?? 0) + gold); + this.vmdata.gold = this.data.gold; + if (is_sync) { + gameDataSync.markDataDirty(); + } + oops.message.dispatchEvent(GameEvent.GOLD_UPDATE) + return true + } + + /** + * 变更钻石(正数获得 / 负数消耗),以 data 为权威源并镜像到 vmdata。 + * @param diamond 变动量 + * @param is_sync 是否标记脏并触发云端/本地同步 + */ + updateDiamond(diamond: number, is_sync: boolean = true) { + this.data.diamond = Math.max(0, (this.data.diamond ?? 0) + diamond); + this.vmdata.diamond = this.data.diamond; if (is_sync) { gameDataSync.markDataDirty(); } diff --git a/assets/script/game/map/VictoryComp.ts b/assets/script/game/map/VictoryComp.ts index cb098d0d..5d873dd1 100644 --- a/assets/script/game/map/VictoryComp.ts +++ b/assets/script/game/map/VictoryComp.ts @@ -560,8 +560,7 @@ export class VictoryComp extends CCComp { // 3. 落地发放 if (gold > 0) { - smc.data.gold = (smc.data.gold || 0) + gold; // 持久化(存档口径) - smc.updateGold(gold); // 驱动 MVVM 展示 + smc.updateGold(gold); // 统一入口:改 data 持久层 + 镜像 vmdata + 标脏同步 } if (talentExp > 0) { smc.addTalentExp(talentExp);