Skip to content

Instantly share code, notes, and snippets.

@general-games
Created October 14, 2024 17:22
Show Gist options
  • Save general-games/a007ca3a6d9fdb2fd919f6c6248e1261 to your computer and use it in GitHub Desktop.
Save general-games/a007ca3a6d9fdb2fd919f6c6248e1261 to your computer and use it in GitHub Desktop.
public class BuildAction : GridAction
{
[SerializeField] private InputModule inputModule;
[SerializeField] private ActionValidation validation;
[SerializeField] private GameObject GhostUI;
private Dictionary<Cell, bool> canBuild = new Dictionary<Cell, bool>();
public override void StartAction()
{
canBuild.Clear();
Entity.GameGrid.cells.ForEach(cell => canBuild.Add(cell ,validation.Validate(cell, this)));
}
public override void Close()
{
}
public override State Get()
{
return !Active ? null : inputModule.Get(this);
}
public bool CanBuild(Cell cell)
{
return canBuild.ContainsKey(cell) && canBuild[cell];
}
public class BuildInputModule : InputModule
{
public override State Get(GridAction action)
{
if (!(action is BuildAction buildAction))
return null;
return new ConfirmBuildState(buildAction, inputReader, listener, onStartInputState);
}
}
public class ConfirmBuildPlacementState : State
{
private readonly IInputReader _inputReader;
private readonly IFilter<ISelectable> _selectionFilter;
private readonly IFilter<ISelectable> _selectionFilterHover;
private readonly BuildAction _buildAction;
private readonly IListener<ISelectable> _listener;
private readonly GridEntity _buildEntity;
private readonly IHighlightCells _highlighter;
private Cell _previousCell;
private GhostUI _ghostUI;
public ConfirmBuildPlacementState(IInputReader inputReader, IListener<ISelectable> listener, IFilter<ISelectable> selectionFilter, BuildAction buildAction, GridEntity buildEntity)
{
_inputReader = inputReader;
_selectionFilter = selectionFilter;
_buildAction = buildAction;
_listener = listener;
_buildEntity = buildEntity;
_selectionFilter = new SelectionFilter<ISelectable>(listener.Listen, listener.ListenAll, HandleNullSelected, HandleEntitySelected, HandleCellSelected);
_selectionFilterHover = new SelectionFilter<ISelectable>(listener.Listen, listener.ListenAll, HandlePointerAboveNull, HandlePointerAboveEntity, HandlePointerAboveCell);
_highlighter = new DefaultHighlighter(_buildAction.Entity.GameGrid, null);
}
public override void Enter()
{
_ghostUI = Object.Instantiate(_buildAction.ghostUI);
//Set the sprite of the ghost here?
_highlighter.SetAsHighlighted(_buildAction.CanBuild);
base.Enter();
}
protected override void Update()
{
_selectionFilter.Filter(_inputReader.Primary());
_selectionFilterHover.Filter(true);
}
private void HandleEntitySelected(GridEntity entity)
{
HandleNullSelected();
}
private void HandleCellSelected(Cell cell)
{
if (_buildAction.CanBuild(cell))
{
Object.Destroy(_ghostUI.gameObject);
// SOME BUILDING CODE HERE THEN?
nextState = null;
Exit();
return;
}
HandleNullSelected();
Exit();
}
private void HandleNullSelected()
{
_buildAction.Close();
Object.Destroy(_ghostUI.gameObject);
nextState = null;
Exit();
}
private void HandlePointerAboveCell(Cell cell)
{
if(cell == _previousCell)
return;
if (_buildAction.CanBuild(cell))
{
_ghostUI.gameObject.SetActive(true);
_ghostUI.transform.position = cell.transform.position;
_highlighter.SetAsHighlighted(_buildAction.CanBuild);
}
else
{
_ghostUI.gameObject.SetActive(false);
}
_previousCell = cell;
}
private void HandlePointerAboveEntity(GridEntity entity)
{
if(entity.Cell == _previousCell)
return;
_highlighter.SetAsHighlighted(_buildAction.CanBuild);
_ghostUI.gameObject.SetActive(false);
_previousCell = entity.Cell;
}
private void HandlePointerAboveNull()
{
_ghostUI.gameObject.SetActive(false);
}
}
public class ConfirmBuildState : State
{
private readonly IInputReader _inputReader;
private readonly IFilter<ISelectable> _selectionFilter;
private readonly IListener<ISelectable> _listener;
private readonly BuildAction _buildAction;
private readonly EntityCallbacks _onStartInput;
public ConfirmBuildState(BuildAction buildAction, IInputReader inputReader, IListener<ISelectable> listener, EntityCallbacks onStart)
{
_inputReader = inputReader;
_listener = listener;
_selectionFilter = _selectionFilter = new SelectionFilter<ISelectable>(listener.Listen, listener.ListenAll, HandleNullSelected, HandleEntitySelected, HandleCellSelected, HandleButtonSelected);
_buildAction = buildAction;
_onStartInput = onStart;
}
public override void Enter()
{
_onStartInput.InvokeAll(_buildAction.Entity, action: _buildAction);
base.Enter();
}
protected override void Update()
{
_selectionFilter.Filter(_inputReader.Primary());
}
private void HandleCellSelected(Cell cell)
{
HandleNullSelected();
}
private void HandleEntitySelected(GridEntity entity)
{
if (SelectedSelf())
{
_buildAction.Close();
var nextAction = _buildAction.Entity.GetNextAction();
nextState = nextAction == _buildAction ? null : nextAction.Get();
Exit();
}
else
{
HandleNullSelected();
}
bool SelectedSelf() => entity == _buildAction.Entity;
}
private void HandleButtonSelected(GridButton gridButton)
{
if ((gridButton is EntityButton entityButton))
{
if(!entityButton.Active)
return;
_buildAction.Close();
nextState = new ConfirmBuildPlacementState(_inputReader, _listener, _selectionFilter, _buildAction, entityButton.entity);
Exit();
return;
}
HandleNullSelected();
}
private void HandleNullSelected()
{
_buildAction.Entity.Deselect();
_buildAction.Close();
nextState = null;
Exit();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment