How to make a Rust explosive damage multiplier plugin (per-weapon raiding)
Scales explosion damage against building blocks, deployables and other structures using per-weapon multipliers keyed by the attacker's weapon prefab short name. It uses OnEntityTakeDamage to intercept explosion hits and rewrites the damage amount.
Vanilla Rust gives every explosive a fixed amount of damage against structures, so balancing a raid meta usually means recompiling the whole game or running several overlapping plugins. This plugin puts one multiplier table in a config file and applies it the moment an explosion lands, so C4, rockets, satchels and explosive ammo can each be tuned independently without touching vanilla values.
It listens to OnEntityTakeDamage, ignores anything that is not explosion damage, and looks up the attacker's weapon prefab short name (for example explosive.satchel or rocket_basic) in a config dictionary. When a match is found it multiplies the hit's total damage and caps the result if a maximum is configured. Damage against players and non-structure entities is left alone, and a global toggle lets you disable the whole system instantly during an event.
The plugin code
using System.Linq;
using System;
using System.Collections.Generic;
using Newtonsoft.Json;
using Oxide.Core;
using UnityEngine;
namespace Oxide.Plugins
{
[Info("Explosive Damage Multiplier", "RustPluginGenerator", "1.0.0")]
[Description("Scales explosion damage against structures and deployables with per-weapon multipliers.")]
public class ExplosiveDamageMultiplier : RustPlugin
{
private const string PermAdmin = "explosivedamagemultiplier.admin";
private PluginConfig config;
private class PluginConfig
{
[JsonProperty("Enabled")]
public bool Enabled = true;
[JsonProperty("Max Multiplier")]
public float MaxMultiplier = 4f;
[JsonProperty("Weapon Multipliers")]
public Dictionary<string, float> WeaponMultipliers = new Dictionary<string, float>
{
["explosive.satchel"] = 1.25f,
["explosive.timed"] = 1.0f,
["rocket_basic"] = 1.5f,
["rocket_hv"] = 1.25f,
["ammo.rocket.basic"] = 1.25f
};
}
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>
{
["Reloaded"] = "Explosive damage multipliers reloaded: {0} weapon entries, enabled: {1}",
["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(PermAdmin, this);
}
private void Unload()
{
config = null;
}
[ChatCommand("edm.reload")]
private void CmdReload(BasePlayer player, string command, string[] args)
{
if (player != null && !permission.UserHasPermission(player.UserIDString, PermAdmin))
{
SendReply(player, Msg("NoPermission", player.UserIDString));
return;
}
LoadConfig();
string msg = Msg("Reloaded", player?.UserIDString, config.WeaponMultipliers.Count, config.Enabled);
if (player != null) SendReply(player, msg);
else PrintWarning(msg);
}
private object OnEntityTakeDamage(BaseCombatEntity entity, HitInfo hitInfo)
{
if (config == null || !config.Enabled || entity == null || hitInfo == null) return null;
if (hitInfo.damageTypes == null) return null;
if (entity is BasePlayer) return null;
if (hitInfo.damageTypes.GetMajorityDamageType() != Rust.DamageType.Explosion) return null;
if (!IsRaidable(entity)) return null;
string prefab = GetWeaponShortName(hitInfo);
if (string.IsNullOrEmpty(prefab)) return null;
float multiplier;
if (!config.WeaponMultipliers.TryGetValue(prefab.ToLower(), out multiplier)) return null;
if (multiplier <= 0f) return null;
float original = hitInfo.damageTypes.Total();
if (original <= 0f) return null;
float capped = Mathf.Min(multiplier, config.MaxMultiplier);
hitInfo.damageTypes.ScaleAll(capped);
return null;
}
private static bool IsRaidable(BaseCombatEntity entity)
{
if (entity is BuildingBlock) return true;
if (entity is Door) return true;
if (entity is StorageContainer) return true;
if (entity is BaseOven) return true;
if (entity is CodeLock) return true;
if (entity is BuildingPrivlidge) return true;
if (entity is AutoTurret) return true;
if (entity is SamSite) return true;
return false;
}
private static string GetWeaponShortName(HitInfo hitInfo)
{
try
{
if (hitInfo.WeaponPrefab != null && !string.IsNullOrEmpty(hitInfo.WeaponPrefab.ShortPrefabName))
return hitInfo.WeaponPrefab.ShortPrefabName;
if (hitInfo.Weapon != null)
{
BaseEntity weaponEntity = hitInfo.Weapon as BaseEntity;
if (weaponEntity != null && !string.IsNullOrEmpty(weaponEntity.ShortPrefabName))
return weaponEntity.ShortPrefabName;
}
}
catch
{
// ignore resolve failures
}
return null;
}
}
}Hooks used: OnEntityTakeDamage
Config file
Created automatically on first load at oxide/config/ExplosiveDamageMultiplier.json.
{
"Enabled": true,
"Max Multiplier": 4,
"Weapon Multipliers": {
"explosive.satchel": 1.25,
"explosive.timed": 1,
"rocket_basic": 1.5,
"rocket_hv": 1.25,
"ammo.rocket.basic": 1.25
}
}Commands and permissions
| Command | What it does | Permission |
|---|---|---|
/edm.reload | Reloads the config from disk and reports the number of active weapon multipliers. | explosivedamagemultiplier.admin |
| Permission | Grants |
|---|---|
explosivedamagemultiplier.admin | Grants access to /edm.reload so staff can re-apply config changes without restarting the plugin. |
How the code works
Read the multiplier config
The nested
PluginConfigclass holds a booleanEnabledswitch, aMaxMultipliercap, and a dictionary namedWeaponMultiplierskeyed by weapon prefab short name. Defaults cover the common raid tools:explosive.satchel,explosive.timed,rocket_basic,rocket_hvandammo.rocket.basic. Because values are stored inoxide/config/ExplosiveDamageMultiplier.json, admins can add new keys as Facepunch ships new explosives without recompiling anything.Filter for explosion damage in OnEntityTakeDamage
The hook receives a
BaseCombatEntityand aHitInfo. The first checks are cheap: bail if the config is disabled, ifhitInfoorhitInfo.damageTypesis null, or if the majority damage type inhitInfo.damageTypes.GetMajorityDamageType()is notRust.DamageType.Explosion. This keeps bullet, melee and decay hits untouched even though the hook fires for every damage event on the server.Restrict to structures and deployables
IsRaidablereturns true forBuildingBlock,Door,StorageContainer,BaseOven,CodeLock,BuildingPrivlidge,AutoTurretandSamSite. Players, animals and NPCs return false, so a rocket that clips a raider through a wall still deals vanilla damage. If you want player damage scaled too, extend the method with aBasePlayerbranch and adjust the multiplier lookup.Resolve the weapon prefab short name
Thrown explosives do not always carry a
HitInfo.Weaponattack entity, so the plugin prefershitInfo.WeaponPrefab.ShortPrefabName, falling back to the short name of theHitInfo.Weaponcast toBaseEntity. The result is lowercased and compared against the dictionary, which the defaults seed in lowercase too. Matching on the short name means the multiplier follows the actual prefab that exploded, not the inventory item the raider used.Scale and cap the damage
When a key matches,
hitInfo.damageTypes.ScaleAll(multiplier)multiplies every damage entry on the hit. The applied factor is clamped toMaxMultiplierbefore scaling, so a config typo like10cannot one-shot a wall. Returningnullfrom the hook lets Rust apply the modified damage normally. Nothing is written to chat, so the hook can fire thousands of times per raid without spamming the console.Reload without restarting
The
/edm.reloadchat command is registered with[ChatCommand("edm.reload")]and gated by theexplosivedamagemultiplier.adminpermission. It calls the plugin's ownLoadConfigand reports the number of dictionary entries back through the language file. Server owners can hand-editoxide/config/ExplosiveDamageMultiplier.json, save, and run the command to apply changes during a wipe without touching player connections.
Install it on your server
Save ExplosiveDamageMultiplier.cs
Keep the file name exactly as the class name. Oxide matches them.Upload it to the plugins folder
Oxide:oxide/plugins/. Carbon:carbon/plugins/. The server compiles and loads it within a few seconds, no restart needed.Edit the config if you want
On first load the default config is written tooxide/config/ExplosiveDamageMultiplier.json(Carbon:carbon/configs/ExplosiveDamageMultiplier.json). After editing, reload it:oxide.reload ExplosiveDamageMultiplier c.reload ExplosiveDamageMultiplier # CarbonGrant the permission
Give it to every player, or swapdefaultfor a group such asvip:oxide.grant group default explosivedamagemultiplier.admin c.grant group default explosivedamagemultiplier.admin # Carbon
Variations
Each one opens the generator with a ready prompt you can tweak.
Scale damage by structure grade
Apply a different multiplier per building grade so wood and stone are softer than metal and HQM.
Generate this versionDiminishing returns per raid
Track a running total of explosive damage per building ID and reduce later hits to slow down raid zerging.
Generate this versionToggle multipliers by day or time
Use a different multiplier table during scheduled raid hours.
Generate this version
FAQ
Will this affect damage to players?
No. IsRaidable only accepts placed structures and deployables, so rockets and C4 that splash a player still deal the vanilla amount. If you want raiders to take scaled damage, add an explicit BasePlayer branch in IsRaidable โ most servers leave it out so raiding stays fair.
Why is my satchel multiplier not applied?
Thrown explosives expose their prefab through hitInfo.WeaponPrefab, which is often explosive.satchel. Confirm the key in oxide/config/ExplosiveDamageMultiplier.json matches the short name exactly and is lowercase. Use items.find in the server console to inspect a prefab's short name if you are unsure.
Does the multiplier stack with decay or fire damage?
No. The hook returns early unless the majority damage type on the hit is Rust.DamageType.Explosion. Decay ticks and fire damage run through separate damage types and never touch the scaling code, so you cannot accidentally amplify passive losses.
How do I install it on Oxide or Carbon?
Drop the compiled .cs file into oxide/plugins on Oxide or carbon/plugins on Carbon. Both frameworks load the same plugin file. Run oxide.reload ExplosiveDamageMultiplier (or c.reload) once to generate oxide/config/ExplosiveDamageMultiplier.json, then edit the multipliers and reload the plugin with /edm.reload.
Does the scale survive plugin reloads mid-raid?
Yes. The multiplier is applied to the live HitInfo.damageTypes before Rust resolves the hit, so it is not a persistent effect. Reloading the plugin between explosions simply changes which multiplier the next hit reads, and no existing building state is re-evaluated.
Customize it for your server
Change the reward, add a cooldown, restrict it to VIPs. Start from this prompt and edit anything.
Edit the prompt on the next screen. 2 free plugins a month, no card.
More raiding plugins
- New player protectionBlocks damage to buildings owned by players under a configurable playtime threshold, tracks playtime per player in oxide/data, and removesโฆOnServerInitializedOnNewSaveOnEntityTakeDamage
- Offline raid protectionScales damage to building blocks and deployables when every player authorized on the covering tool cupboard has been offline for a configurable delay.OnServerInitializedOnCupboardAuthorizeOnCupboardDeauthorize
- Raid alertsChat-alerts online owners and tool cupboard authed players when explosives damage their building, with the attacker name and map grid, throttled toโฆOnServerInitializedOnEntityTakeDamage
Last updated Oct 26, 2026.
Customize explosive damage multiplier
Customize