Skip to content
RustPluginGenerator

OnEntityTakeDamage

OnEntityTakeDamage is called before a BaseCombatEntity applies incoming damage, giving you the chance to inspect or modify the HitInfo or cancel the hit. It fires for players, animals, buildings and most other combat entities.

Signature
object OnEntityTakeDamage(BaseCombatEntity entity, HitInfo hitInfo)

Parameters

Hook parameters
ParameterTypeDescription
entityBaseCombatEntityThe BaseCombatEntity taking the damage. This is the hurt target, which can be a player, animal, building block, deployable, NPC or resource entity depending on what was hit. Null-check it and cast to the specific type you care about.
hitInfoHitInfoThe HitInfo describing the incoming damage: Initiator and InitiatorPlayer, damageTypes (DamageTypeList), isHeadshot, IsProjectile(), Weapon, HitPositionWorld and more. You can scale damage through hitInfo.damageTypes or cancel the hit entirely.

Return value

Returning null lets the original damage path continue with the (possibly modified) HitInfo. Returning any non-null object stops the original code path at that call site, which effectively cancels the hit for entities that route through these injections, so use a non-null return to suppress damage you have fully handled yourself.

How it works

The hook fires from Oxide's own combat wrappers rather than a patched game method, so it runs for virtually everything that can be hurt. The main path is RustCore.IOnBaseCombatEntityHurt, which is invoked for any BaseCombatEntity that is not a BasePlayer. Player hits arrive through RustCore.IOnBasePlayerAttacked and IOnBasePlayerHurt, and two specialized paths exist for ResourceEntity.OnAttacked and Rust.Ai.Gen2.LivestockAnimal.Hurt.

entity is the receiver and hitInfo carries the damage type, the attacker (InitiatorPlayer, Initiator), projectile details and the damage list. Adjust hitInfo.damageTypes (for example Scale(Rust.DamageType.Bullet, 0.5f) or ScaleAll(0f)) to reshape the hit. Declaring a narrower parameter type such as BasePlayer makes Oxide skip calls where the argument is not that type, so you only handle the cases you care about. Because the hook fires constantly, never print to console inside it; cache decisions and keep the body cheap.

Other signatures

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

  • object OnEntityTakeDamage(ResourceEntity resourceEntity, HitInfo info)
  • object OnEntityTakeDamage(Rust.Ai.Gen2.LivestockAnimal livestockAnimal, HitInfo info)
  • object OnEntityTakeDamage(BasePlayer player, HitInfo hitInfo)

Example plugin: Reduce structure damage from explosives

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

namespace Oxide.Plugins
{
    [Info("Explosive Building Damage", "RustPluginGenerator", "1.0.0")]
    [Description("Scales explosion damage taken by buildings and deployables.")]
    public class ExplosiveBuildingDamage : RustPlugin
    {
        private PluginConfig config;

        private class PluginConfig
        {
            [JsonProperty("Explosion damage multiplier")]
            public float Multiplier = 0.5f;
        }

        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();
            }
            if (config.Multiplier < 0f) config.Multiplier = 0f;
            SaveConfig();
        }

        protected override void SaveConfig() => Config.WriteObject(config);

        protected override void LoadDefaultMessages()
        {
            lang.RegisterMessages(new Dictionary<string, string>
            {
                ["Reloaded"] = "Explosive damage multiplier is now {0}."
            }, this);
        }

        private string Msg(string key, string userId = null, params object[] args) =>
            string.Format(lang.GetMessage(key, this, userId), args);

        private void Init()
        {
            Puts("ExplosiveBuildingDamage loaded with multiplier " + config.Multiplier);
        }

        private object OnEntityTakeDamage(BaseCombatEntity entity, HitInfo hitInfo)
        {
            if (entity == null || hitInfo == null || hitInfo.damageTypes == null) return null;
            if (entity is BasePlayer) return null;

            bool isBuilding = entity is BuildingBlock;
            bool isOwned = entity.OwnerID != 0 && entity.GetBuildingPrivilege() != null;
            if (!isBuilding && !isOwned) return null;

            if (hitInfo.damageTypes.GetMajorityDamageType() != DamageType.Explosion) return null;

            hitInfo.damageTypes.Scale(DamageType.Explosion, config.Multiplier);
            return null;
        }
    }
}

The plugin scales explosion damage against building blocks and deployables so raiding costs more on a custom server. OnEntityTakeDamage receives every hurt entity; the body first rejects anything that is not a BuildingBlock or a BaseEntity owned through a building privilege, then reads hitInfo.damageTypes.GetMajorityDamageType(). When the majority type is Explosion, it calls hitInfo.damageTypes.Scale(Rust.DamageType.Explosion, multiplier). Returning null keeps the modified HitInfo so the entity still takes the reduced damage. The multiplier is configurable and reloading config adjusts the behavior without restarting.

Common use cases

  • Explosion damage multiplier

    Scale explosion damage up or down on buildings to tune raid cost without touching weapon configs. Check hitInfo.damageTypes.GetMajorityDamageType() before scaling.

  • Damage immunity zones

    When the receiver is inside a protected area or event zone, call hitInfo.damageTypes.ScaleAll(0f) or return a non-null value to block the hit. This also handles players if you narrow the parameter to BasePlayer.

  • Headshot or weapon-specific tuning

    Read hitInfo.isHeadshot and hitInfo.Weapon to apply custom PvP damage curves, for example reducing bolt-action headshots against armored targets while leaving body shots untouched.

Pitfalls

  • Fires on almost every hit

    This hook runs constantly during combat, so doing expensive lookups (team scans, container checks, permission queries) per call hurts server performance. Cache results or check cheap conditions like entity type first.

  • Mutating hitInfo.damageTypes before checks

    GetMajorityDamageType() reflects the damage list you have already scaled. Read the majority type before applying scaling, otherwise subsequent checks against it can misclassify the hit.

  • Narrow types skip unrelated entities

    Declaring BaseCombatEntity receives everything, but declaring BasePlayer only fires for players. Do not assume a single hook method catches resource or animal hits if you have narrowed the parameter.

Plugin recipes that use OnEntityTakeDamage

Build a plugin with OnEntityTakeDamage

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

Prompt: Explosion damage multiplier using the OnEntityTakeDamage 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 OnEntityTakeDamage

Generate