1. 新增英雄升级相关UI控件与事件流程 2. 实现升级消耗计算与统一扣费逻辑 3. 添加升级预览确认弹窗与属性成长展示 4. 开放tryUpgradeHeroByEid与applyHeroLevel为公共方法
172 lines
5.9 KiB
TypeScript
172 lines
5.9 KiB
TypeScript
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";
|
||
import { FieldSkillType } from "../common/config/SkillSet";
|
||
import { FieldSkillHelper } from "../hero/FieldSkillHelper";
|
||
|
||
/**
|
||
* 局内经济统一管理类
|
||
* 负责统一处理金币的增减、各种费用的计算以及战绩评分中的金币统计。
|
||
*/
|
||
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;
|
||
}
|
||
|
||
/**
|
||
* 计算卡牌刷新费用
|
||
* @param baseCost 基础费用,默认为1
|
||
*/
|
||
static getRefreshCost(baseCost: number = 1): number {
|
||
let cost = baseCost;
|
||
// 驻场英雄带来的"刷新优惠"折扣
|
||
const discount = FieldSkillHelper.getFieldSkillTotalValue(FieldSkillType.RefreshDiscount);
|
||
cost = Math.max(0, cost - discount);
|
||
return Math.floor(cost);
|
||
}
|
||
|
||
/** 获取当前刷新石数量 */
|
||
static getRefreshStone(): number {
|
||
return Math.max(0, Math.floor(smc.vmdata.mission_data.refresh_stone ?? 0));
|
||
}
|
||
|
||
/**
|
||
* 增加刷新石
|
||
* @param amount 增加数量,<=0 时忽略
|
||
*/
|
||
static addRefreshStone(amount: number) {
|
||
if (amount <= 0) return;
|
||
amount = Math.floor(amount);
|
||
smc.vmdata.mission_data.refresh_stone = this.getRefreshStone() + amount;
|
||
|
||
// 发送 UI 更新事件(复用 RefreshStone 事件通知刷新按钮状态刷新)
|
||
oops.message.dispatchEvent(GameEvent.RefreshStone, { delta: amount });
|
||
}
|
||
|
||
/** 单次刷新消耗的刷新石数量 */
|
||
static getRefreshStoneCost(): number {
|
||
return Math.max(1, Math.floor(FightSet.REFRESH_STONE_COST));
|
||
}
|
||
|
||
/**
|
||
* 判断当前是否可以执行一次刷新(刷新石足够或金币足够)
|
||
*/
|
||
static canRefresh(baseCost: number = 1): boolean {
|
||
if (this.getRefreshStone() >= this.getRefreshStoneCost()) return true;
|
||
return this.getCoin() >= this.getRefreshCost(baseCost);
|
||
}
|
||
|
||
/**
|
||
* 执行刷新卡牌:
|
||
* 1. 刷新石足够时优先扣除 REFRESH_STONE_COST 颗刷新石(不消耗金币)。
|
||
* 2. 刷新石不足时扣除金币(含刷新优惠折扣)。
|
||
*/
|
||
static executeRefresh(baseCost: number = 1): boolean {
|
||
// 优先消耗刷新石
|
||
const stoneCost = this.getRefreshStoneCost();
|
||
const stones = this.getRefreshStone();
|
||
if (stones >= stoneCost) {
|
||
smc.vmdata.mission_data.refresh_stone = stones - stoneCost;
|
||
smc.vmdata.scores.refresh_count++;
|
||
oops.message.dispatchEvent(GameEvent.RefreshStone, { delta: -stoneCost });
|
||
return true;
|
||
}
|
||
|
||
// 刷新石不足 → 扣除金币
|
||
const cost = this.getRefreshCost(baseCost);
|
||
const success = this.spendCoin(cost);
|
||
if (success) {
|
||
smc.vmdata.scores.refresh_count++;
|
||
}
|
||
return success;
|
||
}
|
||
|
||
/**
|
||
* 计算英雄升级金币消耗(按当前等级线性缩放:Lv×5)
|
||
* @param heroLevel 当前英雄等级(升级前)
|
||
*/
|
||
static getUpgradeCost(heroLevel: number = 1): number {
|
||
const lv = Math.max(1, Math.floor(heroLevel));
|
||
return lv * 5;
|
||
}
|
||
|
||
/**
|
||
* 执行英雄升级扣费
|
||
* @param heroLevel 当前英雄等级(升级前)
|
||
* @returns true = 扣费成功(金币足够)
|
||
*/
|
||
static executeUpgradeCost(heroLevel: number = 1): boolean {
|
||
return this.spendCoin(this.getUpgradeCost(heroLevel));
|
||
}
|
||
|
||
/**
|
||
* 计算英雄出售金币(按英雄等级缩放)
|
||
*/
|
||
static getSellGold(heroLevel: number = 1): number {
|
||
const sellByLevel: Record<number, number> = { 1: 3, 2: 10, 3: 25 };
|
||
const baseSellGold = sellByLevel[heroLevel] || 3;
|
||
// 驻场英雄带来的"出售金币"加成(包含原 SellBonus 语义,统一在 SellGold 中)
|
||
const goldBoost = FieldSkillHelper.getFieldSkillTotalValue(FieldSkillType.SellGold);
|
||
const totalSellGold = baseSellGold + goldBoost;
|
||
return Math.floor(totalSellGold);
|
||
}
|
||
|
||
/**
|
||
* 执行出售英雄并增加金币
|
||
*/
|
||
static executeSellHero(heroLevel: number = 1): number {
|
||
const gold = this.getSellGold(heroLevel);
|
||
this.addCoin(gold);
|
||
return gold;
|
||
}
|
||
|
||
/**
|
||
* 计算每波基础金币收益
|
||
*/
|
||
static getWaveGold(baseReward: number): number {
|
||
let reward = Math.max(0, Math.floor(baseReward));
|
||
const goldBoost = FieldSkillHelper.getFieldSkillTotalValue(FieldSkillType.WaveGold);
|
||
reward += goldBoost;
|
||
return reward;
|
||
}
|
||
|
||
/**
|
||
* 执行发放每波金币
|
||
*/
|
||
static executeWaveGold(baseReward: number): number {
|
||
const reward = this.getWaveGold(baseReward);
|
||
if (reward > 0) {
|
||
this.addCoin(reward);
|
||
}
|
||
return reward;
|
||
}
|
||
}
|