From 1a067a35632258f2b153f213b5eec6574c6c4690 Mon Sep 17 00:00:00 2001 From: Bragin Stepan Date: Thu, 19 Feb 2026 23:40:03 +0500 Subject: [PATCH] feat: add feature damage --- .../Gameplay/Entities/EntitiesFactory.cs | 10 ++- .../Gameplay/Entities/Generated/EntityAPI.cs | 67 +++++++++++++++++++ .../Logic/Gameplay/Features/Damage.meta | 3 + .../Features/Damage/ApplyDamageSystem.cs | 49 ++++++++++++++ .../Features/Damage/ApplyDamageSystem.cs.meta | 3 + .../Features/Damage/DamageComponents.cs | 12 ++++ .../Features/Damage/DamageComponents.cs.meta | 3 + 7 files changed, 146 insertions(+), 1 deletion(-) create mode 100644 Assets/_Project/Develop/Runtime/Logic/Gameplay/Features/Damage.meta create mode 100644 Assets/_Project/Develop/Runtime/Logic/Gameplay/Features/Damage/ApplyDamageSystem.cs create mode 100644 Assets/_Project/Develop/Runtime/Logic/Gameplay/Features/Damage/ApplyDamageSystem.cs.meta create mode 100644 Assets/_Project/Develop/Runtime/Logic/Gameplay/Features/Damage/DamageComponents.cs create mode 100644 Assets/_Project/Develop/Runtime/Logic/Gameplay/Features/Damage/DamageComponents.cs.meta diff --git a/Assets/_Project/Develop/Runtime/Logic/Gameplay/Entities/EntitiesFactory.cs b/Assets/_Project/Develop/Runtime/Logic/Gameplay/Entities/EntitiesFactory.cs index 05ecb92..30f6d3b 100644 --- a/Assets/_Project/Develop/Runtime/Logic/Gameplay/Entities/EntitiesFactory.cs +++ b/Assets/_Project/Develop/Runtime/Logic/Gameplay/Entities/EntitiesFactory.cs @@ -1,4 +1,5 @@ -using _Project.Develop.Runtime.Logic.Gameplay.Features.Lifetime.Systems; +using _Project.Develop.Runtime.Logic.Gameplay.Features.Damage; +using _Project.Develop.Runtime.Logic.Gameplay.Features.Lifetime.Systems; using _Project.Develop.Runtime.Logic.Gameplay.Features.Movement; using _Project.Develop.Runtime.Utilities.Conditions; using _Project.Develop.Runtime.Utils.InputManagement; @@ -35,6 +36,8 @@ namespace _Project.Develop.Runtime.Entities .AddRotationSpeed(new ReactiveVariable(800)) .AddMaxHealth(new ReactiveVariable(150)) .AddCurrentHealth(new ReactiveVariable(150)) + .AddTakeDamageRequest() + .AddTakeDamageEvent() .AddIsDead() .AddIsMoving() .AddInDeathProcess() @@ -53,14 +56,19 @@ namespace _Project.Develop.Runtime.Entities ICompositeCondition mustSelfRelease = new CompositeCondition() .Add(new FuncCondition(() => entity.IsDead.Value)) .Add(new FuncCondition(() => entity.InDeathProcess.Value == false)); + + ICompositeCondition canApplyDamage = new CompositeCondition() + .Add(new FuncCondition(() => entity.IsDead.Value == false)); entity .AddCanMove(canMove) .AddCanRotate(canRotate) + .AddCanApplyDamage(canApplyDamage) .AddMustDie(mustDie) .AddMustSelfRelease(mustSelfRelease); entity + .AddSystem(new ApplyDamageSystem()) .AddSystem(new RigidbodyMovementSystem()) .AddSystem(new RigidbodyRotationSystem()) .AddSystem(new MoveDirectionByInputSystem(_playerInput)) diff --git a/Assets/_Project/Develop/Runtime/Logic/Gameplay/Entities/Generated/EntityAPI.cs b/Assets/_Project/Develop/Runtime/Logic/Gameplay/Entities/Generated/EntityAPI.cs index 0299f9c..a46df27 100644 --- a/Assets/_Project/Develop/Runtime/Logic/Gameplay/Entities/Generated/EntityAPI.cs +++ b/Assets/_Project/Develop/Runtime/Logic/Gameplay/Entities/Generated/EntityAPI.cs @@ -461,5 +461,72 @@ namespace _Project.Develop.Runtime.Entities return AddComponent(new _Project.Develop.Runtime.Logic.Gameplay.Features.Movement.CanJump() {Value = value}); } + public _Project.Develop.Runtime.Logic.Gameplay.Features.Damage.TakeDamageRequest TakeDamageRequestC => GetComponent<_Project.Develop.Runtime.Logic.Gameplay.Features.Damage.TakeDamageRequest>(); + + public _Project.Develop.Runtime.Utils.ReactiveManagement.Event.ReactiveEvent TakeDamageRequest => TakeDamageRequestC.Value; + + public bool TryGetTakeDamageRequest(out _Project.Develop.Runtime.Utils.ReactiveManagement.Event.ReactiveEvent value) + { + bool result = TryGetComponent(out _Project.Develop.Runtime.Logic.Gameplay.Features.Damage.TakeDamageRequest component); + if(result) + value = component.Value; + else + value = default(_Project.Develop.Runtime.Utils.ReactiveManagement.Event.ReactiveEvent); + return result; + } + + public _Project.Develop.Runtime.Entities.Entity AddTakeDamageRequest() + { + return AddComponent(new _Project.Develop.Runtime.Logic.Gameplay.Features.Damage.TakeDamageRequest() { Value = new _Project.Develop.Runtime.Utils.ReactiveManagement.Event.ReactiveEvent() }); + } + + public _Project.Develop.Runtime.Entities.Entity AddTakeDamageRequest(_Project.Develop.Runtime.Utils.ReactiveManagement.Event.ReactiveEvent value) + { + return AddComponent(new _Project.Develop.Runtime.Logic.Gameplay.Features.Damage.TakeDamageRequest() {Value = value}); + } + + public _Project.Develop.Runtime.Logic.Gameplay.Features.Damage.TakeDamageEvent TakeDamageEventC => GetComponent<_Project.Develop.Runtime.Logic.Gameplay.Features.Damage.TakeDamageEvent>(); + + public _Project.Develop.Runtime.Utils.ReactiveManagement.Event.ReactiveEvent TakeDamageEvent => TakeDamageEventC.Value; + + public bool TryGetTakeDamageEvent(out _Project.Develop.Runtime.Utils.ReactiveManagement.Event.ReactiveEvent value) + { + bool result = TryGetComponent(out _Project.Develop.Runtime.Logic.Gameplay.Features.Damage.TakeDamageEvent component); + if(result) + value = component.Value; + else + value = default(_Project.Develop.Runtime.Utils.ReactiveManagement.Event.ReactiveEvent); + return result; + } + + public _Project.Develop.Runtime.Entities.Entity AddTakeDamageEvent() + { + return AddComponent(new _Project.Develop.Runtime.Logic.Gameplay.Features.Damage.TakeDamageEvent() { Value = new _Project.Develop.Runtime.Utils.ReactiveManagement.Event.ReactiveEvent() }); + } + + public _Project.Develop.Runtime.Entities.Entity AddTakeDamageEvent(_Project.Develop.Runtime.Utils.ReactiveManagement.Event.ReactiveEvent value) + { + return AddComponent(new _Project.Develop.Runtime.Logic.Gameplay.Features.Damage.TakeDamageEvent() {Value = value}); + } + + public _Project.Develop.Runtime.Logic.Gameplay.Features.Damage.CanApplyDamage CanApplyDamageC => GetComponent<_Project.Develop.Runtime.Logic.Gameplay.Features.Damage.CanApplyDamage>(); + + public _Project.Develop.Runtime.Utilities.Conditions.ICompositeCondition CanApplyDamage => CanApplyDamageC.Value; + + public bool TryGetCanApplyDamage(out _Project.Develop.Runtime.Utilities.Conditions.ICompositeCondition value) + { + bool result = TryGetComponent(out _Project.Develop.Runtime.Logic.Gameplay.Features.Damage.CanApplyDamage component); + if(result) + value = component.Value; + else + value = default(_Project.Develop.Runtime.Utilities.Conditions.ICompositeCondition); + return result; + } + + public _Project.Develop.Runtime.Entities.Entity AddCanApplyDamage(_Project.Develop.Runtime.Utilities.Conditions.ICompositeCondition value) + { + return AddComponent(new _Project.Develop.Runtime.Logic.Gameplay.Features.Damage.CanApplyDamage() {Value = value}); + } + } } diff --git a/Assets/_Project/Develop/Runtime/Logic/Gameplay/Features/Damage.meta b/Assets/_Project/Develop/Runtime/Logic/Gameplay/Features/Damage.meta new file mode 100644 index 0000000..7e0b947 --- /dev/null +++ b/Assets/_Project/Develop/Runtime/Logic/Gameplay/Features/Damage.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: b87bc393428846e3b37bf463760253c1 +timeCreated: 1771525636 \ No newline at end of file diff --git a/Assets/_Project/Develop/Runtime/Logic/Gameplay/Features/Damage/ApplyDamageSystem.cs b/Assets/_Project/Develop/Runtime/Logic/Gameplay/Features/Damage/ApplyDamageSystem.cs new file mode 100644 index 0000000..7ab87ac --- /dev/null +++ b/Assets/_Project/Develop/Runtime/Logic/Gameplay/Features/Damage/ApplyDamageSystem.cs @@ -0,0 +1,49 @@ +using System; +using _Project.Develop.Runtime.Entities; +using _Project.Develop.Runtime.Utilities.Conditions; +using _Project.Develop.Runtime.Utils.ReactiveManagement; +using _Project.Develop.Runtime.Utils.ReactiveManagement.Event; + +namespace _Project.Develop.Runtime.Logic.Gameplay.Features.Damage +{ + public class ApplyDamageSystem : IInitializableSystem, IDisposableSystem + { + private ReactiveEvent _damageRequest; + private ReactiveEvent _damageEvent; + + private ReactiveVariable _health; + + private ICompositeCondition _canApplyDamage; + + private IDisposable _requestDisposable; + + public void OnInit(Entity entity) + { + _damageRequest = entity.TakeDamageRequest; + _damageEvent = entity.TakeDamageEvent; + + _health = entity.CurrentHealth; + + _canApplyDamage = entity.CanApplyDamage; + + _requestDisposable = _damageRequest.Subscribe(OnDamageRequest); + } + + public void OnDispose() + { + _requestDisposable.Dispose(); + } + + private void OnDamageRequest(float damage) + { + if (damage < 0) + throw new ArgumentOutOfRangeException(nameof(damage)); + + if (_canApplyDamage.Evaluate() == false) + return; + + _health.Value = MathF.Max(_health.Value - damage, 0); + _damageEvent.Invoke(damage); + } + } +} \ No newline at end of file diff --git a/Assets/_Project/Develop/Runtime/Logic/Gameplay/Features/Damage/ApplyDamageSystem.cs.meta b/Assets/_Project/Develop/Runtime/Logic/Gameplay/Features/Damage/ApplyDamageSystem.cs.meta new file mode 100644 index 0000000..4e897a2 --- /dev/null +++ b/Assets/_Project/Develop/Runtime/Logic/Gameplay/Features/Damage/ApplyDamageSystem.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: bd8ccd1d58fe484d933c61c5c640fff3 +timeCreated: 1771525914 \ No newline at end of file diff --git a/Assets/_Project/Develop/Runtime/Logic/Gameplay/Features/Damage/DamageComponents.cs b/Assets/_Project/Develop/Runtime/Logic/Gameplay/Features/Damage/DamageComponents.cs new file mode 100644 index 0000000..a7d1644 --- /dev/null +++ b/Assets/_Project/Develop/Runtime/Logic/Gameplay/Features/Damage/DamageComponents.cs @@ -0,0 +1,12 @@ +using _Project.Develop.Runtime.Entities; +using _Project.Develop.Runtime.Utilities.Conditions; +using _Project.Develop.Runtime.Utils.ReactiveManagement.Event; + +namespace _Project.Develop.Runtime.Logic.Gameplay.Features.Damage +{ + public class TakeDamageRequest : IEntityComponent { public ReactiveEvent Value; } + + public class TakeDamageEvent : IEntityComponent { public ReactiveEvent Value; } + + public class CanApplyDamage : IEntityComponent { public ICompositeCondition Value; } +} \ No newline at end of file diff --git a/Assets/_Project/Develop/Runtime/Logic/Gameplay/Features/Damage/DamageComponents.cs.meta b/Assets/_Project/Develop/Runtime/Logic/Gameplay/Features/Damage/DamageComponents.cs.meta new file mode 100644 index 0000000..efe6c76 --- /dev/null +++ b/Assets/_Project/Develop/Runtime/Logic/Gameplay/Features/Damage/DamageComponents.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 79d8679b310c457bb73f676d4aaef890 +timeCreated: 1771525646 \ No newline at end of file