Overwatch action

I like the action system, it’s very flexible. However there is one case that I don’t know how to manage. How would you make an action similar to “overwatch” in XCOM, where the character performs the action of shooting if an enemy gets in his line of fire during the enemy’s turn?

4 Likes

By default all the actions are designed with if (!isActive) return; in order to make their logic not run while not active. For an Overwatch you want to change that, you want to keep track of Unit grid position changes even while Overwatch isn’t the active action.

So you would have some kind of boolean in the Overwatch action, when taking action you set that to true
Then before that “!isActive return” you would run the Overwatch logic if the bool was true. You would check if a enemy Unit is within the shoot range, if nothing blocking, and if so shoot.

If you want to make it exactly like XCOM (game slows down, overwatch takes its action) then it’s a bit more complex since you have to come up with some way of “pausing” the enemy action while Moving.

2 Likes

@David_Collado I’ve never actually played XCOM, but I think I get the idea. Would changing the enemy unit’s move speed to 0, or almost 0, for a brief time work?

I’ve actually thought a bit about an Overwatch type function… The best method I can think of is to have some sort of event when a character steps on a particular tile…

Here’s my idea in broad strokes:
In GridObject.cs, we need to add an EventHandler OnUnitAdded, and invoke the OnUnitAdded(this, unit) in it’s AddUnit method.

In LevelGrid, we need two pass through methods to subscribe and unsubscribe to these events.

    public void SubscribeToAddedUnitEvent(GridPosition gridPosition, EventHandler<Unit> OnUnitAdded)
    {
        gridSystem[gridPosition].OnUnitAdded += OnUnitAdded;
    }

    public void UnSubscribeToAddedUnitEvent(GridPosition gridPosition, EventHandler<Unit> OnUnitAdded)
    {
        gridSystem[gridPosition].OnUnitAdded -= OnUnitAdded;
    }

When the TurnEnded event fires, any units of the team that ended it’s turn with OverWatch will need to gather a list of all valid locations that it can Overwatch. Then it needs to call LevelGrid.SubscribeToAddedUnitEvent to every location on that list. When a unit moves into one of these positions, the event will fire and the Overwatch can react.
At this point, the Overwatch has acted, and any further events should be ignored until the end of the turn.
At the end of the turn, the Overwatch actions will have to unsubscribe from the events using the LevelGrid.UnSubscribeToAddedUnitEvent action. Additionally, if a unit DIES, then the Overwatch for that unit will have to unsubscribe as well.

This is, of course, just a rough sketch of what will need to happen.

2 Likes

Would it not be simpler to have a static OnUnitAdded event? That would eliminate the need to subscribe and unsubscribe all the time and an enemy unit could then evaluate the unit’s GridPosition to determine if it is in range, etc.

It would probably be more clear to call it OnUnitMoved and pass custom event arguments holding both the unit and the grid position

public class UnitMovedEventArgs : EventArgs
{
    public Unit Unit { get; }
    public GridPosition GridPosition { get; }
    public UnitMovedEventArgs(Unit unit, GridPosition gridPosition)
    {
        Unit = unit;
        GridPosition = gridPosition;
    }
}

// defined event
public static event EventHandler<UnitMovedEventArgs> OnUnitMoved;

Edit I just looked at the final code in the gitlab repo. There is already an event that fires when units change grid positions called OnAnyUnitMovedGridPosition. It’s different from my code, so I assume these changes were made by Hugo for the final level. These changes include custom event arguments that hold the unit, and its start and end positions. I would probably leverage of this event

1 Like

Actually, you’re quite right. Even without the pre-existing handler from Hugo’s code (it wasn’t in my codebase either, but my own version of the project drifts a bit…), you actually still only need the Unit in the EventHandler. The Overwatch action can quickly get the GridPosition and affiliation from the Unit. I would still pre-cache the locations that the Overwatch could attack for a quick lookup.

I was originally thinking that it could be resource intensive having an event everytime something moves and checking every one.

Then i remembered(half way through asking) that this is a grid turn based game, and only one unit/location will be updated at a time aha.

Always think of optimization of queries after working with an ERP.

This topic was automatically closed 24 hours after the last reply. New replies are no longer allowed.

Privacy & Terms