diff --git a/Assets/Scripts/GameAssembly.asmdef b/Assets/Scripts/GameAssembly.asmdef new file mode 100644 index 0000000..48d70d7 --- /dev/null +++ b/Assets/Scripts/GameAssembly.asmdef @@ -0,0 +1,3 @@ +{ + "name": "GameAssembly" +} diff --git a/Assets/Scripts/GameAssembly.asmdef.meta b/Assets/Scripts/GameAssembly.asmdef.meta new file mode 100644 index 0000000..13d0a8c --- /dev/null +++ b/Assets/Scripts/GameAssembly.asmdef.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 6ee199c72d6db6244ac382d3d4d61bfc +AssemblyDefinitionImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/ILevelObject.cs b/Assets/Scripts/ILevelObject.cs new file mode 100644 index 0000000..13874ff --- /dev/null +++ b/Assets/Scripts/ILevelObject.cs @@ -0,0 +1,3 @@ +public interface ILevelObject +{ +} \ No newline at end of file diff --git a/Assets/Scripts/ILevelObject.cs.meta b/Assets/Scripts/ILevelObject.cs.meta new file mode 100644 index 0000000..1a63bc1 --- /dev/null +++ b/Assets/Scripts/ILevelObject.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: e8c55ebc87e041b419aa13dffc17b91f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/LevelManager.cs b/Assets/Scripts/LevelManager.cs new file mode 100644 index 0000000..6e0001c --- /dev/null +++ b/Assets/Scripts/LevelManager.cs @@ -0,0 +1,58 @@ +using System; +using System.Collections.Generic; + +public class LevelManager : Singleton +{ + public event System.Action Added; + public event System.Action Removed; + + private List levelObjects; + public LevelManager() + { + levelObjects = new List(); + } + + public void Add(ILevelObject levelObject) + { + if (levelObjects.Contains(levelObject)) return; + levelObjects.Add(levelObject); + Added?.Invoke(levelObject); + } + public void Remove(ILevelObject levelObject) + { + if (!levelObjects.Contains(levelObject)) return; + levelObjects.Remove(levelObject); + Removed?.Invoke(levelObject); + } + public void Clear() + { + levelObjects.RemoveAll(obj => + { + Removed?.Invoke(obj); + return true; + }); + } + public T Get(System.Func predicate = default) where T : ILevelObject + { + if (predicate == default) predicate = (t) => true; + return (T)levelObjects.Find(t => t is T t1 && predicate(t1)); + } + public List GetAll(System.Func predicate = default) where T : ILevelObject + { + if (predicate == default) predicate = (t) => true; + List ret = new List(); + foreach (var t in levelObjects) if (t is T t1 && predicate(t1)) ret.Add(t1); + return ret; + } + + public int Count(Func predicate = default) where T : ILevelObject + { + return GetAll(predicate).Count; + } + + public bool Has(System.Func predicate = default) + { + if (predicate == default) predicate = (t) => true; + return levelObjects.Exists(t => t is T && predicate((T)t)); + } +} \ No newline at end of file diff --git a/Assets/Scripts/LevelManager.cs.meta b/Assets/Scripts/LevelManager.cs.meta new file mode 100644 index 0000000..2a75210 --- /dev/null +++ b/Assets/Scripts/LevelManager.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 1af43055ac165604e992f071c5520910 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/ResourceTile.cs b/Assets/Scripts/ResourceTile.cs new file mode 100644 index 0000000..26bfe99 --- /dev/null +++ b/Assets/Scripts/ResourceTile.cs @@ -0,0 +1,42 @@ +using System.Collections; +using System.Collections.Generic; +using UnityEngine; +using UnityEngine.Tilemaps; + + +[CreateAssetMenu(menuName = "Gather And Defend/Resource Tile")] +public class ResourceTile : TileBase +{ + public class ResourceTileData : ILevelObject + { + private Vector3 _position; + private string _resourceType; + + public Vector3 Position => _position; + public string ResourceType => _resourceType; + + public ResourceTileData(Vector2 position, string resourceType) + { + this._position = position; + this._resourceType = resourceType; + } + } + [SerializeField] + private Sprite _sprite; + public override bool StartUp(Vector3Int position, ITilemap tilemap, GameObject go) + { + if (!Application.isPlaying) return base.StartUp(position, tilemap, go); + if (position == new Vector3Int(-5, -5)) + { + Debug.Log("Yo"); + } + LevelManager.Instance.Add(new ResourceTileData((Vector3)position, name)); + return base.StartUp(position, tilemap, go); + } + public override void GetTileData(Vector3Int position, ITilemap tilemap, ref TileData tileData) + { + tileData.sprite = _sprite; + tileData.transform.SetTRS(Vector3.zero, Quaternion.identity, Vector3.one); + tileData.color = Color.white; + } +} \ No newline at end of file diff --git a/Assets/Scripts/ResourceTile.cs.meta b/Assets/Scripts/ResourceTile.cs.meta new file mode 100644 index 0000000..704714e --- /dev/null +++ b/Assets/Scripts/ResourceTile.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 84b05f2a26f63da46a1028488482d079 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Singleton.cs b/Assets/Scripts/Singleton.cs new file mode 100644 index 0000000..274efff --- /dev/null +++ b/Assets/Scripts/Singleton.cs @@ -0,0 +1,12 @@ +public class Singleton where T : Singleton, new() +{ + private static T _instance; + public static T Instance + { + get + { + if (_instance == null) _instance = new T(); + return _instance; + } + } +} \ No newline at end of file diff --git a/Assets/Scripts/Singleton.cs.meta b/Assets/Scripts/Singleton.cs.meta new file mode 100644 index 0000000..6a83a8a --- /dev/null +++ b/Assets/Scripts/Singleton.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 7f3fd6219c44e484db1f5c351626bf3e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Tests.meta b/Assets/Tests.meta new file mode 100644 index 0000000..2f07245 --- /dev/null +++ b/Assets/Tests.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: fc8abee0ea7bd1a47b2fcce297d01648 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Tests/Playmode.meta b/Assets/Tests/Playmode.meta new file mode 100644 index 0000000..904119f --- /dev/null +++ b/Assets/Tests/Playmode.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 48410eca65be77149bf834b1df6f55f5 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Tests/Playmode/Playmode.asmdef b/Assets/Tests/Playmode/Playmode.asmdef new file mode 100644 index 0000000..9e10228 --- /dev/null +++ b/Assets/Tests/Playmode/Playmode.asmdef @@ -0,0 +1,22 @@ +{ + "name": "Tests", + "rootNamespace": "", + "references": [ + "UnityEngine.TestRunner", + "UnityEditor.TestRunner", + "GameAssembly" + ], + "includePlatforms": [], + "excludePlatforms": [], + "allowUnsafeCode": false, + "overrideReferences": true, + "precompiledReferences": [ + "nunit.framework.dll" + ], + "autoReferenced": false, + "defineConstraints": [ + "UNITY_INCLUDE_TESTS" + ], + "versionDefines": [], + "noEngineReferences": false +} \ No newline at end of file diff --git a/Assets/Tests/Playmode/Playmode.asmdef.meta b/Assets/Tests/Playmode/Playmode.asmdef.meta new file mode 100644 index 0000000..6ab6141 --- /dev/null +++ b/Assets/Tests/Playmode/Playmode.asmdef.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 35cea9d83a6dea3488659da5d3f262a9 +AssemblyDefinitionImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Tests/Playmode/TestLevelManager.cs b/Assets/Tests/Playmode/TestLevelManager.cs new file mode 100644 index 0000000..9a1f965 --- /dev/null +++ b/Assets/Tests/Playmode/TestLevelManager.cs @@ -0,0 +1,54 @@ +using System.Collections; +using System.Collections.Generic; +using NUnit.Framework; +using UnityEngine; +using UnityEngine.TestTools; +using UnityEngine.Tilemaps; + +public class TestLevelManager +{ + private ResourceTile farm; + private Tilemap tilemap; + const int size = 25; + const int sqrt_size = 5; + [SetUp] + public void SetUp() + { + farm = ScriptableObject.CreateInstance(); + farm.name = nameof(farm); + + tilemap = new GameObject("Tilemap").AddComponent(); + for (int i = 0; i < size; i++) + { + var pos = new Vector3Int(i % sqrt_size, i / sqrt_size); + tilemap.SetTile(pos, farm); + } + } + [TearDown] + public void TearDown() + { + Object.Destroy(tilemap.gameObject); + } + + // A UnityTest behaves like a coroutine in Play Mode. In Edit Mode you can use + // `yield return null;` to skip a frame. + [UnityTest] + public IEnumerator TestLevelManagerWithEnumeratorPasses() + { + yield return null; + Assert.AreEqual(LevelManager.Instance.Count(), size, "there should be " + size + " tiles"); + for (int i = 0; i < 25; i++) + { + var pos = new Vector3(i % sqrt_size, i / sqrt_size); + var tileExists = LevelManager.Instance.Has(t => Mathf.Approximately(Vector2.Distance(pos, t.Position), 0)); + Assert.True(tileExists, "there should be a tile at position " + pos); + } + + var newPos = new Vector3Int(-5, -5); + tilemap.SetTile(newPos, farm); + yield return null; + + var newTileExists = LevelManager.Instance.Has(t => Mathf.Approximately(Vector3.Distance(t.Position, newPos), 0)); + Assert.True(newTileExists, "new tile wasn't added to level manager"); + } +} diff --git a/Assets/Tests/Playmode/TestLevelManager.cs.meta b/Assets/Tests/Playmode/TestLevelManager.cs.meta new file mode 100644 index 0000000..6de040c --- /dev/null +++ b/Assets/Tests/Playmode/TestLevelManager.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: c8b5cb265fff43142b83e2584ba2620e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: