Files
pixelheros/assets/script/game/map/MissionEconomy.ts
panFD 42c63e6482 feat: 新增刷新石机制并优化抽卡消耗逻辑
1.  新增refresh_stone玩家数据字段与对应变更事件
2.  实现刷新石的获取、消耗和刷新可用性校验逻辑
3.  抽卡优先消耗刷新石,不足时再扣除金币
4.  为购买按钮添加可配置的消耗标签,优化UI查找逻辑
5.  更新对应预制件绑定新的消耗标签组件
2026-07-30 13:46:21 +08:00

147 lines
5.0 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 { 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 canRefresh(baseCost: number = 1): boolean {
if (this.getRefreshStone() > 0) return true;
return this.getCoin() >= this.getRefreshCost(baseCost);
}
/**
* 执行刷新卡牌:
* 1. 刷新石 > 0 时优先扣除 1 颗刷新石(不消耗金币)。
* 2. 刷新石不足时扣除金币(含刷新优惠折扣)。
*/
static executeRefresh(baseCost: number = 1): boolean {
// 优先消耗刷新石
const stones = this.getRefreshStone();
if (stones > 0) {
smc.vmdata.mission_data.refresh_stone = stones - 1;
smc.vmdata.scores.refresh_count++;
oops.message.dispatchEvent(GameEvent.RefreshStone, { delta: -1 });
return true;
}
// 刷新石不足 → 扣除金币
const cost = this.getRefreshCost(baseCost);
const success = this.spendCoin(cost);
if (success) {
smc.vmdata.scores.refresh_count++;
}
return success;
}
/**
* 计算英雄出售金币(按英雄等级缩放)
*/
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;
}
}