Files
peggle-roguelike/Peg.cs
T

115 lines
3.3 KiB
C#

using Godot;
using System;
using System.Collections.Generic;
using System.Linq;
public partial class Peg : HoverableNode
{
[Signal]
public delegate void DeathEventHandler(Peg THIS);
public int _id, _health = 2, _healthMax = 2, _stamina, _staminaRemaining, _movement = 0, _disposition, _visibility;
public Vector2I _address;
public List<Vector2I> _path = new();
public PegController _pegController;
public List<PegAction> _actions;
public int _distanceToGoal
{
get
{
return GetBestPath().Count;
}
}
public override void _Ready()
{
base._Ready();
_actions = [.. GetNode<Node2D>("Actions").GetChildren().Cast<PegAction>()];
}
public virtual PegAction SelectAction()
{
PegAction action = null;
for (int i = 0; i < _actions.Count; i++)
{
if (_actions[i].MeetsCriteria(this))
{
action = _actions[i];
break;
}
}
return action;
}
public virtual void CounterAct(Commander COMMANDER)
{
}
public virtual List<Vector2I> GetBestPath()
{
Map map = _pegController._playArea._map;
List<Vector2I> goals = GetGoals();
List<List<Vector2I>> paths = new();
for (int i = 0; i < goals.Count; i++)
{
paths.Add(map.GetPath(_address, goals[i]));
}
List<List<Vector2I>> pathsOverZeroCount = [.. paths.Where(p => p.Count > 0)];
if (pathsOverZeroCount.Count == 0)
{
return [];
}
return pathsOverZeroCount.OrderBy(p => p.Count).ToList()[0];
}
public virtual List<Vector2I> GetVisibleCells()
{
Map map = _pegController._playArea._map;
return [.. map._cells.Where(c => (c - _address).Length() <= _visibility)];
}
public virtual List<Vector2I> GetGoals()
{
Map map = _pegController._playArea._map;
TileMapLayer pathLayer = _pegController._playArea.GetNode<TileMapLayer>("PathLayer");
List<Vector2I> pl = [.. pathLayer.GetUsedCells()];
List<Vector2I> visible = GetVisibleCells();
if (_id == 4)
for (int i = 0; i < pl.Count; i++)
{
Vector2I cell = pl[i];
pathLayer.GetUsedCells().ToList().ForEach(c => pathLayer.SetCell(cell,0,Vector2I.Down + Vector2I.Right*(visible.IndexOf(cell) > -1 ? 1 : 4)));
}
List<Vector2I> unoccupied = [.. visible.Where(c => !map._astar.IsPointSolid(c))];
List<Vector2I> closest = [.. unoccupied.Where(c => c.Y == (_disposition == -1 ? unoccupied.Min(c => c.Y) : unoccupied.Max(c => c.Y))).OrderByDescending(c => Math.Abs(c.X - _address.X))];
return closest;
}
public Vector2 GetPositionFromAddress()
{
return _pegController._playArea._map.GetCellPositionFromAddress(_address);
}
public virtual void StartTurn()
{
_staminaRemaining = _stamina;
_actions.ForEach(a => a.Reset());
}
public virtual void ChangeHealth(int DELTA, Commander COMMANDER)
{
_health += DELTA;
CounterAct(COMMANDER);
if (_health <= 0)
{
EmitSignal(SignalName.Death, this);
}
else if (_health > _healthMax)
{
_health = _healthMax;
}
}
}