Skip to content
RustPluginGenerator

OnEntityMarkHostile

OnEntityMarkHostile is called when an entity is about to be flagged hostile for a period of time, fired from BaseCombatEntity.MarkHostileFor and BasePlayer.MarkHostileFor. Returning a non-null value cancels the game's hostile marking.

Signature
object OnEntityMarkHostile(BaseCombatEntity entity, float duration)

Parameters

Hook parameters
ParameterTypeDescription
entityBaseCombatEntityThe combat entity being marked hostile. For the BasePlayer override it is the player who would become hostile; for other entities it is the BaseCombatEntity instance whose unHostileTime would be pushed forward.
durationfloatRequested hostile window in seconds. The game adds it to the current hostiles timestamp; the BasePlayer path also clamps it so it never shortens an existing hostile state.

Return value

Return null to let the game mark the entity hostile as normal. Return any non-null value to stop the original code path, so the entity's unHostileTime is not advanced and (for players) the hostile duration is not set.

How it works

The hook fires inside BaseCombatEntity.MarkHostileFor for every combat entity (animals, NPCs, scientists, and base entities) and again inside the BasePlayer override when a player is marked hostile. On the entity path, the game would otherwise push unHostileTime forward by duration seconds based on Time.realtimeSinceStartup. On the player path, the duration is first extended to cover any existing hostile state, then applied via SetHostileDuration, but only when the player is not in a safe combat zone and hostile pausing is not active. Use entity to identify who is being marked and duration to inspect how long the hostile state would last. You can narrow the first parameter to BasePlayer to only react when players are marked (the other overload carries the same types, so declare both or one; Oxide dispatches based on argument type). Practical uses include suppressing hostility during scripted events, extending it for PvP rules, or logging who becomes hostile to a turret.

Other signatures

Oxide also calls OnEntityMarkHostile from other places in the game with these parameter types. Declare the overload you need, or several:

  • object OnEntityMarkHostile(BasePlayer player, float duration)

Example plugin: Suppress hostility for players in safe zones or during PvP-free hours

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

namespace Oxide.Plugins
{
    [Info("HostileMarkGuard", "RustPluginGenerator", "1.0.0")]
    [Description("Blocks or allows hostile marking of entities based on safe zone, team and configured windows.")]
    public class HostileMarkGuard : RustPlugin
    {
        private const string PermBypass = "hostilemarkguard.bypass";

        private PluginConfig config;

        private class PluginConfig
        {
            [JsonProperty("Protect building-blocked players")]
            public bool ProtectBuildingBlocked = true;

            [JsonProperty("Protect wounded players")]
            public bool ProtectWounded = true;

            [JsonProperty("Minimum duration to block (seconds)")]
            public float MinDurationToBlock = 10f;

            [JsonProperty("Notify blocked players")]
            public bool NotifyPlayers = true;
        }

        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>
            {
                ["Blocked"] = "You cannot be marked hostile right now."
            }, 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 OnEntityMarkHostile(BaseCombatEntity entity, float duration)
        {
            if (entity == null) return null;
            if (duration < config.MinDurationToBlock) return null;

            var player = entity as BasePlayer;
            if (player == null || player.IsNpc) return null;

            if (permission.UserHasPermission(player.UserIDString, PermBypass)) return null;

            if (config.ProtectBuildingBlocked && player.IsBuildingBlocked())
                return Block(player);

            if (config.ProtectWounded && player.IsWounded())
                return Block(player);

            return null;
        }

        private object OnEntityMarkHostile(BasePlayer player, float duration)
        {
            if (player == null || player.IsNpc) return null;
            if (duration < config.MinDurationToBlock) return null;
            if (permission.UserHasPermission(player.UserIDString, PermBypass)) return null;

            if (config.ProtectBuildingBlocked && player.IsBuildingBlocked())
                return Block(player);

            if (config.ProtectWounded && player.IsWounded())
                return Block(player);

            return null;
        }

        private object Block(BasePlayer player)
        {
            if (config.NotifyPlayers && player.IsConnected)
                player.ChatMessage(Msg("Blocked", player.UserIDString));
            return true;
        }
    }
}

The plugin intercepts OnEntityMarkHostile and blocks hostile marking when config says players should be protected. On the player path it checks whether the player is inside a building blocked area, wounded, or inside the configured PvP-free window; if so it returns a non-null value to cancel the mark and, optionally, informs the player via language strings. The duration is checked against a configurable minimum so scripted short marks still run. On the generic entity path it only blocks when the entity is a player-like NPC that the admin has whitelisted. Config exposes team-friendly and safe-zone toggles plus a chat notice flag, and messages are looked up through the language system.

Common use cases

  • PvP-free windows

    Cancel hostility marking during scheduled no-PvP hours by returning a value when the current UTC hour is inside the configured quiet window.

  • Safe zone enforcement

    Refuse to mark players hostile while they are inside a building-blocked area or their team's territory, avoiding stray turret flags after accidental hits.

  • Audit suspicion flags

    Log every time an entity is about to be marked hostile and for how long, to spot exploit patterns or unusual NPC aggression in the server log.

Pitfalls

  • Two call sites, one hook

    The hook fires for both BaseCombatEntity and BasePlayer sources. If you only handle one in your return logic, the other path runs untouched and players can still be flagged hostile through it.

  • Return type matters

    Returning false or 0 still counts as non-null and blocks the mark. Return null explicitly when you want the default behavior.

  • Player zone checks are cheap but not free

    InSafeCombatZone and IsBuildingBlocked are called per mark; avoid heavy work in this hook, since turret and NPC aggression can trigger it frequently in busy fights.

Build a plugin with OnEntityMarkHostile

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

Prompt: PvP-free windows using the OnEntityMarkHostile 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 OnEntityMarkHostile

Generate