diff --git a/theProject/Assets/Prefabs/Soldier.prefab b/theProject/Assets/Prefabs/Soldier.prefab index 4fdf4327..60fe757a 100644 --- a/theProject/Assets/Prefabs/Soldier.prefab +++ b/theProject/Assets/Prefabs/Soldier.prefab @@ -78,22 +78,22 @@ MonoBehaviour: m_Script: {fileID: 11500000, guid: d34caf35d0ce610f8bc87cf815ba1915, type: 3} m_Name: m_EditorClassIdentifier: + myTeam: 0 maxHealthPoints: 100 healthPoints: 100 - rangeAttack: 3 - rangeView: 1 - damageAttack: 1 - speedAttack: 2 - lastAttackTick: -1 nameText: {fileID: 6838251604148675782} healthPointsText: {fileID: 8012357605284019061} - target: {fileID: 0} - enemyType: 0 - ourType: 0 - movementDestination: {x: 0, y: 0} - onDeath: + OnDeath: m_PersistentCalls: m_Calls: [] + rangeAttack: 3 + rangeView: 1 + damageAttack: 25 + speedAttack: 2 + lastAttackTick: -1 + target: {fileID: 0} + enemyType: 0 + movementDestination: {x: 0, y: 0} --- !u!1 &1997457243244158843 GameObject: m_ObjectHideFlags: 0 @@ -358,12 +358,12 @@ MonoBehaviour: m_margin: {x: 0, y: 0, z: 0, w: 0} m_isUsingLegacyAnimationComponent: 0 m_isVolumetricText: 0 - m_hasFontAssetChanged: 0 - m_renderer: {fileID: 1498494949006888735} - m_maskType: 0 _SortingLayer: 0 _SortingLayerID: 0 _SortingOrder: 0 + m_hasFontAssetChanged: 0 + m_renderer: {fileID: 1498494949006888735} + m_maskType: 0 --- !u!1 &2062275012809416088 GameObject: m_ObjectHideFlags: 0 @@ -530,9 +530,9 @@ MonoBehaviour: m_margin: {x: 0, y: 0, z: 0, w: 0} m_isUsingLegacyAnimationComponent: 0 m_isVolumetricText: 0 - m_hasFontAssetChanged: 0 - m_renderer: {fileID: 4083783489867894370} - m_maskType: 0 _SortingLayer: 0 _SortingLayerID: 0 _SortingOrder: 0 + m_hasFontAssetChanged: 0 + m_renderer: {fileID: 4083783489867894370} + m_maskType: 0 diff --git a/theProject/Assets/Scenes/SpartaqS.unity b/theProject/Assets/Scenes/SpartaqS.unity index 3f417989..b0858a39 100644 --- a/theProject/Assets/Scenes/SpartaqS.unity +++ b/theProject/Assets/Scenes/SpartaqS.unity @@ -156,16 +156,15 @@ MonoBehaviour: WORLD_SPACE_OFFSET: {x: 0.5, y: 1, z: 0.5} allyBaseCoord: {x: 0, y: 0} soldierStartingPositions: - - {x: 0, y: 0} + - {x: 1, y: 0} - {x: 1, y: 2} enemyBaseCoord: {x: 0, y: 0} enemyStartingPositions: - {x: 2, y: 0} - - {x: 9, y: 5} tilemap: {fileID: 1853262998} soldierPrefab: {fileID: 403095692180922766, guid: a87b1aa46b0ed3e0fba621e11dd4f1e2, type: 3} - basePrefab: {fileID: 6141901885681798073, guid: e79038bbfa9535f45be1d0f0ae0626ce, + basePrefab: {fileID: 403095692180922766, guid: cff761b70fcb1dc55bfd414849823b2e, type: 3} --- !u!4 &282616949 Transform: diff --git a/theProject/Assets/Scripts/Entities.meta b/theProject/Assets/Scripts/Entities.meta new file mode 100644 index 00000000..c364ba69 --- /dev/null +++ b/theProject/Assets/Scripts/Entities.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 2e5f405b6facc6e47a0297f2be93eae4 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/theProject/Assets/Scripts/Entities/Base.cs b/theProject/Assets/Scripts/Entities/Base.cs new file mode 100644 index 00000000..1dbc47c3 --- /dev/null +++ b/theProject/Assets/Scripts/Entities/Base.cs @@ -0,0 +1,9 @@ +using System.Collections; +using System.Collections.Generic; +using TMPro; +using UnityEngine; + +public class Base : Entity +{ + +} diff --git a/theProject/Assets/Scripts/Base.cs.meta b/theProject/Assets/Scripts/Entities/Base.cs.meta similarity index 100% rename from theProject/Assets/Scripts/Base.cs.meta rename to theProject/Assets/Scripts/Entities/Base.cs.meta diff --git a/theProject/Assets/Scripts/Base.cs b/theProject/Assets/Scripts/Entities/Entity.cs similarity index 51% rename from theProject/Assets/Scripts/Base.cs rename to theProject/Assets/Scripts/Entities/Entity.cs index 3b3c9365..74e64ec5 100644 --- a/theProject/Assets/Scripts/Base.cs +++ b/theProject/Assets/Scripts/Entities/Entity.cs @@ -1,73 +1,86 @@ -using System.Collections; -using System.Collections.Generic; -using TMPro; -using UnityEngine; - -public class Base : MonoBehaviour -{ - public enum SoldierType - { - Ally, - Enemy - } - [SerializeField] protected SoldierType ourType; - [SerializeField] private float maxHealthPoints = 100; - [SerializeField] private float healthPoints = 100; - - [SerializeField] private TMP_Text nameText = null; - [SerializeField] private TMP_Text healthPointsText = null; - - public SoldierType TempGetOwnType() - { - return ourType; - } - - // Start is called before the first frame update - protected void Start(){ - healthPoints = maxHealthPoints; // initialize health - UpdateHPDisplay(); - - Debug.Log("Base: " + ourType.ToString() + " has appeared", gameObject); - - switch (ourType) - { - case SoldierType.Ally: - nameText.text = "Ally"; - nameText.color = Color.blue; - break; - case SoldierType.Enemy: - nameText.text = "Enemy"; - nameText.color = Color.red; - break; - default: - nameText.text = "how did we get here (forever)"; - nameText.color = new Color(255, 192, 203); - break; - } - } - - public void setOwnTag(SoldierType type) - { - ourType = type; - } - - protected void OnDestroy() - { - Debug.Log("Soldier: " + ourType.ToString() + " has died", gameObject); - } - protected void ReduceHP(float damage) - { - healthPoints -= damage; - - if (healthPoints <= 0) - Destroy(gameObject); - - UpdateHPDisplay(); - Debug.Log("I took damage, my HP is now: " + healthPoints + " noooo!!!!", gameObject); - } - - protected void UpdateHPDisplay() - { - healthPointsText.text = healthPoints.ToString() + "/" + maxHealthPoints.ToString(); - } -} +using System.Collections; +using System.Collections.Generic; +using TMPro; +using UnityEngine; +using UnityEngine.Events; + +public class Entity : MonoBehaviour +{ + public enum Team + { + Ally, + Enemy + } + [Header("Values")] + [SerializeField] protected Team myTeam; + [SerializeField] protected float maxHealthPoints = 100; + [SerializeField] protected float healthPoints = 100; + + [SerializeField] protected TMP_Text nameText = null; + [SerializeField] protected TMP_Text healthPointsText = null; + + [HideInInspector] public UnityEvent OnDeath = new UnityEvent(); + + + public Team GetOwnTeam() + { + return myTeam; + } + + // Start is called before the first frame update + protected virtual void Start(){ + healthPoints = maxHealthPoints; // initialize health + UpdateHPDisplay(); + + Debug.Log("Entity: " + myTeam.ToString() + " has appeared", gameObject); + + switch (myTeam) + { + case Team.Ally: + nameText.text = "Ally"; + nameText.color = Color.blue; + break; + case Team.Enemy: + nameText.text = "Enemy"; + nameText.color = Color.red; + break; + default: + nameText.text = "how did we get here (forever)"; + nameText.color = new Color(255, 192, 203); + break; + } + } + + public void SetOwnTeam(Team type) + { + myTeam = type; + } + + public void ReduceHP(float damage) + { + healthPoints -= damage; + + if (healthPoints <= 0) + Destroy(gameObject); + + UpdateHPDisplay(); + Debug.Log("I took damage, my HP is now: " + healthPoints + " noooo!!!!", gameObject); + } + + protected virtual void Die() + { + OnDeath.Invoke(this); + Destroy(gameObject); + } + + private void OnDestroy() + { + Debug.Log("Soldier: " + myTeam.ToString() + " has died", gameObject); + } + + + protected void UpdateHPDisplay() + { + healthPointsText.text = healthPoints.ToString() + "/" + maxHealthPoints.ToString(); + } +} diff --git a/theProject/Assets/Scripts/Entities/Entity.cs.meta b/theProject/Assets/Scripts/Entities/Entity.cs.meta new file mode 100644 index 00000000..03b03e8f --- /dev/null +++ b/theProject/Assets/Scripts/Entities/Entity.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: d77d5669fae0f57499970c2aed5af02b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/theProject/Assets/Scripts/Soldier.cs b/theProject/Assets/Scripts/Entities/Soldier.cs similarity index 73% rename from theProject/Assets/Scripts/Soldier.cs rename to theProject/Assets/Scripts/Entities/Soldier.cs index 5c5e4cf4..d609d74c 100644 --- a/theProject/Assets/Scripts/Soldier.cs +++ b/theProject/Assets/Scripts/Entities/Soldier.cs @@ -1,171 +1,157 @@ -using System.Collections; -using System.Collections.Generic; -using TMPro; -using UnityEngine; -using UnityEngine.Events; - -public class Soldier : Base -{ - private Queue actions = new Queue(); - private Queue interrupts = new Queue(); - #region Action Queue Items - abstract class Action // action "template" - { - public virtual void Execute(Soldier soldier, TickSystem.OnTickEventArgs tickEventArgs) { } // called by Soldier when action is supposed to be done - } - - private class Movement : Action - { - public override void Execute(Soldier soldier, TickSystem.OnTickEventArgs tickEventArgs) - {//TO DO: CALL PROPER FUNCTION TO MOVE - throw new System.NotImplementedException($"(tick: {tickEventArgs.tickNumber}) Trying to teleport to {soldier.movementDestination}"); - //??tileMap.Teleport(movementDestination) - } - } - private class TryAttack : Action - { - public override void Execute(Soldier soldier, TickSystem.OnTickEventArgs tickEventArgs) - { - //Debug.LogWarning($"(tick: {tickEventArgs.tickNumber}) Looking for enemy in range"); - if(soldier.TryAttackEnemy()) - soldier.lastAttackTick = tickEventArgs.tickNumber; - } - } - #endregion - - #region Handling Incoming Orders (Interrupts) - public void HandleMovementOrder(Vector2Int destination) - { - movementDestination = destination; - interrupts.Enqueue(new Movement()); // force soldier to find path to the new destination - } - #endregion - - [Header("Values")] - [SerializeField] private float rangeAttack = 100; - [SerializeField] private float rangeView = 1; - [SerializeField] private float damageAttack = 1; - [SerializeField] private int speedAttack = 1; // ticks between attacks - [SerializeField] private int lastAttackTick = -1; - [Header("References")] - [Header("Do-not-change-in-game values")] - [SerializeField] private Soldier target; - [SerializeField] private SoldierType enemyType; - - [SerializeField] private Vector2Int movementDestination = Vector2Int.zero; - - - - // variables not visible in inspector - - [HideInInspector] public UnityEvent onDeath = new UnityEvent(); - - public SoldierType GetOwnType() - { - return ourType; - } - - // Start is called before the first frame update - void Start(){ - base.Start(); - setEnemyTag(); - } - - public void setEnemyTag() - { - if(ourType == SoldierType.Ally) enemyType = SoldierType.Enemy; - else enemyType = SoldierType.Ally; - } - - void Awake() - { - TickSystem.OnTick += HandleTick; - } - - private void Die() - { - TickSystem.OnTick -= HandleTick; - onDeath.Invoke(this); - Destroy(gameObject); - } - - private void OnDestroy() - { - Debug.Log("Soldier: " + ourType.ToString() + " has died", gameObject); - } - - private void HandleTick(TickSystem.OnTickEventArgs tickEventArgs) - { - ref Queue queueToHandle = ref interrupts; - if (interrupts.Count < 1) // if no interrupt actions to do, handle regular queue - queueToHandle = actions; - - if(queueToHandle.Count > 0) - queueToHandle.Dequeue().Execute(this, tickEventArgs); - else - { - if(lastAttackTick + speedAttack <= tickEventArgs.tickNumber) - { - queueToHandle.Enqueue(new TryAttack()); - queueToHandle.Dequeue().Execute(this, tickEventArgs); - } - } - } - - bool TryAttackEnemy () //returns true if an enemy was attacked - { - // Enemies are the game objects tagged with the "Enemy" - //GameObject[] enemies = GameObject.FindGameObjectsWithTag(enemyType); - Soldier[] soldiers = GameObject.FindObjectsOfType(); - - List enemiesList = new List(); - - foreach (Soldier obj in soldiers) - { - if (obj.ourType == enemyType) - enemiesList.Add(obj); - } - - Soldier[] enemies = enemiesList.ToArray(); - - // We have not found enemy yet so the distance to enemy is "infinite" - float shortestDistance = Mathf.Infinity; - Soldier nearestEnemy = null; - foreach ( Soldier enemy in enemies) - { - // Go through each enemy existing - // Calculate distance to this enemy - float distanceToEnemy = Vector3.Distance(transform.position, enemy.transform.position); - if (distanceToEnemy < shortestDistance) - { - shortestDistance = distanceToEnemy; - nearestEnemy = enemy; - } - } - - if (nearestEnemy != null && shortestDistance <= rangeAttack) - { - target = nearestEnemy; - } - else - target = null; - - if (target != null) - target.ReduceHP(damageAttack); - - return target != null; - } - - // Update is called once per frame - void Update() - { - //if (target == null) return; - } - - /* https://www.youtube.com/watch?v=QKhn2kl9_8I 08:54 Soldier attack - void OnDrawGizmosSelected () - { - - } - */ -} +using System.Collections; +using System.Collections.Generic; +using TMPro; +using UnityEngine; +using UnityEngine.Events; + +public class Soldier : Entity +{ + private Queue actions = new Queue(); + private Queue interrupts = new Queue(); + #region Action Queue Items + abstract class Action // action "template" + { + public virtual void Execute(Soldier soldier, TickSystem.OnTickEventArgs tickEventArgs) { } // called by Soldier when action is supposed to be done + } + + private class Movement : Action + { + public override void Execute(Soldier soldier, TickSystem.OnTickEventArgs tickEventArgs) + {//TO DO: CALL PROPER FUNCTION TO MOVE + throw new System.NotImplementedException($"(tick: {tickEventArgs.tickNumber}) Trying to teleport to {soldier.movementDestination}"); + //??tileMap.Teleport(movementDestination) + } + } + private class TryAttack : Action + { + public override void Execute(Soldier soldier, TickSystem.OnTickEventArgs tickEventArgs) + { + //Debug.LogWarning($"(tick: {tickEventArgs.tickNumber}) Looking for enemy in range"); + if(soldier.TryAttackEnemy()) + soldier.lastAttackTick = tickEventArgs.tickNumber; + } + } + #endregion + + #region Handling Incoming Orders (Interrupts) + public void HandleMovementOrder(Vector2Int destination) + { + movementDestination = destination; + interrupts.Enqueue(new Movement()); // force soldier to find path to the new destination + } + #endregion + + [Header("Soldier Values")] + [SerializeField] private float rangeAttack = 100; + [SerializeField] private float rangeView = 1; + [SerializeField] private float damageAttack = 1; + [SerializeField] private int speedAttack = 1; // ticks between attacks + [SerializeField] private int lastAttackTick = -1; + [Header("References")] + [Header("Do-not-change-in-game values")] + [SerializeField] private Entity target; + [SerializeField] private Team enemyType; + + [SerializeField] private Vector2Int movementDestination = Vector2Int.zero; + + // Start is called before the first frame update + protected override void Start(){ + base.Start(); + SetEnemyTag(); + } + + public void SetEnemyTag() + { + if(myTeam == Team.Ally) enemyType = Team.Enemy; + else enemyType = Team.Ally; + } + + void Awake() + { + TickSystem.OnTick += HandleTick; + } + + protected override void Die() + { + TickSystem.OnTick -= HandleTick; + base.Die(); + } + + private void HandleTick(TickSystem.OnTickEventArgs tickEventArgs) + { + ref Queue queueToHandle = ref interrupts; + if (interrupts.Count < 1) // if no interrupt actions to do, handle regular queue + queueToHandle = actions; + + if(queueToHandle.Count > 0) + queueToHandle.Dequeue().Execute(this, tickEventArgs); + else + { + if(lastAttackTick + speedAttack <= tickEventArgs.tickNumber) + { + queueToHandle.Enqueue(new TryAttack()); + queueToHandle.Dequeue().Execute(this, tickEventArgs); + } + } + } + + bool TryAttackEnemy () //returns true if an enemy was attacked + { + // Enemies are the game objects tagged with the "Enemy" + //GameObject[] enemies = GameObject.FindGameObjectsWithTag(enemyType); + Entity[] soldiers = GameObject.FindObjectsOfType(); + + List enemiesList = new List(); + + foreach (Entity obj in soldiers) + { + if (obj.GetOwnTeam() == enemyType) + enemiesList.Add(obj); + } + + Debug.Log(soldiers.Length); + Debug.Log(enemiesList.Count); + Entity[] enemies = enemiesList.ToArray(); + + // We have not found enemy yet so the distance to enemy is "infinite" + float shortestDistance = Mathf.Infinity; + Entity nearestEnemy = null; + foreach (Entity enemy in enemies) + { + // Go through each enemy existing + // Calculate distance to this enemy + float distanceToEnemy = Vector3.Distance(transform.position, + enemy.transform.position); + if (distanceToEnemy < shortestDistance) + { + shortestDistance = distanceToEnemy; + nearestEnemy = enemy; + } + } + + if (nearestEnemy != null && shortestDistance <= rangeAttack) + { + target = nearestEnemy; + } + else + target = null; + + if (target != null) + target.ReduceHP(damageAttack); + + return target != null; + } + + // Update is called once per frame + void Update() + { + //if (target == null) return; + } + + /* https://www.youtube.com/watch?v=QKhn2kl9_8I 08:54 Soldier attack + void OnDrawGizmosSelected () + { + + } + */ +} diff --git a/theProject/Assets/Scripts/Soldier.cs.meta b/theProject/Assets/Scripts/Entities/Soldier.cs.meta similarity index 100% rename from theProject/Assets/Scripts/Soldier.cs.meta rename to theProject/Assets/Scripts/Entities/Soldier.cs.meta diff --git a/theProject/Assets/Scripts/Managers/SquadManager.cs b/theProject/Assets/Scripts/Managers/SquadManager.cs index b9c070c6..5235c370 100644 --- a/theProject/Assets/Scripts/Managers/SquadManager.cs +++ b/theProject/Assets/Scripts/Managers/SquadManager.cs @@ -27,7 +27,7 @@ public class SquadManager : MonoBehaviour var soldiers = FindObjectsOfType(); foreach(var soldier in soldiers) { - if(soldier.GetOwnType() == Soldier.SoldierType.Ally) + if(soldier.GetOwnTeam() == Soldier.Team.Ally) { playerSquad.TempAddSoldierToSquad(soldier); } diff --git a/theProject/Assets/Scripts/Managers/TilemapManager.cs b/theProject/Assets/Scripts/Managers/TilemapManager.cs index bdd22ae9..1b8b9988 100644 --- a/theProject/Assets/Scripts/Managers/TilemapManager.cs +++ b/theProject/Assets/Scripts/Managers/TilemapManager.cs @@ -14,7 +14,7 @@ public class TilemapManager : MonoBehaviour public struct Tile { - public Soldier standingSoldier; + public Entity standingEntity; } [Header("Common Values")] @@ -99,16 +99,16 @@ public class TilemapManager : MonoBehaviour return false; if (isBase) - tiles[x, y].standingSoldier = Instantiate(basePrefab, tilemap.CellToWorld(new Vector3Int(x, y, 0)) + WORLD_SPACE_OFFSET, Quaternion.identity).GetComponent(); - if (isBase) - tiles[x, y].standingSoldier = Instantiate(soldierPrefab, tilemap.CellToWorld(new Vector3Int(x, y, 0)) + WORLD_SPACE_OFFSET, Quaternion.identity).GetComponent(); + tiles[x, y].standingEntity = Instantiate(basePrefab, tilemap.CellToWorld(new Vector3Int(x, y, 0)) + WORLD_SPACE_OFFSET, Quaternion.identity).GetComponent(); + else + tiles[x, y].standingEntity = Instantiate(soldierPrefab, tilemap.CellToWorld(new Vector3Int(x, y, 0)) + WORLD_SPACE_OFFSET, Quaternion.identity).GetComponent(); if (isAlly) - tiles[x, y].standingSoldier.setOwnTag(Soldier.SoldierType.Ally); + tiles[x, y].standingEntity.SetOwnTeam(Base.Team.Ally); else - tiles[x, y].standingSoldier.setOwnTag(Soldier.SoldierType.Enemy); + tiles[x, y].standingEntity.SetOwnTeam(Base.Team.Enemy); - if (tiles[x, y].standingSoldier != null) + if (tiles[x, y].standingEntity != null) return true; return false; @@ -119,42 +119,29 @@ public class TilemapManager : MonoBehaviour if (GetTileState(x, y) != TileState.taken) return false; - Destroy(tiles[x, y].standingSoldier.gameObject); - tiles[x, y].standingSoldier = null; + Destroy(tiles[x, y].standingEntity.gameObject); + tiles[x, y].standingEntity = null; Debug.Log("Despaned a soldier"); return true; } - public Soldier GetSoldier(int x, int y) + public Entity GetSoldier(int x, int y) { if (GetTileState(x, y) != TileState.taken) return null; - return tiles[x,y].standingSoldier; + return tiles[x,y].standingEntity; } - public Soldier[] GetAllSoldiers() - { - List list = new List(); - - foreach (Tile obj in tiles) - { - if (obj.standingSoldier != null) - list.Add(obj.standingSoldier); - } - - return list.ToArray(); - } - - public bool MoveSoldier(int x1, int y1, int x2, int y2) + public bool MoveEntity(int x1, int y1, int x2, int y2) // old MoveSoldier { if (GetTileState(x1, y1) == TileState.taken && GetTileState(x2, y2) == TileState.free) { - tiles[x2, y2].standingSoldier = tiles[x1, y1].standingSoldier; - tiles[x1, y1].standingSoldier = null; + tiles[x2, y2].standingEntity = tiles[x1, y1].standingEntity; + tiles[x1, y1].standingEntity = null; - tiles[x2, y2].standingSoldier.transform.position = tilemap.CellToWorld(new Vector3Int(x2, y2, 0)); + tiles[x2, y2].standingEntity.transform.position = tilemap.CellToWorld(new Vector3Int(x2, y2, 0)) + WORLD_SPACE_OFFSET; return true; } @@ -169,7 +156,7 @@ public class TilemapManager : MonoBehaviour if (x < 0 || y < 0 || x >= mapSize.x || y >= mapSize.y) return TileState.outOfBounds; - if (tiles[x, y].standingSoldier == null) + if (tiles[x, y].standingEntity == null) return TileState.free; return TileState.taken;