This commit is contained in:
CortexCore
2024-03-31 23:31:00 +08:00
parent e179d2eb53
commit b7b89ee71a
641 changed files with 31286 additions and 22134 deletions

View File

@@ -1,6 +1,7 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using UnityEngine;
using BITKit;
using BITKit.SubSystems;
@@ -9,14 +10,16 @@ namespace BITKit.Entities
{
public interface IDamageType { }
public interface IDamageService
{
public event Action<DamageMessage> OnEntityDamaged;
public event Action<DamageMessage> OnEntityKilled;
void Execute(DamageMessage damageMessage);
}
public struct MeleeDamageMessage:IDamageType{}
public struct MeleeDamageMessage : IDamageType
{
public bool Bleeding;
}
public struct BulletDamageMessage:IDamageType{}
[Serializable]
public class DamageServiceSingleton:IDamageService
@@ -71,6 +74,34 @@ namespace BITKit.Entities
public Vector3 Position;
public Quaternion Rotation;
public IDamageType DamageType;
public RaycastHit? RaycastHit;
}
public sealed class DamageMessageNetMessageWriter : NetMessageReader<DamageMessage>
{
public override DamageMessage ReadBinary(BinaryReader reader)
{
UnityEntitiesService.TryGetEntity(reader.ReadUInt64(),out var initiator);
UnityEntitiesService.TryGetEntity(reader.ReadUInt64(),out var target);
return new DamageMessage()
{
Initiator = initiator as Entity,
Target = target as Entity,
RawDamage = reader.ReadBoolean(),
Damage = reader.ReadInt32(),
Position = reader.ReadFloat3(),
Rotation = reader.ReadQuaternion(),
};
}
public override void WriteBinary(BinaryWriter writer, DamageMessage value)
{
writer.Write(value.Initiator?.Id ?? 0);
writer.Write(value.Target?.Id ?? 0);
writer.Write(value.RawDamage);
writer.Write(value.Damage);
writer.WriteFloat3(value.Position);
writer.WriteQuaternion(value.Rotation);
}
}
public interface IDamageCallback
@@ -79,35 +110,65 @@ namespace BITKit.Entities
}
public interface IDamagable
{
IHealth Health { get; }
IUnityEntity UnityEntity { get; }
Rigidbody Rigidbody { get; }
void GiveDamage(DamageMessage message);
}
public class DamageService:MonoBehaviour,IDamageService
{
internal static IDamageService Singleton { get; set; }
public static IDamageService Singleton { get;private set; }
private readonly Queue<DamageMessage> Messages = new();
[SerializeReference,SubclassSelector] private INetClient netClient;
[SerializeReference,SubclassSelector] private INetServer netServer;
private INetProvider netClientProvider => netClient.Source as INetProvider;
private INetProvider netServerProvider => netServer.Source as INetProvider;
private void Awake()
{
Singleton = this;
}
private void Start()
{
netClientProvider.AddCommandListener<DamageMessage>(ExecuteInternal);
}
private void FixedUpdate()
{
if (!netServer.IsRunningServer && netClient.IsConnected) return;
while (Messages.TryDequeue(out var damageMessage))
{
var unityEntity = (Entity)damageMessage.Target;
if (!unityEntity || !unityEntity.TryGetComponent<IHealth>(out var heal) || !heal.IsAlive) continue;
damageMessage.Initiator?.Invoke(damageMessage);
damageMessage.Target?.Invoke(damageMessage);
ExecuteInternal(damageMessage);
netServerProvider?.AllClientCommand(damageMessage);
}
}
private void ExecuteInternal(DamageMessage damageMessage)
{
IHealth heal = null;
if (damageMessage.Target?.TryGetComponent<IHealth>(out heal) is false)
{
return;
}
damageMessage.Initiator?.Invoke(damageMessage);
damageMessage.Target?.Invoke(damageMessage);
if (heal!.IsAlive)
{
OnEntityDamaged?.Invoke(damageMessage);
if (heal.IsAlive is false)
{
OnEntityKilled?.Invoke(damageMessage);
}
}
else
{
OnEntityKilled?.Invoke(damageMessage);
}
}

View File

@@ -1,6 +1,7 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.Remoting.Contexts;
using UnityEngine;
@@ -20,21 +21,34 @@ namespace BITKit.Entities
/// <summary>
/// 当受到伤害时的回调
/// </summary>
public event Func<DamageMessage,int,int> OnDamageFactory;
public event Func<DamageMessage,int,int> OnDamageFactory;
/// <summary>
/// 收到伤害时的回调
/// </summary>
public event Action<DamageMessage> OnDamageRelease;
/// <summary>
/// 当伤害被阻止时的回调
/// </summary>
public event Action<DamageMessage> OnDamageVoid;
int HealthPoint { get; set; }
int MaxHealthPoint { get; set; }
bool IsAlive { get; }
}
[CustomType(typeof(IHealth))]
public class EntityHealth : EntityBehavior, IHealth
public class EntityHealth : EntityBehavior, IHealth,IEntityBinaryComponent
{
[Header(Constant.Header.Settings)]
[SerializeField] private int healthPoint = 100;
[SerializeField] private int maxHealthPoint = 100;
public int Id { get; } = 84946486;
public event Action<int> OnSetHealthPoint;
public event Action<bool> OnSetAlive;
public event Func<DamageMessage,int, int> OnDamageFactory;
public event Action<DamageMessage> OnDamageRelease;
public event Action<DamageMessage> OnDamageVoid;
public int HealthPoint
{
@@ -61,7 +75,7 @@ namespace BITKit.Entities
private void OnHealthPointChangedInternal(int old, int newHP)
{
healthPoint = newHP;
healthPoint =Mathf.Clamp(newHP,-1,maxHealthPoint) ;
var _isAlive = newHP >= 0;
if (_isAlive != IsAlive)
{
@@ -84,15 +98,28 @@ namespace BITKit.Entities
private void OnGetDamage(DamageMessage damageMessage)
{
if (damageMessage.Target != UnityEntity) return;
if (IsAlive is false) return;
var damage = damageMessage.Damage;
foreach (var x in OnDamageFactory.CastAsFunc().Reverse())
if (IsAlive is false)
{
damage = x.Invoke(damageMessage, damage);
if (damage <= 0) break;
OnDamageVoid?.Invoke(damageMessage);
}
else
{
var damage = damageMessage.Damage;
foreach (var x in OnDamageFactory.CastAsFunc())
{
damage = x.Invoke(damageMessage, damage);
if (damage <= 0)
{
OnDamageVoid?.Invoke(damageMessage);
break;
}
}
if (Data.Get<bool>("god") is false)
AddHP(-damage);
damageMessage.Damage = damage;
OnDamageRelease?.Invoke(damageMessage);
}
if (Data.Get<bool>("god") is false)
AddHP(-damage);
}
#if UNITY_EDITOR
[BIT]
@@ -109,6 +136,17 @@ namespace BITKit.Entities
OnHealthPointChangedInternal(100, -1);
}
#endif
public void Serialize(BinaryWriter writer)
{
writer.Write(HealthPoint);
}
public void Deserialize(BinaryReader reader)
{
var newHealthPoint = reader.ReadInt32();
if (HealthPoint != newHealthPoint)
HealthPoint = newHealthPoint;
}
}
}