OnHammerHit
OnHammerHit is called when a player swings a building hammer at a target, before the game runs its repair, rotate or demolish logic.
object OnHammerHit(BasePlayer ownerPlayer, HitInfo info)Parameters
| Parameter | Type | Description |
|---|---|---|
ownerPlayer | BasePlayer | The player who swung the hammer. This is the attacker from the player's own build/repair action, never null when the hook fires. |
info | HitInfo | The HitInfo describing the swing: HitEntity, HitPositionWorld, HitNormal, Weapon and the initiator. Use it to inspect what was hit and where. |
Return value
Returning a non-null value (any object, including false) stops the original code path and skips the vanilla repair, rotate or demolish handling. Returning null lets the game proceed normally. The return value itself is only used as a yes/no gate; it is not passed on as a result.
How it works
The hook fires inside Hammer.DoAttackShared, the shared method the building hammer uses for repair, rotate and demolish actions. It runs only when the game found a valid BaseCombatEntity target and the attacking player is non-null and the action is server-side, so sleeping builds and world entities without health are not covered. ownerPlayer identifies the acting player; info carries the hit entity, hit position, normal and weapon.
Declaring ownerPlayer as BasePlayer marks every argument as a player, which is what the game already guarantees here. Returning non-null aborts the vanilla repair/rotate/demolish branch, which is how you gate or redirect the action. The hook is per swing, not per completed repair, so it fits cooldowns, permission checks and custom damage-to-structure rules. It is not a general damage hook — combat damage goes through OnEntityTakeDamage, and completed repairs through OnStructureRepair.
Example plugin: Restrict hammer repairs to authorized players
using System;
using System.Collections.Generic;
using Newtonsoft.Json;
using UnityEngine;
using Oxide.Core;
namespace Oxide.Plugins
{
[Info("Hammer Repair Guard", "RustPluginGenerator", "1.0.0")]
[Description("Blocks hammer actions on structures the player is not authorized for.")]
public class HammerRepairGuard : RustPlugin
{
private const string PermBypass = "hammerrepairguard.bypass";
private PluginConfig config;
private readonly Dictionary<ulong, float> lastNotice = new Dictionary<ulong, float>();
private class PluginConfig
{
[JsonProperty("Block unauthorized hammer actions")]
public bool BlockUnauthorized = true;
[JsonProperty("Chat notice cooldown (seconds)")]
public float NoticeCooldown = 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();
}
SaveConfig();
}
protected override void SaveConfig() => Config.WriteObject(config);
protected override void LoadDefaultMessages()
{
lang.RegisterMessages(new Dictionary<string, string>
{
["NotAuthorized"] = "You are not authorized to modify this structure."
}, 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 OnHammerHit(BasePlayer ownerPlayer, HitInfo info)
{
if (!config.BlockUnauthorized || ownerPlayer == null || info == null) return null;
var entity = info.HitEntity;
if (entity == null || entity.IsDestroyed) return null;
if (permission.UserHasPermission(ownerPlayer.UserIDString, PermBypass)) return null;
var privilege = entity.GetBuildingPrivilege();
if (privilege == null) return null;
if (privilege.IsAuthed(ownerPlayer)) return null;
float now = Time.realtimeSinceStartup;
float last;
if (!lastNotice.TryGetValue(ownerPlayer.userID, out last) || now - last >= config.NoticeCooldown)
{
lastNotice[ownerPlayer.userID] = now;
ownerPlayer.ChatMessage(Msg("NotAuthorized", ownerPlayer.UserIDString));
}
return false;
}
private void Unload()
{
lastNotice.Clear();
}
}
}The plugin blocks hammer actions on structures a player is not authorized for, unless the player holds the bypass permission. OnHammerHit reads the hit entity, walks up to the building privilege with GetBuildingPrivilege(), and calls IsAuthed. Another player's base therefore rejects the swing while the owner and their team pass. When a swing is denied the plugin sends a rate-limited chat message so spamming the hammer does not flood chat, and returns false to skip the vanilla repair. Config holds a toggle and the chat cooldown; Unload clears the cooldown dictionary.
Common use cases
Building permission gate
Require cupboard authorization or a permission before allowing hammer repairs and demolishes, separating builder roles from regular players.
Repair cooldown per player
Track the last swing time per player and reject rapid swings to stop repair spam on large bases or to meter repair cost.
Log structure vandalism
Record who swung the hammer at which entity and where, giving admins an audit trail for griefing reports since vanilla repair leaves no logs.
Pitfalls
Returning true still blocks
Any non-null return value stops the vanilla path, so returning
trueto "allow" a hit will silently cancel the repair. Always return null to let the game continue.It fires on every hammer action
Rotate and demolish use the same method, so gating repairs also gates those unless you inspect the target or the player's input state.
Building privilege can be null
Entities outside a cupboard radius return null from
GetBuildingPrivilege(). Treat that as unowned rather than null-dereferencing, or your hook throws and breaks the swing.
Plugin recipes that use OnHammerHit
Build a plugin with OnHammerHit
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 OnHammerHit
Generate