diff --git a/project.godot b/project.godot index 0ada405..6e1d07c 100644 --- a/project.godot +++ b/project.godot @@ -22,7 +22,7 @@ config/windows_native_icon="res://icon.ico" LevelController="*res://scripts/LevelController.cs" Cursor="*res://scripts/Cursor.cs" GameRegistry="*res://scripts/systems/GameRegistry.cs" -Cheats="res://scripts/debug/Cheats.cs" +Cheats="*res://scripts/debug/Cheats.cs" AudioSequencer="*res://scenes/audio_sequencer.tscn" [display] diff --git a/resources/effects/GarlicEffect.tres b/resources/effects/GarlicEffect.tres index 374c2cd..5c9f170 100644 --- a/resources/effects/GarlicEffect.tres +++ b/resources/effects/GarlicEffect.tres @@ -5,4 +5,4 @@ [resource] script = ExtResource("1_rfumy") Duration = 0.25 -Slot = 3 +Slot = "garlic" diff --git a/resources/effects/SnowSlow.tres b/resources/effects/SnowSlow.tres index 5851046..5a62fd5 100644 --- a/resources/effects/SnowSlow.tres +++ b/resources/effects/SnowSlow.tres @@ -1,10 +1,10 @@ [gd_resource type="Resource" load_steps=2 format=3 uid="uid://7uj0oe656jfx"] -[ext_resource type="Script" path="res://scripts/systems/effects/SlownessEffect.cs" id="1_8md01"] +[ext_resource type="Script" uid="uid://dyc7fc5bfkdii" path="res://scripts/systems/effects/SlownessEffect.cs" id="1_8md01"] [resource] script = ExtResource("1_8md01") ColorOverride = Color(0, 1, 1, 1) Multiplier = 0.75 Duration = 3.25 -Slot = 0 +Slot = "freeze_slow" diff --git a/scenes/entities/Zombies/zombie.tscn b/scenes/entities/Zombies/zombie.tscn index 82685a4..579b17c 100644 --- a/scenes/entities/Zombies/zombie.tscn +++ b/scenes/entities/Zombies/zombie.tscn @@ -66,9 +66,9 @@ mult_value = 1.0 [node name="Zombie" type="Node2D"] y_sort_enabled = true script = ExtResource("1_qq3f1") -_maxHP = 70 garlicSound = ExtResource("2_hh4qh") freezeSound = ExtResource("3_ltj46") +MaxHP = 70.0 [node name="CanvasGroup" type="CanvasGroup" parent="."] material = SubResource("ShaderMaterial_63ls2") diff --git a/scenes/entities/plants/peashooter.tscn b/scenes/entities/plants/peashooter.tscn index edf0cfe..d9661db 100644 --- a/scenes/entities/plants/peashooter.tscn +++ b/scenes/entities/plants/peashooter.tscn @@ -63,7 +63,6 @@ size = Vector2(20, 44) [node name="Peashooter" instance=ExtResource("1_pyk3o")] MaxHP = 30.0 -_effectImmunities = Array[Resource]([]) [node name="Sprite2D" parent="." index="0"] texture = ExtResource("2_14qlx") diff --git a/scenes/projectiles/snowpea_projectile.tscn b/scenes/projectiles/snowpea_projectile.tscn index 001c48a..bfde097 100644 --- a/scenes/projectiles/snowpea_projectile.tscn +++ b/scenes/projectiles/snowpea_projectile.tscn @@ -18,7 +18,6 @@ script = ExtResource("1_fkydi") _speed = 3.0 _damage = 10 _impactEffect = ExtResource("2_fn62x") -_damageType = 1 particles = ExtResource("3_t6hp0") [node name="Sprite" type="Sprite2D" parent="."] diff --git a/scripts/components/Armor.cs b/scripts/components/Armor.cs index 4326ff0..7e8ba22 100644 --- a/scripts/components/Armor.cs +++ b/scripts/components/Armor.cs @@ -6,13 +6,13 @@ namespace Newlon.Components; public partial class Armor : Node { [Signal] - public delegate void ArmorDamagedEventHandler(int hp); + public delegate void ArmorDamagedEventHandler(float hp); [Signal] public delegate void ArmorLostEventHandler(); [Export] - public int MaxHP { get; private set; } - private int _hp; + public float MaxHP { get; private set; } + private float _hp; private bool _lost = false; public override void _Ready() @@ -20,11 +20,11 @@ public partial class Armor : Node _hp = MaxHP; } - public int RecieveDamage(int damage) + public float RecieveDamage(float damage) { if(_lost) return damage; - int returnAmount = 0; + float returnAmount = 0; _hp -= damage; if(_hp <= 0) { @@ -37,11 +37,11 @@ public partial class Armor : Node return returnAmount; } - public int Heal(int amount) + public float Heal(float amount) { if(_lost) return amount; - int returnAmount = 0; + float returnAmount = 0; _hp += amount; if (_hp >= MaxHP) { diff --git a/scripts/components/DegradingSprite.cs b/scripts/components/DegradingSprite.cs index baa5e8f..3c28adc 100644 --- a/scripts/components/DegradingSprite.cs +++ b/scripts/components/DegradingSprite.cs @@ -14,9 +14,9 @@ public partial class DegradingSprite : Sprite2D armor.ArmorDamaged += OnZombieHPChanged; } - private void OnZombieHPChanged(int hp) + private void OnZombieHPChanged(float hp) { - float percent = (float)hp / (float)armor.MaxHP; + float percent = hp / armor.MaxHP; for (int i = 0; i < degradationStages.Count; i++) { if (percent <= thresholdPercentage[i]) diff --git a/scripts/components/Entity.cs b/scripts/components/Entity.cs index 121bded..f4d181a 100644 --- a/scripts/components/Entity.cs +++ b/scripts/components/Entity.cs @@ -7,8 +7,8 @@ namespace Newlon.Components; public partial class Entity : Node2D { #region Health points - [Export] public float MaxHP { get; private set; } - public float HP { get; private set; } + [Export] public float MaxHP; + public float HP; [Signal] public delegate void OnHPChangedEventHandler(int deltaHP, Node origin); [Signal] public delegate void OnDamagedEventHandler(); @@ -55,9 +55,14 @@ public partial class Entity : Node2D } #endregion #region Effects - [Export] private Array _effectImmunities; - private readonly Effect[] _activeEffectSlots = new Effect[Utility.EffectSlotCount]; - private readonly Timer[] _effectSlotTimers = new Timer[Utility.EffectSlotCount]; + [Export] private Array _effectImmunities = new(); + private readonly Dictionary _activeEffectSlots = new(); + private readonly Dictionary _effectSlotTimers = new(); + + [Signal] public delegate void EffectStartedEventHandler(Effect what); + [Signal] public delegate void EffectEndedEventHandler(Effect what); + [Signal] public delegate void EffectContinuedEventHandler(Effect what); + public virtual void GiveEffect(Effect what) { @@ -65,7 +70,22 @@ public partial class Entity : Node2D { return; } - int slot = (int)what.Slot; + + string slot = what.Slot; + if (_activeEffectSlots.ContainsKey(slot) == false) + { + InitSlot(slot); + } + + if (what == _activeEffectSlots[slot]) + { + EmitSignal(SignalName.EffectContinued, what); + } + else + { + EmitSignal(SignalName.EffectStarted, what); + } + if (_activeEffectSlots[slot] != null) { _effectSlotTimers[slot].Stop(); @@ -76,24 +96,39 @@ public partial class Entity : Node2D 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) { - what.Exit(this); - _activeEffectSlots[(int)what.Slot] = null; + EndEffectAtSlot(what.Slot); } public void ProcessEffects() { - for (int i = 0; i < Utility.EffectSlotCount; i++) - _activeEffectSlots[i]?.Process(this); + foreach(string key in _activeEffectSlots.Keys) + _activeEffectSlots[key]?.Process(this); } - private void EndEffectAtSlot(int slot) + private void EndEffectAtSlot(string slot) { _activeEffectSlots[slot].Exit(this); _activeEffectSlots[slot] = null; + + EmitSignal(SignalName.EffectEnded, _activeEffectSlots[slot]); + } #endregion #region LocalTimescale @@ -113,16 +148,6 @@ public partial class Entity : Node2D public override void _Ready() { HP = MaxHP; - - // Effect timers setup - for(int i = 0; i < Utility.EffectSlotCount; i++) - { - var timer = new Timer() {Autostart = false, OneShot = true}; - _effectSlotTimers[i] = timer; - AddChild(timer); - int current_index = i; - timer.Timeout += () => {EndEffectAtSlot(current_index);}; - } } #endregion } diff --git a/scripts/components/IEntity.cs b/scripts/components/IEntity.cs deleted file mode 100644 index 7446c70..0000000 --- a/scripts/components/IEntity.cs +++ /dev/null @@ -1,17 +0,0 @@ -using Godot; - -namespace Newlon.Components; - -// -// Base interface for entities -// -public interface IEntity -{ - public int Hp { get; } - public int MaxHp { get; } - public void TakeDamage(int amount, Node origin, Utility.DamageTypes damageType = Utility.DamageTypes.PHYSICAL); - public void Heal(int amount, Node origin); - public void DisableBrain(); - public void EnableBrain(); -} - \ No newline at end of file diff --git a/scripts/components/IEntity.cs.uid b/scripts/components/IEntity.cs.uid deleted file mode 100644 index c16d5f4..0000000 --- a/scripts/components/IEntity.cs.uid +++ /dev/null @@ -1 +0,0 @@ -uid://cjdeq452vk2ll diff --git a/scripts/components/ILocalTimescale.cs b/scripts/components/ILocalTimescale.cs deleted file mode 100644 index e60865a..0000000 --- a/scripts/components/ILocalTimescale.cs +++ /dev/null @@ -1,6 +0,0 @@ -namespace Newlon.Components; - -public interface ILocalTimescale -{ - public float LocalTimescale { get; set; } -} \ No newline at end of file diff --git a/scripts/components/ILocalTimescale.cs.uid b/scripts/components/ILocalTimescale.cs.uid deleted file mode 100644 index 48a6d9b..0000000 --- a/scripts/components/ILocalTimescale.cs.uid +++ /dev/null @@ -1 +0,0 @@ -uid://bxu6ljkmmlgd5 diff --git a/scripts/components/LinearProjectile.cs b/scripts/components/LinearProjectile.cs index 156c486..f9ad5c0 100644 --- a/scripts/components/LinearProjectile.cs +++ b/scripts/components/LinearProjectile.cs @@ -17,8 +17,6 @@ public partial class LinearProjectile : Area2D, IProjectile [Export] private Effect _impactEffect; [Export] - private Utility.DamageTypes _damageType = Utility.DamageTypes.PHYSICAL; - [Export] private PackedScene particles; private int _line; private bool used = false; @@ -33,13 +31,13 @@ public partial class LinearProjectile : Area2D, IProjectile public void OnAreaEntered(Area2D area) { if (used == true) return; - var entity = area.GetParent(); + var entity = area.GetParent(); if (entity != null) { - entity.TakeDamage(_damage,this,_damageType); + entity.TakeDamage(_damage,this); used = true; - if (entity is IEffectHandler effectHandler && _impactEffect != null) - effectHandler.GiveEffect(_impactEffect); + if (_impactEffect != null) + entity.GiveEffect(_impactEffect); PoolContainer.Instance.SpawnParticles(particles, GlobalPosition); diff --git a/scripts/components/gui/choose_your_seeds/Previewport.cs b/scripts/components/gui/choose_your_seeds/Previewport.cs index bb90799..71a1709 100644 --- a/scripts/components/gui/choose_your_seeds/Previewport.cs +++ b/scripts/components/gui/choose_your_seeds/Previewport.cs @@ -44,7 +44,7 @@ public partial class Previewport : SubViewport title.Text = Tr(resource.name_key); description.Text = Tr(resource.description_key); AddChild(current_display); - if (current_display is IEntity entity) + if (current_display is Entity entity) entity.DisableBrain(); } diff --git a/scripts/components/plants/Eyesight.cs b/scripts/components/plants/Eyesight.cs index 7922358..2480476 100644 --- a/scripts/components/plants/Eyesight.cs +++ b/scripts/components/plants/Eyesight.cs @@ -7,7 +7,7 @@ public partial class Eyesight : Area2D { private bool _enemyDetected; public bool EnemyDetected => _enemyDetected; - private readonly List _detectedEntities = new List(); + private readonly List _detectedEntities = new List(); private RuntimePlantData _plantData; public override void _Ready() @@ -19,7 +19,7 @@ public partial class Eyesight : Area2D public void OnAreaEntered(Area2D area) { - var entity = area.GetParent(); + var entity = area.GetParent(); if (entity != null) { _detectedEntities.Add(entity); @@ -30,7 +30,7 @@ public partial class Eyesight : Area2D public void OnAreaExited(Area2D area) { - var entity = area.GetParent(); + var entity = area.GetParent(); if (entity != null) { if (_detectedEntities.Contains(entity)) diff --git a/scripts/components/zombies/RuntimeZombieData.cs b/scripts/components/zombies/RuntimeZombieData.cs index e0fcef0..bf4a64a 100644 --- a/scripts/components/zombies/RuntimeZombieData.cs +++ b/scripts/components/zombies/RuntimeZombieData.cs @@ -1,162 +1,48 @@ -using System.Collections.Generic; using Godot; -using Newlon.Systems.Effects; namespace Newlon.Components.Zombies; -public partial class RuntimeZombieData : Node2D, IEntity, ILocalTimescale, IEffectHandler +public partial class RuntimeZombieData : Entity { - [Signal] - public delegate void OnHPChangedEventHandler(int deltaHP, Node origin); - [Signal] - public delegate void OnDamagedEventHandler(); - - [Signal] - public delegate void OnLocalTimescaleChangedEventHandler(int currentTimescale); - - [Export] - private int _hp; - [Export] - private int _maxHP; [Export] private Armor _armor; - [Export] private AudioStream garlicSound; [Export] private AudioStream freezeSound; - - - private float _localTimescale = 1.0f; - public int Hp => _hp; - - public int MaxHp => _maxHP; - public bool AbleToEat = true; - public float LocalTimescale - { - get => _localTimescale; - set - { - _localTimescale = value; - EmitSignal(SignalName.OnLocalTimescaleChanged,_localTimescale); - } - } - - public override void _Ready() - { - _hp = _maxHP; - - // Effect timers setup - for(int i = 0; i < Utility.EffectSlotCount; i++) - { - var timer = new Timer() {Autostart = false, OneShot = true}; - _effectSlotTimers[i] = timer; - AddChild(timer); - int current_index = i; - timer.Timeout += () => {EndEffectAtSlot(current_index);}; - } - } - - public void Heal(int amount,Node origin) - { - if(_armor != null) - { - _hp += _armor.Heal(amount); - } - else - _hp += amount; - EmitSignal(SignalName.OnHPChanged,amount,origin); - - if (MaxHp > 0) - { - _hp = MaxHp; - } - } - - public void TakeDamage(int amount, Node origin, Utility.DamageTypes damageType = Utility.DamageTypes.PHYSICAL) + public override void Heal(float amount, Node origin) { if (_armor != null) { - _hp -= _armor.RecieveDamage(amount); + HP += _armor.Heal(amount); } else - _hp -= amount; - EmitSignal(SignalName.OnHPChanged,-amount, origin); + HP += amount; + EmitSignal(SignalName.OnHPChanged, amount, origin); + + if (HP > MaxHP) + { + HP = MaxHP; + } + } + + public override void TakeDamage(float amount, Node origin) + { + if (_armor != null) + { + HP -= _armor.RecieveDamage(amount); + } + else + HP -= amount; + EmitSignal(SignalName.OnHPChanged, -amount, origin); EmitSignal(SignalName.OnDamaged); - if (_hp <= 0) + if (HP <= 0) { - QueueFree(); + KillByDamage(); } } - #region Effects system - private readonly Effect[] _activeEffectSlots = new Effect[Utility.EffectSlotCount]; - private readonly Timer[] _effectSlotTimers = new Timer[Utility.EffectSlotCount]; - - // Effect handling - - public void GiveEffect(Effect what) - { - int slot = (int)what.Slot; - if (_activeEffectSlots[slot] == null) - { - switch (what.Slot) - { - case Utility.EffectSlots.FREEZE: - AudioSequencer.Play("zombie_freeze", freezeSound); - var settings = new ChannelSettings(); - settings.restartTreshold = -1; - AudioSequencer.ChangeSettings("zombie_freeze",settings); - break; - case Utility.EffectSlots.GARLIC: - AudioSequencer.Play("zombie_garlic", garlicSound); - - break; - } - } - 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; - } - - public void EndEffect(Effect what) - { - what.Exit(this); - _activeEffectSlots[(int)what.Slot] = null; - } - - public void ProcessEffects() - { - for(int i = 0; i < Utility.EffectSlotCount; i++) - _activeEffectSlots[i]?.Process(this); - } - - private void EndEffectAtSlot(int slot) - { - _activeEffectSlots[slot].Exit(this); - _activeEffectSlots[slot] = null; - } - - public void DisableBrain() - { - GetNode("AnimationPlayer").ProcessMode = ProcessModeEnum.Pausable; - ProcessMode = ProcessModeEnum.Disabled; - } - - public void EnableBrain() - { - GetNode("AnimationPlayer").ProcessMode = ProcessModeEnum.Inherit; - ProcessMode = ProcessModeEnum.Inherit; - } - #endregion } diff --git a/scripts/systems/effects/Effect.cs b/scripts/systems/effects/Effect.cs index 43d6e0e..aa80f70 100644 --- a/scripts/systems/effects/Effect.cs +++ b/scripts/systems/effects/Effect.cs @@ -5,7 +5,7 @@ namespace Newlon.Systems.Effects; public abstract partial class Effect : Resource { [Export] public float Duration; - [Export] public Utility.EffectSlots Slot; + [Export] public string Slot; public abstract void Enter(Node target); public abstract void Process(Node target); public abstract void Exit(Node target); diff --git a/scripts/systems/effects/IEffectHandler.cs b/scripts/systems/effects/IEffectHandler.cs deleted file mode 100644 index 6c9b758..0000000 --- a/scripts/systems/effects/IEffectHandler.cs +++ /dev/null @@ -1,8 +0,0 @@ -namespace Newlon.Systems.Effects; - -public interface IEffectHandler -{ - void GiveEffect(Effect what); - void EndEffect(Effect what); - void ProcessEffects(); -} \ No newline at end of file diff --git a/scripts/systems/effects/IEffectHandler.cs.uid b/scripts/systems/effects/IEffectHandler.cs.uid deleted file mode 100644 index 8c581ef..0000000 --- a/scripts/systems/effects/IEffectHandler.cs.uid +++ /dev/null @@ -1 +0,0 @@ -uid://eeqk3fvjwg31 diff --git a/scripts/systems/effects/SlownessEffect.cs b/scripts/systems/effects/SlownessEffect.cs index 1491a2c..19d7a4e 100644 --- a/scripts/systems/effects/SlownessEffect.cs +++ b/scripts/systems/effects/SlownessEffect.cs @@ -11,21 +11,20 @@ public partial class SlownessEffect : Effect public override void Enter(Node target) { - if (target is IEffectHandler handler) + if (target is Entity entity) { - if (target is ILocalTimescale timescalable) - timescalable.LocalTimescale *= Multiplier; - if (target is CanvasItem canvasItem) - canvasItem.Modulate = ColorOverride; + entity.LocalTimescale *= Multiplier; + entity.Modulate = ColorOverride; } } public override void Exit(Node target) { - if(target is ILocalTimescale timescalable) - timescalable.LocalTimescale /= Multiplier; - if(target is CanvasItem canvasItem) - canvasItem.Modulate = Colors.White; + if (target is Entity entity) + { + entity.LocalTimescale /= Multiplier; + entity.Modulate = Colors.White; + } } public override void Process(Node target)