From 858dd43fed171f188ec39df82ecfe56902cbc581 Mon Sep 17 00:00:00 2001 From: Uamgl Date: Tue, 29 Mar 2022 19:13:27 +0200 Subject: [PATCH] Unit work completed --- .vscode/launch.json | 41 ++ Assets/Scripts/AI/AIAgent.cs | 35 +- Assets/Scripts/AI/AIBase.cs | 27 +- Assets/Scripts/AI/AIInvader.cs | 33 ++ .../{AIPatrol.cs.meta => AIInvader.cs.meta} | 0 Assets/Scripts/AI/AIManager.cs | 382 +++++++----------- Assets/Scripts/AI/AIPatrol.cs | 20 - Assets/Scripts/AI/AIWarior.cs | 46 +++ Assets/Scripts/AI/AIWarior.cs.meta | 11 + Assets/Scripts/AI/Unit.cs | 114 ++++++ Assets/Scripts/AI/Unit.cs.meta | 11 + Assets/Scripts/AI/Warior.cs | 92 +++++ Assets/Scripts/AI/Warior.cs.meta | 11 + Assets/Scripts/CheatMenu.cs | 4 +- Assets/Scripts/Controller/GameInit.cs | 12 +- Assets/Scripts/GameUI/PlayerInventoryView.cs | 15 +- Assets/Scripts/Items/Bonus.cs | 5 +- Assets/Scripts/Items/Building.cs | 2 +- Assets/Scripts/Items/SwitchingPlaces.cs | 1 + Assets/Scripts/Units/PlayerControl.cs | 2 +- Assets/Scripts/Units/Unit.cs | 2 +- Assets/Scripts/Units/UnitFactory.cs | 8 +- Assets/Scripts/Units/Views/UnitView.cs | 5 +- Assets/Scripts/Units/Views/ViewBase.cs | 3 +- Assets/Scripts/Units/Views/WariorView.cs | 5 +- .../Units/Wariors/AbstractsBase/Invader.cs | 6 +- Assets/Scripts/Units/Wariors/WariorFactory.cs | 2 +- 27 files changed, 567 insertions(+), 328 deletions(-) create mode 100644 .vscode/launch.json create mode 100644 Assets/Scripts/AI/AIInvader.cs rename Assets/Scripts/AI/{AIPatrol.cs.meta => AIInvader.cs.meta} (100%) delete mode 100644 Assets/Scripts/AI/AIPatrol.cs create mode 100644 Assets/Scripts/AI/AIWarior.cs create mode 100644 Assets/Scripts/AI/AIWarior.cs.meta create mode 100644 Assets/Scripts/AI/Unit.cs create mode 100644 Assets/Scripts/AI/Unit.cs.meta create mode 100644 Assets/Scripts/AI/Warior.cs create mode 100644 Assets/Scripts/AI/Warior.cs.meta diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 00000000..42fe90e4 --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,41 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "name": ".NET Core Launch (console)", + "type": "coreclr", + "request": "launch", + "WARNING01": "*********************************************************************************", + "WARNING02": "The C# extension was unable to automatically decode projects in the current", + "WARNING03": "workspace to create a runnable launch.json file. A template launch.json file has", + "WARNING04": "been created as a placeholder.", + "WARNING05": "", + "WARNING06": "If OmniSharp is currently unable to load your project, you can attempt to resolve", + "WARNING07": "this by restoring any missing project dependencies (example: run 'dotnet restore')", + "WARNING08": "and by fixing any reported errors from building the projects in your workspace.", + "WARNING09": "If this allows OmniSharp to now load your project then --", + "WARNING10": " * Delete this file", + "WARNING11": " * Open the Visual Studio Code command palette (View->Command Palette)", + "WARNING12": " * run the command: '.NET: Generate Assets for Build and Debug'.", + "WARNING13": "", + "WARNING14": "If your project requires a more complex launch configuration, you may wish to delete", + "WARNING15": "this configuration and pick a different template using the 'Add Configuration...'", + "WARNING16": "button at the bottom of this file.", + "WARNING17": "*********************************************************************************", + "preLaunchTask": "build", + "program": "${workspaceFolder}/bin/Debug//.dll", + "args": [], + "cwd": "${workspaceFolder}", + "console": "internalConsole", + "stopAtEntry": false + }, + { + "name": ".NET Core Attach", + "type": "coreclr", + "request": "attach" + } + ] +} \ No newline at end of file diff --git a/Assets/Scripts/AI/AIAgent.cs b/Assets/Scripts/AI/AIAgent.cs index 977ba892..05316bc5 100644 --- a/Assets/Scripts/AI/AIAgent.cs +++ b/Assets/Scripts/AI/AIAgent.cs @@ -1,14 +1,6 @@ -using System; -using System.Collections.Generic; using AI; -using Controller; -using Data; -using DG.Tweening; using HexFiled; -using Runtime.Controller; using Units; -using Units.Wariors.AbstractsBase; -using UnityEngine; namespace DefaultNamespace.AI { @@ -19,6 +11,33 @@ namespace DefaultNamespace.AI } + public override void FixedExecute() + { + if (curentState == BotState.Attack && !_unitBase.IsBusy) + { + _unitBase.Aim(_attackDirection); + _unitBase.StartAttack(); + curentState = Unit.Instance.GetNewBehaviour(this); + } + if (currentPath.Count > 0 && !_unitBase.IsBusy) + { + var dir = currentPath.Dequeue(); + if (!HexManager.UnitCurrentCell.TryGetValue(_unitBase.Color, out var value)) + { + return; + } + while (value.cell == null) + { + dir = dir.PlusSixtyDeg(); + } + _unitBase.Move(dir); + } + if (currentPath.Count == 0 && !_unitBase.IsBusy) + { + curentState = Unit.Instance.GetNewBehaviour(this); + } + } + protected override void InitAgent(UnitBase aiBase) { AIManager.Instance.AddAgent(this); diff --git a/Assets/Scripts/AI/AIBase.cs b/Assets/Scripts/AI/AIBase.cs index b76828d4..a1a7a8ba 100644 --- a/Assets/Scripts/AI/AIBase.cs +++ b/Assets/Scripts/AI/AIBase.cs @@ -45,32 +45,7 @@ namespace DefaultNamespace.AI } - public virtual void FixedExecute() - { - if (curentState == BotState.Attack && !_unitBase.IsBusy) - { - _unitBase.Aim(_attackDirection); - _unitBase.StartAttack(); - curentState = AIManager.Instance.GetNewBehaviour(this); - } - if (currentPath.Count > 0 && !_unitBase.IsBusy) - { - var dir = currentPath.Dequeue(); - if (!HexManager.UnitCurrentCell.TryGetValue(_unitBase.Color, out var value)) - { - return; - } - while (value.cell == null) - { - dir = dir.PlusSixtyDeg(); - } - _unitBase.Move(dir); - } - if(currentPath.Count == 0 && !_unitBase.IsBusy) - { - curentState = AIManager.Instance.GetNewBehaviour(this); - } - } + public abstract void FixedExecute(); public void Dispose() diff --git a/Assets/Scripts/AI/AIInvader.cs b/Assets/Scripts/AI/AIInvader.cs new file mode 100644 index 00000000..d4a92844 --- /dev/null +++ b/Assets/Scripts/AI/AIInvader.cs @@ -0,0 +1,33 @@ +using AI; +using HexFiled; +using Units; + +namespace DefaultNamespace.AI +{ + public class AIInvader : AIWarior + { + public AIInvader(UnitBase unitBase) : base(unitBase) + { + } + public override void FixedExecute() + { + if (currentPath.Count > 0 && !_unitBase.IsBusy) + { + var dir = currentPath.Dequeue(); + if (!HexManager.UnitCurrentCell.TryGetValue(_unitBase.Color, out var value)) + { + return; + } + while (value.cell == null) + { + dir = dir.PlusSixtyDeg(); + } + _unitBase.Move(dir); + } + if (currentPath.Count == 0 && !_unitBase.IsBusy) + { + curentState = Warior.Instance.GetNewBehaviour(this); + } + } + } +} \ No newline at end of file diff --git a/Assets/Scripts/AI/AIPatrol.cs.meta b/Assets/Scripts/AI/AIInvader.cs.meta similarity index 100% rename from Assets/Scripts/AI/AIPatrol.cs.meta rename to Assets/Scripts/AI/AIInvader.cs.meta diff --git a/Assets/Scripts/AI/AIManager.cs b/Assets/Scripts/AI/AIManager.cs index a87843f6..7c42afc6 100644 --- a/Assets/Scripts/AI/AIManager.cs +++ b/Assets/Scripts/AI/AIManager.cs @@ -7,182 +7,158 @@ using DefaultNamespace.AI; using HexFiled; using Items; using Units; -using Units.Wariors.AbstractsBase; using UnityEngine; using Random = UnityEngine.Random; namespace AI { - public class AIManager - { - private int _triesToCalculatePath = 0; - private int _maxTriesToCalculatePath = 5; - private AIData _data; - - private static AIManager _instance; - - - public static AIManager Instance + public abstract class AIManager { - get => _instance; - private set => _instance ??= value; - } + protected int _triesToCalculatePath = 0; + protected int _maxTriesToCalculatePath = 5; + protected AIData _data; + + protected static AIManager _instance; - public AIManager(AIData data) - { - _data = data; - Instance = this; - HexManager.agents = new Dictionary(); - } + public static AIManager Instance + { + get => _instance; + private set => _instance ??= value; + } - public void AddAgent(AIBase agent) - { - agent.OnAgentInited += InitAI; - } - public void RemoveAgent(AIBase agent) - { - agent.OnAgentInited -= InitAI; - } + public AIManager(AIData data) + { + _data = data; + Instance = this; + HexManager.agents = new Dictionary(); + } - private void InitAI(AIBase agent) - { - SetBehaviour(BotState.Patrol, agent,500); - } + public void AddAgent(AIBase agent) + { + agent.OnAgentInited += InitAI; + } - private void StartPatrolBehaviour(AIBase agent) - { - HexManager.GetNearestDifferCell(agent.UnitBase.Color, agent.currentPath); - while (agent.currentPath.Count == 0 && _triesToCalculatePath < _maxTriesToCalculatePath) + public void RemoveAgent(AIBase agent) + { + agent.OnAgentInited -= InitAI; + } + protected abstract void SetBehaviour(BotState state, AIBase agent, int dist); + protected abstract void InitAI(AIBase agent); + + protected void StartPatrolBehaviour(AIBase agent) { HexManager.GetNearestDifferCell(agent.UnitBase.Color, agent.currentPath); - _triesToCalculatePath++; - } - - _triesToCalculatePath = 0; - } - - public static UnitBase GetNearestUnit(int cellDist, UnitBase agent) - { - List<(float dist, UnitBase unit)> res = new List<(float, UnitBase)>(); - try - { - - res.AddRange(from color in (UnitColor[]) Enum.GetValues(typeof(UnitColor)) - where HexManager.UnitCurrentCell.ContainsKey(color) && - HexManager.UnitCurrentCell[color].unit.IsVisible && - HexManager.UnitCurrentCell[color] != (null, null) && - Vector3.Distance(HexManager.UnitCurrentCell[color].unit.Instance.transform.position, - agent.Instance.transform.position) <= cellDist * HexGrid.HexDistance && - HexManager.UnitCurrentCell[color].unit.Color != agent.Color - select ( - Vector3.Distance(HexManager.UnitCurrentCell[color].unit.Instance.transform.position, - agent.Instance.transform.position), HexManager.UnitCurrentCell[color].unit)); - - return res.Count > 0 ? res.OrderBy(x => x.Item1).First().unit : null; - } - catch (Exception e) - { - Debug.Log(e.Message + " " + agent.Color + " "); - return null; - } - } - - - public BotState GetNewBehaviour(AIBase agent) - { - var attack = agent.UnitBase.Inventory.Where(x => x.Item is Bonus { BonusType: BonusType.Attack }).ToList(); - if (agent.CurentState is BotState.Attack && agent.UnitBase.AttackBonus == 0 && attack.Count > 0) - { - SetBehaviour(BotState.AttackBonusUsage, agent,500); - return BotState.AttackBonusUsage; - } - - - var enemy = GetNearestUnit(_data.DistanceToAgr, agent.UnitBase); - if (enemy != null && agent.UnitBase.Hp > agent.UnitBase.maxHP * _data.PercentToRetreet && enemy.IsAlive) - { - if (agent.UnitBase.Hp <= agent.UnitBase.maxHP * _data.PercentToRetreet || - agent.UnitBase.BaseView.AvailableShots == 0) + while (agent.currentPath.Count == 0 && _triesToCalculatePath < _maxTriesToCalculatePath) { - SetBehaviour(BotState.Retreet, agent,500); - return BotState.Retreet; + HexManager.GetNearestDifferCell(agent.UnitBase.Color, agent.currentPath); + _triesToCalculatePath++; } - if (Vector3.Distance(agent.UnitBase.Instance.transform.position, enemy.Instance.transform.position) <= - agent.UnitBase.Weapon.disnatce) - { - SetBehaviour(BotState.Attack, agent,500); - return BotState.Attack; - } - - SetBehaviour(BotState.Agressive, agent,500); - return BotState.Agressive; + _triesToCalculatePath = 0; } - var item = GetNearestItem(agent); - if (item.hex != null) - { - if ((item.dist <= _data.DistaceToCollectBonus || - agent.UnitBase.Mana <= agent.UnitBase.maxMana * _data.ManaPercentToCollectBonus) && - (item.hex.Item.Item.Type == ItemType.DEFENCE - ? agent.UnitBase.InventoryDefence.Count - : agent.UnitBase.Inventory.Count) < agent.UnitBase.InventoryCapacity / 2) - { - SetBehaviour(BotState.CollectingBonus, agent,500); - return BotState.CollectingBonus; - } - } - - - var protect = agent.UnitBase.InventoryDefence.Where(x => x.Item is Bonus { BonusType: BonusType.Defence }) - .ToList(); - if (protect.Count > 0 && agent.UnitBase.Hp <= agent.UnitBase.maxHP * _data.PercentToUseProtectBonus && - agent.UnitBase.DefenceBonus == 0) - { - SetBehaviour(BotState.ProtectBonusUsage, agent,500); - return BotState.ProtectBonusUsage; - } - - - SetBehaviour(BotState.Patrol, agent,500); - return BotState.Patrol; - } - - private void SetBehaviour(BotState state, AIBase agent, int dist) - { - switch (state) + public static UnitBase GetNearestUnit(int cellDist, UnitBase agent) { - case BotState.Patrol: - StartPatrolBehaviour(agent); - break; - case BotState.Agressive: - MoveToEnemy(agent, dist); - break; - case BotState.Attack: - AttackEnemy(agent); - break; - case BotState.CollectingBonus: - StartPatrolBehaviour(agent); - break; - case BotState.ProtectBonusUsage: - StartPatrolBehaviour(agent); - break; - case BotState.AttackBonusUsage: - StartPatrolBehaviour(agent); - break; - case BotState.Dead: - break; - case BotState.Retreet: - Retreet(agent); - break; - default: - throw new ArgumentOutOfRangeException(nameof(state), state, null); - } - } + List<(float dist, UnitBase unit)> res = new List<(float, UnitBase)>(); + try + { - private void UseBonus(AIBase agent, BonusType type) + res.AddRange(from color in (UnitColor[])Enum.GetValues(typeof(UnitColor)) + where HexManager.UnitCurrentCell.ContainsKey(color) && + HexManager.UnitCurrentCell[color].unit.IsVisible && + HexManager.UnitCurrentCell[color] != (null, null) && + Vector3.Distance(HexManager.UnitCurrentCell[color].unit.Instance.transform.position, + agent.Instance.transform.position) <= cellDist * HexGrid.HexDistance && + HexManager.UnitCurrentCell[color].unit.Color != agent.Color + select ( + Vector3.Distance(HexManager.UnitCurrentCell[color].unit.Instance.transform.position, + agent.Instance.transform.position), HexManager.UnitCurrentCell[color].unit)); + + return res.Count > 0 ? res.OrderBy(x => x.Item1).First().unit : null; + } + catch (Exception e) + { + Debug.Log(e.Message + " " + agent.Color + " "); + return null; + } + } + + + public abstract BotState GetNewBehaviour(AIBase agent); + + protected void Retreet(AIBase agent) + { + var enemy = GetNearestUnit(6, agent.UnitBase)?.Instance.transform; + + if (enemy == null) + { + return; + } + + var dir = -DirectionHelper.DirectionTo(agent.UnitBase.Instance.transform.position, + enemy.position); + agent.currentPath.Clear(); + agent.currentPath.Enqueue(DirectionHelper.VectorToDirection(new Vector2(dir.x, dir.z))); + } + + protected (int dist, HexCell hex) GetNearestItem(AIBase agent) + { + var itemsToMove = + (from entry in ItemFabric.Items + where Vector3.Distance(agent.UnitBase.Instance.transform.position, entry.Value.transform.position) < + 10 * HexGrid.HexDistance + orderby Vector3.Distance(agent.UnitBase.Instance.transform.position, entry.Value.transform.position) + select entry).ToList(); + + + if (itemsToMove.Count == 0) + { + return (0, null); + } + + var itemToMove = itemsToMove.First(); + return ( + (int)(Vector3.Distance(itemToMove.Value.transform.position, agent.UnitBase.Instance.transform.position) / + HexGrid.HexDistance), itemToMove.Value); + } + + protected void MoveToBonus(AIBase agent) + { + if (HexManager.UnitCurrentCell.TryGetValue(agent.UnitBase.Color, out var value)) + + Pathfinding.FindPath(value.cell, GetNearestItem(agent).hex, + agent.currentPath); + } + + protected void AttackEnemy(AIBase agent) + { + var enemy = GetNearestUnit(agent.UnitBase.Weapon.disnatce, agent.UnitBase); + var dir = DirectionHelper.DirectionTo(agent.UnitBase.Instance.transform.position, + enemy.Instance.transform.position); + agent.AttackTarget(new Vector2(dir.x, dir.z)); + } + + protected void MoveToEnemy(AIBase agent, int dist) + { + var enemies = HexManager.UnitCurrentCell.Where(unit => + unit.Value.unit.Color != agent.UnitBase.Color && + Vector3.Distance(unit.Value.unit.Instance.transform.position, + agent.UnitBase.Instance.transform.position) <= dist * HexGrid.HexDistance).ToList(); + if (enemies[Random.Range(0, enemies.Count)].Value.unit.Color == agent.UnitBase.Color) return; + + Pathfinding.FindPath(HexManager.UnitCurrentCell[agent.UnitBase.Color].cell, + enemies[Random.Range(0, enemies.Count)].Value.cell, agent.currentPath); + } + protected void CatchHex(AIBase agent) + { + Pathfinding.FindPath(HexManager.UnitCurrentCell[agent.UnitBase.Color].cell, HexManager.CellByColor[UnitColor.Grey].Where(x => x != null).ToList()[ + Random.Range(0, HexManager.CellByColor[UnitColor.Grey].Count - 1)] + , agent.currentPath); + } + + protected void UseBonus(AIAgent agent, BonusType type) { var attack = agent.UnitBase.Inventory.Where(x => x.Item is Bonus bonus && bonus.BonusType == type).ToList(); if (attack.Count == 0 || !agent.UnitBase.IsAlive) @@ -191,90 +167,20 @@ namespace AI return; } - ((Bonus)attack.First().Item).Invoke((Unit)(agent.UnitBase)); + ((Bonus)attack.First().Item).Invoke((Units.Unit.Unit)agent.UnitBase); + } } - private void Retreet(AIBase agent) + + public enum BotState { - var enemy = GetNearestUnit(6, agent.UnitBase)?.Instance.transform; - - if (enemy == null) - { - return; - } - - var dir = -DirectionHelper.DirectionTo(agent.UnitBase.Instance.transform.position, - enemy.position); - agent.currentPath.Clear(); - agent.currentPath.Enqueue(DirectionHelper.VectorToDirection(new Vector2(dir.x, dir.z))); + Patrol, + Agressive, + Attack, + CollectingBonus, + AttackBonusUsage, + ProtectBonusUsage, + Dead, + Retreet } - - private (int dist, HexCell hex) GetNearestItem(AIBase agent) - { - var itemsToMove = - (from entry in ItemFabric.Items - where Vector3.Distance(agent.UnitBase.Instance.transform.position, entry.Value.transform.position) < - 10 * HexGrid.HexDistance - orderby Vector3.Distance(agent.UnitBase.Instance.transform.position, entry.Value.transform.position) - select entry).ToList(); - - - if (itemsToMove.Count == 0) - { - return (0, null); - } - - var itemToMove = itemsToMove.First(); - return ( - (int)(Vector3.Distance(itemToMove.Value.transform.position, agent.UnitBase.Instance.transform.position) / - HexGrid.HexDistance), itemToMove.Value); - } - - private void MoveToBonus(AIBase agent) - { - if (HexManager.UnitCurrentCell.TryGetValue(agent.UnitBase.Color, out var value)) - - Pathfinding.FindPath(value.cell, GetNearestItem(agent).hex, - agent.currentPath); - } - - private void AttackEnemy(AIBase agent) - { - var enemy = GetNearestUnit(agent.UnitBase.Weapon.disnatce, agent.UnitBase); - var dir = DirectionHelper.DirectionTo(agent.UnitBase.Instance.transform.position, - enemy.Instance.transform.position); - agent.AttackTarget(new Vector2(dir.x, dir.z)); - } - - private void MoveToEnemy(AIBase agent, int dist) - { - var enemies = HexManager.UnitCurrentCell.Where(unit => - unit.Value.unit.Color != agent.UnitBase.Color && - Vector3.Distance(unit.Value.unit.Instance.transform.position, - agent.UnitBase.Instance.transform.position) <= dist * HexGrid.HexDistance).ToList(); - if (enemies[Random.Range(0, enemies.Count)].Value.unit.Color == agent.UnitBase.Color) return; - - Pathfinding.FindPath(HexManager.UnitCurrentCell[agent.UnitBase.Color].cell, - enemies[Random.Range(0, enemies.Count)].Value.cell, agent.currentPath); - } - private void CatchHex(AIBase agent) - { - Pathfinding.FindPath(HexManager.UnitCurrentCell[agent.UnitBase.Color].cell, HexManager.CellByColor[UnitColor.Grey].Where(x => x != null).ToList()[ - Random.Range(0, HexManager.CellByColor[UnitColor.Grey].Count - 1)] - , agent.currentPath); - } - } - - - public enum BotState - { - Patrol, - Agressive, - Attack, - CollectingBonus, - AttackBonusUsage, - ProtectBonusUsage, - Dead, - Retreet - } -} \ No newline at end of file + } \ No newline at end of file diff --git a/Assets/Scripts/AI/AIPatrol.cs b/Assets/Scripts/AI/AIPatrol.cs deleted file mode 100644 index b2d160a3..00000000 --- a/Assets/Scripts/AI/AIPatrol.cs +++ /dev/null @@ -1,20 +0,0 @@ -using AI; -using HexFiled; -using Units; - -namespace DefaultNamespace.AI -{ - public class AIPatrol : AIBase - { - public AIPatrol(UnitBase unitBase) : base(unitBase) - { - } - - protected override void InitAgent(UnitBase aiBase) - { - AIManager.Instance.AddAgent(this); - HexManager.agents.Add(aiBase.Instance, this); - OnAgentInited?.Invoke(this); - } - } -} \ No newline at end of file diff --git a/Assets/Scripts/AI/AIWarior.cs b/Assets/Scripts/AI/AIWarior.cs new file mode 100644 index 00000000..88c49312 --- /dev/null +++ b/Assets/Scripts/AI/AIWarior.cs @@ -0,0 +1,46 @@ +using AI; +using HexFiled; +using Units; + +namespace DefaultNamespace.AI +{ + public class AIWarior : AIBase + { + public AIWarior(UnitBase unitBase) : base(unitBase) + { + } + + public override void FixedExecute(){ + if (curentState == BotState.Attack && !_unitBase.IsBusy) + { + _unitBase.Aim(_attackDirection); + _unitBase.StartAttack(); + curentState = Unit.Instance.GetNewBehaviour(this); + } + if (currentPath.Count > 0 && !_unitBase.IsBusy) + { + var dir = currentPath.Dequeue(); + if (!HexManager.UnitCurrentCell.TryGetValue(_unitBase.Color, out var value)) + { + return; + } + while (value.cell == null) + { + dir = dir.PlusSixtyDeg(); + } + _unitBase.Move(dir); + } + if (currentPath.Count == 0 && !_unitBase.IsBusy) + { + curentState = Warior.Instance.GetNewBehaviour(this); + } + } + + protected override void InitAgent(UnitBase aiBase) + { + AIManager.Instance.AddAgent(this); + HexManager.agents.Add(aiBase.Instance, this); + OnAgentInited?.Invoke(this); + } + } +} \ No newline at end of file diff --git a/Assets/Scripts/AI/AIWarior.cs.meta b/Assets/Scripts/AI/AIWarior.cs.meta new file mode 100644 index 00000000..d8889f6c --- /dev/null +++ b/Assets/Scripts/AI/AIWarior.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: d8232766eef26164e9f591cac9961576 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/AI/Unit.cs b/Assets/Scripts/AI/Unit.cs new file mode 100644 index 00000000..e5fa1b0b --- /dev/null +++ b/Assets/Scripts/AI/Unit.cs @@ -0,0 +1,114 @@ +using System; +using System.Linq; +using Data; +using DefaultNamespace.AI; +using Items; +using UnityEngine; + +namespace AI +{ + public sealed class Unit : AIManager + { + public Unit(AIData data) : base(data) + { + } + + protected override void SetBehaviour(BotState state, AIBase agent, int dist) + { + switch (state) + { + case BotState.Patrol: + StartPatrolBehaviour(agent); + break; + case BotState.Agressive: + MoveToEnemy(agent, dist); + break; + case BotState.Attack: + AttackEnemy(agent); + break; + case BotState.CollectingBonus: + StartPatrolBehaviour(agent); + break; + case BotState.ProtectBonusUsage: + StartPatrolBehaviour(agent); + break; + case BotState.AttackBonusUsage: + StartPatrolBehaviour(agent); + break; + case BotState.Dead: + break; + case BotState.Retreet: + Retreet(agent); + break; + default: + throw new ArgumentOutOfRangeException(nameof(state), state, null); + } + } + + protected override void InitAI(AIBase agent) + { + SetBehaviour(BotState.Patrol, agent, 500); + + } + + public override BotState GetNewBehaviour(AIBase agent) + { + var attack = agent.UnitBase.Inventory.Where(x => x.Item is Bonus { BonusType: BonusType.Attack }).ToList(); + if (agent.CurentState is BotState.Attack && agent.UnitBase.AttackBonus == 0 && attack.Count > 0) + { + SetBehaviour(BotState.AttackBonusUsage, agent, 500); + return BotState.AttackBonusUsage; + } + + + var enemy = GetNearestUnit(_data.DistanceToAgr, agent.UnitBase); + if (enemy != null && agent.UnitBase.Hp > agent.UnitBase.maxHP * _data.PercentToRetreet && enemy.IsAlive) + { + if (agent.UnitBase.Hp <= agent.UnitBase.maxHP * _data.PercentToRetreet || + agent.UnitBase.BaseView.AvailableShots == 0) + { + SetBehaviour(BotState.Retreet, agent, 500); + return BotState.Retreet; + } + + if (Vector3.Distance(agent.UnitBase.Instance.transform.position, enemy.Instance.transform.position) <= + agent.UnitBase.Weapon.disnatce) + { + SetBehaviour(BotState.Attack, agent, 500); + return BotState.Attack; + } + + SetBehaviour(BotState.Agressive, agent, 500); + return BotState.Agressive; + } + + var item = GetNearestItem(agent); + if (item.hex != null) + { + if ((item.dist <= _data.DistaceToCollectBonus || + agent.UnitBase.Mana <= agent.UnitBase.maxMana * _data.ManaPercentToCollectBonus) && + (item.hex.Item.Item.Type == ItemType.DEFENCE + ? agent.UnitBase.InventoryDefence.Count + : agent.UnitBase.Inventory.Count) < agent.UnitBase.InventoryCapacity / 2) + { + SetBehaviour(BotState.CollectingBonus, agent, 500); + return BotState.CollectingBonus; + } + } + + + var protect = agent.UnitBase.InventoryDefence.Where(x => x.Item is Bonus { BonusType: BonusType.Defence }) + .ToList(); + if (protect.Count > 0 && agent.UnitBase.Hp <= agent.UnitBase.maxHP * _data.PercentToUseProtectBonus && + agent.UnitBase.DefenceBonus == 0) + { + SetBehaviour(BotState.ProtectBonusUsage, agent, 500); + return BotState.ProtectBonusUsage; + } + + + SetBehaviour(BotState.Patrol, agent, 500); + return BotState.Patrol; + } + } +} \ No newline at end of file diff --git a/Assets/Scripts/AI/Unit.cs.meta b/Assets/Scripts/AI/Unit.cs.meta new file mode 100644 index 00000000..49401391 --- /dev/null +++ b/Assets/Scripts/AI/Unit.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: c95536c68c42e6c46b3075074a074ef9 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/AI/Warior.cs b/Assets/Scripts/AI/Warior.cs new file mode 100644 index 00000000..0fa339cb --- /dev/null +++ b/Assets/Scripts/AI/Warior.cs @@ -0,0 +1,92 @@ +using System; +using System.Linq; +using Data; +using DefaultNamespace.AI; +using UnityEngine; + +namespace AI +{ + public class Invader : Warior + { + public Invader(AIData data) : base(data) + { + } + public override BotState GetNewBehaviour(AIBase agent) + { + var enemy = GetNearestUnit(_data.DistanceToAgr, agent.UnitBase); + if (enemy != null && agent.UnitBase.Hp > agent.UnitBase.maxHP * _data.PercentToRetreet && enemy.IsAlive) + { + if (agent.UnitBase.Hp <= agent.UnitBase.maxHP * _data.PercentToRetreet || + agent.UnitBase.BaseView.AvailableShots == 0) + { + SetBehaviour(BotState.Retreet, agent, 500); + return BotState.Retreet; + } + } + + SetBehaviour(BotState.Patrol, agent, 500); + return BotState.Patrol; + } + } + public class Warior : AIManager + { + public Warior(AIData data) : base(data) + { + } + + public override BotState GetNewBehaviour(AIBase agent) + { + var enemy = GetNearestUnit(_data.DistanceToAgr, agent.UnitBase); + if (enemy != null && agent.UnitBase.Hp > agent.UnitBase.maxHP * _data.PercentToRetreet && enemy.IsAlive) + { + if (agent.UnitBase.Hp <= agent.UnitBase.maxHP * _data.PercentToRetreet || + agent.UnitBase.BaseView.AvailableShots == 0) + { + SetBehaviour(BotState.Retreet, agent, 500); + return BotState.Retreet; + } + + if (Vector3.Distance(agent.UnitBase.Instance.transform.position, enemy.Instance.transform.position) <= + agent.UnitBase.Weapon.disnatce) + { + SetBehaviour(BotState.Attack, agent, 500); + return BotState.Attack; + } + + SetBehaviour(BotState.Agressive, agent, 500); + return BotState.Agressive; + } + + SetBehaviour(BotState.Patrol, agent, 500); + return BotState.Patrol; + } + + protected override void SetBehaviour(BotState state, AIBase agent, int dist) + { + switch (state) + { + case BotState.Patrol: + StartPatrolBehaviour(agent); + break; + case BotState.Agressive: + MoveToEnemy(agent, dist); + break; + case BotState.Attack: + AttackEnemy(agent); + break; + case BotState.Dead: + break; + case BotState.Retreet: + Retreet(agent); + break; + default: + throw new ArgumentOutOfRangeException(nameof(state), state, null); + } + } + + protected override void InitAI(AIBase agent) + { + SetBehaviour(BotState.Patrol, agent, 500); + } + } + } \ No newline at end of file diff --git a/Assets/Scripts/AI/Warior.cs.meta b/Assets/Scripts/AI/Warior.cs.meta new file mode 100644 index 00000000..24e8838d --- /dev/null +++ b/Assets/Scripts/AI/Warior.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b8e820aaee60c1d45983930a2c54a69e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/CheatMenu.cs b/Assets/Scripts/CheatMenu.cs index 33fa9495..aeec9907 100644 --- a/Assets/Scripts/CheatMenu.cs +++ b/Assets/Scripts/CheatMenu.cs @@ -15,7 +15,7 @@ public class CheatMenu : MonoBehaviour [SerializeField] private GameObject grid; [SerializeField] private Button buttonPrefab; [SerializeField] private GameObject gridPrefab; - private Unit _player; + private Units.Unit.Unit _player; private Data.Data _data; private GameObject _itemsPrefab; private List _buttons; @@ -23,7 +23,7 @@ public class CheatMenu : MonoBehaviour public void SetPlayerNData(Data.Data data) { _buttons = new List(); - _player = (Unit)(HexManager.UnitCurrentCell.FirstOrDefault(unit => ((Unit)unit.Value.unit).IsPlayer).Value.unit); + _player = (Units.Unit.Unit)(HexManager.UnitCurrentCell.FirstOrDefault(unit => ((Units.Unit.Unit)unit.Value.unit).IsPlayer).Value.unit); _itemsPrefab = new GameObject("CheatedItems"); showButton.onClick.AddListener(() => scrollRect.SetActive(!scrollRect.activeSelf)); diff --git a/Assets/Scripts/Controller/GameInit.cs b/Assets/Scripts/Controller/GameInit.cs index 2e1e46b1..9a1233ab 100644 --- a/Assets/Scripts/Controller/GameInit.cs +++ b/Assets/Scripts/Controller/GameInit.cs @@ -1,17 +1,12 @@ -using System.Collections.Generic; -using AI; -using CamControl; +using AI; using Chars; using DefaultNamespace; -using DefaultNamespace.AI; using GameUI; using HexFiled; using Items; -using Units; using Units.Wariors; using UnityEngine; -using Weapons; -using Random = UnityEngine.Random; + namespace Controller { @@ -19,7 +14,8 @@ namespace Controller { public GameInit(Controllers controllers, Data.Data data) { - new AIManager(data.AIData); + new Unit(data.AIData); + new Warior(data.AIData); var hexGrid = new HexGrid(data.FieldData); new MusicController(); new VFXController(); diff --git a/Assets/Scripts/GameUI/PlayerInventoryView.cs b/Assets/Scripts/GameUI/PlayerInventoryView.cs index 1aa68a71..36d1afaf 100644 --- a/Assets/Scripts/GameUI/PlayerInventoryView.cs +++ b/Assets/Scripts/GameUI/PlayerInventoryView.cs @@ -5,6 +5,7 @@ using Items; using Units; using UnityEngine; using UnityEngine.UI; +using Unit = Units.Unit.Unit; namespace GameUI { @@ -80,14 +81,14 @@ namespace GameUI switch (Item.Item) { case Bonus bonus: - { - button.onClick.RemoveAllListeners(); - bonus.Invoke(_unit); + { + button.onClick.RemoveAllListeners(); + bonus.Invoke(_unit); - button.onClick.RemoveAllListeners(); - button.gameObject.SetActive(false); - break; - } + button.onClick.RemoveAllListeners(); + button.gameObject.SetActive(false); + break; + } case Building building: Item.OnItemUsed += () => SwitchButton(button); building.Invoke(Item); diff --git a/Assets/Scripts/Items/Bonus.cs b/Assets/Scripts/Items/Bonus.cs index 561bf505..4911df38 100644 --- a/Assets/Scripts/Items/Bonus.cs +++ b/Assets/Scripts/Items/Bonus.cs @@ -1,4 +1,5 @@ -using DefaultNamespace; +using System; +using DefaultNamespace; using HexFiled; using Units; using UnityEngine; @@ -31,7 +32,7 @@ namespace Items public GameObject UsisngVFX => usisngVFX; - public void Invoke(Unit unit) + public void Invoke(Units.Unit.Unit unit) { unit.SetUpBonus(duration, value, bonusType); var vfx = VFXController.Instance.PlayEffect(usisngVFX, unit.Instance.transform); diff --git a/Assets/Scripts/Items/Building.cs b/Assets/Scripts/Items/Building.cs index 9ae27c52..62a34a03 100644 --- a/Assets/Scripts/Items/Building.cs +++ b/Assets/Scripts/Items/Building.cs @@ -69,7 +69,7 @@ namespace Items var obj = Instantiate(buildingPrefab, cell.transform.position + buildingPrefab.transform.position, Quaternion.identity); obj.GetComponent().SetUp(container.Unit); - var unit = (Unit) container.Unit; + var unit = (Units.Unit.Unit) container.Unit; if (!unit.IsPlayer) { obj.transform.GetChilds().Where(x => !x.TryGetComponent(typeof(ISetUp), out _)) diff --git a/Assets/Scripts/Items/SwitchingPlaces.cs b/Assets/Scripts/Items/SwitchingPlaces.cs index c8b81d39..a029dcd1 100644 --- a/Assets/Scripts/Items/SwitchingPlaces.cs +++ b/Assets/Scripts/Items/SwitchingPlaces.cs @@ -5,6 +5,7 @@ using Units; using Units.Views; using UnityEngine; using Object = UnityEngine.Object; +using Unit = Units.Unit.Unit; namespace Items { diff --git a/Assets/Scripts/Units/PlayerControl.cs b/Assets/Scripts/Units/PlayerControl.cs index f7615f80..a1239273 100644 --- a/Assets/Scripts/Units/PlayerControl.cs +++ b/Assets/Scripts/Units/PlayerControl.cs @@ -11,7 +11,7 @@ using Runtime.Controller; using Units; using Units.Views; using UnityEngine; -using Object = UnityEngine.Object; +using Unit = Units.Unit.Unit; namespace Chars { diff --git a/Assets/Scripts/Units/Unit.cs b/Assets/Scripts/Units/Unit.cs index 9fb83389..74f32b01 100644 --- a/Assets/Scripts/Units/Unit.cs +++ b/Assets/Scripts/Units/Unit.cs @@ -15,7 +15,7 @@ using Weapons; using Object = UnityEngine.Object; -namespace Units +namespace Units.Unit { public class Unit : UnitBase { diff --git a/Assets/Scripts/Units/UnitFactory.cs b/Assets/Scripts/Units/UnitFactory.cs index e57859b5..c13162ed 100644 --- a/Assets/Scripts/Units/UnitFactory.cs +++ b/Assets/Scripts/Units/UnitFactory.cs @@ -22,7 +22,7 @@ namespace Chars private readonly Data.Data _data; private readonly Controllers _controllers; private readonly UIController _uiController; - public Unit Player { get; private set; } + public Units.Unit.Unit Player { get; private set; } public UnitFactory(HexGrid grid, Data.Data data, UIController uiController, PaintedController paintedController, Controllers controllers) @@ -56,7 +56,7 @@ namespace Chars if (unitInfo.isPlayer) { - var player = new Unit(unitInfo, _chosenWeapon, _hexGrid, _data); + var player = new Units.Unit.Unit(unitInfo, _chosenWeapon, _hexGrid, _data); PlayerControl playerControl = null; CameraControl cameraControl = @@ -86,7 +86,7 @@ namespace Chars } else { - var enemy = new Unit(unitInfo, + var enemy = new Units.Unit.Unit(unitInfo, _data.WeaponsData.WeaponsList[Random.Range(0, _data.WeaponsData.WeaponsList.Count - 1)], _hexGrid, _data); @@ -94,7 +94,7 @@ namespace Chars if (unitInfo.isAI) { - AIPatrol agent = new AIPatrol(enemy); + AIWarior agent = new AIWarior(enemy); enemy.OnSpawned += x => _controllers.Add(agent); enemy.OnDeath += x => { _controllers.Remove(agent); }; } diff --git a/Assets/Scripts/Units/Views/UnitView.cs b/Assets/Scripts/Units/Views/UnitView.cs index f1eaa43f..0f710155 100644 --- a/Assets/Scripts/Units/Views/UnitView.cs +++ b/Assets/Scripts/Units/Views/UnitView.cs @@ -2,7 +2,6 @@ using System.Collections; using DefaultNamespace; using DG.Tweening; using HexFiled; -using Units; using UnityEngine; using Weapons; @@ -33,12 +32,12 @@ namespace Units.Views protected override IEnumerator Regen() { - if (_mana >= ((Unit)_unit).UnitData.maxMana) + if (_mana >= (( Units.Unit.Unit)_unit).UnitData.maxMana) { yield break; } - while (_mana < ((Unit)_unit).UnitData.maxMana) + while (_mana < ((Units.Unit.Unit)_unit).UnitData.maxMana) { yield return new WaitForSeconds(1f); _mana += _manaRegen; diff --git a/Assets/Scripts/Units/Views/ViewBase.cs b/Assets/Scripts/Units/Views/ViewBase.cs index 7019b561..4386ee12 100644 --- a/Assets/Scripts/Units/Views/ViewBase.cs +++ b/Assets/Scripts/Units/Views/ViewBase.cs @@ -75,7 +75,6 @@ namespace Units.Views public void SetInvisible(bool isVisible) { - var i = 0; transform.GetChilds().ForEach(x => { if (x.gameObject.TryGetComponent(typeof(SkinnedMeshRenderer), out var mesh)) @@ -152,7 +151,7 @@ namespace Units.Views return true; } - public void RegenMana() + public virtual void RegenMana() { _mana = _unit.Mana; if (_previosRegen != null) diff --git a/Assets/Scripts/Units/Views/WariorView.cs b/Assets/Scripts/Units/Views/WariorView.cs index 294feb09..f551688f 100644 --- a/Assets/Scripts/Units/Views/WariorView.cs +++ b/Assets/Scripts/Units/Views/WariorView.cs @@ -2,6 +2,7 @@ using DefaultNamespace; using DG.Tweening; using HexFiled; +using Units.Wariors.AbstractsBase; using UnityEngine; using Weapons; @@ -29,12 +30,12 @@ namespace Units.Views protected override IEnumerator Regen() { - if (_mana >= ((Unit)_unit).UnitData.maxMana) + if (_mana >= ((Warior)_unit).Data.maxMana) { yield break; } - while (_mana < ((Unit)_unit).UnitData.maxMana) + while (_mana < ((Warior)_unit).Data.maxMana) { yield return new WaitForSeconds(1f); _mana += _manaRegen; diff --git a/Assets/Scripts/Units/Wariors/AbstractsBase/Invader.cs b/Assets/Scripts/Units/Wariors/AbstractsBase/Invader.cs index 6cf36b16..4671040f 100644 --- a/Assets/Scripts/Units/Wariors/AbstractsBase/Invader.cs +++ b/Assets/Scripts/Units/Wariors/AbstractsBase/Invader.cs @@ -1,6 +1,7 @@ using Data; using DG.Tweening; using HexFiled; +using UnityEngine; using Weapons; namespace Units.Wariors.AbstractsBase @@ -10,8 +11,9 @@ namespace Units.Wariors.AbstractsBase protected Invader(WariorInfo data, Weapon weapon, HexGrid hexGrid, UnitColor spawnerColor) : base(data, weapon, hexGrid, spawnerColor) { } - public override void Move(HexDirection direction) + public override void Move(HexDirection direction) { + if (_cell.GetNeighbor(direction) == null) return; base.Move(direction); if (_cell.GetNeighbor(direction).Color == Color || (_cell.GetNeighbor(direction).Color == _easyCaptureColor && _easyCaptureColor != UnitColor.Grey)) @@ -34,7 +36,7 @@ namespace Units.Wariors.AbstractsBase public override void StartAttack() { } - public override void SetCell(HexCell cell, bool isInstanceTrans = false, bool isPaintingHex = false) + public override void SetCell(HexCell cell, bool isInstanceTrans = false, bool isPaintingHex = false) { _cell = cell; HexManager.UnitCurrentCell[Color] = (cell, this); diff --git a/Assets/Scripts/Units/Wariors/WariorFactory.cs b/Assets/Scripts/Units/Wariors/WariorFactory.cs index 67a9aa02..0c419d08 100644 --- a/Assets/Scripts/Units/Wariors/WariorFactory.cs +++ b/Assets/Scripts/Units/Wariors/WariorFactory.cs @@ -33,7 +33,7 @@ namespace Units.Wariors var patrol = new TestInvader(wariorInfo,_data.WeaponsData.WeaponsList[Random.Range(0, _data.WeaponsData.WeaponsList.Count - 1)], _hexGrid,unitColor); - AIAgent agent = new AIAgent (patrol); + AIInvader agent = new AIInvader (patrol); patrol.OnSpawned += x => _controllers.Add(agent); patrol.OnDeath += x => { _controllers.Remove(agent); };