Skip to content
RustPluginGenerator

OnCrateLanded

OnCrateLanded is called when a HackableLockedCrate's landing check detects ground contact and the crate becomes lootable, fired once per crate at the moment it settles.

Signature
void OnCrateLanded(HackableLockedCrate hackableLockedCrate)

Parameters

Hook parameters
ParameterTypeDescription
hackableLockedCrateHackableLockedCrateThe HackableLockedCrate entity that has touched the ground. Use it to read the crate's position, net ID, owner, or to schedule timers tied to that specific crate instance.

Return value

The hook is patched with a plain continue and the original LandCheck method returns void, so any return value is ignored. Returning null or a value changes nothing; the crate is already marked landed and its land effect already played before the hook fires.

How it works

The hook fires inside HackableLockedCrate.LandCheck, a repeating check that raycasts downward from just above the crate. When the ray hits terrain or a structure and the crate has not already landed, the game plays the land effect, sets its internal landed flag, calls OnCrateLanded, and cancels further landing checks. That means it triggers exactly once per crate, the instant it stops falling — for supply-style locked crates dropped by a cargo plane, signaled airdrop, or admin spawn. The single parameter is the crate entity itself, so you can read hackableLockedCrate.transform.position, net.ID.Value, OwnerID, or store it for later. Declaring the parameter as a base type such as BaseEntity would still receive the argument, but there is no reason to widen it here. Because it fires once and the crate is now stationary, this is a safe place to spawn markers, effects, announcements, or start a timer that later interacts with the crate.

Example plugin: Announce landed locked crates with a map marker

CrateLandedAnnouncer.cs
using Oxide.Game.Rust.Cui;
using System;
using System.Collections.Generic;
using Newtonsoft.Json;
using Oxide.Core;
using UnityEngine;

namespace Oxide.Plugins
{
    [Info("Crate Landed Announcer", "RustPluginGenerator", "1.0.0")]
    [Description("Announces locked crate landings with their map grid coordinate.")]
    public class CrateLandedAnnouncer : RustPlugin
    {
        private const string PermAnnounce = "cratelandedannouncer.announce";

        private PluginConfig config;

        private class PluginConfig
        {
            [JsonProperty("Announce in global chat")]
            public bool AnnounceInChat = true;

            [JsonProperty("Prefix")]
            public string Prefix = "[Crate]";
        }

        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>
            {
                ["Landed"] = "A locked crate landed at {0}. It is now hackable.",
                ["GridUnknown"] = "A locked crate landed somewhere on the map."
            }, 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(PermAnnounce, this);
        }

        private void OnCrateLanded(HackableLockedCrate hackableLockedCrate)
        {
            if (hackableLockedCrate == null || hackableLockedCrate.IsDestroyed) return;
            if (!config.AnnounceInChat) return;

            string grid = GetGrid(hackableLockedCrate.transform.position);
            string message = string.IsNullOrEmpty(grid)
                ? Msg("GridUnknown")
                : Msg("Landed", null, grid);

            Server.Broadcast($"{config.Prefix} {message}");
        }

        private string GetGrid(Vector3 position)
        {
            const float gridSize = 146.3f;
            int x = Mathf.FloorToInt((position.x + 731.5f) / gridSize);
            int z = Mathf.FloorToInt((position.z + 731.5f) / gridSize);
            if (x < 0 || x > 9 || z < 0 || z > 9) return null;

            char letter = (char)('A' + x);
            int number = 10 - z;
            return $"{letter}{number}";
        }

        private void Unload()
        {
            foreach (var player in BasePlayer.activePlayerList)
            {
                if (player != null)
                    CuiHelper.DestroyUi(player, "CrateLandedStatus");
            }
        }
    }
}

The plugin listens for OnCrateLanded and, when the crate comes to rest, broadcasts a chat message containing its grid location so players know a locked crate is now hackable. It reads transform.position and converts it into Rust's grid format (A1, B2, and so on) using simple math on X and Z. A short permission allows admins to suppress announcements while testing, and the message text is stored in the language file so it can be translated. If you prefer to only announce admin-spawned crates, check OwnerID against a configured list. The plugin keeps no timers and stores nothing, so Unload only walks the active players to clear a small status UI.

Common use cases

  • Notifying players of a landed crate

    Broadcast the crate's grid coordinate to chat or a Discord bridge so players know where to contest the hack. Use the crate position rather than a stored spawn point, since the crate may drift while falling.

  • Spawning a visual marker or smoke column

    Run an effect at the crate position or spawn a temporary marker entity so the crate is easier to find. The land effect has already played, so your marker should be distinct to avoid confusion.

  • Starting a countdown before the crate despawns

    Track each crate by net ID and start a timer from the moment it lands, warning players as time runs out. Store the timer so it can be destroyed in Unload.

Pitfalls

  • It fires once, not per frame

    LandCheck cancels itself after firing the hook, so do not expect repeat calls. If you want ongoing monitoring, start your own timer inside the hook.

  • Already-looted or despawned crates

    The crate may be destroyed shortly after landing if it was already hacked or if an admin clears it. Guard any later timer callback with crate.IsDestroyed before touching the entity.

  • Do not rely on a return value

    The patch discards whatever you return, so returning false or a value will not stop the crate from becoming lootable. Change crate behavior by interacting with the entity or through other hooks.

Build a plugin with OnCrateLanded

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

Prompt: Notifying players of a landed crate using the OnCrateLanded 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 OnCrateLanded

Generate