Files
pixelheros/assets/script/game/map/MissionEconomy.ts
panFD 317a500439 refactor: 将刷新石替换为银币作为卡牌刷新消耗
1. 重构全局配置,移除刷新石相关定义,新增银币刷新消耗常量
2. 新增局外持久货币银币的数据结构与管理逻辑
3. 重构卡牌刷新经济系统,统一使用银币进行刷新消耗
4. 更新UI显示与事件通知,适配银币系统变更
5. 调整清屏奖励逻辑,将刷新石奖励改为金币奖励
2026-09-10 14:12:51 +08:00

139 lines
4.5 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { smc } from "../common/SingletonModuleComp";
import { oops } from "../../../../extensions/oops-plugin-framework/assets/core/Oops";
import { GameEvent } from "../common/config/GameEvent";
import { FightSet } from "../common/config/GameSet";
/**
* 局内经济统一管理类
* 负责统一处理金币的增减、各种费用的计算以及战绩评分中的金币统计。
*/
export class MissionEconomy {
/** 获取当前金币 */
static getCoin(): number {
return Math.max(0, Math.floor(smc.vmdata.mission_data.coin ?? 0));
}
/** 增加金币并更新统计 */
static addCoin(amount: number) {
if (amount <= 0) return;
amount = Math.floor(amount);
smc.vmdata.mission_data.coin = this.getCoin() + amount;
smc.vmdata.scores.gold_earned += amount;
// 发送 UI 更新事件,这里我们统一使用 syncOnly 通知 UI 刷新即可
oops.message.dispatchEvent(GameEvent.CoinAdd, { delta: amount, syncOnly: true });
}
/** 消费金币并更新统计 */
static spendCoin(amount: number): boolean {
if (amount <= 0) return true;
amount = Math.floor(amount);
const current = this.getCoin();
if (current < amount) return false;
smc.vmdata.mission_data.coin = current - amount;
smc.vmdata.scores.gold_spent += amount;
// 发送 UI 更新事件
oops.message.dispatchEvent(GameEvent.CoinAdd, { delta: -amount, syncOnly: true });
return true;
}
/** 获取当前银币数量(局外持久货币,刷新卡牌消耗) */
static getSilver(): number {
return Math.max(0, Math.floor(smc.vmdata.silver ?? 0));
}
/**
* 增加银币
* @param amount 增加数量,<=0 时忽略
*/
static addSilver(amount: number) {
if (amount <= 0) return;
smc.updateSilver(Math.floor(amount));
}
/** 单次刷新消耗的银币数量 */
static getSilverRefreshCost(): number {
return Math.max(1, Math.floor(FightSet.SILVER_REFRESH_COST));
}
/**
* 判断当前是否可以执行一次刷新(银币足够)
*/
static canRefresh(): boolean {
return this.getSilver() >= this.getSilverRefreshCost();
}
/**
* 执行刷新卡牌:
* 银币足够时扣除 SILVER_REFRESH_COST 枚银币,否则刷新失败。
* Why: 英雄卡牌只能银币刷新,不能金币刷新,银币为局外持久货币,靠日常积攒。
*/
static executeRefresh(): boolean {
const cost = this.getSilverRefreshCost();
const silver = this.getSilver();
if (silver < cost) return false;
smc.updateSilver(-cost);
smc.vmdata.scores.refresh_count++;
return true;
}
/**
* 计算英雄升级金币消耗(指数递增:5×2^(lv-1),无限升级下指数控速)
* @param heroLevel 当前英雄等级(升级前)
*/
static getUpgradeCost(heroLevel: number = 1): number {
const lv = Math.max(1, Math.floor(heroLevel));
return Math.floor(5 * Math.pow(2, lv - 1));
}
/**
* 执行英雄升级扣费
* @param heroLevel 当前英雄等级(升级前)
* @returns true = 扣费成功(金币足够)
*/
static executeUpgradeCost(heroLevel: number = 1): boolean {
return this.spendCoin(this.getUpgradeCost(heroLevel));
}
/**
* 计算英雄出售金币(按累计升级投入的 50% 折算,无限升级自动缩放)。
* 累计投入 = 等比数列求和 Σ5×2^(i-1)(i=1..lv-1)= 5×(2^(lv-1) - 1)。
*/
static getSellGold(heroLevel: number = 1): number {
const lv = Math.max(1, Math.floor(heroLevel));
// 基础出售价 3(保底招募残值)+ 累计升级投入的 50%
const investTotal = 5 * (Math.pow(2, lv - 1) - 1);
return Math.floor(3 + Math.floor(investTotal * 0.5));
}
/**
* 执行出售英雄并增加金币
*/
static executeSellHero(heroLevel: number = 1): number {
const gold = this.getSellGold(heroLevel);
this.addCoin(gold);
return gold;
}
/**
* 计算每回合基础金币收益
*/
static getWaveGold(baseReward: number): number {
return Math.max(0, Math.floor(baseReward));
}
/**
* 执行发放每回合金币
*/
static executeWaveGold(baseReward: number): number {
const reward = this.getWaveGold(baseReward);
if (reward > 0) {
this.addCoin(reward);
}
return reward;
}
}