new effect system
This commit is contained in:
parent
f3a6f7a05a
commit
22b02c4590
11 changed files with 146 additions and 89 deletions
|
|
@ -1,9 +1,9 @@
|
|||
[gd_resource type="Resource" load_steps=2 format=3 uid="uid://dsg1vjx76ifgu"]
|
||||
[gd_resource type="Resource" script_class="RandomRedirectEffect" load_steps=2 format=3 uid="uid://dsg1vjx76ifgu"]
|
||||
|
||||
[ext_resource type="Script" uid="uid://bb6lv1djnqjaw" path="res://scripts/systems/effects/RandomRedirectEffect.cs" id="1_rfumy"]
|
||||
|
||||
[resource]
|
||||
script = ExtResource("1_rfumy")
|
||||
tilesWalked = 0.2
|
||||
Duration = 1.0
|
||||
Duration = 3.0
|
||||
Slot = "garlic"
|
||||
|
|
|
|||
|
|
@ -1,9 +1,18 @@
|
|||
[gd_scene load_steps=5 format=3 uid="uid://b2hrv0aqbui7u"]
|
||||
[gd_scene load_steps=7 format=3 uid="uid://b2hrv0aqbui7u"]
|
||||
|
||||
[ext_resource type="Script" uid="uid://dxlwvwy3hj56x" path="res://scripts/projectiles/LinearProjectile.cs" id="1_3kc4s"]
|
||||
[ext_resource type="Texture2D" uid="uid://dq0mul65hevtt" path="res://assets/sprites/plants/pea.tres" id="2_26q5x"]
|
||||
[ext_resource type="Script" uid="uid://bb6lv1djnqjaw" path="res://scripts/systems/effects/RandomRedirectEffect.cs" id="2_fwj1o"]
|
||||
[ext_resource type="PackedScene" uid="uid://1d33w4ubtury" path="res://scenes/particles/pea_particles.tscn" id="2_osqrk"]
|
||||
|
||||
[sub_resource type="Resource" id="Resource_22ej5"]
|
||||
script = ExtResource("2_fwj1o")
|
||||
tilesWalked = 0.2
|
||||
travelTime = 0.2
|
||||
Duration = 0.3
|
||||
Slot = "testra"
|
||||
metadata/_custom_type_script = "uid://bb6lv1djnqjaw"
|
||||
|
||||
[sub_resource type="CircleShape2D" id="CircleShape2D_ix1sk"]
|
||||
radius = 6.0
|
||||
|
||||
|
|
@ -13,6 +22,7 @@ collision_mask = 8
|
|||
script = ExtResource("1_3kc4s")
|
||||
_speed = 3.0
|
||||
_damage = 10
|
||||
_impactEffect = SubResource("Resource_22ej5")
|
||||
particles = ExtResource("2_osqrk")
|
||||
|
||||
[node name="Sprite" type="Sprite2D" parent="."]
|
||||
|
|
|
|||
|
|
@ -1,9 +1,14 @@
|
|||
using Godot;
|
||||
|
||||
namespace Newlon;
|
||||
|
||||
public static class LON
|
||||
{
|
||||
public static float Pr(string path)
|
||||
public static void ForceFinishTween(Tween tween)
|
||||
{
|
||||
return 0;
|
||||
if (tween == null) return;
|
||||
|
||||
tween.Pause();
|
||||
tween.CustomStep(Mathf.Inf);
|
||||
}
|
||||
}
|
||||
|
|
@ -113,8 +113,7 @@ public partial class Entity : Node2D
|
|||
#region Effects
|
||||
[Export] private Array<Effect> _effectImmunities = new();
|
||||
[Export] private bool completeInvulnerability = false;
|
||||
private readonly Dictionary<string, Effect> _activeEffectSlots = new();
|
||||
private readonly Dictionary<string, Timer> _effectSlotTimers = new();
|
||||
private readonly Dictionary<string, EffectHandler> effectHandlers = new();
|
||||
|
||||
[Signal] public delegate void EffectStartedEventHandler(Effect what);
|
||||
[Signal] public delegate void EffectEndedEventHandler(Effect what);
|
||||
|
|
@ -123,50 +122,25 @@ public partial class Entity : Node2D
|
|||
|
||||
public virtual void GiveEffect(Effect what)
|
||||
{
|
||||
if (Killed) return;
|
||||
if (_effectImmunities.Contains(what) || completeInvulnerability)
|
||||
{
|
||||
if (what == null ||
|
||||
Killed ||
|
||||
completeInvulnerability || _effectImmunities.Contains(what))
|
||||
return;
|
||||
}
|
||||
|
||||
string slot = what.Slot;
|
||||
if (_activeEffectSlots.ContainsKey(slot) == false)
|
||||
{
|
||||
var slot = what.Slot;
|
||||
if (effectHandlers.ContainsKey(slot) == false)
|
||||
InitSlot(slot);
|
||||
}
|
||||
|
||||
if (what == _activeEffectSlots[slot])
|
||||
if (effectHandlers[slot].HandledEffect == what)
|
||||
{
|
||||
EmitSignal(SignalName.EffectContinued, what);
|
||||
effectHandlers[slot].Restart();
|
||||
}
|
||||
else
|
||||
{
|
||||
EmitSignal(SignalName.EffectStarted, what);
|
||||
effectHandlers[slot].HandledEffect = what;
|
||||
effectHandlers[slot].Start();
|
||||
}
|
||||
|
||||
if (_activeEffectSlots[slot] != null)
|
||||
{
|
||||
_effectSlotTimers[slot].Stop();
|
||||
_activeEffectSlots[slot].Exit(this);
|
||||
}
|
||||
_effectSlotTimers[slot].WaitTime = what.Duration;
|
||||
_effectSlotTimers[slot].Start();
|
||||
|
||||
what.Enter(this);
|
||||
_activeEffectSlots[slot] = what;
|
||||
|
||||
}
|
||||
|
||||
private void InitSlot(string key)
|
||||
{
|
||||
_activeEffectSlots.Add(key, null);
|
||||
|
||||
var timer = new Timer() { Autostart = false, OneShot = true };
|
||||
AddChild(timer);
|
||||
timer.Timeout += () => { EndEffectAtSlot(key); };
|
||||
|
||||
_effectSlotTimers.Add(key, timer);
|
||||
|
||||
}
|
||||
|
||||
public void EndEffect(Effect what)
|
||||
|
|
@ -174,34 +148,48 @@ public partial class Entity : Node2D
|
|||
EndEffectAtSlot(what.Slot);
|
||||
}
|
||||
|
||||
public Tween CreateTweenEffect(Effect effect)
|
||||
{
|
||||
Tween tween = CreateTween();
|
||||
|
||||
effectHandlers[effect.Slot].EffectTween = tween;
|
||||
|
||||
return tween;
|
||||
}
|
||||
|
||||
protected void ClearEffects()
|
||||
{
|
||||
foreach (var slot in _activeEffectSlots.Keys)
|
||||
foreach (var slot in effectHandlers.Keys)
|
||||
{
|
||||
if (_activeEffectSlots[slot] != null)
|
||||
{
|
||||
_activeEffectSlots[slot].Exit(this);
|
||||
_effectSlotTimers[slot].Stop();
|
||||
_activeEffectSlots[slot] = null;
|
||||
effectHandlers[slot].End();
|
||||
}
|
||||
}
|
||||
private void InitSlot(string key)
|
||||
{
|
||||
effectHandlers.Add(key, new EffectHandler());
|
||||
effectHandlers[key].handler = this;
|
||||
effectHandlers[key].EffectTimer = new();
|
||||
|
||||
AddChild(effectHandlers[key].EffectTimer);
|
||||
effectHandlers[key].EffectTimer.Name = key + "Timer";
|
||||
|
||||
effectHandlers[key].EffectTimer.Timeout += () => { EndEffectAtSlot(key); };
|
||||
}
|
||||
|
||||
public void ProcessEffects()
|
||||
{
|
||||
if (Killed) return;
|
||||
foreach (string key in _activeEffectSlots.Keys)
|
||||
_activeEffectSlots[key]?.Process(this);
|
||||
foreach (var slot in effectHandlers.Keys)
|
||||
{
|
||||
effectHandlers[slot].Process();
|
||||
}
|
||||
}
|
||||
|
||||
private void EndEffectAtSlot(string slot)
|
||||
{
|
||||
_activeEffectSlots[slot].Exit(this);
|
||||
_activeEffectSlots[slot] = null;
|
||||
|
||||
EmitSignal(SignalName.EffectEnded, _activeEffectSlots[slot]);
|
||||
|
||||
EmitSignal(SignalName.EffectEnded, effectHandlers[slot].HandledEffect);
|
||||
effectHandlers[slot].End();
|
||||
}
|
||||
|
||||
#endregion
|
||||
#region LocalTimescale
|
||||
private float _localTimescale = 1.0f;
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
using Godot;
|
||||
using Newlon.Components;
|
||||
|
||||
namespace Newlon.Systems.Effects;
|
||||
|
||||
|
|
@ -7,7 +8,12 @@ public abstract partial class Effect : Resource
|
|||
{
|
||||
[Export] public float Duration;
|
||||
[Export] public string Slot;
|
||||
public abstract void Enter(Node target);
|
||||
public abstract void Process(Node target);
|
||||
public abstract void Exit(Node target);
|
||||
public abstract void Enter(Entity target);
|
||||
public abstract void Process(Entity target);
|
||||
public abstract void Exit(Entity target);
|
||||
|
||||
private Tween CreateTween(Entity fromEntity)
|
||||
{
|
||||
return fromEntity.CreateTweenEffect(this);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
48
scripts/systems/effects/EffectHandler.cs
Normal file
48
scripts/systems/effects/EffectHandler.cs
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
using Godot;
|
||||
using Newlon.Components;
|
||||
|
||||
namespace Newlon.Systems.Effects;
|
||||
|
||||
public partial class EffectHandler : RefCounted
|
||||
{
|
||||
public Entity handler;
|
||||
public Effect HandledEffect;
|
||||
public Timer EffectTimer;
|
||||
public Tween EffectTween;
|
||||
|
||||
public void Start()
|
||||
{
|
||||
EffectTimer.WaitTime = HandledEffect.Duration;
|
||||
EffectTimer.Start();
|
||||
|
||||
HandledEffect.Enter(handler);
|
||||
}
|
||||
public void End()
|
||||
{
|
||||
HandledEffect.Exit(handler);
|
||||
HandledEffect = null;
|
||||
EffectTimer.Stop();
|
||||
if (EffectTween != null)
|
||||
{
|
||||
LON.ForceFinishTween(EffectTween);
|
||||
EffectTween.Kill();
|
||||
}
|
||||
}
|
||||
public void Process()
|
||||
{
|
||||
HandledEffect.Process(handler);
|
||||
}
|
||||
public void Restart()
|
||||
{
|
||||
HandledEffect.Exit(handler);
|
||||
EffectTimer.Stop();
|
||||
if (EffectTween != null)
|
||||
{
|
||||
LON.ForceFinishTween(EffectTween);
|
||||
EffectTween.Kill();
|
||||
}
|
||||
|
||||
HandledEffect.Enter(handler);
|
||||
EffectTimer.Start();
|
||||
}
|
||||
}
|
||||
1
scripts/systems/effects/EffectHandler.cs.uid
Normal file
1
scripts/systems/effects/EffectHandler.cs.uid
Normal file
|
|
@ -0,0 +1 @@
|
|||
uid://csxb8rllqjb1t
|
||||
|
|
@ -8,19 +8,16 @@ public partial class PermanentSpeedEffect : Effect
|
|||
{
|
||||
[Export] public float Multiplier;
|
||||
|
||||
public override void Enter(Node target)
|
||||
public override void Enter(Entity target)
|
||||
{
|
||||
if (target is Entity entity)
|
||||
{
|
||||
entity.LocalTimescale *= Multiplier;
|
||||
}
|
||||
target.LocalTimescale *= Multiplier;
|
||||
}
|
||||
|
||||
public override void Exit(Node target)
|
||||
public override void Exit(Entity target)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Process(Node target)
|
||||
public override void Process(Entity target)
|
||||
{
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
using Godot;
|
||||
using Newlon.Components;
|
||||
using Newlon.Components.Zombies;
|
||||
|
||||
namespace Newlon.Systems.Effects;
|
||||
|
|
@ -7,9 +8,10 @@ namespace Newlon.Systems.Effects;
|
|||
public partial class RandomRedirectEffect : Effect
|
||||
{
|
||||
[Export] private float tilesWalked = 0.2f;
|
||||
[Export] private float travelTime = 1;
|
||||
RandomNumberGenerator RandomNumberGenerator;
|
||||
|
||||
public override void Enter(Node target)
|
||||
public override void Enter(Entity target)
|
||||
{
|
||||
if (RandomNumberGenerator == null)
|
||||
{
|
||||
|
|
@ -19,9 +21,14 @@ public partial class RandomRedirectEffect : Effect
|
|||
if (target is RuntimeZombieData zombieData)
|
||||
zombieData.AbleToEat = false;
|
||||
//Animation call
|
||||
Animation(target);
|
||||
}
|
||||
|
||||
public override void Exit(Node target)
|
||||
public override void Exit(Entity target)
|
||||
{
|
||||
|
||||
}
|
||||
private void Animation(Entity target)
|
||||
{
|
||||
if (target is RuntimeZombieData zombieData)
|
||||
{
|
||||
|
|
@ -46,14 +53,14 @@ public partial class RandomRedirectEffect : Effect
|
|||
}
|
||||
}
|
||||
zombieData.AbleToEat = false;
|
||||
var tween = zombieData.CreateTween();
|
||||
tween.TweenProperty(zombieData, "position:y", zombieData.GlobalPosition.Y + FieldParams.TileHeight * mult, Duration);
|
||||
tween.Parallel().TweenProperty(zombieData, "position:x", zombieData.GlobalPosition.X - FieldParams.TileHeight * tilesWalked, Duration);
|
||||
var tween = zombieData.CreateTweenEffect(this);
|
||||
tween.TweenInterval(Duration-travelTime);
|
||||
tween.TweenProperty(zombieData, "position:y", zombieData.GlobalPosition.Y + FieldParams.TileHeight * mult, travelTime);
|
||||
tween.Parallel().TweenProperty(zombieData, "position:x", zombieData.GlobalPosition.X - FieldParams.TileHeight * tilesWalked, travelTime);
|
||||
tween.TweenCallback(Callable.From(() => { zombieData.AbleToEat = true; }));
|
||||
}
|
||||
}
|
||||
|
||||
public override void Process(Node target)
|
||||
public override void Process(Entity target)
|
||||
{
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
using Godot;
|
||||
using Newlon.Components.Zombies;
|
||||
using Newlon.Components;
|
||||
|
||||
namespace Newlon.Systems.Effects;
|
||||
|
||||
|
|
@ -9,14 +10,14 @@ public partial class RedirectEffect : Effect
|
|||
[Export] private float tilesWalked = 0.2f;
|
||||
[Export] private bool down = false;
|
||||
|
||||
public override void Enter(Node target)
|
||||
public override void Enter(Entity target)
|
||||
{
|
||||
if (target is RuntimeZombieData zombieData)
|
||||
zombieData.AbleToEat = false;
|
||||
//Animation call
|
||||
}
|
||||
|
||||
public override void Exit(Node target)
|
||||
public override void Exit(Entity target)
|
||||
{
|
||||
if (target is RuntimeZombieData zombieData)
|
||||
{
|
||||
|
|
@ -48,7 +49,7 @@ public partial class RedirectEffect : Effect
|
|||
}
|
||||
}
|
||||
|
||||
public override void Process(Node target)
|
||||
public override void Process(Entity target)
|
||||
{
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,25 +9,19 @@ public partial class SlownessEffect : Effect
|
|||
[Export] public Color ColorOverride;
|
||||
[Export] public float Multiplier;
|
||||
|
||||
public override void Enter(Node target)
|
||||
public override void Enter(Entity target)
|
||||
{
|
||||
if (target is Entity entity)
|
||||
{
|
||||
entity.LocalTimescale *= Multiplier;
|
||||
entity.Modulate = ColorOverride;
|
||||
}
|
||||
target.LocalTimescale *= Multiplier;
|
||||
target.Modulate = ColorOverride;
|
||||
}
|
||||
|
||||
public override void Exit(Node target)
|
||||
public override void Exit(Entity target)
|
||||
{
|
||||
if (target is Entity entity)
|
||||
{
|
||||
entity.LocalTimescale /= Multiplier;
|
||||
entity.Modulate = Colors.White;
|
||||
}
|
||||
target.LocalTimescale /= Multiplier;
|
||||
target.Modulate = Colors.White;
|
||||
}
|
||||
|
||||
public override void Process(Node target)
|
||||
public override void Process(Entity target)
|
||||
{
|
||||
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue