From ac25e55bf349cd10a2f7874f953e66b5b5be426c Mon Sep 17 00:00:00 2001 From: cojoedmo Date: Wed, 27 Aug 2025 01:54:43 -0400 Subject: [PATCH] Wednesday, 27 August 2025 01:54:42 --- Gameplay/Actions/Caffeinate.cs | 2 +- Gameplay/Conditions/Caffeinated.cs | 18 +-- Gameplay/Globals.cs | 1 + Gameplay/Main.cs | 8 +- Gameplay/Manager.cs | 129 ++++++++++++++++--- Gameplay/Worker.cs | 194 +++++++++-------------------- Gameplay/action.tscn | 7 +- Gameplay/effect.tscn | 3 - Gameplay/manager.tscn | 4 +- Gameplay/worker.tscn | 47 ++----- art/worker_test.png | Bin 0 -> 10860 bytes art/worker_test.png.import | 34 +++++ 12 files changed, 244 insertions(+), 203 deletions(-) delete mode 100644 Gameplay/effect.tscn create mode 100644 art/worker_test.png create mode 100644 art/worker_test.png.import diff --git a/Gameplay/Actions/Caffeinate.cs b/Gameplay/Actions/Caffeinate.cs index 23b6add..2b74a9f 100644 --- a/Gameplay/Actions/Caffeinate.cs +++ b/Gameplay/Actions/Caffeinate.cs @@ -17,7 +17,7 @@ public partial class Caffeinate : Action Worker target = (Worker)_target; if (!target.HasCondition(GetType().ToString())) { - target._conditions.Add(new Caffeinated(target)); + target._conditions.AddChild(new Caffeinated(target)); } } _target = null; diff --git a/Gameplay/Conditions/Caffeinated.cs b/Gameplay/Conditions/Caffeinated.cs index 10b1b7d..a1ea63e 100644 --- a/Gameplay/Conditions/Caffeinated.cs +++ b/Gameplay/Conditions/Caffeinated.cs @@ -11,26 +11,20 @@ public partial class Caffeinated : Condition _timer.WaitTime = _countdown; _timer.Autostart = true; AddChild(_timer); - // GetNode("Timer").Timeout += Fire; - if (OWNER is Worker) + _timer.Timeout += Fire; + if (_owner is Worker) { - ((Worker)OWNER)._staminaCanDrain = false; + ((Worker)_owner)._agility._effective += 3; } } public override void Fire() { _expired = true; - if (_target != null) + if (_owner is Worker) { - if (_target is Worker) - { - Worker target = (Worker)_target; - target._stamina -= 1; - target._staminaCanDrain = true; - target._conditions.Remove(this); - } - _target = null; + ((Worker)_owner)._agility._effective -= 3; + ((Worker)_owner)._conditions.RemoveChild(this); } } } diff --git a/Gameplay/Globals.cs b/Gameplay/Globals.cs index 6ddc03b..3800164 100644 --- a/Gameplay/Globals.cs +++ b/Gameplay/Globals.cs @@ -5,6 +5,7 @@ using System.Collections.Generic; public partial class Globals : Node { public static Globals Instance; + public bool _battleRunning = false; public Viewport _viewport; public Vector2 _screenSize; public Vector2 _screenCenter; diff --git a/Gameplay/Main.cs b/Gameplay/Main.cs index 9e269af..d0e60a7 100644 --- a/Gameplay/Main.cs +++ b/Gameplay/Main.cs @@ -17,12 +17,16 @@ public partial class Main : Node _currentBattle.Start(); } - public override void _Process(double DELTA_) - { + public override void _Process(double DELTA_) + { if (Input.IsActionJustReleased("quit_game")) { GetTree().Quit(); } + if (Input.IsActionJustPressed("space")) + { + Globals.Instance._battleRunning = !Globals.Instance._battleRunning; + } } } diff --git a/Gameplay/Manager.cs b/Gameplay/Manager.cs index e17326c..a5dde84 100644 --- a/Gameplay/Manager.cs +++ b/Gameplay/Manager.cs @@ -4,19 +4,22 @@ using System.Collections.Generic; using System.Linq; /// TODO alter code to player vs computer to account for differing logic -public partial class Manager : Node +public partial class Manager : Node2D { public bool _dead, _ready; - public int _ballsMoving = 0, _health = 10, _healthMax; + public int _ballsMoving = 0, _health = 10, _healthMax, _speed = 5; public string _imagePath; public CollisionShape2D _startArea; public ManagerPanel _managerPanel = null; public Manager _opponent; public List _workers = new(); + public Worker _hoveredWorker, _selectedWorker, _heldWorker; + public Node _workerNode; public List _tchotckes = new(); public override void _Ready() { + _workerNode = GetNode("Workers"); _healthMax = _health; SetSprite("res://art/ness.png"); @@ -26,15 +29,27 @@ public partial class Manager : Node _managerPanel.SetManager(this); Worker newWorker = Globals.Instance._workerScene.Instantiate(); - newWorker.Position = Globals.Instance._screenCenter + new Vector2(0, 100); + newWorker.Position = Globals.Instance._screenCenter; newWorker._manager = this; - AddChild(newWorker); + _workerNode.AddChild(newWorker); _workers.Add(newWorker); newWorker = Globals.Instance._workerScene.Instantiate(); - newWorker.Position = Globals.Instance._screenCenter - new Vector2(0, 100); + newWorker.Position = Globals.Instance._screenCenter; newWorker._manager = this; - AddChild(newWorker); + _workerNode.AddChild(newWorker); + _workers.Add(newWorker); + + newWorker = Globals.Instance._workerScene.Instantiate(); + newWorker.Position = Globals.Instance._screenCenter; + newWorker._manager = this; + _workerNode.AddChild(newWorker); + _workers.Add(newWorker); + + newWorker = Globals.Instance._workerScene.Instantiate(); + newWorker.Position = Globals.Instance._screenCenter; + newWorker._manager = this; + _workerNode.AddChild(newWorker); _workers.Add(newWorker); // for (int i = 0; i < _workers.Count; i++) @@ -42,20 +57,45 @@ public partial class Manager : Node // _workers[i]._healthBar.Position = _managerPanel.GetNode("Team").GetNode("T"+(i+1)).GlobalPosition; // } - Tchotchke newTchotchke = ResourceLoader.Load("res://Gameplay/Tchotchkes/awfully_hot_coffee_pot.tscn").Instantiate(); - newTchotchke.Position = new Vector2(Globals.Instance._screenSize.X - 100, Globals.Instance._screenCenter.Y); - AddChild(newTchotchke); - _tchotckes.Add(newTchotchke); + // Tchotchke newTchotchke = ResourceLoader.Load("res://Gameplay/Tchotchkes/awfully_hot_coffee_pot.tscn").Instantiate(); + // newTchotchke.Position = new Vector2(Globals.Instance._screenSize.X - 100, Globals.Instance._screenCenter.Y); + // AddChild(newTchotchke); + // _tchotckes.Add(newTchotchke); } public override void _Process(double DELTA_) { - - if (_workers.All(w => w._placed && w._primed)) + if (Globals.Instance._battleRunning) { - for (int i = 0; i < _workers.Count; i++) + ChainMovement(); + } + else + { + MoveChain(); + } + } + + public void ChainMovement() + { + Vector2 mousePosition = GetGlobalMousePosition(); + // _workers[0].LookAt(mousePosition); + Vector2 mouseOffset = mousePosition - _workers[0].GlobalPosition; + if (mouseOffset.Length() > _workers[0]._size) + { + Vector2 mouseOffsetNormal = mouseOffset.Normalized(); + _workers[0].GlobalPosition += mouseOffsetNormal * _speed; + _workers[0]._distanceTraveled += _speed; + _workers[0]._moves.Insert(0, _workers[0].GlobalPosition); + + for (int i = 1; i < _workers.Count; i++) { - _workers[i].Launch(); + if (_workers[i - 1]._distanceTraveled > (_workers[i - 1]._size + _workers[i]._size) * 1.2f) + { + _workers[i]._distanceTraveled += _speed; + _workers[i].GlobalPosition = _workers[i - 1]._moves[^1]; + _workers[i]._moves.Insert(0, _workers[i - 1]._moves[^1]); + _workers[i - 1]._moves.RemoveAt(_workers[i - 1]._moves.Count - 1); + } } } } @@ -74,10 +114,71 @@ public partial class Manager : Node GetNode("Panel").SetValue(_health); } + public void MoveChain() + { + _hoveredWorker = _workers.SingleOrDefault(w => !w._selected && !w._held && w._hovered, null); + + if (_heldWorker != null) + { + _heldWorker.GlobalPosition = GetGlobalMousePosition(); + if (_hoveredWorker != null) + { + SwapPositions(_heldWorker, _hoveredWorker); + _hoveredWorker._hovered = false; + _hoveredWorker = null; + } + if (Input.IsActionJustReleased("left_click")) + { + _heldWorker.GlobalPosition = _heldWorker._chainPosition; + _heldWorker._held = false; + _heldWorker = null; + } + } + else + { + if (_selectedWorker != null) + { + if (Input.IsActionPressed("left_click") && (GetGlobalMousePosition() - _selectedWorker._chainPosition).Length() > 5) + { + + _heldWorker = _selectedWorker; + _heldWorker._held = true; + _heldWorker._selected = false; + _selectedWorker = null; + } + } + if (_hoveredWorker != null) + { + if (Input.IsActionJustPressed("left_click")) + { + _selectedWorker = _hoveredWorker; + _selectedWorker._selected = true; + _selectedWorker._hovered = false; + _hoveredWorker = null; + } + } + } + } + public void SetSprite(string PATH) { _imagePath = PATH; } + public void SwapPositions(Worker A, Worker B) + { + Vector2 positionA = A.Position, positionB = B.Position, chainPositionA = A._chainPosition, chainPositionB = B._chainPosition; + List movesA = new(A._moves), movesB = new(B._moves); + // A.Position = positionB; + B.Position = chainPositionA; + A._chainPosition = chainPositionB; + B._chainPosition = chainPositionA; + A._moves = movesB; + B._moves = movesA; + int indexA = _workers.IndexOf(A), indexB = _workers.IndexOf(B); + Worker C = A; + _workers[indexA] = B; + _workers[indexB] = C; + } } diff --git a/Gameplay/Worker.cs b/Gameplay/Worker.cs index 30dd4bf..8b136c9 100644 --- a/Gameplay/Worker.cs +++ b/Gameplay/Worker.cs @@ -5,22 +5,26 @@ using System.ComponentModel.DataAnnotations; using System.Diagnostics; using System.Linq; -public partial class Worker : RigidBody2D +public partial class Worker : CharacterBody2D { - public bool _dead = false, _hovered = false, _held = false, _placed = false, _selected = false, _primed = false, _moving = false, _staminaCanDrain = true; - public int _health, _healthMax; - public float _stamina, _staminaMax; + public bool _dead = false, _hovered = false, _held = false, _selected = false; + public int _size, _health, _healthMax; + public float _distanceTraveled, _stamina, _staminaMax; public Stat _aptitude = new(), _agility = new(), _ardor = new(), _accumen = new(), _awareness = new(), _appeal = new(); public float _rotationalForce = 0; - public Vector2 _force = Vector2.Zero; - public Node _collisionTarget; + public Vector2 _chainPosition = new Vector2(-1, -1); + public List _moves = new(); public Sprite2D _image; public ProgressBar _healthBar; public Manager _manager; - public List _actions = new(); - public List _conditions = new(); + public Node _actions; + public Node _conditions; public override void _Ready() { + _actions = GetNode("Actions"); + _conditions = GetNode("Conditions"); + _size = (int)(((CircleShape2D)GetNode("Bounds").Shape).Radius); + _aptitude._default = 5; _agility._default = 5; _ardor._default = 5; @@ -37,7 +41,7 @@ public partial class Worker : RigidBody2D _image = GetNode("Sprite2D"); - _actions.Add(new BasicAttack(this)); + _actions.AddChild(new BasicAttack(this)); // _healthBar = GetNode("HealthBar"); // _healthBar.MaxValue = _healthMax; @@ -46,118 +50,62 @@ public partial class Worker : RigidBody2D public override void _Process(double DELTA_) { - if (!_moving) + if (Globals.Instance._battleRunning) { - if (!_placed) - { - if (!_held) - { - if (_hovered) - { - if (Input.IsActionJustPressed("left_click")) - { - Hold(); - } - } - } - } - else - { - if (_selected) - { - Vector2 mousePosition = GetGlobalMousePosition(); - LookAt(mousePosition); - if (Input.IsActionJustReleased("left_click")) - { - _selected = false; - _force = (GlobalPosition - mousePosition) * 100; - _stamina = _agility._effective; - _primed = true; - } - } - else if (_hovered) - { - if (Input.IsActionJustPressed("left_click")) - { - _selected = true; - } - } - } + _chainPosition = GlobalPosition; } else { - // Vector2 towardCenter = (Globals.Instance._screenCenter - GlobalPosition).Normalized(); - // ApplyCentralForce(towardCenter * 100); - _image.Rotate(_stamina); - if (_staminaCanDrain) - { - _stamina -= 0.25f / 60; - } - if (_stamina <= 0f) - { - Stop(); - } + } } - public override void _PhysicsProcess(double DELTA_) - { - if (_held) - { - GlobalPosition = GetGlobalMousePosition(); - if (Input.IsActionJustReleased("left_click")) - { - Transform2D newTransform = GlobalTransform; - newTransform.Origin = Position; - GlobalTransform = newTransform; - Drop(); - } - } - } - - public void ChangeHealth(int CHANGE, Node CHANGEMAKER) - { - if (_health <= 0 && CHANGE < 0) - { - // knock the piece off the board and out for the round! - // process on knockout - } - _health += CHANGE; - _healthBar.Value = _health; - if (_health <= 0) - { - Sleeping = true; - _dead = true; - _health = 0; - FireActions(Trigger.On.Death, _manager); - } - } + // public void ChangeHealth(int CHANGE, Node CHANGEMAKER) + // { + // if (_health <= 0 && CHANGE < 0) + // { + // // knock the piece off the board and out for the round! + // // process on knockout + // } + // _health += CHANGE; + // _healthBar.Value = _health; + // if (_health <= 0) + // { + // Sleeping = true; + // _dead = true; + // _health = 0; + // FireActions(Trigger.On.Death, _manager); + // } + // } public void Drop() { if (_held) { _held = false; - _placed = true; - Freeze = false; } } public void FireActions(Trigger.On TRIGGER, Node TARGET = null) { - List triggeredActions = _actions.Where(e => e._triggers.Contains(TRIGGER)).ToList(); - for (int i = 0; i < triggeredActions.Count; i++) + List children = _actions.GetChildren().ToList(); + for (int i = 0; i < children.Count; i++) { - triggeredActions[i].Target(TARGET); - triggeredActions[i].Fire(); + if (children[i] is Action) + { + Action action = (Action)children[i]; + if (action._triggers.Contains(TRIGGER)) + { + action.Target(TARGET); + action.Fire(); + } + } } - List expiredActions = _actions.Where(e => e._triggers.Contains(TRIGGER)).ToList(); - _actions.Except(expiredActions); } public bool HasCondition(string CONDITION) { - List conditionNames = _conditions.Select(c => c.GetType().ToString()).ToList(); + List conditionNames = _conditions.GetChildren().Select(c => c.GetType().ToString()).ToList(); return conditionNames.Contains(CONDITION); } @@ -167,29 +115,9 @@ public partial class Worker : RigidBody2D { return; } - Freeze = true; _held = true; } - public void Launch() - { - GravityScale = 1.0f; - _moving = true; - ApplyCentralForce(_force); - _force = Vector2.Zero; - _primed = false; - FireActions(Trigger.On.Launch, _manager); - } - - public void Stop() - { - GravityScale = 0.0f; - Sleeping = true; - _moving = false; - _stamina = 0f; - FireActions(Trigger.On.Stop, _manager); - } - public void ResetStats() { _aptitude._effective = _aptitude._default; @@ -211,24 +139,22 @@ public partial class Worker : RigidBody2D _hovered = false; } - private void OnBodyEntered(Node NODE) - { - if (NODE is Worker) - { - _collisionTarget = NODE; - FireActions(Trigger.On.Collision, NODE); + // private void OnBodyEntered(Node NODE) + // { + // if (NODE is Worker) + // { + // FireActions(Trigger.On.Collision, NODE); - _rotationalForce *= 0.8f; - Vector2 rotatedForce = LinearVelocity.Rotated(((Worker)NODE)._rotationalForce); + // _rotationalForce *= 0.8f; + // Vector2 rotatedForce = LinearVelocity.Rotated(((Worker)NODE)._rotationalForce); - ApplyCentralForce(rotatedForce); - _collisionTarget = null; - } - else if (NODE is Tchotchke) - { - Tchotchke tchotchke = (Tchotchke)NODE; - tchotchke.FireActions(Trigger.On.Collision, this); - } - } + // ApplyCentralForce(rotatedForce); + // } + // else if (NODE is Tchotchke) + // { + // Tchotchke tchotchke = (Tchotchke)NODE; + // tchotchke.FireActions(Trigger.On.Collision, this); + // } + // } } diff --git a/Gameplay/action.tscn b/Gameplay/action.tscn index c334a5d..4ead980 100644 --- a/Gameplay/action.tscn +++ b/Gameplay/action.tscn @@ -1,3 +1,6 @@ -[gd_scene load_steps=0 format=3 uid="uid://becqya8l8feni"] +[gd_scene load_steps=2 format=3 uid="uid://dti20yu8jfujq"] -[node name="ProcessEffect" type="Node"] +[ext_resource type="Script" uid="uid://dtccp5uxgkjwm" path="res://Gameplay/Action.cs" id="1_lk435"] + +[node name="Action" type="Node"] +script = ExtResource("1_lk435") diff --git a/Gameplay/effect.tscn b/Gameplay/effect.tscn deleted file mode 100644 index 1fff1b6..0000000 --- a/Gameplay/effect.tscn +++ /dev/null @@ -1,3 +0,0 @@ -[gd_scene format=3 uid="uid://dti20yu8jfujq"] - -[node name="Action" type="Node"] diff --git a/Gameplay/manager.tscn b/Gameplay/manager.tscn index 11823e8..f65f62a 100644 --- a/Gameplay/manager.tscn +++ b/Gameplay/manager.tscn @@ -3,7 +3,7 @@ [ext_resource type="Script" uid="uid://b66ysicyh0m1s" path="res://Gameplay/Manager.cs" id="1_ivgep"] [ext_resource type="PackedScene" uid="uid://8kv00jc35dma" path="res://Gameplay/manager_panel.tscn" id="3_xooeg"] -[node name="Manager" type="Node"] +[node name="Manager" type="Node2D"] script = ExtResource("1_ivgep") [node name="Panel" parent="." instance=ExtResource("3_xooeg")] @@ -13,3 +13,5 @@ offset_right = 551.0 offset_bottom = 280.0 grow_horizontal = 1 grow_vertical = 1 + +[node name="Workers" type="Node" parent="."] diff --git a/Gameplay/worker.tscn b/Gameplay/worker.tscn index f6f39fa..9c28e77 100644 --- a/Gameplay/worker.tscn +++ b/Gameplay/worker.tscn @@ -1,53 +1,32 @@ -[gd_scene load_steps=5 format=3 uid="uid://37hjd4v3p42o"] +[gd_scene load_steps=4 format=3 uid="uid://37hjd4v3p42o"] [ext_resource type="Script" uid="uid://bk6qk4rjmsvtn" path="res://Gameplay/Worker.cs" id="1_e314i"] +[ext_resource type="Texture2D" uid="uid://dmispjd3fmmks" path="res://art/worker_test.png" id="2_m3kx1"] -[sub_resource type="PhysicsMaterial" id="PhysicsMaterial_e314i"] -bounce = 3.0 +[sub_resource type="CircleShape2D" id="CircleShape2D_4poc8"] +radius = 25.0799 -[sub_resource type="CompressedTexture2D" id="CompressedTexture2D_e314i"] -load_path = "res://.godot/imported/beyblade.png-cd6ee3474fe554271afbb31b55fadfb5.ctex" - -[sub_resource type="CircleShape2D" id="CircleShape2D_e314i"] -radius = 32.0 - -[node name="Worker" type="RigidBody2D"] +[node name="Worker" type="CharacterBody2D"] input_pickable = true -physics_material_override = SubResource("PhysicsMaterial_e314i") -gravity_scale = 0.0 -inertia = 1.0 -lock_rotation = true -continuous_cd = 2 -contact_monitor = true -max_contacts_reported = 1 -linear_damp = 0.25 script = ExtResource("1_e314i") [node name="HealthBar" type="ProgressBar" parent="."] +visible = false top_level = true offset_right = 150.0 offset_bottom = 27.0 step = 1.0 +[node name="Bounds" type="CollisionShape2D" parent="."] +shape = SubResource("CircleShape2D_4poc8") + [node name="Sprite2D" type="Sprite2D" parent="."] -scale = Vector2(0.2, 0.2) -texture = SubResource("CompressedTexture2D_e314i") +scale = Vector2(0.5, 0.5) +texture = ExtResource("2_m3kx1") -[node name="CollisionPolygon2D" type="CollisionPolygon2D" parent="."] -scale = Vector2(0.2, 0.2) -polygon = PackedVector2Array(8, -171, -17, -171, -17, -169.9, -26.2, -169, -29.5, -169, -62, -151.2, -84, -152.9, -84, -154.4, -102.4, -151, -104.7, -151, -150.8, -114, -153, -114, -174, -88, -175.3, -88, -180, -77.7, -180, 44.2, -178, 46.7, -178, 48.3, -163.5, 54.9, -155, 81.2, -155, 83.9, -135.8, 102, -134.9, 102, -114, 126.7, -114, 128.2, -97.5, 137, -96.1, 137, -92, 143.6, -92, 146, -82, 152.9, -82, 154.5, -34, 167.4, -34, 168.7, -18.1, 171, 31.2, 171, 49.4, 167, 52.7, 167, 68, 155, 68, 154.2, 110.5, 134, 112.7, 134, 137.7, 114, 139.7, 114, 142, 98.1, 142, 92.9, 156.9, 79, 158.4, 79, 171.4, 45, 173.1, 45, 172, 22.9, 172, 13.6, 180, 1.10001, 180, -65.5, 159, -106.6, 159, -108.7, 134, -140.7, 134, -142.3, 121.4, -148, 112.5, -148, 101.4, -142, 97.3, -142, 75, -151.3, 75, -152.5, 50.3, -159, 47.5, -159, 39, -164.1, 39, -165.8, 8, -169.8) +[node name="Actions" type="Node" parent="."] -[node name="Gravity" type="Area2D" parent="."] -gravity_space_override = 1 -gravity_point = true -gravity_point_unit_distance = 32.0 -gravity_point_center = Vector2(0, 0) -gravity_direction = Vector2(0, 0) -gravity = 5.0 +[node name="Conditions" type="Node" parent="."] -[node name="CollisionShape2D" type="CollisionShape2D" parent="Gravity"] -shape = SubResource("CircleShape2D_e314i") - -[connection signal="body_entered" from="." to="." method="OnBodyEntered"] [connection signal="mouse_entered" from="." to="." method="OnMouseEntered"] [connection signal="mouse_exited" from="." to="." method="OnMouseExited"] diff --git a/art/worker_test.png b/art/worker_test.png new file mode 100644 index 0000000000000000000000000000000000000000..6b55be10b4fc80804027fd39c7025e04e81dd702 GIT binary patch literal 10860 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