From 35c2837ba5787abb1accbe992e514b74287b2c42 Mon Sep 17 00:00:00 2001
From: Adrian Paschkowski <git@wasdennnoch.me>
Date: Wed, 14 Apr 2021 20:21:24 +0200
Subject: [PATCH] Implement round system with Fighters

---
 Assets/Scripts/Fighters/AntiPlayer.cs | 33 ++++++++++++++++---------
 Assets/Scripts/Fighters/Fighter.cs    | 35 +++++++++++++++++++++++++--
 2 files changed, 55 insertions(+), 13 deletions(-)

diff --git a/Assets/Scripts/Fighters/AntiPlayer.cs b/Assets/Scripts/Fighters/AntiPlayer.cs
index 8a7fb9f..8899de7 100644
--- a/Assets/Scripts/Fighters/AntiPlayer.cs
+++ b/Assets/Scripts/Fighters/AntiPlayer.cs
@@ -11,25 +11,15 @@ public class AntiPlayer : Fighter, IFighterCallback
     [SerializeField, Tooltip("After killing an Enemy, how long to stay idle before targeting the next enemy")]
     float delayUntilNextTarget = 0.3f;
 
+    string[] attackAnimationTriggers = new string[] { "Attack1", "Attack2", "Attack3" };
     List<Fighter> enemies = new List<Fighter>();
     Fighter currentTargetEnemy;
-    string[] attackAnimationTriggers = new string[] { "Attack1", "Attack2", "Attack3" };
 
     protected override void Awake()
     {
         base.Awake();
         fighterType = FighterTypes.ANTI_PLAYER;
         opponentTag = "Enemy";
-        // TODO Eventually, the player will be able to place enemies _after_ the AntiPlayer has been created.
-        // Idea: Create a global GameManager-like class where scripts can register an IGameState callback,
-        // which has a `OnRoundStart()` callback.
-        foreach (var enemy in GameObject.FindGameObjectsWithTag("Enemy"))
-        {
-            var fighter = enemy.GetComponent<Fighter>();
-            fighter.callbacks.Add(this);
-            enemies.Add(fighter);
-        }
-        CalculateClosestEnemy();
         animator.SetBool("Grounded", true);
     }
 
@@ -88,4 +78,25 @@ public class AntiPlayer : Fighter, IFighterCallback
         currentTargetEnemy = null;
         Invoke(nameof(CalculateClosestEnemy), delayUntilNextTarget);
     }
+
+    public override void OnRoundStart()
+    {
+        base.OnRoundStart();
+
+        foreach (var enemy in GameObject.FindGameObjectsWithTag("Enemy"))
+        {
+            var fighter = enemy.GetComponent<Fighter>();
+            fighter.callbacks.Add(this);
+            enemies.Add(fighter);
+        }
+        CalculateClosestEnemy();
+    }
+
+    public override void OnRoundEnd()
+    {
+        base.OnRoundEnd();
+
+        enemies.Clear();
+        currentTargetEnemy = null;
+    }
 }
diff --git a/Assets/Scripts/Fighters/Fighter.cs b/Assets/Scripts/Fighters/Fighter.cs
index e8d1f7c..0a48ca9 100644
--- a/Assets/Scripts/Fighters/Fighter.cs
+++ b/Assets/Scripts/Fighters/Fighter.cs
@@ -9,7 +9,7 @@ public interface IFighterCallback
 
 // Generic subclass for any Fighter on the field, whether it's an Enemy or the AntiPlayer.
 // Contains stats management such as health, attacks, damage, death, etc.
-public abstract class Fighter : MonoBehaviour
+public abstract class Fighter : MonoBehaviour, IRoundCallback
 {
 
     [SerializeField] int baseHealth = 100;
@@ -23,12 +23,15 @@ public abstract class Fighter : MonoBehaviour
     protected Animator animator;
     protected new Rigidbody2D rigidbody;
     protected new BoxCollider2D collider;
+    protected SpriteRenderer spriteRenderer;
     protected bool alive { get => currentHealth > 0; }
+    protected bool roundRunning = false;
     protected FighterTypes fighterType;
     protected string opponentTag;
 
     protected Vector3 initalScale;
     protected Vector3 initalPosition;
+    protected Sprite initialSprite;
 
     protected abstract bool CanAttack();
     protected abstract void Attack();
@@ -40,14 +43,19 @@ public abstract class Fighter : MonoBehaviour
         animator = GetComponent<Animator>();
         rigidbody = GetComponent<Rigidbody2D>();
         collider = GetComponent<BoxCollider2D>();
+        spriteRenderer = GetComponent<SpriteRenderer>();
+
         fighterType = FighterTypes.ENEMY;
+        
         initalPosition = transform.position;
         initalScale = transform.localScale;
+        initialSprite = spriteRenderer.sprite;
     }
 
     protected virtual void Start()
     {
-        currentHealth = Mathf.RoundToInt(baseHealth * GetStats().healthMultiplier);
+        RoundController.instance.roundCallbacks.Add(this);
+        OnRoundEnd();
     }
 
     protected virtual void Update()
@@ -111,4 +119,27 @@ public abstract class Fighter : MonoBehaviour
         }
     }
 
+    public virtual void OnRoundStart()
+    {
+        roundRunning = true;
+        animator.enabled = true;
+        collider.enabled = true;
+        rigidbody.bodyType = RigidbodyType2D.Dynamic;
+        currentHealth = Mathf.RoundToInt(baseHealth * GetStats().healthMultiplier);
+        animator.Play("Idle");
+    }
+
+    public virtual void OnRoundEnd()
+    {
+        roundRunning = false;
+        animator.enabled = false;
+        timeSinceLastAttack = float.PositiveInfinity;
+        collider.enabled = false;
+        rigidbody.bodyType = RigidbodyType2D.Kinematic;
+        rigidbody.velocity = Vector2.zero;
+        rigidbody.MovePosition(initalPosition);
+        transform.localScale = initalScale;
+        spriteRenderer.sprite = initialSprite;
+        callbacks.Clear();
+    }
 }
-- 
GitLab