Skip to content
RustPluginGenerator

OnCargoShipEgress

OnCargoShipEgress is called when a CargoShip switches into its departure (egress) phase, right before it stops its horn timer, enables its radiation zone and updates its flags.

Signature
object OnCargoShipEgress(CargoShip cargoShip)

Parameters

Hook parameters
ParameterTypeDescription
cargoShipCargoShipThe CargoShip entity that is beginning its egress (departure) phase. Cast or use it directly to read its position, flags, or attached crates.

Return value

Returning null (or nothing) lets the default egress code run: the horn timer is cancelled, the radiation zone activates, and the ship flags are updated. Returning any non-null value skips that whole block, so the ship begins egressing without the radiation zone or flag update; the method still returns void, so the value is only used as a signal.

How it works

The hook fires from CargoShip.StartEgress, at the point where the ship has been marked as egressing and is about to run its default departure setup. That setup cancels the repeating PlayHorn invoke, turns on the ship's radiation TriggerRadiation, and sends network flag updates. It only runs when the ship is not already doing a harbor approach and not already egressing, so each ship enters this path once per visit cycle.

The single parameter is the CargoShip itself, which is useful for reading transform.position, checking flags, or locating the event crates that have spawned on its deck. There is no narrower type to declare here that would change dispatch in a useful way, since the hook is only ever called with a CargoShip instance.

Because the hook fires before the radiation zone is enabled, it works well as a notification point: you can warn players who are still aboard, announce the ship's departure server-wide, or record timing data. Keep the handler lightweight; it runs once per ship departure, not per frame, but blocking the default path entirely can leave the ship in an inconsistent visual state.

Example plugin: Announce and warn about departing cargo ships

CargoShipDepartureAlert.cs
using System.Linq;
using System;
using System.Collections.Generic;
using Newtonsoft.Json;
using Oxide.Core;
using UnityEngine;

namespace Oxide.Plugins
{
    [Info("Cargo Ship Departure Alert", "RustPluginGenerator", "1.0.0")]
    [Description("Warns nearby players and optionally broadcasts when a cargo ship begins its egress.")]
    public class CargoShipDepartureAlert : RustPlugin
    {
        private const string PermUse = "cargoshipdeparturealert.use";

        private PluginConfig config;

        public class PluginConfig
        {
            [JsonProperty("Warning radius (meters)")]
            public float WarningRadius { get; set; } = 150f;

            [JsonProperty("Broadcast server-wide departure")]
            public bool BroadcastDeparture { get; set; } = true;

            [JsonProperty("Players who enabled personal warnings")]
            public List<string> WarnedPlayers { get; set; } = new List<string>();
        }

        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>
            {
                ["Broadcast"] = "A cargo ship is departing the map. Clear the deck!",
                ["PersonalWarning"] = "The cargo ship you are on is departing. Get off the deck soon.",
                ["ToggleOn"] = "Cargo ship departure warnings are now ON.",
                ["ToggleOff"] = "Cargo ship departure warnings are now OFF.",
                ["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(PermUse, this);
        }

        [ChatCommand("cargowarn")]
        private void CmdCargoWarn(BasePlayer player, string command, string[] args)
        {
            if (player == null) return;
            if (!permission.UserHasPermission(player.UserIDString, PermUse))
            {
                SendReply(player, Msg("NoPermission", player.UserIDString));
                return;
            }

            string id = player.UserIDString;
            if (config.WarnedPlayers.Contains(id))
            {
                config.WarnedPlayers.Remove(id);
                SendReply(player, Msg("ToggleOff", id));
            }
            else
            {
                config.WarnedPlayers.Add(id);
                SendReply(player, Msg("ToggleOn", id));
            }
            SaveConfig();
        }

        private object OnCargoShipEgress(CargoShip cargoShip)
        {
            if (cargoShip == null || cargoShip.IsDestroyed) return null;

            if (config.BroadcastDeparture)
            {
                Server.Broadcast(Msg("Broadcast"));
            }

            Vector3 shipPos = cargoShip.transform.position;
            float radiusSqr = config.WarningRadius * config.WarningRadius;

            foreach (BasePlayer player in BasePlayer.activePlayerList)
            {
                if (player == null || !player.IsConnected) continue;
                if (!config.WarnedPlayers.Contains(player.UserIDString)) continue;
                if ((player.transform.position - shipPos).sqrMagnitude > radiusSqr) continue;

                SendReply(player, Msg("PersonalWarning", player.UserIDString));
            }

            return null;
        }
    }
}

The plugin registers a chat command that toggles a per-player warning preference, stored in the config. When OnCargoShipEgress fires, it reads the ship position and broadcasts a localized server-wide message that a cargo ship is departing. For every connected player who has warnings enabled and is within the configured radius of the ship, it sends a personal chat reminder to leave the deck before the radiation zone activates. The hook returns null so the vanilla egress sequence still runs. Config holds radius, broadcast toggle, and the set of opted-in user IDs.

Common use cases

  • Warn players still on deck

    Iterate connected players and send a chat warning to anyone near the ship's position so they can jump off before radiation turns on.

  • Broadcast departure events

    Send a server-wide message or Discord relay when a cargo ship leaves, which is useful for tracking event timing on PvE servers.

  • Log event timings

    Record the position and timestamp when each cargo ship begins egress to build up patrol route analytics, writing the data through the Oxide data file system.

Pitfalls

  • Returning a value skips the radiation zone

    Any non-null return prevents the default block from running, so the ship departs without enabling its radiation trigger. Only do this deliberately, for example on a custom event ship you control.

  • Not every call is a fresh departure

    The hook only fires when the ship is not already egressing or approaching a harbor, so it is safe to treat each call as a single departure step, but do not assume it repeats on a timer.

  • Ship may be destroyed shortly after

    Egress leads to the ship despawning at the end of its route, so avoid long timers that hold a reference to the CargoShip and always check IsDestroyed before acting on it.

Build a plugin with OnCargoShipEgress

Describe what should happen and get a compiled plugin that uses this hook.

Prompt: Warn players still on deck using the OnCargoShipEgress hook, with a config file and a permission
Generate this plugin

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 OnCargoShipEgress

Generate