초기커밋
This commit is contained in:
352
ServerCommon/Entity/Inventory/InventoryBase.cs
Normal file
352
ServerCommon/Entity/Inventory/InventoryBase.cs
Normal file
@@ -0,0 +1,352 @@
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
|
||||
using ServerCore; using ServerBase;
|
||||
|
||||
|
||||
using MetaAssets;
|
||||
|
||||
|
||||
using SESSION_ID = System.Int32;
|
||||
using WORLD_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;
|
||||
using Google.Protobuf.WellKnownTypes;
|
||||
|
||||
|
||||
|
||||
|
||||
namespace ServerCommon;
|
||||
|
||||
|
||||
public abstract class InventoryBase<TSlotType> : SlotsWrapperBase<SlotsWithEntityBase<TSlotType>>, IWithInventoryAccessor
|
||||
where TSlotType : notnull
|
||||
{
|
||||
public InventoryBase(EntityType entityType, EntityBase parent)
|
||||
: base(entityType, parent)
|
||||
{
|
||||
}
|
||||
|
||||
public virtual Result onTryTakeInEntityBase(TSlotType entityGuid, EntityBase toTakeInEntityBase)
|
||||
{
|
||||
var err_msg = string.Empty;
|
||||
|
||||
var result = tryIsEquipableOrEquipWithEntityBase(entityGuid, toTakeInEntityBase);
|
||||
if (result.isFail())
|
||||
{
|
||||
err_msg = $"Failed to onTryIsEquipableOrEquipWithEntityBase() !!! : {result.toBasicString()}";
|
||||
Log.getLogger().error(err_msg);
|
||||
return result;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public virtual Result onTryTakeOutEnityBase(ENTITY_GUID entityGuid, out EntityBase? takenOutEntityBase)
|
||||
{
|
||||
var err_msg = string.Empty;
|
||||
|
||||
takenOutEntityBase = null;
|
||||
|
||||
var result = tryUnequipableOrUnequipWithEntityBase(entityGuid, out var taken_out_entity_base);
|
||||
if (result.isFail())
|
||||
{
|
||||
err_msg = $"Failed to onTryUnequipableOrUnequipWithEntityBase() !!! : {result.toBasicString()}";
|
||||
Log.getLogger().error(err_msg);
|
||||
return result;
|
||||
}
|
||||
takenOutEntityBase = taken_out_entity_base;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public (Result, List<ItemAttributeBase>, UInt16) findItemAttributeBaseAllByMetaId(META_ID itemMetaId, UInt32 toCheckItemCount = UInt32.MaxValue)
|
||||
{
|
||||
var parent = getDirectParent();
|
||||
NullReferenceCheckHelper.throwIfNull(parent, () => $"paren is null !!!");
|
||||
var inven_data = getData();
|
||||
NullReferenceCheckHelper.throwIfNull(inven_data, () => $"inven_data is null !!! - {parent.toBasicString()}");
|
||||
|
||||
var err_msg = string.Empty;
|
||||
var result = new Result();
|
||||
|
||||
var target_item_attributes = new List<ItemAttributeBase>();
|
||||
|
||||
if (0 >= itemMetaId)
|
||||
{
|
||||
err_msg = $"Invalid ItemMetaId !!! : itemMetaId:{itemMetaId} > 0 - {parent.toBasicString()}";
|
||||
result.setFail(ServerErrorCode.MetaIdInvalid, err_msg);
|
||||
Log.getLogger().error(result.toBasicString());
|
||||
|
||||
return (result, target_item_attributes, 0);
|
||||
}
|
||||
|
||||
// 1. 아이템 메타 정보를 얻는다.
|
||||
if (false == MetaData.Instance._ItemTable.TryGetValue((int)itemMetaId, out var itemMetaData))
|
||||
{
|
||||
err_msg = $"Not found ItemMeta !!! : itemMetaId:{itemMetaId} - {parent.toBasicString()}";
|
||||
result.setFail(ServerErrorCode.ItemMetaDataNotFound, err_msg);
|
||||
Log.getLogger().error(result.toBasicString());
|
||||
|
||||
return (result, target_item_attributes, 0);
|
||||
}
|
||||
|
||||
// 2. 동일한 종류의 현재 Origin ItemAttributeBase 목록을 얻는다.
|
||||
var found_origin_item_attributes = getHasSlotsWithEntityBases().Where(x =>
|
||||
{
|
||||
var item_attribute_base = x.Value.getOriginEntityAttribute<ItemAttributeBase>();
|
||||
NullReferenceCheckHelper.throwIfNull(item_attribute_base, () => $"item_attribute_base is null !!! - {parent.toBasicString()}");
|
||||
|
||||
if ( item_attribute_base.ItemMetaId == itemMetaId
|
||||
&& item_attribute_base.ItemStackCount > 0)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}).Select(x =>
|
||||
{
|
||||
var item_attribute_base = x.Value.getOriginEntityAttribute<ItemAttributeBase>();
|
||||
NullReferenceCheckHelper.throwIfNull(item_attribute_base, () => $"item_attribute_base is null !!! - {parent.toBasicString()}");
|
||||
|
||||
return (item_attribute_base.ItemGuid, item_attribute_base);
|
||||
}).ToDictionary();
|
||||
|
||||
// 3. 동일한 종류의 예약된 Cloned ItemAttributeBase 목록을 얻는다.
|
||||
var found_cloned_item_attributes = new Dictionary<ITEM_GUID, ItemAttributeBase>();
|
||||
var found_transaction_runner = parent.findTransactionRunner(TransactionIdType.PrivateContents);
|
||||
if (null != found_transaction_runner)
|
||||
{
|
||||
var entity_attribute_transactors = found_transaction_runner.getEntityAttributeTransactorAll(parent.onGetAvailableItemAttributeType());
|
||||
found_cloned_item_attributes = entity_attribute_transactors.Where(x =>
|
||||
{
|
||||
var item_attribute_base = x.Value.getClonedEntityAttribute() as ItemAttributeBase;
|
||||
NullReferenceCheckHelper.throwIfNull(item_attribute_base, () => $"item_attribute_base is null !!! - {parent.toBasicString()}");
|
||||
|
||||
if ( item_attribute_base.ItemMetaId == itemMetaId
|
||||
&& item_attribute_base.ItemStackCount >= 0 )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}).Select(x =>
|
||||
{
|
||||
var item_attribute = x.Value.getClonedEntityAttribute() as ItemAttributeBase;
|
||||
NullReferenceCheckHelper.throwIfNull(item_attribute, () => $"item_attribute is null !!! - {parent.toBasicString()}");
|
||||
|
||||
return (item_attribute.ItemGuid, item_attribute);
|
||||
}).ToDictionary();
|
||||
}
|
||||
|
||||
// 4. Cloned 정보가 있거나, Origin 정보만 있는 경우 대상 아이템으로 추가한다 !!!
|
||||
var all_keys = found_origin_item_attributes.Keys.Concat(found_cloned_item_attributes.Keys).Distinct();
|
||||
foreach (var key in all_keys)
|
||||
{
|
||||
// 4.1. Cloned 정보가 있는데, 삭제 대상일 경우는 Origin & Cloned 모두 무시 한다.
|
||||
if(true == found_cloned_item_attributes.TryGetValue(key, out var found_cloned_attribute))
|
||||
{
|
||||
var stack_count = found_cloned_attribute.ItemStackCount;
|
||||
if (0 >= stack_count)
|
||||
{
|
||||
// 4.1.1. Cloned 정보가 삭제 대상일 경우 추가하지 않는다. (삭제될거니까...)
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
// 4.1.2. Cloned 정보의 아이템 개수가 존재 한다면 추가 한다.
|
||||
target_item_attributes.Add(found_cloned_attribute);
|
||||
}
|
||||
}
|
||||
// 4.2. Origin 정보만 있는 경우 추가 한다.
|
||||
else if (found_origin_item_attributes.ContainsKey(key) && false == found_cloned_item_attributes.ContainsKey(key))
|
||||
{
|
||||
var only_origin_item_attribute = found_origin_item_attributes[key];
|
||||
|
||||
target_item_attributes.Add(only_origin_item_attribute);
|
||||
}
|
||||
}
|
||||
|
||||
// 5. 조건에 총족된 대상 아이템들의 StackCount 합산 개수를 얻는다.
|
||||
var item_has_count = target_item_attributes.Sum(x => {
|
||||
return x.ItemStackCount;
|
||||
});
|
||||
|
||||
return (result, target_item_attributes, (UInt16)item_has_count);
|
||||
}
|
||||
|
||||
public EntityBase? findEntityBase(TSlotType toFindEntityBaseKey)
|
||||
{
|
||||
var parent = getDirectParent();
|
||||
NullReferenceCheckHelper.throwIfNull(parent, () => $"parent is null !!!");
|
||||
|
||||
var inven_data = getData();
|
||||
NullReferenceCheckHelper.throwIfNull(inven_data, () => $"inven_data is null !!! - {parent.toBasicString()}");
|
||||
|
||||
var found_entity_base = inven_data.findEntityBaseInSlotType(toFindEntityBaseKey);
|
||||
if (null == found_entity_base)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return found_entity_base;
|
||||
}
|
||||
|
||||
public override void onWriteLog()
|
||||
{
|
||||
var parent = getDirectParent();
|
||||
NullReferenceCheckHelper.throwIfNull(parent, () => $"parent is null !!!");
|
||||
|
||||
var has_items = getHasSlotsWithEntityBases();
|
||||
NullReferenceCheckHelper.throwIfNull(has_items, () => $"has_items is null !!! - {parent.toBasicString()}");
|
||||
|
||||
foreach (var each in has_items)
|
||||
{
|
||||
var slot_type = each.Key;
|
||||
|
||||
META_ID item_meta_id = 0;
|
||||
var item_guid = string.Empty;
|
||||
var item_stack_count = 0;
|
||||
var item_max_stack_count = 0;
|
||||
|
||||
var item_base = each.Value as ItemBase;
|
||||
if (null != item_base)
|
||||
{
|
||||
var item_attibute_base = item_base.getEntityAttribute<ItemAttributeBase>();
|
||||
NullReferenceCheckHelper.throwIfNull(item_attibute_base, () => $"item_attibute_base is null !!!");
|
||||
|
||||
item_meta_id = (META_ID)item_attibute_base.ItemMetaId;
|
||||
item_guid = item_attibute_base.ItemGuid;
|
||||
item_stack_count = item_attibute_base.ItemStackCount;
|
||||
|
||||
if (true == MetaData.Instance._ItemTable.TryGetValue((int)item_meta_id, out var found_item_meta))
|
||||
{
|
||||
item_max_stack_count = found_item_meta.StackMaxCount;
|
||||
}
|
||||
}
|
||||
|
||||
var err_msg = $"SlotType:{slot_type}, ItemMetaId:{item_meta_id}, StackCount:{item_stack_count}, MaxStackCount:{item_max_stack_count}, ItemGuid:{item_guid}";
|
||||
Log.getLogger().info(err_msg);
|
||||
}
|
||||
}
|
||||
|
||||
public ConcurrentDictionary<TSlotType, EntityBase> getHasSlotsWithEntityBases()
|
||||
{
|
||||
var parent = getDirectParent();
|
||||
NullReferenceCheckHelper.throwIfNull(parent, () => $"parent is null !!!");
|
||||
|
||||
var inven_data = getData();
|
||||
NullReferenceCheckHelper.throwIfNull(inven_data, () => $"inven_data is null !!! - {parent.toBasicString()}");
|
||||
|
||||
var slots = inven_data.getSlots() as ConcurrentDictionary<TSlotType, EntityBase>;
|
||||
NullReferenceCheckHelper.throwIfNull(slots, () => $"slots is null !!! - {parent.toBasicString()}");
|
||||
|
||||
return slots;
|
||||
}
|
||||
|
||||
public List<EntityBase> getHasEntityBases()
|
||||
{
|
||||
var parent = getDirectParent();
|
||||
NullReferenceCheckHelper.throwIfNull(parent, () => $"parent is null !!!");
|
||||
|
||||
var inven_data = getData();
|
||||
NullReferenceCheckHelper.throwIfNull(inven_data, () => $"inven_data is null !!! - {parent.toBasicString()}");
|
||||
|
||||
var slots_with_entity_bases = getHasSlotsWithEntityBases();
|
||||
NullReferenceCheckHelper.throwIfNull(slots_with_entity_bases, () => $"slots_with_entity_bases is null !!! - {parent.toBasicString()}");
|
||||
|
||||
return slots_with_entity_bases.Select(x => x.Value).ToList();
|
||||
}
|
||||
|
||||
// IWithInventoryAccessor.clearItemAll()
|
||||
public void clearItemAll()
|
||||
{
|
||||
var parent = getDirectParent();
|
||||
NullReferenceCheckHelper.throwIfNull(parent, () => $"paren is null !!!");
|
||||
var inven_data = getData();
|
||||
NullReferenceCheckHelper.throwIfNull(inven_data, () => $"inven_data is null !!! - {parent.toBasicString()}");
|
||||
|
||||
var slots = inven_data.getSlots() as ConcurrentDictionary<TSlotType, EntityBase>;
|
||||
NullReferenceCheckHelper.throwIfNull(slots, () => $"slots is null !!! - {parent.toBasicString()}");
|
||||
|
||||
slots.Clear();
|
||||
}
|
||||
|
||||
// IWithInventoryAccessor.getHasItemBases()
|
||||
public List<ItemBase> getHasItemBases()
|
||||
{
|
||||
var parent = getDirectParent();
|
||||
NullReferenceCheckHelper.throwIfNull(parent, () => $"parent is null !!!");
|
||||
|
||||
return getHasSlotsWithEntityBases().Select(x =>
|
||||
{
|
||||
var item_base = x.Value as ItemBase;
|
||||
NullReferenceCheckHelper.throwIfNull(item_base, () => $"item_base is null !!! - {parent.toBasicString()}");
|
||||
|
||||
return item_base;
|
||||
|
||||
}).ToList();
|
||||
}
|
||||
|
||||
// IWithInventoryAccessor.tryEquipWithItemBase()
|
||||
public ServerErrorCode tryEquipWithItemBase(string slotType, ItemBase itemBase)
|
||||
{
|
||||
var parent = getDirectParent();
|
||||
NullReferenceCheckHelper.throwIfNull(parent, () => $"parent is null !!!");
|
||||
|
||||
var inven_data = getData();
|
||||
NullReferenceCheckHelper.throwIfNull(inven_data, () => $"inven_data is null !!! - {parent.toBasicString()}");
|
||||
|
||||
var err_msg = string.Empty;
|
||||
|
||||
if(false == slotType.fillupEnumTypeAndValueStringToEnum<TSlotType>("None", out var target_slot_type) || null == target_slot_type)
|
||||
{
|
||||
err_msg = $"Failed to fillupEnumTypeAndValueStringToEnum<TSlotType>() !!!, SlotType of Target Inventory : targetSlotType:{slotType} - {parent.toBasicString()}";
|
||||
Log.getLogger().error(err_msg);
|
||||
|
||||
return ServerErrorCode.StringConvertToEnumFailed;
|
||||
}
|
||||
|
||||
return inven_data.onTryEquipWithEntityBase(target_slot_type, itemBase);
|
||||
}
|
||||
|
||||
// IWithInventoryAccessor.tryUnequipWithItemBase()
|
||||
public ServerErrorCode tryUnequipWithItemBase(string slotType, out ItemBase? itemBase)
|
||||
{
|
||||
itemBase = null;
|
||||
|
||||
var parent = getDirectParent();
|
||||
NullReferenceCheckHelper.throwIfNull(parent, () => $"parent is null !!!");
|
||||
|
||||
var inven_data = getData();
|
||||
NullReferenceCheckHelper.throwIfNull(inven_data, () => $"inven_data is null !!! - {parent.toBasicString()}");
|
||||
|
||||
var err_msg = string.Empty;
|
||||
|
||||
if (false == slotType.fillupEnumTypeAndValueStringToEnum<TSlotType>("None", out var target_slot_type) || null == target_slot_type)
|
||||
{
|
||||
err_msg = $"Failed to fillupEnumTypeAndValueStringToEnum<TSlotType>() !!!, SlotType of Target Inventory : targetSlotType:{slotType} - {parent.toBasicString()}";
|
||||
Log.getLogger().error(err_msg);
|
||||
|
||||
return ServerErrorCode.StringConvertToEnumFailed;
|
||||
}
|
||||
|
||||
var result_code = inven_data.onTryUnequipWithEntityBase(target_slot_type, out EntityBase? entity_base);
|
||||
if (ServerErrorCode.Success == result_code)
|
||||
{
|
||||
itemBase = entity_base as ItemBase;
|
||||
}
|
||||
|
||||
return result_code;
|
||||
}
|
||||
}
|
||||
339
ServerCommon/Entity/Inventory/InventoryRule.cs
Normal file
339
ServerCommon/Entity/Inventory/InventoryRule.cs
Normal file
@@ -0,0 +1,339 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
|
||||
|
||||
using Amazon.Runtime.Internal.Transform;
|
||||
|
||||
|
||||
|
||||
using ServerCore; using ServerBase;
|
||||
|
||||
|
||||
|
||||
using SESSION_ID = System.Int32;
|
||||
using WORLD_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 ServerCommon
|
||||
{
|
||||
public abstract class RuleBase
|
||||
{
|
||||
public HashSet<MetaAssets.EItemLargeType> EquipableItemLargeTypes { get; set; } = new();
|
||||
|
||||
public HashSet<MetaAssets.EItemSmallType> EquipableItemSmallTypes { get; set; } = new();
|
||||
|
||||
public EntityDynamoDbSortKeyType EntitySKType { get; set; } = EntityDynamoDbSortKeyType.None;
|
||||
|
||||
public RuleBase() { }
|
||||
}
|
||||
|
||||
public class BagRule : RuleBase
|
||||
{
|
||||
public InvenBagType InvenBagType { get; set; } = InvenBagType.None;
|
||||
|
||||
public BagTabType UsableBagTabType { get; set; } = BagTabType.None;
|
||||
|
||||
|
||||
public BagRule()
|
||||
{ }
|
||||
}
|
||||
|
||||
public abstract class EquipRuleBase : RuleBase
|
||||
{
|
||||
public InvenEquipType InvenEquipType { get; set; } = InvenEquipType.None;
|
||||
|
||||
public abstract Result onConfigure(InvenEquipType equipType);
|
||||
}
|
||||
|
||||
public class ToolEquipRule : EquipRuleBase
|
||||
{
|
||||
public List<ToolSlotType> UsableToolSlotTypes { get; set; } = new();
|
||||
|
||||
public ToolEquipRule()
|
||||
{ }
|
||||
|
||||
public override Result onConfigure(InvenEquipType equipType)
|
||||
{
|
||||
var result = new Result();
|
||||
var err_msg = string.Empty;
|
||||
|
||||
foreach (var item_large_type in equipType.toEquipableItemLargeTypes())
|
||||
{
|
||||
if (false == EquipableItemLargeTypes.Add(item_large_type))
|
||||
{
|
||||
err_msg = $"Failed to Add() EquipableItemLargeTypes !!!, duplicated EItemLargeType : EItemLargeType:{item_large_type} - InvenEquipType:{equipType}";
|
||||
result.setFail(ServerErrorCode.ToolEquipRuleItemLargeTypeDuplicated, err_msg);
|
||||
Log.getLogger().error(result.toBasicString());
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
UsableToolSlotTypes = equipType.toEquipableToolSlotTypes();
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
public class ClothEquipRule : EquipRuleBase
|
||||
{
|
||||
public Dictionary<ClothSlotType, List<MetaAssets.EItemSmallType>> m_slots_by_cloth_slot_type = new();
|
||||
public Dictionary<MetaAssets.EItemSmallType, List<ClothSlotType>> m_slots_by_item_type = new();
|
||||
|
||||
public ClothEquipRule()
|
||||
{ }
|
||||
|
||||
public override Result onConfigure(InvenEquipType equipType)
|
||||
{
|
||||
var result = new Result();
|
||||
var err_msg = string.Empty;
|
||||
|
||||
foreach (var item_large_type in equipType.toEquipableItemLargeTypes())
|
||||
{
|
||||
if (false == EquipableItemLargeTypes.Add(item_large_type))
|
||||
{
|
||||
err_msg = $"Failed to Add() EquipableItemLargeTypes !!!, duplicated EItemLargeType : EItemLargeType:{item_large_type} - InvenEquipType:{equipType}";
|
||||
result.setFail(ServerErrorCode.ClothEquipRuleItemLargeTypeDuplicated, err_msg);
|
||||
Log.getLogger().error(result.toBasicString());
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
var cloth_slot_types = EnumHelper.getValuesWithoutScopeAll<ClothSlotType>();
|
||||
foreach(var slot_type in cloth_slot_types)
|
||||
{
|
||||
if (false == m_slots_by_cloth_slot_type.TryGetValue(slot_type, out var found_item_small_types))
|
||||
{
|
||||
found_item_small_types = new List<MetaAssets.EItemSmallType>();
|
||||
m_slots_by_cloth_slot_type.Add(slot_type, found_item_small_types);
|
||||
}
|
||||
found_item_small_types = equipType.toEquipableItemSmallTypesWithClothSlotType(slot_type);
|
||||
|
||||
foreach(var item_small_type in found_item_small_types)
|
||||
{
|
||||
if (false == m_slots_by_item_type.TryGetValue(item_small_type, out var found_slot_types))
|
||||
{
|
||||
found_slot_types = new List<ClothSlotType>();
|
||||
m_slots_by_item_type.Add(item_small_type, found_slot_types);
|
||||
}
|
||||
if(false == found_slot_types.Exists(x => x == slot_type))
|
||||
{
|
||||
found_slot_types.Add(slot_type);
|
||||
}
|
||||
|
||||
EquipableItemSmallTypes.Add(item_small_type);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
public class TattooEquipRule : EquipRuleBase
|
||||
{
|
||||
public List<TattooSlotType> UsableTattooSlotPosOfDefault { get; set; } = new();
|
||||
|
||||
public List<TattooSlotType> UsableTattooSlotPosOfUgcNpc { get; set; } = new();
|
||||
|
||||
public TattooEquipRule()
|
||||
{ }
|
||||
|
||||
public override Result onConfigure(InvenEquipType equipType)
|
||||
{
|
||||
var result = new Result();
|
||||
var err_msg = string.Empty;
|
||||
|
||||
foreach (var item_large_type in equipType.toEquipableItemLargeTypes())
|
||||
{
|
||||
if (false == EquipableItemLargeTypes.Add(item_large_type))
|
||||
{
|
||||
err_msg = $"Failed to Add() EquipableItemLargeTypes !!!, duplicated EItemLargeType : EItemLargeType:{item_large_type} - InvenEquipType:{equipType}";
|
||||
result.setFail(ServerErrorCode.TattooEquipRuleItemLargeTypeDuplicated, err_msg);
|
||||
Log.getLogger().error(result.toBasicString());
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
UsableTattooSlotPosOfDefault = equipType.toEquipableTattooSlotTypes();
|
||||
UsableTattooSlotPosOfUgcNpc = equipType.toEquipableTattooSlotTypes(EntityType.UgcNpc);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public List<TattooSlotType> getUsableTattooSlotPos(EntityType entityType)
|
||||
{
|
||||
if( EntityType.UgcNpc == entityType
|
||||
|| EntityType.Beacon == entityType )
|
||||
{
|
||||
return UsableTattooSlotPosOfUgcNpc;
|
||||
}
|
||||
|
||||
return UsableTattooSlotPosOfDefault;
|
||||
}
|
||||
}
|
||||
|
||||
public class InventoryRule : IRule
|
||||
{
|
||||
private readonly Dictionary<InvenBagType, BagRule> m_bag_rules = new();
|
||||
private readonly Dictionary<MetaAssets.EItemLargeType, List<BagRule>> m_bag_rules_by_item_type = new();
|
||||
private readonly Dictionary<InvenEquipType, EquipRuleBase> m_equip_rule_bases = new();
|
||||
private readonly Dictionary<MetaAssets.EItemLargeType, List<EquipRuleBase>> m_equip_rule_bases_by_item_type = new();
|
||||
|
||||
public InventoryRule()
|
||||
{
|
||||
}
|
||||
|
||||
public async Task<Result> onInit()
|
||||
{
|
||||
var result = await configure();
|
||||
if(result.isFail())
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public async Task<Result> configure()
|
||||
{
|
||||
var result = new Result();
|
||||
var err_msg = string.Empty;
|
||||
|
||||
var inven_bag_type_enums = EnumHelper.getValuesWithoutScopeAll<InvenBagType>();
|
||||
foreach(var value in inven_bag_type_enums)
|
||||
{
|
||||
var bag_rule = new BagRule();
|
||||
bag_rule.InvenBagType = value;
|
||||
foreach(var item_type in value.toEquipableItemLargeTypes())
|
||||
{
|
||||
if(false == bag_rule.EquipableItemLargeTypes.Add(item_type))
|
||||
{
|
||||
err_msg = $"Failed to Add() EquipableItemLargeTypes !!!, duplicated EItemLargeType : EItemLargeType:{item_type} - InvenBagType:{value}";
|
||||
result.setFail(ServerErrorCode.BagRuleItemLargeTypeDuplicated, err_msg);
|
||||
Log.getLogger().error(result.toBasicString());
|
||||
return result;
|
||||
}
|
||||
}
|
||||
bag_rule.UsableBagTabType = value.toUsableBagTabType();
|
||||
m_bag_rules.Add(value, bag_rule);
|
||||
}
|
||||
|
||||
var item_type_to_bag_types = EnumHelper.getValuesWithoutScopeAll<MetaAssets.EItemLargeType>();
|
||||
foreach (var item_type in item_type_to_bag_types)
|
||||
{
|
||||
foreach(var eache in m_bag_rules)
|
||||
{
|
||||
if(false == eache.Value.EquipableItemLargeTypes.Contains(item_type))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if(false == m_bag_rules_by_item_type.TryGetValue(item_type, out var found_bag_rules))
|
||||
{
|
||||
found_bag_rules = new List<BagRule>();
|
||||
m_bag_rules_by_item_type.Add(item_type, found_bag_rules);
|
||||
}
|
||||
found_bag_rules.Add(eache.Value);
|
||||
}
|
||||
}
|
||||
|
||||
var inven_equip_type_enums = EnumHelper.getValuesWithoutScopeAll<InvenEquipType>();
|
||||
foreach (var value in inven_equip_type_enums)
|
||||
{
|
||||
var equip_rule_base = newEquipRuleBaseByInvenEquipType(value);
|
||||
if (equip_rule_base == null)
|
||||
continue;
|
||||
|
||||
equip_rule_base.InvenEquipType = value;
|
||||
result = equip_rule_base.onConfigure(value);
|
||||
if(result.isFail())
|
||||
{
|
||||
return result;
|
||||
}
|
||||
equip_rule_base.EntitySKType = value.toEntitySKType();
|
||||
m_equip_rule_bases.Add(value, equip_rule_base);
|
||||
}
|
||||
|
||||
var item_type_to_equip_types = EnumHelper.getValuesWithoutScopeAll<MetaAssets.EItemLargeType>();
|
||||
foreach (var item_type in item_type_to_equip_types)
|
||||
{
|
||||
foreach (var eache in m_equip_rule_bases)
|
||||
{
|
||||
if (false == eache.Value.EquipableItemLargeTypes.Contains(item_type))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (false == m_equip_rule_bases_by_item_type.TryGetValue(item_type, out var found_equip_rule_bases))
|
||||
{
|
||||
found_equip_rule_bases = new List<EquipRuleBase>();
|
||||
m_equip_rule_bases_by_item_type.Add(item_type, found_equip_rule_bases);
|
||||
}
|
||||
found_equip_rule_bases.Add(eache.Value);
|
||||
}
|
||||
}
|
||||
|
||||
return await Task.FromResult(result);
|
||||
}
|
||||
|
||||
public EquipRuleBase? newEquipRuleBaseByInvenEquipType(InvenEquipType equipType)
|
||||
{
|
||||
switch(equipType)
|
||||
{
|
||||
case InvenEquipType.Tool:
|
||||
return new ToolEquipRule();
|
||||
|
||||
case InvenEquipType.Cloth:
|
||||
return new ClothEquipRule();
|
||||
|
||||
case InvenEquipType.Tattoo:
|
||||
return new TattooEquipRule();
|
||||
|
||||
default:
|
||||
var err_msg = $"Failed to newEquipRuleBaseByInvenEquipType() !!!, Invalid InvenEquipType : InvenEquipType:{equipType}";
|
||||
Log.getLogger().error(err_msg);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public BagRule? getBagRuleByInvenBagType(InvenBagType bagType)
|
||||
{
|
||||
m_bag_rules.TryGetValue(bagType, out var found_bag_rules);
|
||||
return found_bag_rules;
|
||||
}
|
||||
|
||||
public EquipRuleBase? getEquipRuleBaseByInvenEquipType(InvenEquipType equipType)
|
||||
{
|
||||
m_equip_rule_bases.TryGetValue(equipType, out var found_equip_rule_bases);
|
||||
return found_equip_rule_bases;
|
||||
}
|
||||
|
||||
public List<BagRule>? getBagRulesByItemLargeType(MetaAssets.EItemLargeType itemType)
|
||||
{
|
||||
m_bag_rules_by_item_type.TryGetValue(itemType, out var found_bag_rules);
|
||||
return found_bag_rules;
|
||||
}
|
||||
|
||||
public List<EquipRuleBase>? getEquipRuleBasesByItemLargeType(MetaAssets.EItemLargeType itemType)
|
||||
{
|
||||
m_equip_rule_bases_by_item_type.TryGetValue(itemType, out var found_equip_rule_bases);
|
||||
return found_equip_rule_bases;
|
||||
}
|
||||
|
||||
public Dictionary<InvenBagType, BagRule> getBagRules() => m_bag_rules;
|
||||
|
||||
public Dictionary<InvenEquipType, EquipRuleBase> getEquipRuleBases() => m_equip_rule_bases;
|
||||
}
|
||||
}
|
||||
207
ServerCommon/Entity/Inventory/SlotBase.cs
Normal file
207
ServerCommon/Entity/Inventory/SlotBase.cs
Normal file
@@ -0,0 +1,207 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
|
||||
using Axion.Collections.Concurrent;
|
||||
|
||||
|
||||
using ServerCore; using ServerBase;
|
||||
|
||||
|
||||
using SESSION_ID = System.Int32;
|
||||
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 ServerCommon
|
||||
{
|
||||
public abstract class SlotsBase
|
||||
{
|
||||
private AtomicInt32 m_slot_max_count = new(0);
|
||||
|
||||
public virtual bool onInitSlots(int slotMaxCount)
|
||||
{
|
||||
m_slot_max_count.set(slotMaxCount);
|
||||
return true;
|
||||
}
|
||||
|
||||
public abstract UInt32 onGetCurrSlotCount();
|
||||
|
||||
public UInt32 getSlotMaxCount()
|
||||
{
|
||||
return (UInt32)m_slot_max_count.Value;
|
||||
}
|
||||
|
||||
public virtual string toBasicString()
|
||||
{
|
||||
return $"{this.getTypeName()}, UsingSlotCount:{onGetCurrSlotCount()}, SlotMaxCount:{m_slot_max_count.Value}";
|
||||
}
|
||||
}
|
||||
|
||||
public class Slots<TSlotType> : SlotsBase, ISlotsWithType<TSlotType>
|
||||
where TSlotType : Enum
|
||||
{
|
||||
private ConcurrentHashSet<TSlotType> m_slots = new();
|
||||
|
||||
public Slots()
|
||||
{ }
|
||||
|
||||
public override bool onInitSlots(int slotMaxCount)
|
||||
{
|
||||
m_slots = new ConcurrentHashSet<TSlotType>(MultiThreadHelper.getThreadOptimalCount(), (int)slotMaxCount);
|
||||
return true;
|
||||
}
|
||||
|
||||
public virtual ServerErrorCode onIsEquipable(TSlotType targetSlot)
|
||||
{
|
||||
return (false == m_slots.Contains(targetSlot)) ? ServerErrorCode.Success : ServerErrorCode.SlotsAlreadyEquiped;
|
||||
}
|
||||
|
||||
public virtual ServerErrorCode onTryEquip(TSlotType targetSlot)
|
||||
{
|
||||
return (true == m_slots.TryAdd(targetSlot, out _)) ? ServerErrorCode.Success : ServerErrorCode.SlotsAlreadyEquiped;
|
||||
}
|
||||
|
||||
public virtual ServerErrorCode onIsUnequipable(TSlotType targetSlot)
|
||||
{
|
||||
return (true == m_slots.Contains(targetSlot)) ? ServerErrorCode.Success : ServerErrorCode.SlotsAlreadyUnequiped;
|
||||
}
|
||||
|
||||
public virtual ServerErrorCode onTryUnequip(TSlotType targetSlot)
|
||||
{
|
||||
return (true == m_slots.TryRemove(targetSlot, out _)) ? ServerErrorCode.Success : ServerErrorCode.SlotsAlreadyUnequiped;
|
||||
}
|
||||
|
||||
public virtual ServerErrorCode onTryEquipWithEntityBase(TSlotType targetSlot, EntityBase entityBase) => ServerErrorCode.FunctionNotImplemented;
|
||||
|
||||
public virtual ServerErrorCode onTryUnequipWithEntityBase(TSlotType targetSlot, out EntityBase? entityBase)
|
||||
{
|
||||
entityBase = null;
|
||||
return ServerErrorCode.FunctionNotImplemented;
|
||||
}
|
||||
|
||||
public virtual EntityBase? onFindEntityBase(TSlotType targetSlot)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public bool isExistSlotType(TSlotType slotType)
|
||||
{
|
||||
return true == m_slots.Contains(slotType);
|
||||
}
|
||||
|
||||
public override UInt32 onGetCurrSlotCount()
|
||||
{
|
||||
return (UInt32)m_slots.Count;
|
||||
}
|
||||
|
||||
public List<EntityBase> getEntityBases()
|
||||
{
|
||||
return new List<EntityBase>();
|
||||
}
|
||||
|
||||
public ICollection getSlots() => m_slots;
|
||||
}
|
||||
|
||||
public class SlotsWithEntityBase<TSlotType> : SlotsBase, ISlotsWithType<TSlotType>
|
||||
where TSlotType : notnull
|
||||
{
|
||||
private ConcurrentDictionary<TSlotType, EntityBase> m_slots = new();
|
||||
|
||||
public SlotsWithEntityBase()
|
||||
{
|
||||
}
|
||||
|
||||
public override bool onInitSlots(int slotMaxCount)
|
||||
{
|
||||
m_slots = new ConcurrentDictionary<TSlotType, EntityBase>(MultiThreadHelper.getThreadOptimalCount(), (int)slotMaxCount);
|
||||
return true;
|
||||
}
|
||||
|
||||
public virtual ServerErrorCode onIsEquipable(TSlotType targetSlot)
|
||||
{
|
||||
return (false == m_slots.ContainsKey(targetSlot)) ? ServerErrorCode.Success : ServerErrorCode.SlotsAlreadyEquiped;
|
||||
}
|
||||
|
||||
public virtual ServerErrorCode onTryEquipWithEntityBase(TSlotType targetSlot, EntityBase entityBase)
|
||||
{
|
||||
return (true == m_slots.TryAdd(targetSlot, entityBase)) ? ServerErrorCode.Success : ServerErrorCode.SlotsAlreadyEquiped;
|
||||
}
|
||||
|
||||
public virtual ServerErrorCode onIsUnequipable(TSlotType targetSlot)
|
||||
{
|
||||
return (true == m_slots.ContainsKey(targetSlot)) ? ServerErrorCode.Success : ServerErrorCode.SlotsAlreadyUnequiped;
|
||||
}
|
||||
|
||||
public virtual ServerErrorCode onTryUnequipWithEntityBase(TSlotType targetSlot, out EntityBase? removedEntityBase)
|
||||
{
|
||||
removedEntityBase = null;
|
||||
if (false == m_slots.TryRemove(targetSlot, out var removed_entity_base))
|
||||
{
|
||||
return ServerErrorCode.SlotsAlreadyUnequiped;
|
||||
}
|
||||
removedEntityBase = removed_entity_base;
|
||||
|
||||
return ServerErrorCode.Success;
|
||||
}
|
||||
|
||||
public virtual EntityBase? onFindEntityBase(TSlotType targetSlot)
|
||||
{
|
||||
return findEntityBaseInSlotType(targetSlot);
|
||||
}
|
||||
|
||||
public EntityBase? findEntityBaseInSlotType(TSlotType targetSlot)
|
||||
{
|
||||
if(false == m_slots.TryGetValue(targetSlot, out var found_entity_base))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
return found_entity_base;
|
||||
}
|
||||
|
||||
public EntityBase? findEntityBaseBy(Func<EntityBase, bool> isFound)
|
||||
{
|
||||
foreach(var each in m_slots)
|
||||
{
|
||||
var is_success = isFound(each.Value);
|
||||
if(true == is_success)
|
||||
{
|
||||
return each.Value;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public bool isExistSlotType(TSlotType slotType)
|
||||
{
|
||||
return true == m_slots.ContainsKey(slotType);
|
||||
}
|
||||
|
||||
public override UInt32 onGetCurrSlotCount()
|
||||
{
|
||||
return (UInt32)m_slots.Count;
|
||||
}
|
||||
|
||||
public List<EntityBase> getEntityBases()
|
||||
{
|
||||
return m_slots.Values.ToList();
|
||||
}
|
||||
|
||||
public ICollection getSlots() => m_slots;
|
||||
|
||||
public virtual ServerErrorCode onTryEquip(TSlotType targetSlot) => ServerErrorCode.FunctionNotImplemented;
|
||||
|
||||
public virtual ServerErrorCode onTryUnequip(TSlotType targetSlot) => ServerErrorCode.FunctionNotImplemented;
|
||||
}
|
||||
}
|
||||
266
ServerCommon/Entity/Inventory/SlotsWrapper.cs
Normal file
266
ServerCommon/Entity/Inventory/SlotsWrapper.cs
Normal file
@@ -0,0 +1,266 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
|
||||
using Pipelines.Sockets.Unofficial.Buffers;
|
||||
|
||||
|
||||
using ServerCore; using ServerBase;
|
||||
|
||||
|
||||
using SESSION_ID = System.Int32;
|
||||
using WORLD_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 ServerCommon
|
||||
{
|
||||
public abstract partial class SlotsWrapperBase<TSlots> : EntityBase
|
||||
where TSlots : ISlots, new()
|
||||
{
|
||||
private readonly TSlots m_slots;
|
||||
|
||||
public SlotsWrapperBase(EntityType entityType, EntityBase parent)
|
||||
: base(entityType, parent)
|
||||
{
|
||||
m_slots = new TSlots();
|
||||
}
|
||||
|
||||
public virtual bool onInitSlots(int slotMaxCount)
|
||||
{
|
||||
return m_slots.onInitSlots(slotMaxCount);
|
||||
}
|
||||
|
||||
public Result tryIsEquipableOrEquip<TSlotType>(TSlotType targetSlotType)
|
||||
where TSlotType : Enum
|
||||
{
|
||||
var result = new Result();
|
||||
var err_msg = string.Empty;
|
||||
|
||||
var direct_parent = getDirectParent();
|
||||
ArgumentNullException.ThrowIfNull(direct_parent, $"direct_parent is null !!!");
|
||||
|
||||
var slots = getData() as ISlotsWithType<TSlotType>;
|
||||
ArgumentNullException.ThrowIfNull(slots, $"slots is null !!! - {direct_parent.toBasicString()}");
|
||||
|
||||
var parent = getRootParent();
|
||||
if (null != parent)
|
||||
{
|
||||
// Transaction 활성화 상태일 경우
|
||||
var transaction_runner = parent.findTransactionRunner(TransactionIdType.PrivateContents);
|
||||
if (null != transaction_runner)
|
||||
{
|
||||
var slot_type = targetSlotType.ToString();
|
||||
var to_check_slot_type = slot_type;
|
||||
if (true == EnumHelper.isEnumType(to_check_slot_type))
|
||||
{
|
||||
slot_type = to_check_slot_type.convertEnumToEnumTypeAndValueString();
|
||||
}
|
||||
|
||||
// 장착 슬롯에 슬롯과 EntityBase를 장착 해제 예약 한다.
|
||||
result = transaction_runner.tryEquipToReserveSlot(direct_parent, getEntityType(), slot_type);
|
||||
if (result.isFail())
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
err_msg = $"Succss tryEquipToReserveSlot() : targetSlotType:{slot_type} - {toBasicString()}, {parent.toBasicString()}";
|
||||
Log.getLogger().info(err_msg);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
var error_code = slots.onTryEquip(targetSlotType);
|
||||
if (error_code.isFail())
|
||||
{
|
||||
err_msg = $"Failed to onTryEquip() !!! : targetSlotType:{targetSlotType} - {toBasicString()}, {parent?.toBasicString()}";
|
||||
result.setFail(error_code, err_msg);
|
||||
return result;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public Result tryIsEquipableOrEquipWithEntityBase<TSlotType>(TSlotType targetSlotType, EntityBase entityBase)
|
||||
where TSlotType : notnull
|
||||
{
|
||||
var result = new Result();
|
||||
var err_msg = string.Empty;
|
||||
|
||||
var direct_parent = getDirectParent();
|
||||
ArgumentNullException.ThrowIfNull(direct_parent, $"direct_parent is null !!!");
|
||||
|
||||
var slots = getData() as ISlotsWithType<TSlotType>;
|
||||
ArgumentNullException.ThrowIfNull(slots, $"slots is null !!! - {direct_parent.toBasicString()}");
|
||||
|
||||
var parent = getRootParent();
|
||||
if (null != parent)
|
||||
{
|
||||
// Transaction 활성화 상태일 경우
|
||||
var transaction_runner = parent.findTransactionRunner(TransactionIdType.PrivateContents);
|
||||
if (null != transaction_runner)
|
||||
{
|
||||
var slot_type = targetSlotType.ToString();
|
||||
NullReferenceCheckHelper.throwIfNull(slot_type, () => $"slot_type is null !!!");
|
||||
var to_check_slot_type = slot_type;
|
||||
NullReferenceCheckHelper.throwIfNull(to_check_slot_type, () => $"to_check_slot_type is null !!!");
|
||||
|
||||
if (true == EnumHelper.isEnumType(to_check_slot_type))
|
||||
{
|
||||
slot_type = to_check_slot_type.convertEnumToEnumTypeAndValueString();
|
||||
}
|
||||
|
||||
// 장착 슬롯에 슬롯과 EntityBase를 장착 예약 한다.
|
||||
result = transaction_runner.tryEquipToReserveSlotWithEntityBase(direct_parent, getEntityType(), slot_type, entityBase);
|
||||
if (result.isFail())
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
err_msg = $"Succss tryEquipToReserveSlotWithEntityBase() : targetSlotType:{slot_type} - {toBasicString()}, {parent.toBasicString()}";
|
||||
Log.getLogger().info(err_msg);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
var error_code = slots.onTryEquipWithEntityBase(targetSlotType, entityBase);
|
||||
if (error_code.isFail())
|
||||
{
|
||||
err_msg = $"Failed to onTryEquipWithEntityBase() !!! : {error_code.toBasicString()}, targetSlotType:{targetSlotType}, {entityBase.toBasicString()} - {toBasicString()}, {parent?.toBasicString()}";
|
||||
result.setFail(error_code, err_msg);
|
||||
return result;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public Result tryUnequipableOrUnequip<TSlotType>(TSlotType targetSlotType)
|
||||
where TSlotType : Enum
|
||||
{
|
||||
var result = new Result();
|
||||
var err_msg = string.Empty;
|
||||
|
||||
var direct_parent = getDirectParent();
|
||||
ArgumentNullException.ThrowIfNull(direct_parent, $"direct_parent is null !!!");
|
||||
|
||||
var slots = getData() as ISlotsWithType<TSlotType>;
|
||||
ArgumentNullException.ThrowIfNull(slots, $"slots is null !!! - {direct_parent.toBasicString()}");
|
||||
|
||||
var parent = getRootParent();
|
||||
if (null != parent)
|
||||
{
|
||||
// Transaction 활성화 상태일 경우
|
||||
var transaction_runner = parent.findTransactionRunner(TransactionIdType.PrivateContents);
|
||||
if (null != transaction_runner)
|
||||
{
|
||||
var slot_type = targetSlotType.ToString();
|
||||
var to_check_slot_type = slot_type;
|
||||
if (true == EnumHelper.isEnumType(to_check_slot_type))
|
||||
{
|
||||
slot_type = to_check_slot_type.convertEnumToEnumTypeAndValueString();
|
||||
}
|
||||
|
||||
// 장착 슬롯에 슬롯과 EntityBase를 장착 해제 예약 한다.
|
||||
result = transaction_runner.tryUnequipToReserveSlot(direct_parent, getEntityType(), slot_type);
|
||||
if (result.isFail())
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
err_msg = $"Success tryUnequipToReserveSlot() : targetSlotType:{slot_type} - {toBasicString()}, {parent.toBasicString()}";
|
||||
Log.getLogger().info(err_msg);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
var error_code = slots.onTryUnequip(targetSlotType);
|
||||
if (error_code.isFail())
|
||||
{
|
||||
err_msg = $"Failed to onTryUnequip() !!! : targetSlotType:{targetSlotType} - {toBasicString()}, {parent?.toBasicString()}";
|
||||
result.setFail(error_code, err_msg);
|
||||
return result;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public Result tryUnequipableOrUnequipWithEntityBase<TSlotType>(TSlotType targetSlotType, out EntityBase? unequipedEntityBase)
|
||||
where TSlotType : notnull
|
||||
{
|
||||
unequipedEntityBase = null;
|
||||
|
||||
var result = new Result();
|
||||
var err_msg = string.Empty;
|
||||
|
||||
var direct_parent = getDirectParent();
|
||||
ArgumentNullException.ThrowIfNull(direct_parent, $"direct_parent is null !!!");
|
||||
|
||||
var slots = getData() as ISlotsWithType<TSlotType>;
|
||||
ArgumentNullException.ThrowIfNull(slots, $"slots is null !!! - {direct_parent.toBasicString()}");
|
||||
|
||||
var parent = getRootParent();
|
||||
if (null != parent)
|
||||
{
|
||||
// Transaction 활성화 상태일 경우
|
||||
var transaction_runner = parent.findTransactionRunner(TransactionIdType.PrivateContents);
|
||||
if (null != transaction_runner)
|
||||
{
|
||||
var slot_type = targetSlotType.ToString();
|
||||
NullReferenceCheckHelper.throwIfNull(slot_type, () => $"slot_type is null !!!");
|
||||
var to_check_slot_type = slot_type;
|
||||
NullReferenceCheckHelper.throwIfNull(to_check_slot_type, () => $"to_check_slot_type is null !!!");
|
||||
|
||||
if (true == EnumHelper.isEnumType(to_check_slot_type))
|
||||
{
|
||||
slot_type = to_check_slot_type.convertEnumToEnumTypeAndValueString();
|
||||
}
|
||||
|
||||
// 장착 슬롯에 슬롯과 EntityBase를 장착 해제 예약 한다.
|
||||
result = transaction_runner.tryUnequipToReserveSlotWithEntityBase(direct_parent, getEntityType(), slot_type, slots.onFindEntityBase(targetSlotType));
|
||||
if (result.isFail())
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
err_msg = $"Success tryUnequipToReserveSlotWithEntityBase() : targetSlotType:{slot_type} - {toBasicString()}, {parent.toBasicString()}";
|
||||
Log.getLogger().info(err_msg);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
var error_code = slots.onTryUnequipWithEntityBase(targetSlotType, out var unequiped_entity_base);
|
||||
if (error_code.isFail())
|
||||
{
|
||||
err_msg = $"Failed to onTryUnequipWithEntityBase() !!! : {error_code.toBasicString()}, targetSlotType:{targetSlotType} - {toBasicString()}, {parent?.toBasicString()}";
|
||||
result.setFail(error_code, err_msg);
|
||||
return result;
|
||||
}
|
||||
|
||||
unequipedEntityBase = unequiped_entity_base;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public virtual void onWriteLog()
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
public TSlots getData() => m_slots;
|
||||
|
||||
public override string toBasicString()
|
||||
{
|
||||
return $"{this.getTypeName()}, {m_slots.toBasicString()}";
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user