# Premade Actions — Shooter Enemy

`GOAPEngine.Demo` includes eight ready-to-use action classes for a shooter-game enemy NPC. Drop them onto an `AIBehavior`, wire up sensors and TargetBinders, extend the virtual hooks for your game logic, and you have a fully functional combat AI.

***

## Recommended Goal Stack Setup

| Goal Stack  | Goal Condition                      | Priority | Interruptible |
| ----------- | ----------------------------------- | -------- | ------------- |
| Patrol      | `atPatrolPoint = 1`                 | 1        | true          |
| Investigate | `atInvestigatePoint = 1`            | 2        | true          |
| Engage      | `playerInRange = 1, ammoLoaded = 1` | 3        | true          |
| Survive     | `isInCover = 1`                     | 4        | false         |

***

## State Key Contract

| Key                  | Written by                      |
| -------------------- | ------------------------------- |
| `playerInSight`      | `LineOfSightSensor`             |
| `playerInRange`      | `RangeSensor` (attack range)    |
| `playerNearby`       | `RangeSensor` (awareness range) |
| `ammoLoaded`         | `ReloadAction` effect           |
| `lowHealth`          | Your health component           |
| `isInCover`          | `TakeCoverAction` effect        |
| `atPatrolPoint`      | `PatrolAction` effect           |
| `playerHeard`        | Your noise/alert system         |
| `atInvestigatePoint` | `InvestigateAction` effect      |

***

## PatrolAction

Navigate to patrol waypoints (TargetBinder objects). Dwells at each point before replanning to the next nearest.

* **Requirements**: `playerInSight == 0`, `playerNearby == 0`
* **Effects**: `atPatrolPoint = 1`
* **TargetBinder setup**: Add `TargetBinder` to patrol-point GameObjects; set Compatible Actions = `PatrolAction`
* **Hook**: `OnPatrolPointReached()` — override to play an idle animation

***

## ChaseAction

Navigate toward the player until `playerInRange` becomes true. Uses `NavMeshAgent.SetDestination()` directly each frame to track a moving player without triggering AIBehavior's built-in proximity check.

* **Requirements**: `playerInSight == 1`
* **Effects**: `playerInRange = 1` (assumed by planner; confirmed by sensor each frame)
* **Fields**: `_speedMultiplier` (boosts nav speed while chasing), `_playerTransform` (or auto-found by `"Player"` tag)
* **Hooks**: `OnChaseStarted()`, `OnChaseUpdate()`, `OnChaseEnded()`

***

## FireWeaponAction

Fire at the player while `playerInRange` and `playerInSight` are both true. When the `GOAPENGINE_CHARACTER` scripting symbol is defined, delegates entirely to `CharacterWeapon.Fire()` — the Weapon component handles fire rate and ammo tracking. When the magazine empties, writes `ammoStateKey = 0` into GOAP state so the planner can immediately chain `ReloadAction`. Without the Character system, falls back to a configurable timer-based path.

Demonstrates three v1.3 features: **Parametric Actions** (`GetParameter("damage")`, `GetParameter("fireInterval")`), **Plan Ordering DSL** (`"Fire[After]Reload"` in the name field), and **Dynamic Cost** (scales with distance to player).

* **Requirements**: `playerInSight == 1`, `playerInRange == 1`, `ammoLoaded == 1`
* **Effects**: `ammoLoaded = 0` (written from code when magazine empties); `playerNeutralized = 1` (optional, set by health system)
* **Fields**: `_ammoStateKey` (default `"ammoLoaded"`), `_rotationSpeed`; `damage` and `fireInterval` as **Parameters** on the Inspector instance
* **Hooks**: override `FireShot()` (timer path) or rely on `CharacterWeapon.Fire()` (Character path)

***

## TakeCoverAction

Navigate to the nearest available cover position (TargetBinder) when health is low.

* **Requirements**: `lowHealth == 1`
* **Effects**: `isInCover = 1`
* **TargetBinder setup**: Add `TargetBinder` to cover GameObjects; set Compatible Actions = `TakeCoverAction`
* **Hooks**: `OnCoverReached()`, `OnLeaveCover()` (on interrupt)

***

## ReloadAction

Stand still and reload over a configurable duration. No navigation.

* **Requirements**: `ammoLoaded == 0`, optionally `isInCover == 1`
* **Effects**: `ammoLoaded = 1`
* **Fields**: `_reloadTime` (default 2 s)
* **Hooks**: `OnReloadStart()`, `OnReloadComplete()`, `OnReloadCancelled()` (on interrupt)

***

## AlertAction

Raise an alert in place (no navigation) when either `playerNearby == 1` **or** `soundHeard == 1`. Demonstrates **Or-condition logic** via an `IsAchievable()` override — the two requirements are evaluated with `Or` instead of the default `And`. Also demonstrates **DSL Effects** (`"isAlert = 1"`).

* **Requirements**: `playerNearby == 1` **or** `soundHeard == 1` (Or logic via `IsAchievable` override)
* **Effects**: `isAlert = 1`
* **Fields**: `_timer` (default 0.5 s — brief pause before effect applies)
* **No navigation**: the guard alerts in place; no TargetBinder required

***

## InvestigateAction

Move to a last-known player position (set from code) and dwell before giving up.

* **Requirements**: `playerHeard == 1`, `playerInSight == 0`
* **Effects**: `playerHeard = 0`, `atInvestigatePoint = 1`
* **Fields**: `_dwellTime` (default 2 s)
* **Public method**: `SetInvestigateTarget(Vector3)` — call from a sensor callback or noise event to set the destination
* **Hook**: `OnInvestigateArrived()` — override for look-around animation/sound

```csharp
// Wire up from a noise event or sensor callback
var behavior = enemy.GetComponent<AIBehavior>();
var investigate = behavior.GetAction<InvestigateAction>() as InvestigateAction;
investigate?.SetInvestigateTarget(lastKnownPosition);
behavior.State["playerHeard"] = 1f;
```

***

## PickUpAction

Navigate to the best available `WeaponPickup` TargetBinder and collect it. Requires the `GOAPENGINE_CHARACTER` scripting symbol and `CharacterPickUp` + `CharacterWeapon` abilities on the character.

Weapon candidates are scored as `distance / (binder.Priority × categoryMultiplier)`. The `_pickupPriority` list (ordered from most-wanted to least-wanted weapon category) sets the multipliers — index 0 gets the highest weight. Weapons already in the inventory are skipped (ammo-refill pickups are auto-collected by `CharacterPickUp` on trigger entry, no navigation needed).

* **Requirements**: `hasWeapon == 0`
* **Effects**: `hasWeapon = 1` (written from code on successful collection)
* **Fields**: `_pickupPriority` (ordered list of `WeaponCategory`; categories absent from the list are excluded)
* **TargetBinder setup**: add `TargetBinder` to each `WeaponPickup` prefab; set Compatible Actions = `PickUpAction`; set Priority to reflect weapon desirability (e.g. BigGun = 4, Handgun = 3, Melee = 2)
* **Hooks**: `OnPickupStarted()`, `OnPickupCollected()`, `OnPickupCancelled()`


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://beelabs-dev.gitbook.io/beelabs-docs/goap-engine/premade-actions.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
