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
201 lines
6.8 KiB
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();
|
|
}
|
|
}
|
|
}
|
|
}
|