diff --git a/Damager.cs b/Damager.cs new file mode 100644 index 0000000..2dd5ebc --- /dev/null +++ b/Damager.cs @@ -0,0 +1,22 @@ +using System; +using Godot; +using NodeWar.scripts.components; + +public partial class Damager : Timer +{ + [Export] + public float Damage { get; set; } = 1; + + public override void _Ready() + { + Timeout += OnTimeout; + } + + private void OnTimeout() + { + var healthComponent = GetParent().GetNode("HealthComponent"); + healthComponent?.TakeDamage(Damage); + } + + public override void _Process(double delta) { } +} diff --git a/Damager.cs.uid b/Damager.cs.uid new file mode 100644 index 0000000..39d6049 --- /dev/null +++ b/Damager.cs.uid @@ -0,0 +1 @@ +uid://bfi1cm0m4wuk2 diff --git a/main.tscn b/main.tscn index 0bc75cb..23d470e 100644 --- a/main.tscn +++ b/main.tscn @@ -65,5 +65,5 @@ position = Vector2(707, 439) Faction = 2 [node name="Pip" parent="." unique_id=1889156888 node_paths=PackedStringArray("Target") instance=ExtResource("6_7mycd")] -position = Vector2(546, 310) +position = Vector2(-7, -14) Target = NodePath("../EnemyBase") diff --git a/pip.tscn b/pip.tscn index 483bdbd..f06dd90 100644 --- a/pip.tscn +++ b/pip.tscn @@ -2,17 +2,27 @@ [ext_resource type="Script" uid="uid://cdbkkb2cpwkn1" path="res://scripts/Pip.cs" id="1_2foya"] [ext_resource type="Texture2D" uid="uid://dkpk1ubnmbl68" path="res://assets/pip.png" id="2_46jm3"] +[ext_resource type="PackedScene" uid="uid://dn6jqa3wj40ir" path="res://scripts/components/health_component.tscn" id="3_46jm3"] +[ext_resource type="Script" uid="uid://bfi1cm0m4wuk2" path="res://Damager.cs" id="4_6fdkq"] -[node name="Pip" type="Area2D" unique_id=1889156888 node_paths=PackedStringArray("Target")] +[node name="Pip" type="Area2D" unique_id=1889156888] script = ExtResource("1_2foya") Faction = 1 -Target = NodePath("") [node name="CollisionPolygon2D" type="CollisionPolygon2D" parent="." unique_id=528123989] polygon = PackedVector2Array(-18.5, -18.5, -18.5, 18.5, 18.5, 18.5, 18.5, -18.5) [node name="Gfx" type="Sprite2D" parent="." unique_id=1494214084] -modulate = Color(0.5376854, 0.9999998, 0.6650417, 1) texture = ExtResource("2_46jm3") +[node name="HealthComponent" parent="." unique_id=1360050278 node_paths=PackedStringArray("Gfx") instance=ExtResource("3_46jm3")] +visible = false +Gfx = NodePath("../Gfx") +Health = 5.0 +MaxHealth = 5.0 + +[node name="Damager" type="Timer" parent="." unique_id=1839733483] +autostart = true +script = ExtResource("4_6fdkq") + [connection signal="area_entered" from="." to="." method="_on_area_entered"] diff --git a/scripts/Base.cs b/scripts/Base.cs index de3c424..625eafa 100644 --- a/scripts/Base.cs +++ b/scripts/Base.cs @@ -2,11 +2,13 @@ using System; using Godot; using NodeWar; using NodeWar.Scripts; +using NodeWar.scripts.components; public partial class Base : Area2D { private ProgressBar _progressBar; - private ProgressBar _healthBar; + public HealthComponent HealthComponent; + private Node2D _selection; private Node2D _gfx; @@ -16,12 +18,6 @@ public partial class Base : Area2D [Export] public Faction Faction = Faction.Neutral; - [Export] - public float Health { get; set; } = 50; - - [Export] - public float MaxHealth { get; set; } = 50; - private float _buildSpeed = 28; private float _buildProgress = 0; private float _maxBuildProgress = 100; @@ -34,15 +30,15 @@ public partial class Base : Area2D MouseEntered += OnMouseEntered; MouseExited += OnMouseExited; - _healthBar = GetNode("HealthBar"); + HealthComponent = GetNode("HealthComponent"); _progressBar = GetNode("ProgressBar"); _selection = GetNode("Selection"); _gfx = GetNode("Gfx"); _selection.Visible = false; _progressBar.MaxValue = _maxBuildProgress; - _healthBar.MaxValue = MaxHealth; - _healthBar.Value = Health; + HealthComponent.MaxHealth = 100; + HealthComponent.Health = 100; UpdateColor(); } @@ -59,6 +55,7 @@ public partial class Base : Area2D var pip = _pipScene.Instantiate(); GetParent().AddChild(pip); + pip.Faction = Faction; pip.GlobalPosition = GlobalPosition; pip.Target = GetTree().GetFirstNodeInGroup("enemyBase") as Base; } @@ -88,7 +85,6 @@ public partial class Base : Area2D private void UpdateProgressBars() { _progressBar.Value = _buildProgress; - _healthBar.Value = Health; } private void OnMouseExited() diff --git a/scripts/Pip.cs b/scripts/Pip.cs index 4078a65..4914f2c 100644 --- a/scripts/Pip.cs +++ b/scripts/Pip.cs @@ -1,3 +1,4 @@ +using System; using Godot; namespace NodeWar.Scripts; @@ -13,8 +14,20 @@ public partial class Pip : Area2D [Export] public float Speed { get; set; } = 100; + private Sprite2D _gfx; + public override void _Ready() { + _gfx = GetNode("Gfx"); + + _gfx.Modulate = Faction switch + { + Faction.Neutral => Colors.Gray, + Faction.Player => Colors.DarkGreen, + Faction.Computer => Colors.DarkRed, + _ => throw new ArgumentOutOfRangeException(), + }; + AreaEntered += OnAreaEntered; } @@ -31,7 +44,7 @@ public partial class Pip : Area2D { if (body is Base { Faction: Faction.Computer } enteredBase) { - enteredBase.Health -= 1; + enteredBase.HealthComponent.TakeDamage(1); QueueFree(); } } diff --git a/scripts/components/HealthComponent.cs b/scripts/components/HealthComponent.cs new file mode 100644 index 0000000..b901a90 --- /dev/null +++ b/scripts/components/HealthComponent.cs @@ -0,0 +1,60 @@ +using System.Threading.Tasks; +using Godot; + +namespace NodeWar.scripts.components; + +public partial class HealthComponent : ProgressBar +{ + [Export] + public Sprite2D Gfx { get; set; } + + [Export] + public float Health { get; set; } = 100; + + [Export] + public float MaxHealth { get; set; } = 100; + + [Signal] + public delegate float HealthChangedEventHandler(float oldHealth, float newHealth); + + public void TakeDamage(float damage) + { + Health -= damage; + EmitSignal(SignalName.HealthChanged, Health + damage, Health); + + if (Health <= 0) + { + Die(); + return; + } + + if (Gfx != null) + { + var originalColor = Gfx.Modulate; + + Gfx.Modulate = new Color(10, 10, 10); + + GetTree().CreateTimer(0.1f).Timeout += () => + { + Gfx.Modulate = originalColor; + }; + } + } + + public void Die() + { + GD.Print("I am dying!"); + GetParent().QueueFree(); + } + + public override void _Ready() + { + Value = Health; + MaxValue = MaxHealth; + } + + public override void _Process(double delta) + { + Value = Health; + } +} diff --git a/scripts/components/HealthComponent.cs.uid b/scripts/components/HealthComponent.cs.uid new file mode 100644 index 0000000..8476cd0 --- /dev/null +++ b/scripts/components/HealthComponent.cs.uid @@ -0,0 +1 @@ +uid://b26j7cq2pgk6q diff --git a/scripts/components/health_component.tscn b/scripts/components/health_component.tscn new file mode 100644 index 0000000..e429a7e --- /dev/null +++ b/scripts/components/health_component.tscn @@ -0,0 +1,29 @@ +[gd_scene format=3 uid="uid://dn6jqa3wj40ir"] + +[ext_resource type="Script" uid="uid://b26j7cq2pgk6q" path="res://scripts/components/HealthComponent.cs" id="1_kkm8u"] + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_21bcp"] +bg_color = Color(0.4249828, 0.6869066, 0, 1) +corner_radius_top_left = 6 +corner_radius_top_right = 6 +corner_radius_bottom_right = 6 +corner_radius_bottom_left = 6 + +[node name="HealthComponent" type="ProgressBar" unique_id=1360050278] +anchors_preset = 8 +anchor_left = 0.5 +anchor_top = 0.5 +anchor_right = 0.5 +anchor_bottom = 0.5 +offset_left = -13.5 +offset_top = -64.0 +offset_right = 13.5 +offset_bottom = 64.0 +grow_horizontal = 2 +grow_vertical = 2 +theme_override_styles/fill = SubResource("StyleBoxFlat_21bcp") +max_value = 10.0 +value = 5.36 +fill_mode = 3 +show_percentage = false +script = ExtResource("1_kkm8u")