using System; using System.Collections.Generic; using UnityEngine; public class TagManager : MonoBehaviour { public enum ETag { PlayerOwned, EnemyOwned, Player, CastleCenter, MeeleFighter, RangedFighter, Flying, PlayerUnit, Building, SiegeWeapon, AUTO_Alive, AUTO_KnockedOutAndHealOnDawn, Wall, InfrastructureEconomy, TakesReducedDamageFromPlayerAttacks, PracticeTargets, FastMoving, ArmoredAgainstRanged, VulnerableVsRanged, Monster, House, WallOrTower, AUTO_Commanded, TakesIncreasedDamageFromTowers, Tower, AUTO_NoReviveNextMorning, PlayerOwnedPriorityTarget, BlockableEnemyProjectile, Boss, UselessWallThatDoesNotBlockPath } public static TagManager instance; [SerializeField] private Dictionary> dictonaryOfListsOfTaggedObjects; private List tempTaggedObjectList = new List(); private List bufferedPlayerUnits = new List(); private List bufferedEnemyUnits = new List(); private List bufferedPlayers = new List(); public List playerBuildingInteractors = new List(); public List freeCoins = new List(); public List coins = new List(); public IReadOnlyList PlayerUnits => bufferedPlayerUnits.AsReadOnly(); public IReadOnlyList EnemyUnits => bufferedEnemyUnits.AsReadOnly(); public IReadOnlyList Players => bufferedPlayers.AsReadOnly(); private void OnEnable() { instance = this; dictonaryOfListsOfTaggedObjects = new Dictionary>(); for (int i = 0; i < Enum.GetValues(typeof(ETag)).Length; i++) { dictonaryOfListsOfTaggedObjects.Add((ETag)i, new List()); } } public void AddTaggedObject(TaggedObject _taggedObject) { foreach (ETag tag in _taggedObject.Tags) { AddTag(_taggedObject, tag); if (tag == ETag.EnemyOwned) { bufferedEnemyUnits.Add(_taggedObject); } if (tag == ETag.PlayerUnit) { bufferedPlayerUnits.Add(_taggedObject); } if (tag == ETag.Player) { bufferedPlayers.Add(_taggedObject); } } } public void RemoveTaggedObject(TaggedObject _taggedObject) { if (bufferedEnemyUnits.Contains(_taggedObject)) { bufferedEnemyUnits.Remove(_taggedObject); } if (bufferedPlayerUnits.Contains(_taggedObject)) { bufferedPlayerUnits.Remove(_taggedObject); } foreach (ETag tag in _taggedObject.Tags) { RemoveTag(_taggedObject, tag); } } public void AddTag(TaggedObject _taggedObject, ETag _tag) { List list = dictonaryOfListsOfTaggedObjects[_tag]; if (!list.Contains(_taggedObject)) { list.Add(_taggedObject); } } public void RemoveTag(TaggedObject _taggedObject, ETag _tag) { List list = dictonaryOfListsOfTaggedObjects[_tag]; if (list.Contains(_taggedObject)) { list.Remove(_taggedObject); } } public int CountObjectsWithTag(ETag _tag) { return dictonaryOfListsOfTaggedObjects[_tag].Count; } public void FindAllTaggedObjectsWithTags(List _listToPolulate, List _mustHaveTags, List _mayNotHaveTags) { _listToPolulate.Clear(); if (_mustHaveTags.Count <= 0) { return; } List list = null; int num = int.MaxValue; for (int i = 0; i < _mustHaveTags.Count; i++) { List list2 = dictonaryOfListsOfTaggedObjects[_mustHaveTags[i]]; if (list2.Count < num) { list = list2; num = list2.Count; } } if (list.Count == 0) { return; } for (int j = 0; j < list.Count; j++) { TaggedObject taggedObject = list[j]; List tags = taggedObject.Tags; bool flag = true; if (_mustHaveTags != null) { for (int k = 0; k < _mustHaveTags.Count; k++) { if (!tags.Contains(_mustHaveTags[k])) { flag = false; break; } } } if (_mayNotHaveTags != null) { for (int l = 0; l < _mayNotHaveTags.Count; l++) { if (tags.Contains(_mayNotHaveTags[l])) { flag = false; break; } } } if (flag) { _listToPolulate.Add(taggedObject); } } } public TaggedObject FindClosestTaggedObjectWithTags(Vector3 _position, List _mustHaveTags, List _mayNotHaveTags) { tempTaggedObjectList.Clear(); FindAllTaggedObjectsWithTags(tempTaggedObjectList, _mustHaveTags, _mayNotHaveTags); TaggedObject result = null; float num = float.MaxValue; for (int i = 0; i < tempTaggedObjectList.Count; i++) { TaggedObject taggedObject = tempTaggedObjectList[i]; float num2 = MeasureDistanceToTaggedObject(taggedObject, _position); if (num2 < num) { num = num2; result = taggedObject; } } return result; } public float MeasureDistanceToTaggedObject(TaggedObject _taggedObj, Vector3 _pos) { if (_taggedObj.colliderForBigOjectsToMeasureDistance != null) { return (_taggedObj.colliderForBigOjectsToMeasureDistance.ClosestPoint(_pos) - _pos).magnitude; } return (_taggedObj.transform.position - _pos).magnitude; } public int CountAllTaggedObjectsWithTag(ETag _mustHaveTag) { return dictonaryOfListsOfTaggedObjects[_mustHaveTag].Count; } }