1849 lines
88 KiB
C#
1849 lines
88 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Text;
|
|
using System.Threading.Tasks;
|
|
using System.Collections.Concurrent;
|
|
|
|
|
|
|
|
using Axion.Collections.Concurrent;
|
|
using Amazon.S3.Model;
|
|
using NeoSmart.AsyncLock;
|
|
using MySqlConnector;
|
|
|
|
|
|
using MetaAssets;
|
|
using ServerCore; using ServerBase;
|
|
using ServerCommon;
|
|
|
|
|
|
|
|
using SESSION_ID = System.Int32;
|
|
using WORLD_META_ID = System.UInt32;
|
|
using META_ID = System.UInt32;
|
|
using ENTITY_GUID = System.String;
|
|
using ACCOUNT_ID = System.String;
|
|
using OWNER_GUID = System.String;
|
|
using USER_GUID = System.String;
|
|
using CHARACTER_GUID = System.String;
|
|
using ITEM_GUID = System.String;
|
|
|
|
|
|
|
|
|
|
namespace GameServer
|
|
{
|
|
public abstract partial class InventoryActionBase : EntityActionBase
|
|
{
|
|
private readonly BagInven m_bag_inven;
|
|
|
|
private readonly ConcurrentDictionary<InvenEquipType, EntityBase> m_equip_invens = new();
|
|
|
|
private AsyncLock m_async_lock = new();
|
|
|
|
public static Int64 ENTITY_UPDATE_INTERVAL_MSEC = ConstValue.default_1_min_to_sec * ConstValue.default_1000_millisec;
|
|
|
|
private SimpleTimer m_entity_update_timer = new(ENTITY_UPDATE_INTERVAL_MSEC);
|
|
|
|
public InventoryActionBase(EntityBase owner)
|
|
: base(owner)
|
|
{
|
|
m_bag_inven = new BagInven(owner);
|
|
|
|
m_entity_update_timer.activate();
|
|
}
|
|
|
|
public void clear()
|
|
{
|
|
var owner = getOwner();
|
|
NullReferenceCheckHelper.throwIfNull(owner, () => $"owner is null !!!");
|
|
|
|
m_bag_inven.clearItemAll();
|
|
m_bag_inven.resetItemCountInTabs();
|
|
|
|
var target_inven_equip_types = EnumHelper.getValuesWithoutScopeAll<InvenEquipType>();
|
|
foreach (var inven_equip_type in target_inven_equip_types)
|
|
{
|
|
if (false == getEquipInvens().TryGetValue(inven_equip_type, out var found_equip_inven))
|
|
{
|
|
continue;
|
|
}
|
|
|
|
var inven_accessor = found_equip_inven as IWithInventoryAccessor;
|
|
if (inven_accessor == null)
|
|
{
|
|
var err_msg = $"Failed to cast IWithInventoryAccessor !!! : invenEquipType:{inven_equip_type} - {owner.toBasicString()}";
|
|
Log.getLogger().error(err_msg);
|
|
continue;
|
|
}
|
|
|
|
inven_accessor.clearItemAll();
|
|
}
|
|
}
|
|
|
|
public async Task clearItemAllFromMemory()
|
|
{
|
|
var owner = getOwner();
|
|
NullReferenceCheckHelper.throwIfNull(owner, () => $"owner is null !!!");
|
|
|
|
var err_msg = string.Empty;
|
|
|
|
(var result, var _) = await tryDeleteItemAll();
|
|
if (result.isFail())
|
|
{
|
|
err_msg = $"Failed to tryDeleteItemAll() !!! : {result.toBasicString()} - {owner.toBasicString()}";
|
|
Log.getLogger().error(err_msg);
|
|
}
|
|
|
|
m_bag_inven.resetItemCountInTabs();
|
|
}
|
|
|
|
public Item? tryGetItemByItemGuid(ITEM_GUID itemGuid)
|
|
{
|
|
var found_item = m_bag_inven.findEntityBase(itemGuid);
|
|
return found_item as Item;
|
|
}
|
|
|
|
public List<Item> tryGetItemAllByItemMetaId(META_ID itemMetaId)
|
|
{
|
|
return m_bag_inven.getItemAllByMetaId(itemMetaId);
|
|
}
|
|
|
|
public Int32 getItemCountAllByMetaId(META_ID itemMetaId)
|
|
{
|
|
return m_bag_inven.getItemCountAllByMetaId(itemMetaId);
|
|
}
|
|
|
|
public Int32 getItemStackCountAllByMetaId(META_ID itemMetaId)
|
|
{
|
|
return m_bag_inven.getItemStackCountAllByMetaId(itemMetaId);
|
|
}
|
|
|
|
public Item? tryGetEquipItemByItemGuid(ITEM_GUID itemGuid)
|
|
{
|
|
var owner = getOwner();
|
|
NullReferenceCheckHelper.throwIfNull(owner, () => $"owner is null !!!");
|
|
|
|
var equip_items = new List<Item>();
|
|
|
|
var err_msg = string.Empty;
|
|
|
|
var target_inven_equip_types = EnumHelper.getValuesWithoutScopeAll<InvenEquipType>();
|
|
foreach (var inven_equip_type in target_inven_equip_types)
|
|
{
|
|
if (false == getEquipInvens().TryGetValue(inven_equip_type, out var found_equip_inven))
|
|
{
|
|
continue;
|
|
}
|
|
|
|
var inven_accessor = found_equip_inven as IWithInventoryAccessor;
|
|
if (inven_accessor == null)
|
|
{
|
|
err_msg = $"Failed to cast IWithInventoryAccessor !!! : invenEquipType:{inven_equip_type} - {owner.toBasicString()}";
|
|
Log.getLogger().error(err_msg);
|
|
continue;
|
|
}
|
|
|
|
foreach (var item_base in inven_accessor.getHasItemBases())
|
|
{
|
|
var curr_item = item_base as Item;
|
|
NullReferenceCheckHelper.throwIfNull(curr_item, () => $"curr_item is null !!! - {owner.toBasicString()}");
|
|
var item_attribute_base = curr_item.getEntityAttributeWithReadOnly<ItemAttributeBase>();
|
|
NullReferenceCheckHelper.throwIfNull(item_attribute_base, () => $"item_attribute_base is null !!! - {owner.toBasicString()}");
|
|
|
|
if( item_attribute_base.ItemGuid == itemGuid
|
|
&& item_attribute_base.ItemStackCount > 0 )
|
|
{
|
|
return curr_item;
|
|
}
|
|
}
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
public async Task<(Result, Item?)> tryGetEquipItemByInvenEquipType<TSlotType>( InvenEquipType invenEquipType, TSlotType targetSlotType
|
|
, bool isFailOnItemNotFound = true )
|
|
where TSlotType : Enum
|
|
{
|
|
var owner = getOwner();
|
|
NullReferenceCheckHelper.throwIfNull(owner, () => $"owner is null !!!");
|
|
|
|
var result = new Result();
|
|
var err_msg = string.Empty;
|
|
|
|
if (false == getEquipInvens().TryGetValue(invenEquipType, out var found_equip_inven))
|
|
{
|
|
err_msg = $"Not found EquipInven !!! : invenEquipType:{invenEquipType} - {owner.toBasicString()}";
|
|
result.setFail(ServerErrorCode.EquipInvenNotFound, err_msg);
|
|
Log.getLogger().error(result.toBasicString());
|
|
|
|
return (result, null);
|
|
}
|
|
|
|
var equip_inven = found_equip_inven as InventoryBase<TSlotType>;
|
|
NullReferenceCheckHelper.throwIfNull(equip_inven, () => $"equip_inven is null !!! - {owner.toBasicString()}");
|
|
|
|
var has_slots_with_entity_bases = equip_inven.getHasSlotsWithEntityBases();
|
|
NullReferenceCheckHelper.throwIfNull(has_slots_with_entity_bases, () => $"has_slots_with_entity_bases is null !!! - {owner.toBasicString()}");
|
|
|
|
if(false == has_slots_with_entity_bases.TryGetValue(targetSlotType, out var found_entity_base))
|
|
{
|
|
if(true == isFailOnItemNotFound)
|
|
{
|
|
err_msg = $"Not found SlotType !!! : slotType:{targetSlotType} - {owner.toBasicString()}";
|
|
result.setFail(ServerErrorCode.SlotTypeNotFound, err_msg);
|
|
Log.getLogger().error(result.toBasicString());
|
|
}
|
|
|
|
return (result, null);
|
|
}
|
|
|
|
var found_item = found_entity_base as Item;
|
|
NullReferenceCheckHelper.throwIfNull(found_item, () => $"found_item is null !!! - {owner.toBasicString()}");
|
|
|
|
return await Task.FromResult((result, found_item));
|
|
}
|
|
|
|
public async Task<(Result, Item?)> tryUseItemByGuid(ITEM_GUID itemGuid, UInt16 toDeleteCount)
|
|
{
|
|
var owner = getOwner();
|
|
NullReferenceCheckHelper.throwIfNull(owner, () => $"owner is null !!!");
|
|
|
|
var result = new Result();
|
|
|
|
(result, var found_delete_item) = await tryDeleteItemByGuid(itemGuid, toDeleteCount);
|
|
if (result.isFail())
|
|
{
|
|
return (result, found_delete_item);
|
|
}
|
|
NullReferenceCheckHelper.throwIfNull(found_delete_item, () => $"found delete item is null !!! - {owner.toBasicString()}");
|
|
|
|
var item_use_action = found_delete_item.getEntityAction<ItemUseAction>();
|
|
NullReferenceCheckHelper.throwIfNull(item_use_action, () => $"item_use_action is null !!! - {owner.toBasicString()}");
|
|
|
|
result = await item_use_action.onUseItem();
|
|
if (result.isFail())
|
|
{
|
|
return (result, found_delete_item);
|
|
}
|
|
|
|
return (result, found_delete_item);
|
|
}
|
|
|
|
//=========================================================================================
|
|
// 아이템을 가방에만 지급 하기
|
|
// 아이템 StackMaxCount가 1보다 크면 meta로 새로 만들면서 스텍을 쌓아준다.
|
|
//=========================================================================================
|
|
public async Task<(Result, List<Item>?)> tryTakableToBagWithNewItem(ItemDoc doc)
|
|
{
|
|
var owner = getOwner();
|
|
NullReferenceCheckHelper.throwIfNull(owner, () => $"owner is null !!!");
|
|
ArgumentNullReferenceCheckHelper.throwIfNull(doc, () => $"doc is null !!! - {owner.toBasicString()}");
|
|
|
|
var result = new Result();
|
|
var err_msg = string.Empty;
|
|
|
|
var doc_item_attrib = doc.getAttrib<ItemAttrib>();
|
|
NullReferenceCheckHelper.throwIfNull(doc_item_attrib, () => $"doc_item_attrib is null !!! - {owner.toBasicString()}");
|
|
|
|
if (MetaData.Instance._ItemTable.TryGetValue((int)doc_item_attrib.ItemMetaId, out var item_meta_data) == false)
|
|
{
|
|
err_msg = $"Not found meta of Item !!! : ItemMetaId:{doc_item_attrib.ItemMetaId} - {owner.toBasicString()}";
|
|
result.setFail(ServerErrorCode.ItemMetaDataNotFound, err_msg);
|
|
Log.getLogger().error(err_msg);
|
|
return (result, null);
|
|
}
|
|
|
|
if(item_meta_data.StackMaxCount > 1)
|
|
{
|
|
return await tryTakalbleToBag(doc_item_attrib.ItemMetaId, doc_item_attrib.ItemStackCount);
|
|
}
|
|
|
|
(result, var item) = await tryTakableToBag(doc);
|
|
if (result.isFail() || item == null)
|
|
{
|
|
return (result, null);
|
|
}
|
|
|
|
return (result, new List<Item>() { item });
|
|
}
|
|
|
|
//=========================================================================================
|
|
// 아이템을 가방에만 지급 하기 (from Memory)
|
|
//=========================================================================================
|
|
public async Task<(Result, Item?)> tryTakableToBag(ItemDoc doc)
|
|
{
|
|
var owner = getOwner();
|
|
NullReferenceCheckHelper.throwIfNull(owner, () => $"owner is null !!!");
|
|
ArgumentNullReferenceCheckHelper.throwIfNull(doc, () => $"doc is null !!! - {owner.toBasicString()}");
|
|
|
|
var result = new Result();
|
|
var err_msg = string.Empty;
|
|
|
|
var doc_item_attrib = doc.getAttrib<ItemAttrib>();
|
|
NullReferenceCheckHelper.throwIfNull(doc_item_attrib, () => $"doc_item_attrib is null !!! - {owner.toBasicString()}");
|
|
|
|
// InvenEquipType 비장작 상태인 경우만 허용 한다. !!! - kangms
|
|
if (InvenEquipType.None != doc_item_attrib.EquipedInvenType)
|
|
{
|
|
err_msg = $"Not found InventoryRule !!! : ItemMetaId:{doc_item_attrib.ItemMetaId}, itemGuid:{doc_item_attrib.OwnerGuid} - {owner.toBasicString()}";
|
|
result.setFail(ServerErrorCode.InvenEquipTypeInvalid, err_msg);
|
|
Log.getLogger().error(result.toBasicString());
|
|
return (result, null);
|
|
}
|
|
|
|
(result, var took_in_item) = await m_bag_inven.tryTakableInItemBase(doc, true);
|
|
if (result.isFail())
|
|
{
|
|
return (result, null);
|
|
}
|
|
NullReferenceCheckHelper.throwIfNull(took_in_item, () => $"took_in_item is null !!! - {owner.toBasicString()}");
|
|
|
|
return (result, took_in_item);
|
|
}
|
|
|
|
//=========================================================================================
|
|
// 아이템을 가방에 지급하고 장착 하기 (from Memory)
|
|
//=========================================================================================
|
|
public async Task<(Result, Item?)> tryTakableToBagWithEquip(ItemDoc doc, Int16 toEquipSlotPos)
|
|
{
|
|
var owner = getOwner();
|
|
NullReferenceCheckHelper.throwIfNull(owner, () => $"owner is null !!!");
|
|
ArgumentNullReferenceCheckHelper.throwIfNull(doc, () => $"doc is null !!! - {owner.toBasicString()}");
|
|
|
|
var result = new Result();
|
|
var err_msg = string.Empty;
|
|
|
|
var doc_item_attrib = doc.getAttrib<ItemAttrib>();
|
|
NullReferenceCheckHelper.throwIfNull(doc_item_attrib, () => $"doc_item_attrib is null !!! - {owner.toBasicString()}");
|
|
|
|
(result, var took_in_item) = await m_bag_inven.tryTakableInItemBase(doc, true);
|
|
if (result.isFail())
|
|
{
|
|
return (result, null);
|
|
}
|
|
NullReferenceCheckHelper.throwIfNull(took_in_item, () => $"took_in_item is null !!! - {owner.toBasicString()}");
|
|
|
|
result = await tryTakableToEquip(took_in_item, toEquipSlotPos);
|
|
if (result.isFail())
|
|
{
|
|
return (result, null);
|
|
}
|
|
|
|
return (result, took_in_item);
|
|
}
|
|
|
|
//=========================================================================================
|
|
// 아이템을 가방에 지급하고 장착 하기 (from DB)
|
|
//=========================================================================================
|
|
public async Task<(Result, Item?)> tryTakableToBagWithEquip(ItemDoc doc, Dictionary<InvenEquipType, HashSet<Int16>> reservedSlotTypes)
|
|
{
|
|
var owner = getOwner();
|
|
NullReferenceCheckHelper.throwIfNull(owner, () => $"owner is null !!!");
|
|
ArgumentNullReferenceCheckHelper.throwIfNull(doc, () => $"doc is null !!! - {owner.toBasicString()}");
|
|
|
|
var server_logic = GameServerApp.getServerLogic();
|
|
var dynamo_db_client = server_logic.getDynamoDbClient();
|
|
|
|
var result = new Result();
|
|
var err_msg = string.Empty;
|
|
|
|
(result, var took_in_item) = await m_bag_inven.tryTakableInItemBase(doc);
|
|
if (result.isFail())
|
|
{
|
|
return (result, null);
|
|
}
|
|
NullReferenceCheckHelper.throwIfNull(took_in_item, () => $"took_in_item is null !!! - {owner.toBasicString()}");
|
|
var item_meta = took_in_item.getItemMeta();
|
|
NullReferenceCheckHelper.throwIfNull(item_meta, () => $"item_meta is null !!! - {owner.toBasicString()}");
|
|
|
|
var item_attribute = took_in_item.getEntityAttribute<ItemAttributeBase>();
|
|
NullReferenceCheckHelper.throwIfNull(item_attribute, () => $"item_attribute is null !!! - {owner.toBasicString()}");
|
|
|
|
// InvenEquipType 장착 상태인 경우만 장착 시켜준다 !!! - kangms
|
|
if (InvenEquipType.None != item_attribute.EquipedInvenType)
|
|
{
|
|
var equiped_pos = item_attribute.EquipedPos;
|
|
result = await tryTakableToEquip(took_in_item, (Int16)equiped_pos);
|
|
if (result.isFail())
|
|
{
|
|
return (result, took_in_item);
|
|
}
|
|
|
|
if(false == reservedSlotTypes.TryGetValue(item_attribute.EquipedInvenType, out var reserved_slots))
|
|
{
|
|
reserved_slots = new HashSet<Int16>();
|
|
reservedSlotTypes.Add(item_attribute.EquipedInvenType, reserved_slots);
|
|
}
|
|
reserved_slots.Add((Int16)equiped_pos);
|
|
}
|
|
|
|
return (result, took_in_item);
|
|
}
|
|
|
|
//=========================================================================================
|
|
// 아이템을 가방에 지급 하기 (from Meta)
|
|
//=========================================================================================
|
|
public async Task<(Result, List<Item>)> tryTakalbleToBag(META_ID itemMetaId, UInt16 toAddCount = 1)
|
|
{
|
|
var owner = getOwner();
|
|
NullReferenceCheckHelper.throwIfNull(owner, () => $"owner is null !!!");
|
|
|
|
var result = new Result();
|
|
var err_msg = string.Empty;
|
|
|
|
(result, var reserved_items) = await m_bag_inven.tryTakableInItemBase(itemMetaId, toAddCount);
|
|
if (result.isFail())
|
|
{
|
|
return (result, reserved_items);
|
|
}
|
|
NullReferenceCheckHelper.throwIfNull(reserved_items, () => $"reserved_items is null !!! - {owner.toBasicString()}");
|
|
|
|
return (result, reserved_items);
|
|
}
|
|
|
|
//=========================================================================================
|
|
// 아이템을 가방에 지급하고 장착 하기 (from Meta)
|
|
//=========================================================================================
|
|
public async Task<(Result, List<Item>)> tryTakableToBagWithEquip(META_ID itemMetaId, UInt16 toAddCount = 1, Int16 slotPos = -1)
|
|
{
|
|
var owner = getOwner();
|
|
NullReferenceCheckHelper.throwIfNull(owner, () => $"owner is null !!!");
|
|
|
|
var result = new Result();
|
|
var err_msg = string.Empty;
|
|
|
|
(result, var reserved_items) = await m_bag_inven.tryTakableInItemBase(itemMetaId, toAddCount);
|
|
if (result.isFail() || 0 >= reserved_items.Count)
|
|
{
|
|
return (result, reserved_items);
|
|
}
|
|
NullReferenceCheckHelper.throwIfNull(reserved_items, () => $"reserved_items is null !!! - {owner.toBasicString()}");
|
|
|
|
foreach (var item in reserved_items)
|
|
{
|
|
result = await tryTakableToEquip(item, slotPos);
|
|
if (result.isFail())
|
|
{
|
|
return (result, reserved_items);
|
|
}
|
|
}
|
|
|
|
return (result, reserved_items);
|
|
}
|
|
|
|
//=========================================================================================
|
|
// 아이템을 장착 하기
|
|
//=========================================================================================
|
|
public async Task<Result> tryTakableToEquip(Item item, Int16 slotPos = -1)
|
|
{
|
|
var owner = getOwner();
|
|
NullReferenceCheckHelper.throwIfNull(owner, () => $"owner is null !!!");
|
|
ArgumentNullReferenceCheckHelper.throwIfNull(item, () => $"item is null !!! - {owner.toBasicString()}");
|
|
|
|
var result = new Result();
|
|
var err_msg = string.Empty;
|
|
|
|
var item_doc_attrib = item.getEntityAttribute<ItemAttributeBase>();
|
|
NullReferenceCheckHelper.throwIfNull(item_doc_attrib, () => $"item_doc_attrib is null !!! - {owner.toBasicString()}");
|
|
|
|
var inven_rule = GameServerApp.getServerLogic().findRule<InventoryRule>();
|
|
if (null == inven_rule)
|
|
{
|
|
err_msg = $"Not found InventoryRule !!! : ItemMetaId:{item_doc_attrib.ItemMetaId} - {owner.toBasicString()}";
|
|
result.setFail(ServerErrorCode.InventoryRuleNotFound, err_msg);
|
|
Log.getLogger().error(result.toBasicString());
|
|
|
|
return result;
|
|
}
|
|
|
|
var item_meta = item.getItemMeta();
|
|
NullReferenceCheckHelper.throwIfNull(item_meta, () => $"item_meta is null !!! - {owner.toBasicString()}");
|
|
|
|
var equip_rule_bases = inven_rule.getEquipRuleBasesByItemLargeType(item_meta.TypeLarge);
|
|
if (null == equip_rule_bases)
|
|
{
|
|
err_msg = $"Not found EquipRuleBase !!! : ItemMetaId:{item_doc_attrib.ItemMetaId} - {owner.toBasicString()}";
|
|
Log.getLogger().warn(err_msg);
|
|
}
|
|
else
|
|
{
|
|
foreach (var equip_rule in equip_rule_bases)
|
|
{
|
|
(result, var equip_slot_type) = await tryTakableToEquipByRule(equip_rule, item, slotPos);
|
|
if (result.isFail())
|
|
{
|
|
err_msg = $"Failed to tryTakableToEquipByRule() !!! : {result.toBasicString()}, invenEquipType:{equip_rule.InvenEquipType}, equipSlot:{equip_slot_type} - {owner.toBasicString()}";
|
|
Log.getLogger().warn(err_msg);
|
|
continue;
|
|
}
|
|
|
|
return result;
|
|
}
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
//=========================================================================================
|
|
// 아이템 장착 정책을 참조하여 아이템 장착 하기
|
|
//=========================================================================================
|
|
private async Task<(Result, Int16)> tryTakableToEquipByRule(EquipRuleBase equipRuleBase, Item toEquipItem, Int16 slotPos)
|
|
{
|
|
var owner = getOwner();
|
|
NullReferenceCheckHelper.throwIfNull(owner, () => $"owner is null !!!");
|
|
ArgumentNullReferenceCheckHelper.throwIfNull(equipRuleBase, () => $"equipRuleBase is null !!! - {owner.toBasicString()}");
|
|
ArgumentNullReferenceCheckHelper.throwIfNull(toEquipItem, () => $"toEquipItem is null !!! - {owner.toBasicString()}");
|
|
|
|
await Task.CompletedTask;
|
|
|
|
var result = new Result();
|
|
var err_msg = string.Empty;
|
|
|
|
if (false == m_equip_invens.TryGetValue(equipRuleBase.InvenEquipType, out var found_equip_inven))
|
|
{
|
|
err_msg = $"Not found EquipInven !!! : invenEquipType:{equipRuleBase.InvenEquipType}, {toEquipItem.toBasicString()} - {owner.toBasicString()}";
|
|
result.setFail(ServerErrorCode.EquipInvenNotFound, err_msg);
|
|
Log.getLogger().error(result.toBasicString());
|
|
|
|
return (result, -1);
|
|
}
|
|
NullReferenceCheckHelper.throwIfNull(found_equip_inven, () => $"found_equip_inven is null !!! - {owner.toBasicString()}");
|
|
|
|
var item_attribute = toEquipItem.getEntityAttribute<ItemAttributeBase>();
|
|
NullReferenceCheckHelper.throwIfNull(item_attribute, () => $"item_attribute is null !!! - {owner.toBasicString()}");
|
|
|
|
var to_equip_pos = -1;
|
|
|
|
var item_meta = toEquipItem.getItemMeta();
|
|
NullReferenceCheckHelper.throwIfNull(item_meta, () => $"item_meta is null !!! - {owner.toBasicString()}");
|
|
|
|
var item_small_type = item_meta.TypeSmall;
|
|
switch (equipRuleBase.InvenEquipType)
|
|
{
|
|
case InvenEquipType.Tool:
|
|
{
|
|
var tool_equip_rule = equipRuleBase as ToolEquipRule;
|
|
NullReferenceCheckHelper.throwIfNull(tool_equip_rule, () => $"tool_equip_rule is null !!! - {owner.toBasicString()}");
|
|
|
|
var found_tool_slot_type = tool_equip_rule.UsableToolSlotTypes.FirstOrDefault(x => x == (ToolSlotType)slotPos, ToolSlotType.None);
|
|
if (ToolSlotType.None == found_tool_slot_type)
|
|
{
|
|
err_msg = $"Not found ToolSlotType !!! : ToolSlotType:{(ToolSlotType)slotPos}, itemSmallType:{item_small_type}, {toEquipItem.toBasicString()} - {owner.toBasicString()}";
|
|
result.setFail(ServerErrorCode.ToolEquipRuleToolSlotTypeNotFound, err_msg);
|
|
Log.getLogger().error(result.toBasicString());
|
|
|
|
return (result, -1);
|
|
}
|
|
|
|
var equip_inven = found_equip_inven as ToolEquipInven;
|
|
NullReferenceCheckHelper.throwIfNull(equip_inven, () => $"equip_inven is null !!! - {owner.toBasicString()}");
|
|
|
|
result = equip_inven.tryIsEquipableOrEquipWithEntityBase(found_tool_slot_type, toEquipItem);
|
|
if (result.isFail())
|
|
{
|
|
return (result, (Int16)found_tool_slot_type);
|
|
}
|
|
to_equip_pos = (Int16)found_tool_slot_type;
|
|
} break;
|
|
|
|
case InvenEquipType.Cloth:
|
|
{
|
|
var cloth_equip_rule = equipRuleBase as ClothEquipRule;
|
|
NullReferenceCheckHelper.throwIfNull(cloth_equip_rule, () => $"cloth_equip_rule is null !!! - {owner.toBasicString()}");
|
|
|
|
if (false == cloth_equip_rule.m_slots_by_item_type.TryGetValue(item_small_type, out var found_cloth_slot_types))
|
|
{
|
|
err_msg = $"Not found ClothSlotType !!! : itemSmallType:{item_small_type}, {toEquipItem.toBasicString()} - {owner.toBasicString()}";
|
|
result.setFail(ServerErrorCode.ClothEquipRuleClothSlotTypeNotFound, err_msg);
|
|
Log.getLogger().error(result.toBasicString());
|
|
|
|
return (result, -1);
|
|
}
|
|
NullReferenceCheckHelper.throwIfNull(found_cloth_slot_types, () => $"found_cloth_slot_types is null !!! - {owner.toBasicString()}");
|
|
|
|
var equip_inven = found_equip_inven as ClothEquipInven;
|
|
NullReferenceCheckHelper.throwIfNull(equip_inven, () => $"equip_inven is null !!! - {owner.toBasicString()}");
|
|
|
|
foreach (var cloth_slot_type in found_cloth_slot_types)
|
|
{
|
|
result = equip_inven.tryIsEquipableOrEquipWithEntityBase(cloth_slot_type, toEquipItem);
|
|
if (result.isFail())
|
|
{
|
|
return (result, (Int16)cloth_slot_type);
|
|
}
|
|
to_equip_pos = (Int16)cloth_slot_type;
|
|
break;
|
|
}
|
|
} break;
|
|
|
|
case InvenEquipType.Tattoo:
|
|
{
|
|
var tattoo_equip_rule = equipRuleBase as TattooEquipRule;
|
|
NullReferenceCheckHelper.throwIfNull(tattoo_equip_rule, () => $"tattoo_equip_rule is null !!! - {owner.toBasicString()}");
|
|
|
|
var found_tattoo_slot_type = tattoo_equip_rule.getUsableTattooSlotPos(owner.getEntityType()).FirstOrDefault(x => x == (TattooSlotType)slotPos, TattooSlotType.None);
|
|
if (TattooSlotType.None == found_tattoo_slot_type)
|
|
{
|
|
err_msg = $"Not found TattooSlotType !!! : TattooSlotType:{(TattooSlotType)slotPos}, itemSmallType:{item_small_type}, {toEquipItem.toBasicString()} - {owner.toBasicString()}";
|
|
result.setFail(ServerErrorCode.TattooEquipRuleTattooSlotTypeNotFound, err_msg);
|
|
Log.getLogger().error(result.toBasicString());
|
|
|
|
return (result, -1);
|
|
}
|
|
|
|
var equip_inven = found_equip_inven as TattooEquipInven;
|
|
NullReferenceCheckHelper.throwIfNull(equip_inven, () => $"equip_inven is null !!! - {owner.toBasicString()}");
|
|
|
|
result = equip_inven.tryIsEquipableOrEquipWithEntityBase(found_tattoo_slot_type, toEquipItem);
|
|
if (result.isFail())
|
|
{
|
|
return (result, (Int16)found_tattoo_slot_type);
|
|
}
|
|
to_equip_pos = (Int16)found_tattoo_slot_type;
|
|
|
|
// tattoo 의 ability 를 user 의 ability 에 추가
|
|
var ability_action = owner.getEntityAction<AbilityAction>();
|
|
NullReferenceCheckHelper.throwIfNull(ability_action, () => $"ability_action is null !!! - {owner.toBasicString()}");
|
|
|
|
result = await ability_action.setAbilities(toEquipItem, (Int16)item_attribute.Level, false);
|
|
if (result.isFail())
|
|
{
|
|
return (result, (Int16)found_tattoo_slot_type);
|
|
}
|
|
} break;
|
|
}
|
|
|
|
item_attribute.EquipedInvenType = equipRuleBase.InvenEquipType;
|
|
item_attribute.EquipedPos = (UInt16)to_equip_pos;
|
|
item_attribute.modifiedEntityAttribute();
|
|
|
|
return (result, (Int16)to_equip_pos);
|
|
}
|
|
|
|
//=========================================================================================
|
|
// 아이템 삭제 하기 (from META + Count)
|
|
// toDeleteCount == 0 일 경우 보유중인 itemMetaId 의 모두 찾아 삭제 한다.
|
|
//=========================================================================================
|
|
public async Task<(Result, List<Item>)> tryDeleteItemByMetaId(META_ID itemMetaId, UInt32 toDeleteCount = UInt32.MaxValue)
|
|
{
|
|
var owner = getOwner();
|
|
NullReferenceCheckHelper.throwIfNull(owner, () => $"owner is null !!!");
|
|
|
|
// 1. 가방에서 아이템들을 제거 한다.
|
|
var (result, reserved_items) = await m_bag_inven.tryTakableOutItemBase(itemMetaId, toDeleteCount);
|
|
if (result.isFail())
|
|
{
|
|
return (result, reserved_items);
|
|
}
|
|
NullReferenceCheckHelper.throwIfNull(reserved_items, () => $"reserved_items is null !!! - {owner.toBasicString()}");
|
|
|
|
foreach (var reserved_item in reserved_items)
|
|
{
|
|
var item_attribute = reserved_item.getEntityAttribute<ItemAttributeBase>();
|
|
NullReferenceCheckHelper.throwIfNull(item_attribute, () => $"item_attribute is null !!! - {owner.toBasicString()}");
|
|
|
|
// 2. 장착 인벤으로 설정되어 있는 경우, 장착을 해제 한다.
|
|
if (InvenEquipType.None != item_attribute.EquipedInvenType)
|
|
{
|
|
(result, var unequiped_item) = await tryTakableOutFromEquip(reserved_item);
|
|
if (result.isFail())
|
|
{
|
|
return (result, reserved_items);
|
|
}
|
|
NullReferenceCheckHelper.throwIfNull(unequiped_item, () => $"unequiped_item is null !!! - {owner.toBasicString()}");
|
|
}
|
|
}
|
|
|
|
return (result, reserved_items);
|
|
}
|
|
|
|
//=========================================================================================
|
|
// 아이템 삭제 하기 (from ITEM_GUID + Count)
|
|
//=========================================================================================
|
|
public async Task<(Result, Item?)> tryDeleteItemByGuid(ITEM_GUID itemGuid, UInt16 toDeleteCount = 1)
|
|
{
|
|
var owner = getOwner();
|
|
NullReferenceCheckHelper.throwIfNull(owner, () => $"owner is null !!!");
|
|
|
|
// 1. 가방에서 아이템을 제거 한다.
|
|
var (result, reserved_item) = await m_bag_inven.tryTakableOutItemBase(itemGuid, toDeleteCount);
|
|
if (result.isFail())
|
|
{
|
|
return (result, null);
|
|
}
|
|
NullReferenceCheckHelper.throwIfNull(reserved_item, () => $"reserved_item is null !!! - {owner.toBasicString()}");
|
|
|
|
var item_attribute = reserved_item.getEntityAttribute<ItemAttributeBase>();
|
|
NullReferenceCheckHelper.throwIfNull(item_attribute, () => $"item_attribute is null !!! - {owner.toBasicString()}");
|
|
|
|
// 2. 장착 인벤으로 설정되어 있는 경우, 장착을 해제 한다.
|
|
if (InvenEquipType.None != item_attribute.EquipedInvenType)
|
|
{
|
|
(result, var unequiped_item) = await tryTakableOutFromEquip(reserved_item);
|
|
if (result.isFail())
|
|
{
|
|
return (result, null);
|
|
}
|
|
NullReferenceCheckHelper.throwIfNull(unequiped_item, () => $"unequiped_item is null !!! - {owner.toBasicString()}");
|
|
}
|
|
|
|
return (result, reserved_item);
|
|
}
|
|
|
|
public async Task<(Result, Item?)> tryTakableOutFromEquip(Item item)
|
|
{
|
|
var owner = getOwner();
|
|
NullReferenceCheckHelper.throwIfNull(owner, () => $"owner is null !!!");
|
|
|
|
var result = new Result();
|
|
var err_msg = string.Empty;
|
|
|
|
var item_attribute = item.getEntityAttribute<ItemAttributeBase>();
|
|
NullReferenceCheckHelper.throwIfNull(item_attribute, () => $"item_attribute is null !!! - {owner.toBasicString()}");
|
|
|
|
var inven_rule = GameServerApp.getServerLogic().findRule<InventoryRule>();
|
|
if (null == inven_rule)
|
|
{
|
|
err_msg = $"Not found InventoryRule !!! : ItemMetaId:{item_attribute.ItemMetaId} - {owner.toBasicString()}";
|
|
result.setFail(ServerErrorCode.InventoryRuleNotFound, err_msg);
|
|
Log.getLogger().error(result.toBasicString());
|
|
|
|
return (result, null);
|
|
}
|
|
|
|
var item_meta = item.getItemMeta();
|
|
NullReferenceCheckHelper.throwIfNull(item_meta, () => $"item_meta is null !!! - {owner.toBasicString()}");
|
|
|
|
var equip_rule_bases = inven_rule.getEquipRuleBasesByItemLargeType(item_meta.TypeLarge);
|
|
if (null == equip_rule_bases)
|
|
{
|
|
err_msg = $"Not found EquipRuleBase !!! : ItemTypeLarge:{item_meta.TypeLarge}, ItemMetaId:{item_attribute.ItemMetaId} - {owner.toBasicString()}";
|
|
Log.getLogger().warn(err_msg);
|
|
}
|
|
else
|
|
{
|
|
foreach (var equip_rule in equip_rule_bases)
|
|
{
|
|
(var unequip_result, var unequip_slot_type) = await tryTakableOutFromEquipByRule(equip_rule, item);
|
|
if (unequip_result.isFail())
|
|
{
|
|
err_msg = $"Failed to tryTakableOutFromEquipByRule() !!! : {unequip_result.toBasicString()}, invenEquipType:{equip_rule.InvenEquipType}, unequipSlot:{unequip_slot_type} - {owner.toBasicString()}";
|
|
Log.getLogger().warn(err_msg);
|
|
|
|
continue;
|
|
}
|
|
|
|
return (result, item);
|
|
}
|
|
}
|
|
|
|
return (result, item);
|
|
}
|
|
|
|
private async Task<(Result, Int16)> tryTakableOutFromEquipByRule(EquipRuleBase equipRuleBase, Item toUnequipItem)
|
|
{
|
|
var owner = getOwner();
|
|
NullReferenceCheckHelper.throwIfNull(owner, () => $"owner is null !!!");
|
|
ArgumentNullReferenceCheckHelper.throwIfNull(equipRuleBase, () => $"equipRuleBase is null !!! - {owner.toBasicString()}");
|
|
ArgumentNullReferenceCheckHelper.throwIfNull(toUnequipItem, () => $"toUnequipItem is null !!! - {owner.toBasicString()}");
|
|
|
|
await Task.CompletedTask;
|
|
|
|
var result = new Result();
|
|
var err_msg = string.Empty;
|
|
|
|
var to_unequip_pos = 0;
|
|
|
|
if (false == m_equip_invens.TryGetValue(equipRuleBase.InvenEquipType, out var found_equip_inven))
|
|
{
|
|
err_msg = $"Not found EquipInven !!! : invenEquipType:{equipRuleBase.InvenEquipType}, {toUnequipItem.toBasicString()} - {owner.toBasicString()}";
|
|
result.setFail(ServerErrorCode.EquipInvenNotFound, err_msg);
|
|
Log.getLogger().error(result.toBasicString());
|
|
|
|
return (result, -1);
|
|
}
|
|
NullReferenceCheckHelper.throwIfNull(found_equip_inven, () => $"found_equip_inven is null !!! - {owner.toBasicString()}");
|
|
|
|
var item_attribute = toUnequipItem.getEntityAttribute<ItemAttributeBase>();
|
|
NullReferenceCheckHelper.throwIfNull(item_attribute, () => $"item_attribute is null !!! - {owner.toBasicString()}");
|
|
|
|
var slot_pos = item_attribute.EquipedPos;
|
|
|
|
var item_meta = toUnequipItem.getItemMeta();
|
|
NullReferenceCheckHelper.throwIfNull(item_meta, () => $"item_meta is null !!! - {owner.toBasicString()}");
|
|
|
|
var item_small_type = item_meta.TypeSmall;
|
|
switch (equipRuleBase.InvenEquipType)
|
|
{
|
|
case InvenEquipType.Tool:
|
|
{
|
|
var tool_equip_rule = equipRuleBase as ToolEquipRule;
|
|
NullReferenceCheckHelper.throwIfNull(tool_equip_rule, () => $"tool_equip_rule is null !!! - {owner.toBasicString()}");
|
|
|
|
var found_tool_slot_type = tool_equip_rule.UsableToolSlotTypes.FirstOrDefault(x => x == (ToolSlotType)slot_pos, ToolSlotType.None);
|
|
if (ToolSlotType.None == found_tool_slot_type)
|
|
{
|
|
err_msg = $"Not found ToolSlotType !!! : ToolSlotType:{(ToolSlotType)slot_pos}, itemSmallType:{item_small_type}, {toUnequipItem.toBasicString()} - {owner.toBasicString()}";
|
|
result.setFail(ServerErrorCode.ToolEquipRuleToolSlotTypeNotFound, err_msg);
|
|
Log.getLogger().error(result.toBasicString());
|
|
|
|
return (result, -1);
|
|
}
|
|
|
|
var tool_equip_inven = found_equip_inven as ToolEquipInven;
|
|
NullReferenceCheckHelper.throwIfNull(tool_equip_inven, () => $"tool_equip_inven is null !!! - {owner.toBasicString()}");
|
|
|
|
result = tool_equip_inven.tryUnequipableOrUnequipWithEntityBase(found_tool_slot_type, out _);
|
|
if (result.isFail())
|
|
{
|
|
return (result, (Int16)found_tool_slot_type);
|
|
}
|
|
to_unequip_pos = (Int16)found_tool_slot_type;
|
|
|
|
var root_parent = owner.getRootParent();
|
|
NullReferenceCheckHelper.throwIfNull(root_parent, () => $"root_parent is null !!! - {owner.toBasicString()}");
|
|
|
|
var item_tool_action = root_parent.getEntityAction<ItemToolAction>();
|
|
if(null != item_tool_action)
|
|
{
|
|
var tool_result = await item_tool_action.tryUnactivateItemTool();
|
|
if (tool_result.isFail())
|
|
{
|
|
err_msg = $"Failed to tryUnactivateItemTool() : {tool_result.toBasicString()} - {owner.toBasicString()}";
|
|
Log.getLogger().error(err_msg);
|
|
}
|
|
}
|
|
} break;
|
|
|
|
case InvenEquipType.Cloth:
|
|
{
|
|
var cloth_equip_rule = equipRuleBase as ClothEquipRule;
|
|
NullReferenceCheckHelper.throwIfNull(cloth_equip_rule, () => $"cloth_equip_rule is null !!! - {owner.toBasicString()}");
|
|
|
|
if (false == cloth_equip_rule.m_slots_by_item_type.TryGetValue(item_small_type, out var found_cloth_slot_types))
|
|
{
|
|
err_msg = $"Not found ClothSlotType !!! : itemSmallType:{item_small_type}, {toUnequipItem.toBasicString()} - {owner.toBasicString()}";
|
|
result.setFail(ServerErrorCode.ClothEquipRuleClothSlotTypeNotFound, err_msg);
|
|
Log.getLogger().error(result.toBasicString());
|
|
|
|
return (result, -1);
|
|
}
|
|
|
|
var cloth_equip_inven = found_equip_inven as ClothEquipInven;
|
|
NullReferenceCheckHelper.throwIfNull(cloth_equip_inven, () => $"cloth_equip_inven is null !!! - {owner.toBasicString()}");
|
|
|
|
foreach (var cloth_slot_type in found_cloth_slot_types)
|
|
{
|
|
result = cloth_equip_inven.tryUnequipableOrUnequipWithEntityBase(cloth_slot_type, out _);
|
|
if (result.isFail())
|
|
{
|
|
return (result, (Int16)cloth_slot_type);
|
|
}
|
|
to_unequip_pos = (Int16)cloth_slot_type;
|
|
break;
|
|
}
|
|
} break;
|
|
|
|
case InvenEquipType.Tattoo:
|
|
{
|
|
var tattoo_equip_rule = equipRuleBase as TattooEquipRule;
|
|
NullReferenceCheckHelper.throwIfNull(tattoo_equip_rule, () => $"tattoo_equip_rule is null !!! - {owner.toBasicString()}");
|
|
|
|
var found_tattoo_slot_type = tattoo_equip_rule.getUsableTattooSlotPos(owner.getEntityType()).FirstOrDefault(x => x == (TattooSlotType)slot_pos, TattooSlotType.None);
|
|
if (TattooSlotType.None == found_tattoo_slot_type)
|
|
{
|
|
err_msg = $"Not found TattooSlotType !!! : TattooSlotType:{(TattooSlotType)slot_pos}, itemSmallType:{item_small_type}, {toUnequipItem.toBasicString()} - {owner.toBasicString()}";
|
|
result.setFail(ServerErrorCode.TattooEquipRuleTattooSlotTypeNotFound, err_msg);
|
|
Log.getLogger().error(result.toBasicString());
|
|
|
|
return (result, -1);
|
|
}
|
|
|
|
var tattoo_equip_inven = found_equip_inven as TattooEquipInven;
|
|
NullReferenceCheckHelper.throwIfNull(tattoo_equip_inven, () => $"tattoo_equip_inven is null !!! - {owner.toBasicString()}");
|
|
|
|
result = tattoo_equip_inven.tryUnequipableOrUnequipWithEntityBase(found_tattoo_slot_type, out _);
|
|
if (result.isFail())
|
|
{
|
|
return (result, (Int16)found_tattoo_slot_type);
|
|
}
|
|
to_unequip_pos = (Int16)found_tattoo_slot_type;
|
|
|
|
// tattoo 의 ability 를 user 의 ability 에 추가
|
|
var ability_action = getOwner().getEntityAction<AbilityAction>();
|
|
NullReferenceCheckHelper.throwIfNull(ability_action, () => $"ability_action is null !!! - {owner.toBasicString()}");
|
|
|
|
result = await ability_action.setAbilities(toUnequipItem, (Int16)item_attribute.Level, true);
|
|
if (result.isFail())
|
|
{
|
|
return (result, (Int16)found_tattoo_slot_type);
|
|
}
|
|
} break;
|
|
}
|
|
|
|
item_attribute.EquipedInvenType = InvenEquipType.None;
|
|
item_attribute.EquipedPos = 0;
|
|
item_attribute.modifiedEntityAttribute();
|
|
|
|
return (result, (Int16)to_unequip_pos);
|
|
}
|
|
|
|
public async Task<(Result, List<Item>?)> tryDeleteItemAll()
|
|
{
|
|
var owner = getOwner();
|
|
NullReferenceCheckHelper.throwIfNull(owner, () => $"owner is null !!!");
|
|
|
|
var bag_inven = getBagInven();
|
|
NullReferenceCheckHelper.throwIfNull(bag_inven, () => $"bag_inven is null !!! - {owner.toBasicString()}");
|
|
var bag_slot_data = bag_inven.getData();
|
|
NullReferenceCheckHelper.throwIfNull(bag_slot_data, () => $"bag_slot_data is null !!! - {owner.toBasicString()}");
|
|
|
|
var result = new Result();
|
|
var to_delete_items = new List<Item>();
|
|
|
|
var bag_items = bag_slot_data.getEntityBases();
|
|
NullReferenceCheckHelper.throwIfNull(bag_items, () => $"bag_items is null !!! - {owner.toBasicString()}");
|
|
|
|
foreach (var bag_item in bag_items)
|
|
{
|
|
var has_item = bag_item as Item;
|
|
NullReferenceCheckHelper.throwIfNull(has_item, () => $"has_item is null !!! - {owner.toBasicString()}");
|
|
|
|
var item_attribute = has_item.getEntityAttribute<ItemAttributeBase>();
|
|
NullReferenceCheckHelper.throwIfNull(item_attribute, () => $"item_attribute is null !!! - {owner.toBasicString()}");
|
|
|
|
var to_delete_item_guid = item_attribute.ItemGuid;
|
|
var to_delete_item_count = item_attribute.ItemStackCount;
|
|
|
|
(result, var item) = await tryDeleteItemByGuid(to_delete_item_guid, to_delete_item_count);
|
|
if (result.isFail())
|
|
{
|
|
return (result, null);
|
|
}
|
|
|
|
to_delete_items.Add(has_item);
|
|
}
|
|
|
|
var equiped_items = getEquipItemAll();
|
|
NullReferenceCheckHelper.throwIfNull(equiped_items, () => $"equiped_items is null !!! - {owner.toBasicString()}");
|
|
|
|
foreach (var equiped_item in equiped_items)
|
|
{
|
|
var item_attribute = equiped_item.getEntityAttribute<ItemAttributeBase>();
|
|
NullReferenceCheckHelper.throwIfNull(item_attribute, () => $"item_attribute is null !!! - {owner.toBasicString()}");
|
|
|
|
var to_delete_item_guid = item_attribute.ItemGuid;
|
|
var to_delete_item_count = item_attribute.ItemStackCount;
|
|
|
|
(result, var item) = await tryDeleteItemByGuid(to_delete_item_guid, to_delete_item_count);
|
|
if (result.isFail())
|
|
{
|
|
return (result, null);
|
|
}
|
|
|
|
to_delete_items.Add(equiped_item);
|
|
}
|
|
|
|
return (result, to_delete_items);
|
|
}
|
|
|
|
public async Task<(Result, Item?, Item?)> tryDivideItem(ITEM_GUID itemGuid, UInt16 toDivideCount = 1)
|
|
{
|
|
var owner = getOwner();
|
|
NullReferenceCheckHelper.throwIfNull(owner, () => $"owner is null !!!");
|
|
var parent = owner.getRootParent();
|
|
NullReferenceCheckHelper.throwIfNull(parent, () => $"parent is null !!! - {owner.toBasicString()}");
|
|
|
|
var (result, divided_item, new_item) = await m_bag_inven.tryDivideItem(itemGuid, toDivideCount);
|
|
if (result.isFail())
|
|
{
|
|
return (result, null, null);
|
|
}
|
|
NullReferenceCheckHelper.throwIfNull(divided_item, () => $"reserved_item is null !!! - {parent.toBasicString()}");
|
|
|
|
return (result, divided_item, new_item);
|
|
}
|
|
|
|
public async Task<Result> tryResetAttributeByTattoo()
|
|
{
|
|
var owner = getOwner();
|
|
NullReferenceCheckHelper.throwIfNull(owner, () => $"owner is null !!!");
|
|
var parent = owner.getRootParent();
|
|
NullReferenceCheckHelper.throwIfNull(parent, () => $"parent is null !!! - {owner.toBasicString()}");
|
|
|
|
var result = new Result();
|
|
var err_msg = string.Empty;
|
|
|
|
if (false == m_equip_invens.TryGetValue(InvenEquipType.Tattoo, out var found_equip_inven))
|
|
{
|
|
err_msg = $"Not found InvenEquipType.Tattoo !!! - {parent.toBasicString()}";
|
|
result.setFail(ServerErrorCode.EquipInvenNotFound, err_msg);
|
|
Log.getLogger().error(result.toBasicString());
|
|
|
|
return result;
|
|
}
|
|
|
|
var inven_accessor = found_equip_inven as IWithInventoryAccessor;
|
|
NullReferenceCheckHelper.throwIfNull(inven_accessor, () => $"inven_accessor is null !!! - {owner.toBasicString()}");
|
|
|
|
foreach (var item in inven_accessor.getHasItemBases())
|
|
{
|
|
var item_attribute = item.getEntityAttribute<ItemAttributeBase>();
|
|
NullReferenceCheckHelper.throwIfNull(item_attribute, () => $"item_attribute is null !!! - {owner.toBasicString()}");
|
|
|
|
var ability_action = owner.getEntityAction<AbilityAction>();
|
|
NullReferenceCheckHelper.throwIfNull(ability_action, () => $"ability_action is null !!! - {owner.toBasicString()}");
|
|
|
|
result = await ability_action.setAbilities(item, (Int16)item_attribute.Level, false);
|
|
if (result.isFail())
|
|
{
|
|
return result;
|
|
}
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
protected async Task onUpdateItemAll()
|
|
{
|
|
var owner = getOwner();
|
|
NullReferenceCheckHelper.throwIfNull(owner, () => $"owner is null !!!");
|
|
var parent = owner.getRootParent();
|
|
NullReferenceCheckHelper.throwIfNull(parent, () => $"parent is null !!! - {owner.toBasicString()}");
|
|
|
|
var err_msg = string.Empty;
|
|
var result = new Result();
|
|
|
|
if (false == m_entity_update_timer.isOn()) { return; }
|
|
|
|
var has_item_guids = getBagInven().getHasSlotsWithEntityBases().Keys.ToList();
|
|
|
|
foreach (var target_item_guid in has_item_guids)
|
|
{
|
|
var found_item_base = getBagInven().findEntityBase(target_item_guid);
|
|
if(null == found_item_base)
|
|
{
|
|
err_msg = $"Not found Item !!! : itemGuid:{target_item_guid} - {parent.toBasicString()}";
|
|
Log.getLogger().debug(err_msg);
|
|
continue;
|
|
}
|
|
|
|
var item_action = found_item_base.getEntityAction<ItemAction>();
|
|
NullReferenceCheckHelper.throwIfNull(item_action, () => $"item_action is null !!! - {parent.toBasicString()}");
|
|
|
|
await item_action.onTick();
|
|
}
|
|
}
|
|
|
|
public override async Task onTick()
|
|
{
|
|
await onUpdateItemAll();
|
|
}
|
|
|
|
public abstract Item onAllocItem();
|
|
|
|
public async Task<Result> onMergeInventory(List<ReservedSlotOnInven> reservedSlotOnInvens, TransactionRunner transactionRunner)
|
|
{
|
|
var owner = getOwner();
|
|
NullReferenceCheckHelper.throwIfNull(owner, () => $"owner is null !!!");
|
|
ArgumentNullReferenceCheckHelper.throwIfNull(reservedSlotOnInvens, () => $"reservedSlotOnInvens is null !!! - {owner.toBasicString()}");
|
|
ArgumentNullReferenceCheckHelper.throwIfNull(transactionRunner, () => $"transactionRunner is null !!! - {owner.toBasicString()}");
|
|
|
|
var result = new Result();
|
|
var err_msg = string.Empty;
|
|
|
|
foreach(var reserved_inven in reservedSlotOnInvens)
|
|
{
|
|
var entity_inven_type = reserved_inven.getEntityType();
|
|
|
|
switch (entity_inven_type)
|
|
{
|
|
case EntityType.BagInven:
|
|
{
|
|
foreach(var each_slot in reserved_inven.getReservedSlots())
|
|
{
|
|
var bag_tab_type_key = each_slot.Key;
|
|
var reserved_slot = each_slot.Value;
|
|
|
|
bool is_bag_tab_type = true;
|
|
|
|
// 1. 가방에 보관된 예약 아이템을 적용 한다.
|
|
var to_equip_item = reserved_slot.getEquipEntity() as Item;
|
|
if (null != to_equip_item)
|
|
{
|
|
result = m_bag_inven.onMergeTakeInItem(to_equip_item);
|
|
if (result.isFail())
|
|
{
|
|
continue;
|
|
}
|
|
|
|
var item_attribute = to_equip_item.getEntityAttributeWithReadOnly<ItemAttributeBase>();
|
|
NullReferenceCheckHelper.throwIfNull(item_attribute, () => $"item_attribute is null !!! - {owner.toBasicString()}");
|
|
err_msg = $"Successfully called onMergeTakeInItem() !!! : itemGuid:{item_attribute.ItemGuid}, itemMetaId:{item_attribute.ItemMetaId}, itemCount:{item_attribute.ItemStackCount} - {owner.toBasicString()}";
|
|
Log.getLogger().info(err_msg);
|
|
|
|
await transactionRunner.onApplyCommonResultOfInsertedItem(to_equip_item);
|
|
|
|
is_bag_tab_type = false;
|
|
}
|
|
|
|
// 2. 가방에 보관 해제된 예약 아이템을 적용 한다.
|
|
var to_unequip_item = reserved_slot.getUnequipEntity() as Item;
|
|
if (null != to_unequip_item)
|
|
{
|
|
result = m_bag_inven.onMergeTakeOutItem(to_unequip_item);
|
|
if (result.isFail())
|
|
{
|
|
continue;
|
|
}
|
|
|
|
var item_attribute = to_unequip_item.getEntityAttributeWithReadOnly<ItemAttributeBase>();
|
|
NullReferenceCheckHelper.throwIfNull(item_attribute, () => $"item_attribute is null !!! - {owner.toBasicString()}");
|
|
err_msg = $"Successfully called onMergeTakeOutItem() !!! : itemGuid:{item_attribute.ItemGuid}, itemMetaId:{item_attribute.ItemMetaId}, itemCount:{item_attribute.ItemStackCount} - {owner.toBasicString()}";
|
|
Log.getLogger().info(err_msg);
|
|
|
|
await transactionRunner.onApplyCommonResultOfDeletedItem(to_unequip_item);
|
|
|
|
is_bag_tab_type = false;
|
|
}
|
|
|
|
// 3. 장착/해제 아이템 관련 처리가 아닌 경우 : BagTabType의 예약된 보관 개수를 적용 한다.
|
|
if (true == is_bag_tab_type)
|
|
{
|
|
// 3. 예약된 BagTabType의 슬롯 갯수를 적용 한다.
|
|
var bag_tab_type = EnumHelper.convertEnumTypeAndValueStringToEnum<BagTabType>(bag_tab_type_key, BagTabType.None);
|
|
if (BagTabType.None == bag_tab_type)
|
|
{
|
|
err_msg = $"Failed to convertEnumTypeAndValueStringToEnum() !!! : BagTabTypeKey:{bag_tab_type_key} - {owner.toBasicString()}";
|
|
result.setFail(ServerErrorCode.BagTabTypeInvalid, err_msg);
|
|
Log.getLogger().error(result.toBasicString());
|
|
|
|
continue;
|
|
}
|
|
|
|
if (false == m_bag_inven.getBagTabs().TryGetValue(bag_tab_type, out var found_bag_tab))
|
|
{
|
|
err_msg = $"Failed to TryGetValue() !!! : BagTabTypeKey:{bag_tab_type} - {owner.toBasicString()}";
|
|
result.setFail(ServerErrorCode.BagTabTypeNotFound, err_msg);
|
|
Log.getLogger().error(result.toBasicString());
|
|
|
|
continue;
|
|
}
|
|
NullReferenceCheckHelper.throwIfNull(found_bag_tab, () => $"found_bag_tab is null !!! - {owner.toBasicString()}");
|
|
|
|
var curr_count = found_bag_tab.TakeInItemCount;
|
|
var reserved_count = reserved_slot.getReservedCount();
|
|
if (false == found_bag_tab.onMergeTakeInItemCount(reserved_count))
|
|
{
|
|
err_msg = $"Failed to onMergeTakeInItemCount() !!! : reservedCount:{reserved_count}, currCount:{curr_count}, BagTabType:{bag_tab_type}, {found_bag_tab.toBasicString()} - {owner.toBasicString()}";
|
|
result.setFail(ServerErrorCode.BagTabCountMergeFailed, err_msg);
|
|
Log.getLogger().error(result.toBasicString());
|
|
|
|
continue;
|
|
}
|
|
else
|
|
{
|
|
err_msg = $"Successfully called onMergeTakeInItemCount() !!! : reservedCount:{reserved_count}, currCount:{curr_count}, BagTabType:{bag_tab_type}, {found_bag_tab.toBasicString()} - {owner.toBasicString()}";
|
|
Log.getLogger().info(err_msg);
|
|
}
|
|
}
|
|
}
|
|
}break;
|
|
|
|
case EntityType.ClothEquipInven:
|
|
case EntityType.ToolEquipInven:
|
|
case EntityType.TattooEquipInven:
|
|
{
|
|
var inven_equip_type = reserved_inven.getEntityType().toInvenEquipType();
|
|
if(InvenEquipType.None == inven_equip_type)
|
|
{
|
|
err_msg = $"Failed to toInvenEquipType() !!! : entityType:{entity_inven_type} - {owner.toBasicString()}";
|
|
result.setFail(ServerErrorCode.InvenEquipTypeInvalid, err_msg);
|
|
Log.getLogger().error(result.toBasicString());
|
|
|
|
continue;
|
|
}
|
|
|
|
if(false == m_equip_invens.TryGetValue(inven_equip_type, out var found_equip_inven))
|
|
{
|
|
err_msg = $"Not found EquipInven() !!! : entityType:{entity_inven_type} - {owner.toBasicString()}";
|
|
result.setFail(ServerErrorCode.EquipInvenNotFound, err_msg);
|
|
Log.getLogger().error(result.toBasicString());
|
|
|
|
continue;
|
|
}
|
|
|
|
var inven_accessor = found_equip_inven as IWithInventoryAccessor;
|
|
NullReferenceCheckHelper.throwIfNull(inven_accessor, () => $"inven_accessor is null !!!");
|
|
|
|
foreach (var each_slot in reserved_inven.getReservedSlots())
|
|
{
|
|
var reserved_key = each_slot.Key;
|
|
var reserved_slot = each_slot.Value;
|
|
var delta_count = reserved_slot.getReservedCount();
|
|
|
|
var error_code = ServerErrorCode.Success;
|
|
|
|
if (0 >= delta_count)
|
|
{
|
|
var unequip_item = reserved_slot.getUnequipEntity() as Item;
|
|
NullReferenceCheckHelper.throwIfNull(unequip_item, () => $"unequip_item is null !!! - {owner.toBasicString()}");
|
|
var item_attribute = unequip_item.getEntityAttributeWithReadOnly<ItemAttributeBase>();
|
|
NullReferenceCheckHelper.throwIfNull(item_attribute, () => $"item_attribute is null !!! - {owner.toBasicString()}");
|
|
|
|
error_code = inven_accessor.tryUnequipWithItemBase(reserved_key, out _);
|
|
if (error_code.isFail())
|
|
{
|
|
err_msg = $"Failed to onTryUnequipWithEntityBase() !!! : {error_code.toBasicString()}, deltaCount:{delta_count} - {owner.toBasicString()}";
|
|
result.setFail(error_code, err_msg);
|
|
Log.getLogger().error(result.toBasicString());
|
|
}
|
|
else
|
|
{
|
|
err_msg = $"Successfully called onTryUnequipWithEntityBase() !!! : deltaCount:{delta_count}, itemGuid:{item_attribute.ItemGuid}, itemMetaId:{item_attribute.ItemMetaId} - {owner.toBasicString()}";
|
|
Log.getLogger().info(err_msg);
|
|
} }
|
|
|
|
if (0 <= delta_count)
|
|
{
|
|
var equip_item = reserved_slot.getEquipEntity() as Item;
|
|
NullReferenceCheckHelper.throwIfNull(equip_item, () => $"equip_item is null !!! - {owner.toBasicString()}");
|
|
var item_attribute = equip_item.getEntityAttributeWithReadOnly<ItemAttributeBase>();
|
|
NullReferenceCheckHelper.throwIfNull(item_attribute, () => $"item_attribute is null !!! - {owner.toBasicString()}");
|
|
|
|
error_code = inven_accessor.tryEquipWithItemBase(reserved_key, equip_item);
|
|
if (error_code.isFail())
|
|
{
|
|
err_msg = $"Failed to onTryEquipWithEntityBase() !!! : {error_code.toBasicString()}, deltaCount:{delta_count}, itemGuid:{item_attribute.ItemGuid}, itemMetaId:{item_attribute.ItemMetaId} - {owner.toBasicString()}";
|
|
result.setFail(error_code, err_msg);
|
|
Log.getLogger().error(result.toBasicString());
|
|
}
|
|
else
|
|
{
|
|
err_msg = $"Successfully called onTryEquipWithEntityBase() !!! : deltaCount:{delta_count}, itemGuid:{item_attribute.ItemGuid}, itemMetaId:{item_attribute.ItemMetaId} - {owner.toBasicString()}";
|
|
Log.getLogger().info(err_msg);
|
|
} }
|
|
}
|
|
} break;
|
|
|
|
default:
|
|
{
|
|
err_msg = $"Invalid EntityType of reservedSlotOnInvens !!! : entityType:{entity_inven_type} - {owner.toBasicString()}";
|
|
result.setFail(ServerErrorCode.InventoryEntityTypeInvalid, err_msg);
|
|
Log.getLogger().error(result.toBasicString());
|
|
|
|
continue;
|
|
}
|
|
}
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
public (Result, Int16) getEquipableSlotOfEquipInven( MetaAssets.ItemMetaData itemMeta
|
|
, Dictionary<InvenEquipType, HashSet<Int16>> reservedSlotTypes )
|
|
{
|
|
var owner = getOwner();
|
|
NullReferenceCheckHelper.throwIfNull(owner, () => $"owner is null !!!");
|
|
ArgumentNullReferenceCheckHelper.throwIfNull(itemMeta, () => $"itemMeta is null !!! - {owner.toBasicString()}");
|
|
|
|
var result = new Result();
|
|
var err_msg = string.Empty;
|
|
|
|
var server_logic = GameServerApp.getServerLogic();
|
|
|
|
var inven_rule = server_logic.findRule<InventoryRule>();
|
|
if (null == inven_rule)
|
|
{
|
|
err_msg = $"Not found InventoryRule !!! : ItemMetaId:{itemMeta.ItemId} - {owner.toBasicString()}";
|
|
result.setFail(ServerErrorCode.InventoryRuleNotFound, err_msg);
|
|
Log.getLogger().error(result.toBasicString());
|
|
|
|
return (result, -1);
|
|
}
|
|
|
|
var equip_rule_bases = inven_rule.getEquipRuleBasesByItemLargeType(itemMeta.TypeLarge);
|
|
if (null == equip_rule_bases)
|
|
{
|
|
err_msg = $"Not found EquipRuleBase !!! : ItemMetaId:{itemMeta.ItemId} - {owner.toBasicString()}";
|
|
Log.getLogger().warn(err_msg);
|
|
|
|
return (result, -1);
|
|
}
|
|
|
|
foreach (var equip_rule_base in equip_rule_bases)
|
|
{
|
|
if (false == getEquipInvens().TryGetValue(equip_rule_base.InvenEquipType, out var found_equip_inven))
|
|
{
|
|
err_msg = $"Not found EquipInven !!! : invenEquipType:{equip_rule_base.InvenEquipType}, ItemMetaId:{itemMeta.ItemId} - {owner.toBasicString()}";
|
|
result.setFail(ServerErrorCode.EquipInvenNotFound, err_msg);
|
|
Log.getLogger().error(result.toBasicString());
|
|
|
|
return (result, -1);
|
|
}
|
|
NullReferenceCheckHelper.throwIfNull(found_equip_inven, () => $"found_equip_inven is null !!! - {owner.toBasicString()}");
|
|
|
|
if (false == reservedSlotTypes.TryGetValue(equip_rule_base.InvenEquipType, out var found_reserved_slot_type))
|
|
{
|
|
found_reserved_slot_type = new HashSet<Int16>();
|
|
reservedSlotTypes.TryAdd(equip_rule_base.InvenEquipType, found_reserved_slot_type);
|
|
}
|
|
|
|
var item_small_type = itemMeta.TypeSmall;
|
|
|
|
switch (equip_rule_base.InvenEquipType)
|
|
{
|
|
case InvenEquipType.Tool:
|
|
{
|
|
var tool_inven = getEquipInvens()[InvenEquipType.Tool] as ToolEquipInven;
|
|
NullReferenceCheckHelper.throwIfNull(tool_inven, () => $"tool_inven is null !!! - {owner.toBasicString()}");
|
|
|
|
var tool_equip_rule = equip_rule_base as ToolEquipRule;
|
|
NullReferenceCheckHelper.throwIfNull(tool_equip_rule, () => $"tool_equip_rule is null !!! - {owner.toBasicString()}");
|
|
|
|
foreach (var tool_slot_type in tool_equip_rule.UsableToolSlotTypes)
|
|
{
|
|
if (true == tool_inven.getHasSlotsWithEntityBases().TryGetValue(tool_slot_type, out var found_item))
|
|
{
|
|
var item_attibute = found_item.getEntityAttribute<ItemAttributeBase>();
|
|
NullReferenceCheckHelper.throwIfNull(item_attibute, () => $"item_attibute is null !!! - {owner.toBasicString()}");
|
|
if(0 < item_attibute.ItemStackCount)
|
|
{
|
|
continue;
|
|
}
|
|
}
|
|
|
|
Int16 slot_pos = (Int16)tool_slot_type;
|
|
if (true == found_reserved_slot_type.Contains(slot_pos))
|
|
{
|
|
continue;
|
|
}
|
|
|
|
found_reserved_slot_type.Add(slot_pos);
|
|
return (result, slot_pos);
|
|
}
|
|
}
|
|
break;
|
|
|
|
case InvenEquipType.Cloth:
|
|
{
|
|
var cloth_inven = getEquipInvens()[InvenEquipType.Cloth] as ClothEquipInven;
|
|
NullReferenceCheckHelper.throwIfNull(cloth_inven, () => $"cloth_inven is null !!! - {owner.toBasicString()}");
|
|
|
|
var cloth_equip_rule = equip_rule_base as ClothEquipRule;
|
|
NullReferenceCheckHelper.throwIfNull(cloth_equip_rule, () => $"cloth_equip_rule is null !!! - {owner.toBasicString()}");
|
|
|
|
if (false == cloth_equip_rule.m_slots_by_item_type.TryGetValue(item_small_type, out var found_cloth_slot_types))
|
|
{
|
|
err_msg = $"Not found ClothSlotType !!! : itemSmallType:{item_small_type}, ItemMetaId:{itemMeta.ItemId} - {owner.toBasicString()}";
|
|
result.setFail(ServerErrorCode.ClothEquipRuleClothSlotTypeNotFound, err_msg);
|
|
Log.getLogger().error(result.toBasicString());
|
|
|
|
return (result, -1);
|
|
}
|
|
|
|
foreach (var cloth_slot_type in found_cloth_slot_types)
|
|
{
|
|
if (true == cloth_inven.getHasSlotsWithEntityBases().TryGetValue(cloth_slot_type, out var found_item))
|
|
{
|
|
var item_attibute = found_item.getEntityAttribute<ItemAttributeBase>();
|
|
NullReferenceCheckHelper.throwIfNull(item_attibute, () => $"item_attibute is null !!! - {owner.toBasicString()}");
|
|
if (0 < item_attibute.ItemStackCount)
|
|
{
|
|
continue;
|
|
}
|
|
}
|
|
|
|
Int16 slot_pos = (Int16)cloth_slot_type;
|
|
if (true == found_reserved_slot_type.Contains(slot_pos))
|
|
{
|
|
continue;
|
|
}
|
|
|
|
found_reserved_slot_type.Add(slot_pos);
|
|
return (result, slot_pos);
|
|
}
|
|
}
|
|
break;
|
|
|
|
case InvenEquipType.Tattoo:
|
|
{
|
|
var tatoo_inven = getEquipInvens()[InvenEquipType.Tattoo] as TattooEquipInven;
|
|
NullReferenceCheckHelper.throwIfNull(tatoo_inven, () =>$"tatoo_inven is null !!! - {owner.toBasicString()}");
|
|
|
|
var tattoo_equip_rule = equip_rule_base as TattooEquipRule;
|
|
NullReferenceCheckHelper.throwIfNull(tattoo_equip_rule, () => $"tattoo_equip_rule is null !!! - {owner.toBasicString()}");
|
|
|
|
foreach (var tattoo_slot_type in tattoo_equip_rule.getUsableTattooSlotPos(owner.getEntityType()))
|
|
{
|
|
if (true == tatoo_inven.getHasSlotsWithEntityBases().TryGetValue(tattoo_slot_type, out var found_item))
|
|
{
|
|
var item_attibute = found_item.getEntityAttribute<ItemAttributeBase>();
|
|
NullReferenceCheckHelper.throwIfNull(item_attibute, () => $"item_attibute is null !!! - {owner.toBasicString()}");
|
|
if (0 < item_attibute.ItemStackCount)
|
|
{
|
|
continue;
|
|
}
|
|
}
|
|
|
|
Int16 slot_pos = (Int16)tattoo_slot_type;
|
|
if (true == found_reserved_slot_type.Contains(slot_pos))
|
|
{
|
|
continue;
|
|
}
|
|
|
|
found_reserved_slot_type.Add(slot_pos);
|
|
return (result, slot_pos);
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
err_msg = $"Not found EquipInven !!! : ItemMetaId:{itemMeta.ItemId} - {owner.toBasicString()}";
|
|
result.setFail(ServerErrorCode.EquipInvenNotFound, err_msg);
|
|
|
|
return (result, -1);
|
|
}
|
|
|
|
public List<Item> getEquipItemAll()
|
|
{
|
|
var owner = getOwner();
|
|
NullReferenceCheckHelper.throwIfNull(owner, () => $"owner is null !!!");
|
|
|
|
var equip_items = new List<Item>();
|
|
|
|
var err_msg = string.Empty;
|
|
|
|
var target_inven_equip_types = EnumHelper.getValuesWithoutScopeAll<InvenEquipType>();
|
|
foreach (var inven_equip_type in target_inven_equip_types)
|
|
{
|
|
if (false == getEquipInvens().TryGetValue(inven_equip_type, out var found_equip_inven))
|
|
{
|
|
continue;
|
|
}
|
|
|
|
var equip_inven = found_equip_inven as IWithInventoryAccessor;
|
|
if (equip_inven == null)
|
|
{
|
|
err_msg = $"Failed to cast IWithInventoryAccessor !!! : invenEquipType:{found_equip_inven.getTypeName()} - {owner.toBasicString()}";
|
|
Log.getLogger().error(err_msg);
|
|
continue;
|
|
}
|
|
|
|
foreach (var entity_base in equip_inven.getHasItemBases())
|
|
{
|
|
var curr_item = entity_base as Item;
|
|
NullReferenceCheckHelper.throwIfNull(curr_item, () => $"curr_item is null !!! - {owner.toBasicString()}");
|
|
|
|
var item_attribute = curr_item.getEntityAttribute<ItemAttributeBase>();
|
|
NullReferenceCheckHelper.throwIfNull(item_attribute, () => $"item_attribute is null !!! - {owner.toBasicString()}");
|
|
|
|
if(0 >= item_attribute.ItemStackCount)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
equip_items.Add(curr_item);
|
|
}
|
|
}
|
|
|
|
return equip_items;
|
|
}
|
|
|
|
public List<Item> getBagItemAll()
|
|
{
|
|
var owner = getOwner();
|
|
NullReferenceCheckHelper.throwIfNull(owner, () => $"owner is null !!!");
|
|
|
|
var bag_items = new List<Item>();
|
|
|
|
var err_msg = string.Empty;
|
|
|
|
var bag_inven = getBagInven();
|
|
NullReferenceCheckHelper.throwIfNull(bag_inven, () => $"bag_inven is null !!! - {owner.toBasicString()}");
|
|
|
|
foreach (var item_base in bag_inven.getHasItemBases())
|
|
{
|
|
var curr_item = item_base as Item;
|
|
NullReferenceCheckHelper.throwIfNull(curr_item, () => $"curr_item is null !!! - {owner.toBasicString()}");
|
|
|
|
var item_attribute = curr_item.getEntityAttribute<ItemAttributeBase>();
|
|
NullReferenceCheckHelper.throwIfNull(item_attribute, () => $"item_attribute is null !!! - {owner.toBasicString()}");
|
|
|
|
if (0 >= item_attribute.ItemStackCount)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
bag_items.Add(curr_item);
|
|
}
|
|
|
|
return bag_items;
|
|
}
|
|
|
|
public bool hasItemByMetaId(META_ID itemMetaId, UInt32 toCheckCount = 1)
|
|
{
|
|
var owner = getOwner();
|
|
NullReferenceCheckHelper.throwIfNull(owner, () => $"owner is null !!!");
|
|
var err_msg = string.Empty;
|
|
|
|
var bag_inven = getBagInven();
|
|
NullReferenceCheckHelper.throwIfNull(bag_inven, () => $"bag_inven is null !!! - item meta id: {itemMetaId} / {owner.toBasicString()}");
|
|
|
|
return bag_inven.hasItemByMetaId(itemMetaId, toCheckCount);
|
|
}
|
|
|
|
public ConcurrentDictionary<META_ID, UInt16> getItemsCountByMetaIds(List<META_ID> itemMetaIds)
|
|
{
|
|
var owner = getOwner();
|
|
NullReferenceCheckHelper.throwIfNull(owner, () => $"owner is null !!!");
|
|
var err_msg = string.Empty;
|
|
|
|
var bag_inven = getBagInven();
|
|
NullReferenceCheckHelper.throwIfNull(bag_inven, () => $"bag_inven is null !!! - item meta ids: {itemMetaIds} / {owner.toBasicString()}");
|
|
|
|
return bag_inven.getItemsCountByMetaIds(itemMetaIds);
|
|
}
|
|
|
|
public (Result, InvenBagType, BagTabType) toBagTypeAndTabType(ItemMetaData itemMetaData)
|
|
{
|
|
var owner = getOwner();
|
|
NullReferenceCheckHelper.throwIfNull(owner, () => $"owner is null !!!");
|
|
ArgumentNullReferenceCheckHelper.throwIfNull(itemMetaData, () => $"metaData is null !!! - {owner.toBasicString()}");
|
|
|
|
var server_logic = GameServerApp.getServerLogic();
|
|
|
|
var inventory_rule = server_logic.findRule<InventoryRule>();
|
|
NullReferenceCheckHelper.throwIfNull(inventory_rule, () => $"inventory_rule is null !!! - {owner.toBasicString()}");
|
|
|
|
var result = new Result();
|
|
var err_msg = string.Empty;
|
|
|
|
var found_bag_rules = inventory_rule.getBagRulesByItemLargeType(itemMetaData.TypeLarge);
|
|
if ( null != found_bag_rules
|
|
&& found_bag_rules.Count > 0 )
|
|
{
|
|
foreach (var bag_rule in found_bag_rules)
|
|
{
|
|
var target_bag_type = bag_rule.InvenBagType;
|
|
var usable_bag_tab_type = target_bag_type.toUsableBagTabType().toNFTTabOffset(itemMetaData);
|
|
|
|
return (result, target_bag_type, usable_bag_tab_type);
|
|
}
|
|
}
|
|
|
|
err_msg = $"Not found InventoryRule !!! : ItemMetaId:{itemMetaData.ItemId} - {owner.toBasicString()}";
|
|
result.setFail(ServerErrorCode.InventoryRuleNotFound, err_msg);
|
|
Log.getLogger().error(result.toBasicString());
|
|
|
|
return (result, InvenBagType.None, BagTabType.None);
|
|
}
|
|
|
|
public global::Inventory? toBagInven4Client()
|
|
{
|
|
var owner = getOwner();
|
|
NullReferenceCheckHelper.throwIfNull(owner, () => $"owner is null !!!");
|
|
|
|
var server_logic = GameServerApp.getServerLogic();
|
|
|
|
var inventory_rule = server_logic.findRule<InventoryRule>();
|
|
NullReferenceCheckHelper.throwIfNull(inventory_rule, () => $"inventory_rule is null !!! - {owner.toBasicString()}");
|
|
|
|
var inventory_ui = new global::Inventory();
|
|
|
|
foreach(var item_base in m_bag_inven.getHasItemBases())
|
|
{
|
|
var item = item_base as Item;
|
|
NullReferenceCheckHelper.throwIfNull(item, () => $"item is null !!! - {owner.toBasicString()}");
|
|
|
|
var item_ui = item.toItemData4Client();
|
|
NullReferenceCheckHelper.throwIfNull(item_ui, () => $"item_ui is null !!! - {owner.toBasicString()}");
|
|
var item_meta = item.getItemMeta();
|
|
NullReferenceCheckHelper.throwIfNull(item_meta, () => $"item_meta is null !!! - {owner.toBasicString()}");
|
|
|
|
var found_bag_rules = inventory_rule.getBagRulesByItemLargeType(item_meta.TypeLarge);
|
|
if (found_bag_rules == null)
|
|
{
|
|
var err_msg = $"Not found InventoryRule !!! : ItemMetaId:{item_meta.ItemId} - {owner.toBasicString()}";
|
|
Log.getLogger().error(err_msg);
|
|
continue;
|
|
}
|
|
|
|
foreach (var bag_rule in found_bag_rules)
|
|
{
|
|
var target_bag_type = bag_rule.InvenBagType;
|
|
var usable_bag_tab_type = target_bag_type.toUsableBagTabType().toNFTTabOffset(item_meta);
|
|
|
|
switch(usable_bag_tab_type)
|
|
{
|
|
case BagTabType._0:
|
|
inventory_ui.EtcItem.Add(item_ui);
|
|
break;
|
|
|
|
case BagTabType._1:
|
|
inventory_ui.CostumeItem.Add(item_ui);
|
|
break;
|
|
|
|
case BagTabType._2:
|
|
inventory_ui.InteriorItem.Add(item_ui);
|
|
break;
|
|
|
|
case BagTabType._3:
|
|
inventory_ui.BeautyItem.Add(item_ui);
|
|
break;
|
|
|
|
case BagTabType._4:
|
|
inventory_ui.TattooItem.Add(item_ui);
|
|
break;
|
|
|
|
case BagTabType._5:
|
|
inventory_ui.EtcItemNft.Add(item_ui);
|
|
break;
|
|
|
|
case BagTabType._6:
|
|
inventory_ui.CostumeItemNft.Add(item_ui);
|
|
break;
|
|
|
|
case BagTabType._7:
|
|
inventory_ui.InteriorItemNft.Add(item_ui);
|
|
break;
|
|
|
|
case BagTabType._8:
|
|
inventory_ui.BeautyItemNft.Add(item_ui);
|
|
break;
|
|
|
|
case BagTabType._9:
|
|
inventory_ui.TattooItemNft.Add(item_ui);
|
|
break;
|
|
|
|
default:
|
|
var err_msg = $"Invalid BagTabType !!! : BagTabType:{usable_bag_tab_type}, {item.toBasicString()} - {owner.toBasicString()}";
|
|
Log.getLogger().error(err_msg);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
return inventory_ui;
|
|
}
|
|
|
|
public ClothInfo? toClothInven4Client()
|
|
{
|
|
var owner = getOwner();
|
|
NullReferenceCheckHelper.throwIfNull(owner, () => $"owner is null !!!");
|
|
|
|
var result = new Result();
|
|
|
|
var item_cloth_action = owner.getEntityAction<ItemClothAction>();
|
|
NullReferenceCheckHelper.throwIfNull(item_cloth_action, () => $"item_cloth_action is null !!! - {owner.toBasicString()}");
|
|
|
|
var inven_cloth = m_equip_invens[InvenEquipType.Cloth] as ClothEquipInven;
|
|
NullReferenceCheckHelper.throwIfNull(inven_cloth, () => $"inven_cloth is null !!! - {owner.toBasicString()}");
|
|
|
|
var cloth_info = new ClothInfo();
|
|
|
|
var cloth_slot_types = EnumHelper.getValues<ClothSlotType>();
|
|
foreach (var cloth_slot_type in cloth_slot_types)
|
|
{
|
|
var found_cloth = inven_cloth.getData().findEntityBaseInSlotType(cloth_slot_type) as Item;
|
|
if (null == found_cloth)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
result = item_cloth_action.fillupCloth(cloth_slot_type, found_cloth, ref cloth_info);
|
|
if (result.isFail())
|
|
{
|
|
var err_msg = $"Failed to fillupCloth() !!! : {result.toBasicString()} - {owner.toBasicString()}";
|
|
Log.getLogger().error(err_msg);
|
|
}
|
|
}
|
|
|
|
return cloth_info;
|
|
}
|
|
|
|
public List<TattooSlotInfo> toTattooInven4Client()
|
|
{
|
|
var owner = getOwner();
|
|
NullReferenceCheckHelper.throwIfNull(owner, () => $"owner is null !!!");
|
|
|
|
var result = new Result();
|
|
|
|
var item_tattoo_action = owner.getEntityAction<ItemTattooAction>();
|
|
NullReferenceCheckHelper.throwIfNull(item_tattoo_action, () => $"item_tattoo_action is null !!! - {owner.toBasicString()}");
|
|
|
|
var tattoo_slots = new List<TattooSlotInfo>();
|
|
|
|
var inven_tattoo = m_equip_invens[InvenEquipType.Tattoo] as TattooEquipInven;
|
|
NullReferenceCheckHelper.throwIfNull(inven_tattoo, () => $"inven_tattoo is null !!! - {owner.toBasicString()}");
|
|
|
|
var custom_defined_ui_action = owner.getEntityAction<CustomDefinedUiAction>();
|
|
NullReferenceCheckHelper.throwIfNull(custom_defined_ui_action, () => $"custom_defined_ui_action is null !!! - {owner.toBasicString()}");
|
|
|
|
var tattoo_slot_types = InvenEquipType.Tattoo.toEquipableTattooSlotTypes(owner.getEntityType());
|
|
foreach (var tattoo_slot_type in tattoo_slot_types)
|
|
{
|
|
var tattoo_slot = new TattooSlotInfo();
|
|
tattoo_slot.ItemInfo = new();
|
|
if (false == custom_defined_ui_action.getTattooVisible(tattoo_slot_type, out var found_visible))
|
|
{
|
|
found_visible = true;
|
|
}
|
|
tattoo_slot.IsVisible = found_visible == true ? 1 : 0;
|
|
tattoo_slots.Add(tattoo_slot);
|
|
|
|
var found_tattoo = inven_tattoo.getData().findEntityBaseInSlotType(tattoo_slot_type) as Item;
|
|
if (null == found_tattoo)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
item_tattoo_action.fillupTattooSlotInfo(tattoo_slot_type, found_tattoo, ref tattoo_slot);
|
|
}
|
|
|
|
return tattoo_slots;
|
|
}
|
|
|
|
public List<MyTattooSlotInfo> toTattooSimple4Client()
|
|
{
|
|
var owner = getOwner();
|
|
NullReferenceCheckHelper.throwIfNull(owner, () => $"owner is null !!!");
|
|
|
|
var result = new Result();
|
|
|
|
var item_tattoo_action = owner.getEntityAction<ItemTattooAction>();
|
|
NullReferenceCheckHelper.throwIfNull(item_tattoo_action, () => $"item_tattoo_action is null !!! - {owner.toBasicString()}");
|
|
|
|
var tattoo_simples = new List<MyTattooSlotInfo>();
|
|
|
|
var inven_tattoo = m_equip_invens[InvenEquipType.Tattoo] as TattooEquipInven;
|
|
NullReferenceCheckHelper.throwIfNull(inven_tattoo, () => $"inven_tattoo is null !!! - {owner.toBasicString()}");
|
|
|
|
var custom_defined_ui_action = owner.getEntityAction<CustomDefinedUiAction>();
|
|
NullReferenceCheckHelper.throwIfNull(custom_defined_ui_action, () => $"custom_defined_ui_action is null !!! - {owner.toBasicString()}");
|
|
|
|
var tattoo_slot_types = InvenEquipType.Tattoo.toEquipableTattooSlotTypes(owner.getEntityType());
|
|
foreach (var tattoo_slot_type in tattoo_slot_types)
|
|
{
|
|
var tattoo_simple = new MyTattooSlotInfo();
|
|
|
|
if(false == custom_defined_ui_action.getTattooVisible(tattoo_slot_type, out var found_visible))
|
|
{
|
|
found_visible = true;
|
|
}
|
|
tattoo_simple.IsVisible = found_visible == true ? 1 : 0;
|
|
|
|
tattoo_simples.Add(tattoo_simple);
|
|
|
|
var found_tattoo = inven_tattoo.getData().findEntityBaseInSlotType(tattoo_slot_type);
|
|
if (null == found_tattoo)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
var item_attribute = found_tattoo.getEntityAttribute<ItemAttributeBase>();
|
|
NullReferenceCheckHelper.throwIfNull(item_attribute, () => $"ItemAttributeBase is null !!! - {owner.toBasicString()}");
|
|
tattoo_simple.ItemGuid = item_attribute.ItemGuid;
|
|
}
|
|
|
|
return tattoo_simples;
|
|
}
|
|
|
|
public List<string> toToolSlotInven4Client()
|
|
{
|
|
var owner = getOwner();
|
|
NullReferenceCheckHelper.throwIfNull(owner, () => $"owner is null !!!");
|
|
|
|
var tool_guids = new List<string>();
|
|
|
|
var item_tool_action = owner.getEntityAction<ItemToolAction>();
|
|
NullReferenceCheckHelper.throwIfNull(item_tool_action, () => $"item_tool_action is null !!! - {owner.toBasicString()}");
|
|
|
|
var inven_tool = m_equip_invens[InvenEquipType.Tool] as ToolEquipInven;
|
|
NullReferenceCheckHelper.throwIfNull(inven_tool, () => $"inven_tool is null !!! - {owner.toBasicString()}");
|
|
|
|
var cloth_info = new ClothInfo();
|
|
|
|
var tool_slot_types = EnumHelper.getValuesWithoutScopeAll<ToolSlotType>();
|
|
foreach (var tool_slot_type in tool_slot_types)
|
|
{
|
|
var found_tool = inven_tool.getData().findEntityBaseInSlotType(tool_slot_type) as Item;
|
|
if (null == found_tool)
|
|
{
|
|
tool_guids.Add(string.Empty);
|
|
}
|
|
else
|
|
{
|
|
var item_attribute = found_tool.getEntityAttribute<ItemAttributeBase>();
|
|
NullReferenceCheckHelper.throwIfNull(item_attribute, () => $"item_attribute is null !!! - {owner.toBasicString()}");
|
|
|
|
tool_guids.Add(item_attribute.ItemGuid);
|
|
}
|
|
}
|
|
|
|
return tool_guids;
|
|
}
|
|
|
|
|
|
public List<Int32> toSlotMaxCountOfBagAll4Client()
|
|
{
|
|
var owner = getOwner();
|
|
NullReferenceCheckHelper.throwIfNull(owner, () => $"owner is null !!!");
|
|
|
|
var slot_max_counts = new List<Int32>();
|
|
|
|
foreach (var each in m_bag_inven.getBagTabs())
|
|
{
|
|
var bag_tab = each.Value as BagTab;
|
|
NullReferenceCheckHelper.throwIfNull(bag_tab, () => $"bag_tab is null !!! - {owner.toBasicString()}");
|
|
|
|
slot_max_counts.Add(bag_tab.getSlotMaxCount());
|
|
}
|
|
|
|
return slot_max_counts;
|
|
}
|
|
|
|
public void writeLog()
|
|
{
|
|
var err_msg = string.Empty;
|
|
|
|
var owner = getOwner();
|
|
NullReferenceCheckHelper.throwIfNull(owner, () => $"owner is null !!!");
|
|
|
|
var bag_inven = getBagInven();
|
|
NullReferenceCheckHelper.throwIfNull(bag_inven, () => $"bag_inven is null !!! - {owner.toBasicString()}");
|
|
|
|
bag_inven.onWriteLog();
|
|
|
|
var target_inven_equip_types = EnumHelper.getValuesWithoutScopeAll<InvenEquipType>();
|
|
foreach (var inven_equip_type in target_inven_equip_types)
|
|
{
|
|
if (false == getEquipInvens().TryGetValue(inven_equip_type, out var found_equip_inven))
|
|
{
|
|
continue;
|
|
}
|
|
|
|
var equip_inven = found_equip_inven as IWithInventoryAccessor;
|
|
if (equip_inven == null)
|
|
{
|
|
err_msg = $"Failed to cast IWithInventoryAccessor !!! : invenEquipType:{found_equip_inven.getTypeName()} - {owner.toBasicString()}";
|
|
Log.getLogger().error(err_msg);
|
|
continue;
|
|
}
|
|
|
|
equip_inven.onWriteLog();
|
|
}
|
|
}
|
|
|
|
public BagInven getBagInven() => m_bag_inven;
|
|
|
|
public ConcurrentDictionary<InvenEquipType, EntityBase> getEquipInvens() => m_equip_invens;
|
|
|
|
public async Task<IDisposable> getAsyncLock() => await m_async_lock.LockAsync();
|
|
}
|
|
}
|