diff --git a/Enemy.cs b/Enemy.cs index 7a236ca..6d2edfa 100644 --- a/Enemy.cs +++ b/Enemy.cs @@ -9,8 +9,10 @@ public partial class Enemy : StaticBody2D public delegate void DeathEventHandler(Enemy THIS); [Signal] public delegate void ClickedEventHandler(Enemy THIS); + [Signal] + public delegate void RightClickedEventHandler(Enemy THIS); public bool _hovered = false, _track = false; - public int _damage = 1, _health = 2, _speed, _speedRemaining, _visibilityRange = 4; + public int _damage = 1, _health = 2, _speed, _speedRemaining, _visibilityRange = 4, _hitRange = 1; public Vector2I _address = -Vector2I.One, _range = Vector2I.Up; public List _path = new(); public float _movement = 0; @@ -30,6 +32,10 @@ public partial class Enemy : StaticBody2D { EmitSignal(SignalName.Clicked, this); } + if (Input.IsActionJustPressed("rightClick")) + { + EmitSignal(SignalName.RightClicked, this); + } } } public override void _PhysicsProcess(double delta) diff --git a/EnemyController.cs b/EnemyController.cs index 6a8f185..37d5f7b 100644 --- a/EnemyController.cs +++ b/EnemyController.cs @@ -18,6 +18,7 @@ public partial class EnemyController : TurnController Enemy newEnemy = _enemyScene.Instantiate(); newEnemy.Death += RemoveEnemy; newEnemy.Clicked += HandleEnemyClick; + newEnemy.RightClicked += HandleEnemyRightClick; newEnemy._speed = Globals._rng.Next(2,4+1); newEnemy.Modulate = new Color(newEnemy._speed == 2 ? "#FF0000" : newEnemy._speed == 3 ? "#00FF00" : "#0000FF"); @@ -36,9 +37,9 @@ public partial class EnemyController : TurnController Enemy newEnemy = _enemyScene.Instantiate(); newEnemy.Death += RemoveEnemy; newEnemy.Clicked += HandleEnemyClick; + newEnemy.RightClicked += HandleEnemyRightClick; newEnemy._speed = Globals._rng.Next(2,4+1); - newEnemy._speed = 3; newEnemy.Modulate = new Color(newEnemy._speed == 2 ? "#FF0000" : newEnemy._speed == 3 ? "#00FF00" : "#0000FF"); newEnemy._enemyController = this; @@ -49,55 +50,62 @@ public partial class EnemyController : TurnController } - public Vector2I GetBestGoal(Enemy ENEMY, Vector2I GOAL) + public void EnemyAttacks() { - Vector2I goal = GOAL; - while (_playArea._map.IsRowFull(goal.Y)) + List attackingEnemies = [.. _enemies.Where(e => e._address.Y <= e._hitRange)]; + for (int i = 0; i < attackingEnemies.Count; i++) { - goal.Y++; + Enemy enemy = attackingEnemies[i]; + // enemy.Attack(); } - int loop = 0; - while (_playArea._map.HasOccupant(goal)) - { - Vector2I leftGoal = new (Math.Clamp(ENEMY._address.X - loop / 2 - 1, _playArea._map._minX, _playArea._map._maxX), goal.Y); - Vector2I rightGoal = new (Math.Clamp(ENEMY._address.X + loop / 2 + 1, _playArea._map._minX, _playArea._map._maxX), goal.Y); - List leftPath = _playArea._map.GetPath(ENEMY._address, leftGoal); - List rightPath = _playArea._map.GetPath(ENEMY._address, rightGoal); + } - if (rightPath.Count < leftPath.Count && !_playArea._map.HasOccupant(rightGoal)) + public List GetBestPath(Enemy ENEMY) + { + Vector2I goal = Vector2I.One * -1000; + + goal.Y = _playArea._map.GetFirstOpenRow(); + List openCells = [.. _playArea._map._cells.Where(c => c.Y == goal.Y && !_playArea._map._astar.IsPointSolid(c))]; + List testPath, bestPath = new(); + + int bestLength = 999999; + + for (int i = 0; i < openCells.Count; i++) + { + testPath = _playArea._map.GetPath(ENEMY._address, openCells[i]); + int testLength = testPath.Count; + if (testLength < bestLength) { - goal = rightGoal; + bestPath = testPath; + bestLength = testLength; + goal = openCells[i]; } - else if (leftPath.Count < rightPath.Count && !_playArea._map.HasOccupant(leftGoal)) + else if (testLength == bestLength) { - goal = leftGoal; + if (Math.Abs(openCells[i].X - ENEMY._address.X) < Math.Abs(goal.X - ENEMY._address.X)) + { + bestPath = testPath; + bestLength = testLength; + goal = openCells[i]; + } } - else if (!_playArea._map.HasOccupant(rightGoal)) - { - goal = rightGoal; - } - else if (!_playArea._map.HasOccupant(leftGoal)) - { - goal = leftGoal; - } - loop++; } - return goal; + return bestPath; + } + + public void GetRemainingSpeed(Enemy ENEMY) + { + ENEMY._speedRemaining = ENEMY._address.Y <= _playArea._map.GetFirstOpenRow() || ENEMY._address.Y <= ENEMY._hitRange ? 0 : ENEMY._speed; } public void HandleEnemyClick(Enemy ENEMY) { - GD.Print(ENEMY._address, _playArea._map._astar.IsPointSolid(ENEMY._address)); - // if (ENEMY._speedRemaining <= 0){ - // return; - // } - TileMapLayer pathLayer = _playArea.GetNode("PathLayer"); - Vector2I goal = GetBestGoal(ENEMY, new(ENEMY._address.X, Math.Max(ENEMY._address.Y - ENEMY._visibilityRange, _playArea._map._minY))); - if (ENEMY._address == Vector2I.Zero) - { - GD.Print(0,goal); + if (ENEMY._speedRemaining <= 0){ + return; } - List newPath = [.. _playArea._map.GetPath(ENEMY._address, goal)]; + TileMapLayer pathLayer = _playArea.GetNode("PathLayer"); + List newPath = GetBestPath(ENEMY); + pathLayer.GetUsedCells().ToList().ForEach(c => pathLayer.SetCell(c,0,Vector2I.Down*4)); for (int i = 0; i < newPath.Count; i++) @@ -106,6 +114,11 @@ public partial class EnemyController : TurnController } } + public void HandleEnemyRightClick(Enemy ENEMY) + { + RemoveEnemy(ENEMY); + } + public void Initiate() { List positions = [.. _playArea.GetNode("InitialPositions").GetUsedCells()]; @@ -119,16 +132,12 @@ public partial class EnemyController : TurnController for (int i = 0; i < _enemies.Count; i++) { Enemy enemy = _enemies[i]; - enemy._speedRemaining = enemy._address.Y <= map._minY ? 0 : enemy._speed; + GetRemainingSpeed(enemy); if (enemy._speedRemaining > 0) { - Vector2I goal = GetBestGoal(enemy, new(enemy._address.X, Math.Max(enemy._address.Y - enemy._visibilityRange, map._minY))); - if (enemy._address == Vector2I.Zero) - { - GD.Print(1,goal); - } - enemy._path = map.GetPath(enemy._address, goal); + enemy._path = GetBestPath(enemy); + if (enemy._path.Count <= 0) { enemy._speedRemaining = 0; @@ -136,7 +145,7 @@ public partial class EnemyController : TurnController } } - List remainingEnemies = SortEnemies(_enemies); + List remainingEnemies = GetRemainingEnemies(_enemies); _enemies.ForEach(e => e._path.Clear()); if (remainingEnemies.Count == 0) { @@ -144,7 +153,7 @@ public partial class EnemyController : TurnController } while (remainingEnemies.Count > 0) { - remainingEnemies = SortEnemies(remainingEnemies); + remainingEnemies = GetRemainingEnemies(remainingEnemies); for (int i = 0; i < remainingEnemies.Count; i++) { Enemy enemy = remainingEnemies[i]; @@ -152,28 +161,24 @@ public partial class EnemyController : TurnController { continue; } - if (enemy._address.Y <= map._minY) + if (enemy._address.Y <= map.GetFirstOpenRow()) { enemy._speedRemaining = 0; continue; } - Vector2I goal = GetBestGoal(enemy, new(enemy._address.X, Math.Max(enemy._address.Y - enemy._visibilityRange, map._minY))); - if (enemy._address == Vector2I.Zero) - { - GD.Print(2,goal); - } - List path = map.GetPath(enemy._address, goal); + List path = GetBestPath(enemy); + if (path.Count == 0) { continue; } Vector2I cell = path[0]; - if (enemy._address == Vector2I.Zero) + if (cell.Y <= enemy._address.Y) { - GD.Print(3, enemy._address); + map.SetCellEnemy(cell, enemy); + enemy._path.Add(cell); } - map.SetCellEnemy(cell, enemy); - enemy._path.Add(cell); + enemy._speedRemaining--; } } @@ -215,9 +220,9 @@ public partial class EnemyController : TurnController ENEMY_TO_REMOVE.QueueFree(); } - public List SortEnemies(List ENEMIES) + public List GetRemainingEnemies(List ENEMIES) { - return [.. ENEMIES.Where(e => e._speedRemaining > 0).OrderByDescending(e => e._path.Count).ThenBy(e => e._address.Y).ThenBy(e => Math.Abs(e._address.X - _playArea._map._maxX / 2))]; + return [.. ENEMIES.Where(e => e._speedRemaining > 0).OrderByDescending(e => GetBestPath(e).Count).ThenBy(e => e._address.Y).ThenBy(e => Math.Abs(e._address.X - _playArea._map._maxX / 2))]; } public override void StartTurn() @@ -226,6 +231,7 @@ public partial class EnemyController : TurnController MoveEnemies(); + EnemyAttacks(); } public void SetEnemy(Enemy ENEMY, Vector2I CELL) diff --git a/Map.cs b/Map.cs index 370674d..3c8199d 100644 --- a/Map.cs +++ b/Map.cs @@ -91,13 +91,16 @@ public partial class Map : TileMapLayer public void SetCellEnemy(Vector2I ADDRESS, Enemy ENEMY) { - if (ENEMY._address != -Vector2I.One) + if (ENEMY != null) { - _addressOccupants[ENEMY._address] = null; - SetCellSolid(ENEMY._address); + if (ENEMY._address != -Vector2I.One) + { + _addressOccupants[ENEMY._address] = null; + SetCellSolid(ENEMY._address); + } + ENEMY._address = ADDRESS; } - ENEMY._address = ADDRESS; _addressOccupants[ADDRESS] = ENEMY; SetCellSolid(ADDRESS); @@ -112,11 +115,14 @@ public partial class Map : TileMapLayer public void SetupAstar() { _astar.Region = new Rect2I(_minX, _minY, _topRow.Count, _leftmostColumn.Count); - // GD.Print(_astar.Region); _astar.CellSize = _cellSize; _astar.DefaultComputeHeuristic = AStarGrid2D.Heuristic.Manhattan; _astar.DiagonalMode = AStarGrid2D.DiagonalModeEnum.Never; _astar.Update(); + // for (int i = 0; i < _cells.Count; i++) + // { + // _astar.SetPointWeightScale(_cells[i], _cells[i].Y * 5); + // } EvaluateSolidCells(); }