179 lines
6.0 KiB
C#
179 lines
6.0 KiB
C#
using Google.Protobuf;
|
|
using Google.Protobuf.WellKnownTypes;
|
|
|
|
|
|
using ServerCore;
|
|
using ServerBase;
|
|
using ServerCommon;
|
|
using ServerCommon.BusinessLogDomain;
|
|
using MetaAssets;
|
|
|
|
|
|
using META_ID = System.UInt32;
|
|
|
|
|
|
namespace GameServer;
|
|
|
|
|
|
public class ItemBuyAction : EntityActionBase
|
|
{
|
|
public List<GameServer.Item>? BuyItems => m_buy_items;
|
|
private List<GameServer.Item>? m_buy_items { get; set; }
|
|
|
|
public ItemBuyAction(Player owner) : base(owner)
|
|
{
|
|
}
|
|
|
|
public override async Task<Result> onInit()
|
|
{
|
|
await Task.CompletedTask;
|
|
|
|
var result = new Result();
|
|
return result;
|
|
}
|
|
|
|
public override void onClear()
|
|
{
|
|
return;
|
|
}
|
|
|
|
public async Task<Result> tryBuyItem(META_ID item_id, int buy_count)
|
|
{
|
|
var result = new Result();
|
|
|
|
var discount = checkPurchaseDiscountType((int)item_id);
|
|
|
|
// 1. item data 체크
|
|
(result, var item_data) = checkBuyItemConditions((int)item_id, buy_count);
|
|
if (result.isFail()) return result;
|
|
|
|
// 2. 구매 처리
|
|
(result, var spent_currency_type, var spent_currency) = await processForItem(item_data!, buy_count, discount.discount_rate);
|
|
if (result.isFail()) return result;
|
|
|
|
// 3. 재화 차감
|
|
result = await processSpent(spent_currency_type, spent_currency);
|
|
if (result.isFail()) return result;
|
|
|
|
result = await updateItemFirstPurchaseHistory(discount.discount_type, (int)item_id);
|
|
|
|
return result;
|
|
}
|
|
|
|
private async Task<(Result result, CurrencyType spent_currency_type, double spent_currency)> processForItem(
|
|
MetaAssets.ItemMetaData item_data, int buy_count, int discountRate)
|
|
{
|
|
var result = new Result();
|
|
string err_msg;
|
|
|
|
var player = getOwner() as Player;
|
|
|
|
var inventory_action = player?.getEntityAction<InventoryActionBase>();
|
|
if (null == inventory_action)
|
|
{
|
|
err_msg = $"Fail to get Inventory Action : {nameof(InventoryActionBase)}.";
|
|
result.setFail(ServerErrorCode.EntityActionNotFound, err_msg);
|
|
Log.getLogger().error(err_msg);
|
|
|
|
return (result, CurrencyType.None, 0);
|
|
}
|
|
|
|
(result, var changed_items) = await inventory_action.tryTakalbleToBag((META_ID)item_data.ItemId, (ushort)buy_count);
|
|
if (result.isFail()) return (result, CurrencyType.None, 0);
|
|
|
|
m_buy_items ??= new();
|
|
m_buy_items.AddRange(changed_items);
|
|
|
|
var check_currency_type = ShopHelper.checkCurrencyTypeFromCurrencyId(item_data.Buy_id);
|
|
if (check_currency_type.result.isFail()) return (check_currency_type.result, CurrencyType.None, 0);
|
|
|
|
var price = await ShopHelper.checkCaliumCurrency(check_currency_type.currencyType, item_data.BuyPrice, discountRate);
|
|
|
|
return (result, check_currency_type.currencyType, buy_count * price);
|
|
}
|
|
|
|
private async Task<Result> processSpent(CurrencyType spent_currency_type, double spent_currency)
|
|
{
|
|
var result = new Result();
|
|
|
|
var money_action = getOwner().getEntityAction<MoneyAction>();
|
|
if (null == money_action)
|
|
{
|
|
var err_msg = $"Fail to get Money Action : {nameof(MoneyAction)}.";
|
|
result.setFail(ServerErrorCode.EntityActionNotFound, err_msg);
|
|
Log.getLogger().error(err_msg);
|
|
|
|
return result;
|
|
}
|
|
|
|
result = await money_action.changeMoney(spent_currency_type, -1 * spent_currency);
|
|
return result;
|
|
}
|
|
|
|
(DiscountType discount_type, int discount_rate) checkPurchaseDiscountType(int itemMetaId)
|
|
{
|
|
var discount_type = DiscountType.None;
|
|
int discount_rate = 0;
|
|
|
|
var player = getOwner().getRootParent() as Player;
|
|
NullReferenceCheckHelper.throwIfNull(player, () => "player is null !!!");
|
|
|
|
var item_first_purchase_history_agent_action = player.getEntityAction<ItemFirstPurchaseHistoryAgentAction>();
|
|
NullReferenceCheckHelper.throwIfNull(item_first_purchase_history_agent_action, () => $"ItemFirstPurchaseHistoryAgentAction is null !!! - {player.toBasicString()}");
|
|
|
|
if (!MetaData.Instance._ItemTable.TryGetValue(itemMetaId, out var item_meta_data))
|
|
return (discount_type, discount_rate);
|
|
|
|
if (item_first_purchase_history_agent_action.isItemFirstPurchase(item_meta_data.ItemId))
|
|
{
|
|
discount_type = DiscountType.ItemFirstPurchase;
|
|
discount_rate = item_meta_data.Buy_Discount_Rate;
|
|
}
|
|
|
|
return (discount_type, discount_rate);
|
|
}
|
|
|
|
(Result result, MetaAssets.ItemMetaData? item_data) checkBuyItemConditions(int itemMetaId, int buyItemCount)
|
|
{
|
|
var result = new Result();
|
|
|
|
(result, var item_data) = ShopHelper.checkItemIdFromTableData(itemMetaId);
|
|
if (result.isFail())
|
|
{
|
|
Log.getLogger().error(result.toBasicString());
|
|
return (result, null);
|
|
}
|
|
|
|
var player = getOwner().getRootParent() as Player;
|
|
NullReferenceCheckHelper.throwIfNull(player, () => "player is null !!!");
|
|
|
|
result = player.checkItemFirstPurchaseItemCount((int)itemMetaId, buyItemCount);
|
|
if (result.isFail())
|
|
{
|
|
return (result, null);
|
|
}
|
|
|
|
return (result, item_data);
|
|
}
|
|
|
|
async Task<Result> updateItemFirstPurchaseHistory(DiscountType discountType, int itemMetaId)
|
|
{
|
|
var result = new Result();
|
|
|
|
var player = getOwner().getRootParent();
|
|
|
|
if (discountType != DiscountType.ItemFirstPurchase)
|
|
return result;
|
|
|
|
var item_first_purchase_history_agent_action = player.getEntityAction<ItemFirstPurchaseHistoryAgentAction>();
|
|
NullReferenceCheckHelper.throwIfNull(item_first_purchase_history_agent_action, () => $"ItemFirstPurchaseHistoryAgentAction is null !!! - {player.toBasicString()}");
|
|
|
|
result = await item_first_purchase_history_agent_action.tryAddItemFirstPurchaseHistoryFromMetaId(itemMetaId);
|
|
if (result.isFail())
|
|
{
|
|
return result;
|
|
}
|
|
|
|
return result;
|
|
}
|
|
} |