You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

201 lines
6.8 KiB

1 month ago
using System.Collections.Generic;
using System.Runtime.CompilerServices;
using Entitas;
using xFrame;
using Proto;
using Sog;
namespace CoreGame.Render
{
public struct Modifer
{
public Fixed64 val;
public int def;
}
public delegate void OnPropertyChange(PropertyDef def, float dt, float val);
// PropertyContainer 是 PropertyComponent 的友元类
public partial class PropertyContainer {
[Combat]
public class PropertyComponent : IComponent, IReset
{
public CombatEntity ent;
public PropertyContainer container;
private readonly Dictionary<PropertyDef, List<OnPropertyChange>> m_PostChange = new();
private readonly Dictionary<int, Modifer> m_Modifiers = new();
public void SetLinkProperty(PropertyDef def)
{
container.SetLinkProperty(def, true);
}
public void SetLinkEid(int eid)
{
container.m_Eid = eid;
}
public void RegisterPostChange(PropertyDef propertyDef, OnPropertyChange onPostChange)
{
if (m_PostChange.TryGetValue(propertyDef, out var acts) == false)
{
acts = ListPool<OnPropertyChange>.Pop();
m_PostChange.Add(propertyDef, acts);
return;
}
acts.Add(onPostChange);
}
public void SetProperty(PropertyDef propertyDef, Fixed64 baseVal, bool force = false)
{
if (container.m_Properties[(int)propertyDef] != 0)
{
if (force == false)
{
XLog.LogWarning($"PropertyDef {propertyDef} has been set");
return;
}
}
container.m_Properties[(int)propertyDef] = baseVal;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void SetProperty_TenThousand(in PropertyDef propertyDef, long val, bool force = false)
{
if (container.m_Properties[(int)propertyDef] != 0)
{
if (force == false)
{
XLog.LogWarning($"PropertyDef {propertyDef} has been set");
return;
}
}
container.m_Properties[(int)propertyDef] = val * Fixed64.EN4;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public Fixed64 GetProperty(in PropertyDef propertyDef)
{
return container.GetProperty(propertyDef);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public long GetProperty_Long(in PropertyDef propertyDef)
{
return container.GetProperty_Long(propertyDef);
}
//没有modifyid的话,是isntant的,无法撤销
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void Rest(PropertyDef propertyDef)
{
container.m_Properties[(int)propertyDef] = 0;
}
//没有modifyid的话,是isntant的,无法撤销
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void AddValue(PropertyDef propertyDef, Fixed64 value)
{
PushModifer(propertyDef, value, 0);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void PushModifer_TenThousand(PropertyDef propertyDef, long value, int modifyId)
{
PushModifer(propertyDef, value * Fixed64.EN4, modifyId);
}
//没有modifyid的话,是isntant的,无法撤销
//[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void PushModifer(PropertyDef propertyDef, Fixed64 value, int modifyId)
{
if (modifyId == 0)
{
BattleLogger.LogInfoByEntity(ent, $"PushModifer [{propertyDef}] = [{value}] modifyId:{modifyId}");
container.AddProperty(propertyDef, value);
return;
}
if (m_Modifiers.TryGetValue(modifyId, out var modifer))
{
if (modifer.def == (int)propertyDef)
{
container.AddProperty(propertyDef, -modifer.val);
m_Modifiers.Remove(modifyId);
}
}
modifer = new Modifer
{
val = value,
def = (int)propertyDef
};
m_Modifiers.Add(modifyId, modifer);
BattleLogger.LogInfoByEntity(ent, $"PushModifer [{propertyDef}] = [{modifer.val}] modifyId:{modifyId}");
container.AddProperty(propertyDef, modifer.val);
}
//没有modifyid的话,是isntant的,无法撤销
//[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void PopModifer(PropertyDef propertyDef, int modifyId, bool nocheck = false)
{
if (m_Modifiers.TryGetValue(modifyId, out var modifer))
{
if (modifer.def == (int)propertyDef)
{
BattleLogger.LogInfoByEntity(ent, $"PopModifer [{propertyDef}] = [{modifer.val}] modifyId:{modifyId}");
container.AddProperty(propertyDef, -modifer.val);
m_Modifiers.Remove(modifyId);
}
else
{
BattleLogger.LogInfoByEntity(ent,$"RevertModifer failed, modifyId:{modifyId} propertyDef:{propertyDef}");
}
}
else
{
if (nocheck == false)
BattleLogger.LogInfoByEntity(ent,$"RevertModifer failed, modifyId:{modifyId} propertyDef:{propertyDef}");
}
}
public void TaskSnapShot(PropertyContainer cont)
{
for (int i = 0; i < container.m_Properties.Length; i++)
{
if (container.m_PropIsLink[i])
{
cont.m_Properties[i] = container.GetProperty((PropertyDef)i);
}
else
{
cont.m_Properties[i] = container.m_Properties[i];
}
}
}
public bool HasModifer()
{
return m_Modifiers.Count > 0;
}
#region 计算属性_中间属性
public Fixed64 Atk => container.Atk;
public Fixed64 MoveSpeed => container.MoveSpeed;
public Fixed64 PickupRange => container.PickupRange;
public long TotalHp => container.TotalHp;
#endregion
public void Reset()
{
foreach (var value in m_PostChange)
{
var onPropertyChanges = value.Value;
ListPool<OnPropertyChange>.Push(ref onPropertyChanges);
}
m_PostChange.Clear();
SptPool<PropertyContainer>.Free(ref container);
m_Modifiers.Clear();
}
}
}
}