OnHelicopterDropDoorOpen
OnHelicopterDropDoorOpen is called when the CH47 Chinook AI controller runs SetDropDoorOpen, i.e. right before the rear cargo door flag is toggled. Returning a non-null value cancels the door update for that call.
object OnHelicopterDropDoorOpen(CH47HelicopterAIController controller)Parameters
| Parameter | Type | Description |
|---|---|---|
controller | CH47HelicopterAIController | The CH47HelicopterAIController whose rear drop door is about to change state. Use its helicopter property to reach the CH47Helicopter entity, read flags, and check position. |
Return value
Returning null lets the original SetDropDoorOpen run and toggle the door flag as normal. Returning any non-null object stops the method before the flag is set or the network update is sent, so the door state does not change for that call. The original method returns void, so the value itself is discarded beyond the null check.
How it works
The hook fires inside CH47HelicopterAIController.SetDropDoorOpen(bool open) on the server, before the controller sets its Flags.Reserved8 flag with a network update. The game calls this method as part of the Chinook's crate drop sequence and whenever the AI decides to open or close the rear door. Because the method is shared between open and close calls, the hook does not tell you whether the door is opening or closing directly; read the current state from controller.HasFlag(BaseEntity.Flags.Reserved8) or inspect the helicopter.
The single parameter is the AI controller, not the helicopter entity itself. The door flag lives on that controller (it inherits BaseEntity), and the visible CH47Helicopter is reached through the controller's helicopter field. There is no way to narrow this hook to a more specific type, since only one parameter type exists.
Practical use: gate the door state, log or react to a Chinook reaching its drop point, or completely lock a custom-spawned Chinook so it never opens its cargo door. Since the hook also fires when the AI tries to close the door, blocking every call can leave the chopper stuck with a half-open state, so decide carefully which calls you block.
Example plugin: Lock the Chinook cargo door per permission
using System;
using System.Collections.Generic;
using Newtonsoft.Json;
using Oxide.Core;
using UnityEngine;
namespace Oxide.Plugins
{
[Info("ChinookDoorLock", "RustPluginGenerator", "1.0.0")]
[Description("Restricts the CH47 Chinook cargo door toggle unless the caller has a bypass permission.")]
public class ChinookDoorLock : RustPlugin
{
private const string PermBypass = "chinookdoorlock.bypass";
private PluginConfig config;
private readonly Dictionary<string, float> lastNotice = new Dictionary<string, float>();
private class PluginConfig
{
[JsonProperty("Block door when nobody holds bypass")]
public bool BlockDoor = true;
[JsonProperty("Notify nearby players when blocked")]
public bool NotifyNearby = true;
[JsonProperty("Notification cooldown in seconds")]
public float NoticeCooldown = 10f;
[JsonProperty("Nearby player radius")]
public float NoticeRadius = 30f;
}
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>
{
["DoorLocked"] = "The Chinook cargo door is locked.",
["Toggled"] = "Chinook door locking is now {0}.",
["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(PermBypass, this);
}
private object OnHelicopterDropDoorOpen(CH47HelicopterAIController controller)
{
if (controller == null || !config.BlockDoor) return null;
if (HasNearbyBypass(controller)) return null;
if (config.NotifyNearby) NotifyNearbyPlayers(controller);
return true;
}
private bool HasNearbyBypass(CH47HelicopterAIController controller)
{
var position = controller.transform.position;
foreach (var player in BasePlayer.activePlayerList)
{
if (player == null || player.IsNpc || !player.IsConnected) continue;
if (!permission.UserHasPermission(player.UserIDString, PermBypass)) continue;
if (Vector3.Distance(player.transform.position, position) <= config.NoticeRadius) return true;
}
return false;
}
private void NotifyNearbyPlayers(CH47HelicopterAIController controller)
{
var now = UnityEngine.Time.realtimeSinceStartup;
var position = controller.transform.position;
foreach (var player in BasePlayer.activePlayerList)
{
if (player == null || player.IsNpc || !player.IsConnected) continue;
if (Vector3.Distance(player.transform.position, position) > config.NoticeRadius) continue;
float last;
if (lastNotice.TryGetValue(player.UserIDString, out last) && now - last < config.NoticeCooldown) continue;
lastNotice[player.UserIDString] = now;
player.ChatMessage(Msg("DoorLocked", player.UserIDString));
}
}
[ChatCommand("doorlock")]
private void CmdDoorLock(BasePlayer player, string command, string[] args)
{
if (player == null) return;
if (!player.IsAdmin && !permission.UserHasPermission(player.UserIDString, PermBypass))
{
player.ChatMessage(Msg("NoPermission", player.UserIDString));
return;
}
config.BlockDoor = !config.BlockDoor;
SaveConfig();
player.ChatMessage(Msg("Toggled", player.UserIDString, config.BlockDoor ? "enabled" : "disabled"));
}
private void Unload()
{
lastNotice.Clear();
}
}
}The plugin lets admins with the chinookdoorlock.bypass permission decide whether the Chinook cargo door can be toggled. When OnHelicopterDropDoorOpen fires it looks up the controller's helicopter, checks whether the caller holds the bypass permission, and returns a non-null object to block the door update for everyone else. Cool-down messages are pushed to chat only when a player is nearby and never more than once every few seconds per player. Admins can run /doorlock to toggle the restriction on the fly, and the state is kept in config so it survives restarts.
Common use cases
Disable crate door opening on events
Block the door toggle while a custom event is running so players cannot collect a Chinook's crates mid-round, then allow it again when the event ends.
Log Chinook door activity
Record when the AI reaches its drop location by printing a warning the first time the door tries to open near a monitored position, helping admins debug crate spawns.
Restrict door to authorized players
Only permit the door update when a staff member holding a bypass permission is nearby, preventing random players from looting an admin-spawned Chinook.
Pitfalls
The hook fires for both open and close
SetDropDoorOpen is used for both directions, so a blanket non-null return leaves the door stuck in whatever state it was in. If you only want to block opening, check the current flag first.
The parameter is the AI controller
The argument is CH47HelicopterAIController, not CH47Helicopter. Casting it to a helicopter type always fails; reach the vehicle through the controller's helicopter field instead.
Blocking too often stalls crate drops
Returning a value cancels the whole method call including the network update. If you block every call during a Chinook's route, players will never see the door open and crates will not be visibly dropped.
Build a plugin with OnHelicopterDropDoorOpen
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 OnHelicopterDropDoorOpen
Generate