C#:
using Network;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using UnityEngine;
namespace Oxide.Plugins {
[Info("ExplosiveChest", "0xF", "1")]
public class ExplosiveChest : RustPlugin {
const string givePerm = "explosivechest.give";
#region Commands
[ConsoleCommand("give.echest")]
void GiveExplosiveChest(ConsoleSystem.Arg arg) {
BasePlayer player = arg.Player();
if (player == null) return;
if (player.IsAdmin || player.IPlayer.HasPermission("explosivechest.give")) player.inventory.GiveItem(ItemManager.Create(ItemManager.FindItemDefinition("box.wooden"), 100, config.SkinId));
}
[ConsoleCommand("give.echest.large")]
void GiveExplosiveChestLarge(ConsoleSystem.Arg arg) {
BasePlayer player = arg.Player();
if (player == null) return;
if (player.IsAdmin || player.IPlayer.HasPermission("explosivechest.give")) player.inventory.GiveItem(ItemManager.Create(ItemManager.FindItemDefinition("box.wooden.large"), 100, config.SkinId));
}
#endregion
#region Hooks
private void Init() {
LoadConfig();
permission.RegisterPermission(givePerm, this);
if (config.Explosion.Mode) Unsubscribe(nameof(OnLootEntityEnd));
else Unsubscribe(nameof(OnLootEntity));
}
void OnLootEntity(BasePlayer player, BaseEntity entity) => Boom(player, entity);
void OnLootEntityEnd(BasePlayer player, BaseEntity entity) => Boom(player, entity);
void OnEntityTakeDamage(BaseCombatEntity entity, HitInfo info) {
if (entity.skinID != config.SkinId) return;
if (config.Attacking.OnlyPlayerDamage && !(info.Initiator is BasePlayer)) return;
info.damageTypes.ScaleAll(0);
switch (config.Attacking.Mode) {
case ConfigData.AttackingSettings.Modes.Explosion : Boom(info.InitiatorPlayer, info.HitEntity);
break;
case ConfigData.AttackingSettings.Modes.Rocket : entity.transform.LookAt(info.Initiator.transform);
entity.SendNetworkUpdate();
string prefabName;
switch (config.Attacking.Rocket.RocketType) {
case ConfigData.AttackingSettings.RocketTypes.Basic : prefabName = "assets/prefabs/ammo/rocket/rocket_basic.prefab";
break;
case ConfigData.AttackingSettings.RocketTypes.HV : prefabName = "assets/prefabs/ammo/rocket/rocket_hv.prefab";
break;
case ConfigData.AttackingSettings.RocketTypes.Fire : prefabName = "assets/prefabs/ammo/rocket/rocket_fire.prefab";
break;
case ConfigData.AttackingSettings.RocketTypes.Smoke : prefabName = "assets/prefabs/ammo/rocket/rocket_smoke.prefab";
break;
case ConfigData.AttackingSettings.RocketTypes.MLRS : prefabName = "assets/content/vehicles/mlrs/rocket_mlrs.prefab";
break;
default : PrintError("An unknown type of rocket is chosen!");
return;
}
var rocket = GameManager.server.CreateEntity(prefabName, entity.GetNetworkPosition() + new Vector3(0, 1), entity.GetNetworkRotation());
if (rocket == null) return;
var proj = rocket.GetComponent<ServerProjectile>();
if (proj == null) return;
proj.InitializeVelocity(entity.transform.forward * config.Attacking.Rocket.RocketSpeed);
timer.Once(config.Attacking.Timer, () => {
if (config.Attacking.ClearChest) entity.GetComponentInChildren<StorageContainer>().inventory?.Kill();
entity.Kill();
rocket.Spawn();
}
);
break;
default : break;
}
}
#endregion
#region Methods
private void Boom(BasePlayer player, BaseEntity entity) {
if (entity.skinID == config.SkinId) {
global : : Effect.server.Run("assets/bundled/prefabs/fx/weapons/landmine/landmine_trigger.prefab", entity.transform.position, entity.transform.up, null, true);
timer.Once(config.Explosion.Timer, () => {
if (entity == null) return;
global : : Effect.server.Run("assets/bundled/prefabs/fx/weapons/landmine/landmine_explosion.prefab", entity.transform.position, entity.transform.up, null, true);
global : : DamageUtil.RadiusDamage(entity, GameManager.server.FindPrefab("assets/prefabs/deployable/landmine/landmine.prefab").ToBaseEntity(), entity.WorldSpaceBounds().position, config.Explosion.MinRadius, config.Explosion.Radius, new List<Rust.DamageTypeEntry>() {
new Rust.DamageTypeEntry() {
type = Rust.DamageType.Explosion, amount = config.Explosion.Damage
}
}
, 2263296, true);
if (config.Explosion.ClearChest) entity.GetComponentInChildren<StorageContainer>().inventory?.Kill();
entity.Kill();
}
);
}
}
#endregion
#region Config
private static ConfigData config;
private class ConfigData {
public class AttackingSettings {
public enum Modes {
Disabled, Explosion, Rocket
}
public enum RocketTypes {
Basic, HV, Fire, Smoke, MLRS,
}
public class RocketSettings {
[JsonProperty(PropertyName = "Rocket Type (0 - Basic | 1 - HV | 2 - Fire | 3 - Smoke | 4 - MLRS)")]
public RocketTypes RocketType {
get;
set;
}
= RocketTypes.HV;
[JsonProperty(PropertyName = "Rocket Speed")]
public float RocketSpeed {
get;
set;
}
= 20f;
}
[JsonProperty(PropertyName = "React only to damage from the player?")]
public bool OnlyPlayerDamage {
get;
set;
}
= true;
[JsonProperty(PropertyName = "Time to launch after the trigger (in seconds)")]
public float Timer {
get;
set;
}
= 0.5f;
[JsonProperty(PropertyName = "Clear the chest inventory?")]
public bool ClearChest {
get;
set;
}
= true;
[JsonProperty(PropertyName = "Mode (0 - disabled | 1 - explosion | 2 - rocket launch at the player)")]
public Modes Mode {
get;
set;
}
= Modes.Rocket;
[JsonProperty(PropertyName = "Rocket Settings")]
public RocketSettings Rocket {
get;
set;
}
= new RocketSettings();
}
public class ExplosionSettings {
[JsonProperty(PropertyName = "When to blow up? (true - after opening, false - after closing)")]
public bool Mode {
get;
set;
}
= true;
[JsonProperty(PropertyName = "Time to explode after the trigger (in seconds)")]
public float Timer {
get;
set;
}
= 0.3f;
[JsonProperty(PropertyName = "Clear the chest inventory?")]
public bool ClearChest {
get;
set;
}
= false;
[JsonProperty(PropertyName = "Damage")]
public float Damage {
get;
set;
}
= 50f;
[JsonProperty(PropertyName = "Min Radius")]
public float MinRadius {
get;
set;
}
= 1f;
[JsonProperty(PropertyName = "Radius")]
public float Radius {
get;
set;
}
= 5f;
}
[JsonProperty(PropertyName = "SkinId for the Explosive Chest")]
public ulong SkinId {
get;
set;
}
= 377663254519;
[JsonProperty(PropertyName = "Explosion Settings")]
public ExplosionSettings Explosion {
get;
set;
}
= new ExplosionSettings();
[JsonProperty(PropertyName = "Settings when attacking the chest")]
public AttackingSettings Attacking {
get;
set;
}
= new AttackingSettings();
}
private ConfigData GetDefaultConfig() {
return new ConfigData();
}
protected override void LoadConfig() {
base.LoadConfig();
try {
config = Config.ReadObject<ConfigData>();
if (config == null) LoadDefaultConfig();
else SaveConfig();
}
catch (Exception ex) {
if (ex is JsonSerializationException || ex is NullReferenceException || ex is JsonReaderException) {
Puts($"Exception: {ex}");
LoadDefaultConfig();
return;
}
throw;
}
}
protected override void LoadDefaultConfig() {
Puts("Configuration file missing or corrupt, creating default config file.");
config = GetDefaultConfig();
SaveConfig();
}
protected override void SaveConfig() {
Config.WriteObject(config);
}
#endregion
}
}