Files
caliverse_server/GameServer/Contents/Calium/Action/CaliumConverterAction.cs
2025-05-01 07:20:41 +09:00

218 lines
9.0 KiB
C#

using ServerCore;
using ServerBase;
using ServerCommon;
namespace GameServer;
public class CaliumConverterAction : EntityActionBase
{
public CaliumConverterAction(Player owner) : base(owner)
{
}
public override async Task<Result> onInit() => await Task.FromResult(new Result());
public override void onClear()
{
return;
}
public async Task<(double calium, double currency)> calculationConvertCalium(Dictionary<int, int> useMaterials)
{
var total_fluxEtheron = 0.0;
// 1. 플럭스 에테론 변환 처리
foreach (var material in useMaterials)
{
if (!MetaData.Instance._CaliumConverterMaterialTable.TryGetValue(material.Key, out var material_data)) continue;
var fluxEtheron = material_data.Value * material.Value;
total_fluxEtheron = CaliumStorageHelper.AddDoubleByLong(total_fluxEtheron, fluxEtheron);
}
// 2. calium 계산 : fluxEtheron * 기본 변환율 * 에너지 효율 / 소수점 버림 처리
var calium_storage_entity = GameServerApp.getServerLogic().findGlobalEntity<CaliumStorageEntity>();
NullReferenceCheckHelper.throwIfNull(calium_storage_entity, () => $"calium_storage_entity is null !!! : {getOwner().toBasicString()}");
var calium_storage_action = calium_storage_entity.getEntityAction<CaliumStorageAction>();
NullReferenceCheckHelper.throwIfNull(calium_storage_action, () => $"calium_storage_action is null !!! : {getOwner().toBasicString()}");
var efficiency = await calium_storage_action.getCaliumConverterEfficiency();
var calium = total_fluxEtheron * (double)MetaHelper.GameConfigMeta.CaliumConverterConversionRate * efficiency;
calium = CaliumStorageHelper.roundDownDefaultDigitsFromDouble(calium);
// 3. 요구 재화 계산 : 소수점 올림 처리
var currency = total_fluxEtheron * (double)ServerCommon.MetaHelper.GameConfigMeta.CaliumConverterCommissionRate;
currency = Math.Ceiling(currency);
return (calium, currency);
}
public Result checkConvertConditions(Dictionary<int, int> useMaterials, double convertCalium, double currency)
{
var server_logic = GameServerApp.getServerLogic();
var player = getOwner() as Player;
NullReferenceCheckHelper.throwIfNull(player, () => $"player is null !!!");
var result = new Result();
string err_msg;
var calium_storage_entity = server_logic.findGlobalEntity<CaliumStorageEntity>();
var calium_storage_action = calium_storage_entity?.getEntityAction<CaliumStorageAction>();
NullReferenceCheckHelper.throwIfNull(calium_storage_action, () => $"calium_storage_action is null !!!");
// 1. Calium 총량 체크
var total_calium = calium_storage_action.getTotalCalium(CaliumStorageType.Converter);
if (total_calium < 0)
{
err_msg = $"fail to convert calium!!! : loading calium - {checkConvertConditions}";
result.setFail(ServerErrorCode.FailToLoadCalium, err_msg);
Log.getLogger().error(err_msg);
return result;
}
if (convertCalium > total_calium)
{
err_msg = $"fail to convert calium!!! : lack of total calium - calium[{convertCalium}] / total[{total_calium}]";
result.setFail(ServerErrorCode.LackOfTotalCalium, err_msg);
Log.getLogger().error(err_msg);
return result;
}
// 2. 1일 제한 용량 체크
var user_calium_attribute = player.getEntityAttribute<CaliumAttribute>();
NullReferenceCheckHelper.throwIfNull(user_calium_attribute, () => $"user_calium_attribute is null !!! - {player.toBasicString()}");
var daily_calium = CaliumStorageHelper.roundHalfUpDefaultDigitsFromDouble(user_calium_attribute.DailyCalium);
if (convertCalium > daily_calium)
{
err_msg = $"fail to convert calium!!! : lack of daily calium - calium[{convertCalium}] / daily[{user_calium_attribute.DailyCalium}] / roundUp[{daily_calium}]";
result.setFail(ServerErrorCode.LackOfDailyCalium, err_msg);
Log.getLogger().error(err_msg);
return result;
}
// 3. 재화 보유 체크
if (! checkCurrencyForConvertCalium(currency))
{
err_msg = $"fail to convert calium!!! : lack of currency - currency[{currency}]";
result.setFail(ServerErrorCode.LackOfCommissionCurrency, err_msg);
Log.getLogger().error(err_msg);
return result;
}
// 4. 아이템 보유 체크
if (!checkItemForConvertCalium(useMaterials))
{
err_msg = $"fail to convert calium!!! : lack of meterial - useMaterials[{useMaterials}]";
result.setFail(ServerErrorCode.LackOfCommissionMaterials, err_msg);
Log.getLogger().error(err_msg);
return result;
}
return result;
}
private bool checkCurrencyForConvertCalium(double currency)
{
var money_attribute = getOwner().getEntityAttribute<MoneyAttribute>();
NullReferenceCheckHelper.throwIfNull(money_attribute, () => $"money_attribute is null !!!");
var owner_currency = MetaHelper.GameConfigMeta.CaliumConverterCommissionType switch
{
CurrencyType.Gold => money_attribute.Gold,
CurrencyType.Sapphire => money_attribute.Sapphire,
CurrencyType.Ruby => money_attribute.Ruby,
_ => 0.0
};
return currency <= owner_currency;
}
private bool checkItemForConvertCalium(Dictionary<int, int> useMaterials)
{
foreach (var material in useMaterials)
{
var inventory_action = getOwner().getEntityAction<InventoryActionBase>();
if (!MetaData.Instance._CaliumConverterMaterialTable.TryGetValue(material.Key, out var material_data))
{
return false;
}
NullReferenceCheckHelper.throwIfNull(inventory_action, () => $"inventory_action is null !!!");
var own_count = inventory_action.getItemStackCountAllByMetaId((uint)material_data.ItemId);
if (material.Value > own_count) return false;
}
return true;
}
public async Task<(Result result, IEnumerable<GameServer.Item>? items)> deleteMaterials(Dictionary<int, int> useMaterials)
{
var result = new Result();
string err_msg;
var inventory_action = getOwner().getEntityAction<InventoryActionBase>();
NullReferenceCheckHelper.throwIfNull(inventory_action, () => $"inventory_action is null !!!");
var items = new List<GameServer.Item>();
foreach (var material in useMaterials)
{
if (!MetaData.Instance._CaliumConverterMaterialTable.TryGetValue(material.Key, out var material_data))
{
err_msg = $"fail to convert calium !!! : invalid material slot id - input slotId[{material.Key}]";
result.setFail(ServerErrorCode.InvalidMaterialSlotId, err_msg);
Log.getLogger().error(result.toBasicString());
return (result, null);
}
(result, var item) = await inventory_action.tryDeleteItemByMetaId((uint)material_data.ItemId, (ushort)material.Value);
if (result.isFail())
{
err_msg = $"fail to convert calium !!! : lack of material count - input slotId[{material.Key}] / cout[{material.Value}]";
result.setFail(ServerErrorCode.LackOfCommissionMaterials, err_msg);
Log.getLogger().error(result.toBasicString());
return (result, null);
}
items.AddRange(item);
}
return (result, items);
}
public async Task<Result> changeCurrency(double obtainCalium, CurrencyType currencyType, double spendCurrency)
{
var result = new Result();
var money_action = getOwner().getEntityAction<MoneyAction>();
NullReferenceCheckHelper.throwIfNull(money_action, () => $"money_action is null !!!");
// 1. calium 획득
result = await money_action.changeMoney(CurrencyType.Calium, obtainCalium, useCaliumEvent: false);
if (result.isFail()) return result;
// 2. 변환을 위한 재화 소모
result = await money_action.changeMoney(currencyType, -1 * spendCurrency, useCaliumEvent: false);
return result;
}
public Result changeDailyCalium(Player player, double calium)
{
var result = new Result();
// 1. 개인 daily calium 수량 수정
var user_calium_attribute = player.getEntityAttribute<CaliumAttribute>();
NullReferenceCheckHelper.throwIfNull(user_calium_attribute, () => $"user_calium_attribute is null !!! - calium:{calium} / {player.toBasicString()}");
user_calium_attribute.DailyCalium -= calium;
user_calium_attribute.modifiedEntityAttribute();
return result;
}
}