OnNoGoZoneAdded
OnNoGoZoneAdded is called when the patrol helicopter AI registers a new danger zone, right before the vanilla code decides whether to make the helicopter flee.
object OnNoGoZoneAdded(PatrolHelicopterAI patrolHelicopterAI, PatrolHelicopterAI.DangerZone zone)Parameters
| Parameter | Type | Description |
|---|---|---|
patrolHelicopterAI | PatrolHelicopterAI | The PatrolHelicopterAI instance that registered the danger zone, i.e. the AI controller of the patrol helicopter whose navigation logic is reacting. |
zone | PatrolHelicopterAI.DangerZone | The PatrolHelicopterAI.DangerZone that was just added. Exposes the zone position and radius plus the IsInMonument flag the vanilla code checks. |
Return value
Returning null lets the original code run: the helicopter clears targets and flees unless zone.IsInMonument is true. Returning any non-null value (for example true) stops the method, so the helicopter does not clear targets or enter the flee state for that zone.
How it works
The hook fires inside PatrolHelicopterAI.NoGoZoneAdded, which the AI calls when a new DangerZone is added to the helicopter's no-go list while danger zones are enabled. In vanilla, the helicopter immediately clears its targets and enters the flee state unless the zone is inside a monument. Because the hook is evaluated first and a non-null return skips the rest of that method body, you get a clean place to veto or react to the flee behavior.
The patrolHelicopterAI parameter is the AI controller itself, so you can inspect or mutate its state, read its position, or look up the entity through patrolHelicopterAI.helicopter. The zone parameter is the danger zone record; zone.IsInMonument tells you whether the vanilla code would already have skipped the flee reaction, which matters when you want to treat monument zones differently from player-made ones.
The hook is dispatched for every helicopter, so keep the method cheap and guard against a null zone. Declaring the second parameter as the nested PatrolHelicopterAI.DangerZone type is required; declaring a broader type would stop Oxide from matching and the hook would never run.
Example plugin: Let monuments-only zones be ignored and log player-made ones
using System;
using System.Collections.Generic;
using Newtonsoft.Json;
using Oxide.Core;
using UnityEngine;
namespace Oxide.Plugins
{
[Info("Helicopter Zone Logger", "RustPluginGenerator", "1.0.0")]
[Description("Announces patrol helicopter danger zones and can suppress the default flee reaction")]
public class HelicopterZoneLogger : RustPlugin
{
private const string PermNotify = "helicopterzonelogger.notify";
private class PluginConfig
{
[JsonProperty("Announce zones in chat to permitted players")]
public bool AnnounceZones = true;
[JsonProperty("Suppress flee for zones outside monuments")]
public bool SuppressFleeForNonMonumentZones = false;
}
private PluginConfig config;
protected override void LoadDefaultConfig() => config = new PluginConfig();
protected override void LoadConfig()
{
base.LoadConfig();
try
{
config = Config.ReadObject<PluginConfig>();
if (config == null) throw new Exception();
}
catch
{
PrintWarning("Configuration file is invalid, using defaults");
LoadDefaultConfig();
}
SaveConfig();
}
protected override void SaveConfig() => Config.WriteObject(config);
protected override void LoadDefaultMessages()
{
lang.RegisterMessages(new Dictionary<string, string>
{
["ZoneAdded"] = "Helicopter zone registered at {0}: monument zone = {1}, reaction suppressed = {2}",
["NoPermission"] = "You do not have permission to use this command."
}, this);
}
private string Msg(string key, string userId = null, params object[] args) =>
string.Format(lang.GetMessage(key, this, userId), args);
private void Init()
{
permission.RegisterPermission(PermNotify, this);
}
[ChatCommand("hzone")]
private void CmdHZone(BasePlayer player, string command, string[] args)
{
if (!permission.UserHasPermission(player.UserIDString, PermNotify))
{
SendReply(player, Msg("NoPermission", player.UserIDString));
return;
}
SendReply(player, $"Suppress flee: {config.SuppressFleeForNonMonumentZones}, announce: {config.AnnounceZones}");
}
private object OnNoGoZoneAdded(PatrolHelicopterAI patrolHelicopterAI, PatrolHelicopterAI.DangerZone zone)
{
if (patrolHelicopterAI == null || zone == null) return null;
bool suppressed = config.SuppressFleeForNonMonumentZones && !zone.IsInMonument;
if (config.AnnounceZones)
{
Vector3 pos = patrolHelicopterAI.transform != null
? patrolHelicopterAI.transform.position
: Vector3.zero;
string text = Msg("ZoneAdded", null, pos.ToString("F1"), zone.IsInMonument, suppressed);
foreach (BasePlayer player in BasePlayer.activePlayerList)
{
if (player != null && player.IsConnected && permission.UserHasPermission(player.UserIDString, PermNotify))
player.ChatMessage(text);
}
}
return suppressed ? (object)true : null;
}
}
}The plugin announces every danger zone the patrol helicopter registers and optionally suppresses the flee reaction for zones that are not inside a monument, so a helicopter can be configured to ignore certain player-created threat areas.
OnNoGoZoneAdded null-checks the zone, reads zone.IsInMonument and the helicopter's world position, and builds a chat message from the language file for every connected admin who has the helicopterzonelogger.notify permission. If SuppressFleeForNonMonumentZones is enabled in the config, it returns true to stop the vanilla flee path and prints the result to console; otherwise it returns null and vanilla behavior is untouched. All messages go through Oxide lang, and the hook avoids Puts/PrintWarning in normal operation.
Common use cases
PvE servers that want helicopters to ignore player bases
Return a non-null value for zones that belong to player buildings so the helicopter keeps its current state instead of fleeing, while still letting monument zones behave normally.
Admin notifications about helicopter threats
Broadcast a chat or console notice to permitted staff whenever a new danger zone is registered, including whether it was inside a monument.
Adjusting helicopter state yourself
Return a value to cancel the default flee logic, then apply your own behavior on the AI instance, such as clearing targets only when the zone is close to the helicopter.
Pitfalls
The zone parameter can be null
Guard
zonebefore readingIsInMonument; dereferencing it when null throws inside the AI and can break the helicopter's state machine.Returning non-null silently disables fleeing
Any non-null return stops the whole method body, so the helicopter will not call ClearTargets, ExitCurrentState or State_Flee_Enter. Only return a value when that is exactly what you want.
Do not return null by accident after side effects
If you mutate state and then return null, vanilla still runs and can override your changes; order your logic so the return value reflects your intent.
Build a plugin with OnNoGoZoneAdded
Describe what should happen and get a compiled plugin that uses this hook.
Edit the prompt on the next screen. 2 free plugins a month, no card.
Last updated Oct 26, 2026. Found a mistake? Email support@rustplugingenerator.com.
Build a plugin with OnNoGoZoneAdded
Generate