초기커밋
This commit is contained in:
258
GameServer/Entity/Player/Action/AbilityAction.cs
Normal file
258
GameServer/Entity/Player/Action/AbilityAction.cs
Normal file
@@ -0,0 +1,258 @@
|
||||
using MetaAssets;
|
||||
using Microsoft.IdentityModel.Tokens;
|
||||
using ServerCommon;
|
||||
using ServerCore; using ServerBase;
|
||||
|
||||
namespace GameServer
|
||||
{
|
||||
public class AbilityAction : EntityActionBase
|
||||
{
|
||||
private Dictionary<AttributeType, int> m_abilities { get; set; } = new();
|
||||
|
||||
public AbilityAction(EntityBase owner)
|
||||
: base(owner)
|
||||
{
|
||||
}
|
||||
|
||||
public override async Task<Result> onInit()
|
||||
{
|
||||
await Task.CompletedTask;
|
||||
|
||||
var result = new Result();
|
||||
|
||||
clearAbility();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public override void onClear()
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
public void clearAbility()
|
||||
{
|
||||
foreach (var ability in EnumHelper.getValuesWithoutScope<AttributeType>())
|
||||
{
|
||||
m_abilities[ability] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
public int? getAbility(AttributeType abilityId) => m_abilities.TryGetValue(abilityId, out var ability) ? ability : null;
|
||||
|
||||
public Dictionary<AttributeType, int> getAbilities() => m_abilities;
|
||||
|
||||
public async Task<Result> forceResetAll()
|
||||
{
|
||||
clearAbility();
|
||||
|
||||
var owner = getOwner();
|
||||
NullReferenceCheckHelper.throwIfNull(owner, () => $"owner is null !!! - {toBasicString()}");
|
||||
|
||||
|
||||
var inventory_action_base = owner.getEntityAction<InventoryActionBase>();
|
||||
NullReferenceCheckHelper.throwIfNull(inventory_action_base, () => $"inventory_action_base is null !!! - {owner.toBasicString()}");
|
||||
|
||||
var result = await inventory_action_base.tryResetAttributeByTattoo();
|
||||
if(result.isFail())
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
var buff_action = owner.getEntityAction<BuffAction>();
|
||||
NullReferenceCheckHelper.throwIfNull(buff_action, () => $"buff_action is null !!! - {owner.toBasicString()}");
|
||||
result = await buff_action.tryResetAttributeByBuff();
|
||||
if (result.isFail())
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public void forceSetAbilityAll(int toSetAbility)
|
||||
{
|
||||
var owner = getOwner();
|
||||
NullReferenceCheckHelper.throwIfNull(owner, () => $"owner is null !!! - {toBasicString()}");
|
||||
|
||||
var attribute_types = EnumHelper.getValuesWithoutScopeAll<AttributeType>();
|
||||
foreach (var attribute_type in attribute_types)
|
||||
{
|
||||
m_abilities[attribute_type] = toSetAbility;
|
||||
}
|
||||
}
|
||||
|
||||
public void setAbility(AttributeType abilityId, int ability, bool decrease)
|
||||
{
|
||||
var change_value = decrease ? ability * -1 : ability;
|
||||
m_abilities[abilityId] += change_value;
|
||||
}
|
||||
|
||||
public async Task<Result> setAbilities(ItemBase item, Int16 level, bool decrease)
|
||||
{
|
||||
ArgumentNullReferenceCheckHelper.throwIfNull(item, () => $"item is null !!! - {toBasicString()}");
|
||||
|
||||
await Task.CompletedTask;
|
||||
|
||||
var result = new Result();
|
||||
string err_msg;
|
||||
|
||||
var item_attribute = item.getEntityAttribute<ItemAttributeBase>();
|
||||
NullReferenceCheckHelper.throwIfNull(item_attribute, () => $"item_attribute is null !!! - {toBasicString()}");
|
||||
|
||||
var item_meta = item.getItemMeta();
|
||||
NullReferenceCheckHelper.throwIfNull(item_meta, () => $"item_meta is null !!! - {toBasicString()}");
|
||||
var enchant = getEnchantData(level, item_meta);
|
||||
if (null == enchant)
|
||||
{
|
||||
err_msg = $"Fail to get enchant data : {nameof(getEnchantData)}";
|
||||
result.setFail(ServerErrorCode.ItemEnchantNotFoundInMeta, err_msg);
|
||||
Log.getLogger().error(err_msg);
|
||||
return result;
|
||||
}
|
||||
|
||||
// 배열의 위치를 AttributeType으로 활용하다보니 불필요한 예외 처리 코드를 작성해야 한다. !!!
|
||||
// Key-Value 구조로 바꾸고 싶지만... 간단한 수정 범위는 아니다.
|
||||
// MetaHelper를 통해 메타 데이터를 가공하는 방법도 있다.... - kangms
|
||||
for(var i = 0; i < enchant.Count; i++)
|
||||
{
|
||||
if (false == EnumHelper.isDefined<AttributeType>(item_attribute.Attributes[i]))
|
||||
{
|
||||
Log.getLogger().warn($"Invalid Ability Enum Type : {item_attribute.Attributes[i]}");
|
||||
continue;
|
||||
}
|
||||
|
||||
if (item_attribute.Attributes.Count <= i)
|
||||
{
|
||||
Log.getLogger().warn($"Ability Type outof range !!! : enchantIndex:{i} > itemAttributeIndex:{i}");
|
||||
item_attribute.Attributes.Add(0);
|
||||
}
|
||||
|
||||
setAbility((AttributeType)item_attribute.Attributes[i], enchant[i], decrease);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public async Task<Result> changeAbilities(ItemBase item, Dictionary<int, int> slotWithAttributeIds, bool decrease)
|
||||
{
|
||||
await Task.CompletedTask;
|
||||
|
||||
var owner = getOwner();
|
||||
NullReferenceCheckHelper.throwIfNull(owner, () => $"owner is null !!!");
|
||||
|
||||
ArgumentNullReferenceCheckHelper.throwIfNull(item, () => $"item is null !!! - {owner.toBasicString()}");
|
||||
ArgumentNullReferenceCheckHelper.throwIfNull(slotWithAttributeIds, () => $"slotWithAttributeIds is null !!! - {owner.toBasicString()}");
|
||||
|
||||
var result = new Result();
|
||||
string err_msg;
|
||||
|
||||
var item_attribute = item.getEntityAttribute<ItemAttributeBase>();
|
||||
NullReferenceCheckHelper.throwIfNull(item_attribute, () => $"item_attribute is null !!! - {owner.toBasicString()}");
|
||||
|
||||
var item_meta = item.getItemMeta();
|
||||
NullReferenceCheckHelper.throwIfNull(item_meta, () => $"item_meta is null !!! - {owner.toBasicString()}");
|
||||
var enchant = getEnchantData(item_attribute.Level, item_meta);
|
||||
if (null == enchant)
|
||||
{
|
||||
err_msg = $"Fail to get enchant data : {nameof(getEnchantData)}";
|
||||
result.setFail(ServerErrorCode.ItemEnchantNotFoundInMeta, err_msg);
|
||||
Log.getLogger().error(err_msg);
|
||||
return result;
|
||||
}
|
||||
|
||||
foreach (var each in slotWithAttributeIds)
|
||||
{
|
||||
if (false == EnumHelper.isDefined<AttributeType>(each.Value))
|
||||
{
|
||||
Log.getLogger().warn($"Invalid Ability Enum Type : {each.Value}");
|
||||
continue;
|
||||
}
|
||||
|
||||
// 배열의 위치를 AttributeType으로 활용하다보니 불필요한 예외 처리 코드를 작성해야 한다. !!!
|
||||
// Key-Value 구조로 바꾸고 싶지만... MetaHelper를 통해 메타 데이터를 가공하는 방법도 있다.... - kangms
|
||||
if (each.Key >= enchant.Count)
|
||||
{
|
||||
Log.getLogger().warn($"Ability Type outof range !!! : enchantCount:{enchant.Count} > slotWithAttributeIndex:{each.Key}");
|
||||
continue;
|
||||
}
|
||||
|
||||
setAbility((AttributeType)each.Value, enchant[each.Key], decrease);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public Result hasAbilities(Dictionary<string, Int32> toCheckAbilities)
|
||||
{
|
||||
var owner = getOwner();
|
||||
NullReferenceCheckHelper.throwIfNull(owner, () => $"owner is null !!! - {toBasicString()}");
|
||||
ArgumentNullReferenceCheckHelper.throwIfNull(toCheckAbilities, () => $"toCheckAbilities is null !!! - {owner.toBasicString()}");
|
||||
|
||||
var result = new Result();
|
||||
var err_msg = string.Empty;
|
||||
|
||||
var ability_action = owner.getEntityAction<AbilityAction>();
|
||||
NullReferenceCheckHelper.throwIfNull(ability_action, () => $"ability_action is null !!! - {toBasicString()}");
|
||||
|
||||
foreach (var each in toCheckAbilities)
|
||||
{
|
||||
var ability_name = each.Key;
|
||||
var ability_value = each.Value;
|
||||
|
||||
if (false == EnumHelper.tryParse<AttributeType>(ability_name, out var attribute_type))
|
||||
{
|
||||
err_msg = $"Invalid Ability Enum Type : {attribute_type} - {owner.toBasicString()}";
|
||||
result.setFail(ServerErrorCode.ServerTypeInvalid, err_msg);
|
||||
Log.getLogger().error(err_msg);
|
||||
return result;
|
||||
}
|
||||
|
||||
var curr_value = ability_action.getAbility(attribute_type);
|
||||
if (curr_value == null)
|
||||
{
|
||||
err_msg = $"Invalid Ability Enum Type : {attribute_type} - {owner.toBasicString()}";
|
||||
result.setFail(ServerErrorCode.ServerTypeInvalid, err_msg);
|
||||
Log.getLogger().error(err_msg);
|
||||
return result;
|
||||
}
|
||||
|
||||
if (curr_value < ability_value)
|
||||
{
|
||||
err_msg = $"Not enough Ability !!! : AbilityName:{attribute_type}, currValue:{curr_value} >= reqValue:{ability_value} - {getOwner().toBasicString()}";
|
||||
result.setFail(ServerErrorCode.AbilityNotEnough, err_msg);
|
||||
Log.getLogger().info(err_msg);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private IReadOnlyList<int>? getEnchantData(int level, MetaAssets.ItemMetaData item)
|
||||
{
|
||||
ArgumentNullReferenceCheckHelper.throwIfNull(item, () => $"item is null !!! - {toBasicString()}");
|
||||
|
||||
if (false == MetaData.Instance._ItemLevelEnchantMetaTable.TryGetValue(level, out var enchant_by_level))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
var enchant = enchant_by_level.GetConsumeItem(item.Rarity);
|
||||
return enchant?.AttributeValues;
|
||||
}
|
||||
|
||||
public AbilityInfo toAbilityInfo()
|
||||
{
|
||||
var owner = getOwner();
|
||||
NullReferenceCheckHelper.throwIfNull(owner, () => $"owner is null !!!");
|
||||
|
||||
var ability_info = new AbilityInfo();
|
||||
foreach(var each in m_abilities)
|
||||
{
|
||||
ability_info.Values.Add((Int16)each.Key, each.Value);
|
||||
}
|
||||
|
||||
return ability_info;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user