using System; using System.Linq; using System.Collections.Generic; using UnityEngine; using ProtoBuf; using Newtonsoft.Json; using Newtonsoft.Json.Linq; using Facepunch; using Oxide.Core; using Oxide.Core.Plugins; using Rust; #region Changelogs and ToDo /********************************************************************** * * 0.0.1 : - Initial write start/injection test * 0.0.2 : - skins junk and diving items (signal test) * 0.0.3 : - Car parts added * - Added 1 item cap on items after gathering ignoring gathermultiplyer plugins * - Rearranged chat info colors * 0.0.4 : - Added cap for roadsigns/license plates through config * 1.0.0 : - Release * 1.0.1 : - patched max signals * - Fixed injection NRE if lootprofile list is empty * - Added min/max amount of items when using gathermultiplier plugins/variables * - Added Custom category names in cfg * - Added Custom Category colors in cfg * 1.0.2 : - Coding cleanup * - Optimised message hooks * - Supply signal handout rewritten * - Added msg "DroppedSignal" when player inventory is full * - Added prefix to config * **********************************************************************/ #endregion namespace Oxide.Plugins { [Info("SharkLoot", "Krungh Crow", "1.0.2")] [Description("Spawn some loot inside a sharks belly")] class SharkLoot : RustPlugin { #region Variables const string Chat_Perm = "sharkloot.chat"; ulong chaticon; string prefix; bool Debug = false; bool GiveSignal = true; bool ShowMsg = true; int _MaxSharkSignals; int _MinJunkItems; int _MaxJunkItems; int _MinClothingItems; int _MaxClothingItems; int _MinCarParts; int _MaxCarParts; int _MaxPlates; string RandomItem; string Cat1Color; string Cat2Color; string Cat3Color; #endregion #region Configuration void Init() { if (!LoadConfigVariables()) { Puts("Config file issue detected. Please delete file, or check syntax and fix."); return; } permission.RegisterPermission(Chat_Perm, this); Debug = configData.PlugCFG.Debug; GiveSignal = configData.PlugCFG.SignalGive; ShowMsg = configData.PlugCFG.Msg; prefix = configData.PlugCFG.Prefix; chaticon = 76561199202433767; _MaxSharkSignals = configData.PlugCFG.MaxSignals; _MinJunkItems = configData.MinJunkItems; _MaxJunkItems = configData.MaxJunkItems; _MinClothingItems = configData.MinClothingItems; _MaxClothingItems = configData.MaxClothingItems; _MinCarParts = configData.MinCarParts; _MaxCarParts = configData.MaxCarParts; _MaxPlates = configData.PlugCFG.MaxPlates; Cat1Color = configData.Cat1Color; Cat2Color = configData.Cat2Color; Cat3Color = configData.Cat3Color; if (Debug) Puts($"[Debug] Debug is activated if unintentional disable this in the config !"); } private ConfigData configData; class ConfigData { [JsonProperty(PropertyName = "Plugin Settings")] public SettingsPlugin PlugCFG = new SettingsPlugin(); [JsonProperty(PropertyName = "Junk Items Custom category name")] public string Cat1Name = "Junk"; [JsonProperty(PropertyName = "Junk Category color")] public string Cat1Color = "green"; [JsonProperty(PropertyName = "min Junk Items")] public int MinJunkItems = 1; [JsonProperty(PropertyName = "max Junk Items")] public int MaxJunkItems = 3; [JsonProperty(PropertyName = "Junk Items")] public List JunkItems = new List(); [JsonProperty(PropertyName = "Clothing Items Custom category name")] public string Cat2Name = "Clothing"; [JsonProperty(PropertyName = "Clothing Category color")] public string Cat2Color = "#4A95CC"; [JsonProperty(PropertyName = "min Clothing Items")] public int MinClothingItems = 1; [JsonProperty(PropertyName = "max Clothing Items")] public int MaxClothingItems = 3; [JsonProperty(PropertyName = "Clothing Items")] public List ClothingItems = new List(); [JsonProperty(PropertyName = "Car Parts Custom category name")] public string Cat3Name = "Car Parts"; [JsonProperty(PropertyName = "Car Parts Category color")] public string Cat3Color = "red"; [JsonProperty(PropertyName = "min Car Items")] public int MinCarParts = 1; [JsonProperty(PropertyName = "max Car Parts")] public int MaxCarParts = 3; [JsonProperty(PropertyName = "Car Parts")] public List CarItems = new List(); } class SettingsPlugin { [JsonProperty(PropertyName = "Debug (true/false)")] public bool Debug = false; [JsonProperty(PropertyName = "Show Chat messages")] public bool Msg = true; [JsonProperty(PropertyName = "Prefix")] public string Prefix = "[Shark Loot] : "; [JsonProperty(PropertyName = "Add a supply signal to loot")] public bool SignalGive = true; [JsonProperty(PropertyName = "Supply signal name")] public string SignalName = "Shark kill reward signal"; [JsonProperty(PropertyName = "max supply signals")] public int MaxSignals = 1; [JsonProperty(PropertyName = "max Plates (roadsigns & License plates")] public int MaxPlates = 3; } private bool LoadConfigVariables() { try { configData = Config.ReadObject(); } catch { return false; } SaveConf(); return true; } protected override void LoadDefaultConfig() { Puts("Fresh install detected Creating a new config file."); configData = new ConfigData(); #region Default Generated Loot configData.JunkItems = new List { {"speargun.spear"}, {"speargun"}, {"smallwaterbottle"}, {"sign.wooden.small"}, {"tarp"}, {"beachtowel"}, {"boogieboard"} }; configData.ClothingItems = new List { {"diving.fins"}, {"diving.mask"}, {"diving.tank"}, {"diving.wetsuit"} }; configData.CarItems = new List { {"carburetor1"}, {"crankshaft1"}, {"piston1"}, {"sparkplug1"}, {"valve1"}, {"carburetor2"}, {"crankshaft2"}, {"piston2"}, {"sparkplug2"}, {"valve2"}, {"carburetor3"}, {"crankshaft3"}, {"piston3"}, {"sparkplug3"}, {"valve3"}, }; #endregion SaveConf(); } void SaveConf() => Config.WriteObject(configData, true); #endregion #region LanguageAPI protected override void LoadDefaultMessages() { lang.RegisterMessages(new Dictionary { ["FoundSignal"] = "You found {0} Shark Reward Signal the shark didn't digest yet", ["DroppedSignal"] = "You found {0} Shark Reward Signal but it dropped as your inventory was full", ["Info"] = "\nWhen chopping up the shark corpse you can get various items that the shark had for dinner\nAvailable Commands :\n/shark info : Shows info on version/author and commands\n/shark loot : Lists what you can find in a sharks belly", ["InvalidInput"] = "Please enter a valid command!", ["ItemsFound"] = "Items found inside sharks", ["Version"] = "Version : V", ["NoPermission"] = "You do not have permission to use this command!", }, this); } #endregion #region Commands [ChatCommand("shark")] private void cmdPrimary(BasePlayer player, string command, string[] args) { if (!permission.UserHasPermission(player.UserIDString, Chat_Perm)) { Player.Message(player, string.Format(msg("NoPermission", player.UserIDString)), chaticon); if (Debug) Puts($"[Debug] {player} had no permission for using Commands"); return; } if (args.Length == 0) { Player.Message(player, string.Format(msg("InvalidInput", player.UserIDString)), chaticon); } else { if (args[0].ToLower() == "info") { Player.Message(player, string.Format(msg("Version", player.UserIDString)) + this.Version.ToString() + " By : " + this.Author.ToString() + info("Info") , chaticon); return; } if (args[0].ToLower() == "loot") { foreach (var item in configData.JunkItems) { junklist += $"> {item}\n"; } if (configData.JunkItems.Count != 0) { JunkInfo = $"[{configData.Cat1Name}]"; } foreach (var item in configData.ClothingItems) { clotheslist += $"> {item}\n"; } if (configData.ClothingItems.Count != 0) { ClothingInfo = $"[{configData.Cat2Name}]"; } foreach (var item in configData.CarItems) { carlist += $"> {item}\n"; } if (configData.CarItems.Count != 0) { CarPartsInfo = $"[{configData.Cat3Name}]"; } if (GiveSignal) { SignalList = "> supply.signal"; BonusInfo = "[Bonus]"; } Player.Message(player, string.Format(msg("ItemsFound", player.UserIDString)) + " :\n[+11]" + JunkInfo + ClothingInfo + CarPartsInfo + BonusInfo + "\n" + $"> roadsigns\n" + $"> licenceplates\n" + (junklist.ToString()) + (clotheslist.ToString()) + (carlist.ToString()) + SignalList + "[/+]" , chaticon); } else { Player.Message(player, string.Format(msg("InvalidInput", player.UserIDString)), chaticon); } } } #endregion #region Hooks #region item injection void OnEntitySpawned(BaseCorpse corpse) { if (corpse == null || corpse.IsDestroyed) return; if (corpse.ToString().Contains("shark.corpse")) { var dispenser = corpse.GetComponent(); Item numberplate = ItemManager.CreateByName("roadsigns", 1, 0); ItemAmount NumberPlate = new ItemAmount() { itemDef = numberplate.info, amount = 3, startAmount = 1 }; Item Signal = ItemManager.CreateByName("supply.signal", 1, 0); ItemAmount _Signal = new ItemAmount() { itemDef = Signal.info, amount = _MaxSharkSignals, startAmount = 1 }; if (configData.JunkItems.Count != 0) { string RandomJunkItem = configData.JunkItems[new System.Random().Next(configData.JunkItems.Count())];//random item from JunkList Item JunkItem = ItemManager.CreateByName($"{RandomJunkItem}", _MinJunkItems, 0); ItemAmount _JunkItem = new ItemAmount() { itemDef = JunkItem.info, amount = _MinJunkItems, startAmount = 1 }; if (_JunkItem != null) { dispenser.containedItems.Add(_JunkItem); if (Debug)Puts($"{JunkItem} x {JunkItem.amount}"); } } if (configData.ClothingItems.Count != 0) { string RandomDiveItem = configData.ClothingItems[new System.Random().Next(configData.ClothingItems.Count())];//random item from ClothingList Item DiveItem = ItemManager.CreateByName($"{RandomDiveItem}", _MinClothingItems, 0); ItemAmount _DiveItem = new ItemAmount() { itemDef = DiveItem.info, amount = _MinClothingItems, startAmount = 1 }; if (_DiveItem != null) { dispenser.containedItems.Add(_DiveItem); } } if (configData.CarItems.Count != 0) { string RandomCarPart = configData.CarItems[new System.Random().Next(configData.CarItems.Count())];//random item from CarList Item CarItem = ItemManager.CreateByName($"{RandomCarPart}", _MinCarParts, 0); ItemAmount _CarItem = new ItemAmount() { itemDef = CarItem.info, amount = _MinCarParts, startAmount = 1 }; if (CarItem != null) { dispenser.containedItems.Add(_CarItem); } } if (dispenser != null) { if (NumberPlate != null) { dispenser.containedItems.Add(NumberPlate); } if (_Signal != null && GiveSignal) { dispenser.containedItems.Add(_Signal); } dispenser.Initialize(); return; } return; } return; } #endregion #region Helpers private void MakeSignal(BasePlayer player) { Item _Signal = ItemManager.CreateByName("supply.signal", _MaxSharkSignals, 2585626070UL); if (_Signal != null && GiveSignal) { _Signal.name = configData.PlugCFG.SignalName; _Signal.MarkDirty(); if (!player.inventory.containerMain.IsFull()) { _Signal.MoveToContainer(player.inventory.containerMain); if (ShowMsg && GiveSignal) Player.Message(player, string.Format(msg("FoundSignal", player.UserIDString), _MaxSharkSignals), chaticon); } else { _Signal.DropAndTossUpwards(player.eyes.position); if (ShowMsg && GiveSignal) Player.Message(player, string.Format(msg("DroppedSignal", player.UserIDString), _MaxSharkSignals), chaticon); if (Debug) Puts("players inventory is full Signal was dropped"); } } } #endregion #region skin handling and item caps void OnDispenserGather(ResourceDispenser dispenser, BaseEntity entity, Item item) { BasePlayer player = entity.ToPlayer(); if (player == null || dispenser == null || entity == null || item == null) return; if (dispenser.ToString().Contains("shark.corpse")) { if (item.info.itemid == 1199391518)//roadsigns { switch (UnityEngine.Random.Range(0, 2)) { case 0: { item.name = "Licence Plate"; item.skin = 2584636285UL;//licence plate item.MarkDirty(); if (Debug) Puts($"Changed X{item.amount} [roadsigns] into [Licence plates]"); break; } default: if (Debug) Puts($"X{item.amount} [roadsigns] did not change into [Licence plates]"); break; } if (item.amount >= _MaxPlates) { item.UseItem(item.amount - _MaxPlates); item.MarkDirty(); if (Debug) Puts($"Max set Roadsigns & License Plates reduced to ({_MaxPlates})"); return; } } if (item.info.itemid == 1397052267)//supplysignal { item.name = configData.PlugCFG.SignalName; item.skin = 2585626070UL;//shark signal if(item.amount > _MaxSharkSignals && configData.PlugCFG.SignalGive == true) { item.UseItem(item.amount); item.MarkDirty(); MakeSignal(player); if (Debug) Puts($"Max set signals reduced to ({_MaxSharkSignals})"); return; } item.MarkDirty(); if (Debug) Puts($"found X{item.amount} [Supplysignal]"); if (ShowMsg && GiveSignal) Player.Message(player, string.Format(msg("FoundSignal", player.UserIDString), item.amount), chaticon); return; } if (configData.CarItems.Contains(item.info.shortname)) { if (item.amount >= _MaxCarParts) { item.UseItem(item.amount - _MaxCarParts); item.MarkDirty(); if (Debug) Puts($"gathermultipliers for [{item.info.shortname}] was capped"); } } if (configData.JunkItems.Contains(item.info.shortname)) { if (item.amount >= _MaxJunkItems) { item.UseItem(item.amount - _MaxJunkItems); item.MarkDirty(); if (Debug) Puts($"gathermultipliers for [{item.info.shortname}] was capped"); } } if (configData.ClothingItems.Contains(item.info.shortname)) { if (item.amount >= _MaxClothingItems) { item.UseItem(item.amount - _MaxClothingItems); item.MarkDirty(); if (Debug) Puts($"gathermultipliers for [{item.info.shortname}] was capped"); } } } return; } #endregion #endregion #region Message helpers private string msg(string key, string id = null) => prefix + lang.GetMessage(key, this, id); private string info(string key, string id = null) => lang.GetMessage(key, this, id); string clotheslist = ""; string junklist = ""; string carlist = ""; string SignalList = ""; string BonusInfo = ""; string JunkInfo = ""; string CarPartsInfo = ""; string ClothingInfo = ""; #endregion } }