C#:
using System;
using Oxide.Core;
using System.Collections.Generic;
using Newtonsoft.Json;
using Oxide.Core.Configuration;
using UnityEngine;
using System.Linq;
using Oxide.Core.Libraries.Covalence;
using Oxide.Game.Rust.Libraries;
namespace Oxide.Plugins
{
[Info("SimpleLootTable", "Fruster", "1.0.4")]
[Description("SimpleLootTable")]
class SimpleLootTable : CovalencePlugin
{
public class SimpleLootTableItem
{
public string itemName { get; set; }
public string displayName { get; set; }
public ulong skinID { get; set; }
public float dropChance { get; set; }
public int minAmount { get; set; }
public int maxAmount { get; set; }
}
public class SimpleLootTableList
{
public string name { get; set; }
public List<SimpleLootTableItem> table { get; set; }
}
public class SimpleLootTableUse
{
public string entityPrefabName { get; set; }
public string tableName { get; set; }
public int minItems { get; set; }
public int maxItems { get; set; }
public float multiplier { get; set; }
}
private DynamicConfigFile exampleTable = Interface.Oxide.DataFileSystem.GetDatafile("SimpleLootTable/exampleTable");
private List<SimpleLootTableItem> itemsList = new List<SimpleLootTableItem>();
private List<SimpleLootTableList> tablesList = new List<SimpleLootTableList>();
private List<string> tablesNamesList = new();
private List<LootContainer> containersList = new();
private ConfigData Configuration;
class ConfigData
{
[JsonProperty("Use tables for entities")]
public List<SimpleLootTableUse> tables = new List<SimpleLootTableUse>()
{
new SimpleLootTableUse{entityPrefabName = "loot_barrel_1", tableName = "", minItems = 2, maxItems = 5, multiplier = 1},
new SimpleLootTableUse{entityPrefabName = "loot_barrel_2", tableName = "", minItems = 2, maxItems = 5, multiplier = 1}
};
}
void SaveConfig(object config) => Config.WriteObject(config, true);
void LoadConfig()
{
base.Config.Settings.ObjectCreationHandling = ObjectCreationHandling.Replace;
Configuration = Config.ReadObject<ConfigData>();
SaveConfig(Configuration);
}
protected override void LoadDefaultConfig()
{
Configuration = new ConfigData();
SaveConfig();
}
private void Init()
{
Unsubscribe("OnEntitySpawned");
Unsubscribe("OnEntityKill");
LoadConfig();
CreateDefaultTable();
LoadAllTables();
tablesNamesList.AddRange(Configuration.tables.Where(table => !string.IsNullOrEmpty(table.tableName)).Select(table => table.entityPrefabName));
if (tablesNamesList.Any())
{
Subscribe("OnEntitySpawned");
Subscribe("OnEntityKill");
foreach (var container in BaseNetworkable.serverEntities.OfType<LootContainer>())
{
var matchingTable = Configuration.tables.FirstOrDefault(table => table.entityPrefabName == container.PrefabName && !string.IsNullOrEmpty(table.tableName));
if (matchingTable != null && !containersList.Contains(container))
containersList.Add(container);
}
}
}
private void OnEntitySpawned(LootContainer container)
{
if (!tablesNamesList.Contains(container.PrefabName)) return;
if (!containersList.Contains(container))
containersList.Add(container);
var matchingTable = Configuration.tables.FirstOrDefault(table => table.entityPrefabName == container.PrefabName && !string.IsNullOrEmpty(table.tableName));
if (matchingTable != null)
timer.Once(0.5f, () =>
{
if (container == null || container.IsDestroyed) return;
GetSetItems(container as BaseEntity, matchingTable.tableName, matchingTable.minItems, matchingTable.maxItems, matchingTable.multiplier);
});
}
private void OnEntityKill(LootContainer container)
{
if (containersList.Contains(container))
containersList.Remove(container);
}
private void CreateDefaultTable()
{
if (exampleTable["0"] == null)
{
itemsList.Add(new SimpleLootTableItem { itemName = "scrap", displayName = "", skinID = 0, dropChance = 100, minAmount = 50, maxAmount = 100 });
itemsList.Add(new SimpleLootTableItem { itemName = "blueberries", displayName = "", skinID = 0, dropChance = 90, minAmount = 3, maxAmount = 10 });
itemsList.Add(new SimpleLootTableItem { itemName = "ammo.rifle", displayName = "", skinID = 0, dropChance = 80, minAmount = 64, maxAmount = 128 });
itemsList.Add(new SimpleLootTableItem { itemName = "ammo.rifle.explosive", displayName = "", skinID = 0, dropChance = 50, minAmount = 64, maxAmount = 128 });
itemsList.Add(new SimpleLootTableItem { itemName = "ammo.pistol", displayName = "", skinID = 0, dropChance = 80, minAmount = 64, maxAmount = 128 });
itemsList.Add(new SimpleLootTableItem { itemName = "techparts", displayName = "", skinID = 0, dropChance = 40, minAmount = 1, maxAmount = 3 });
itemsList.Add(new SimpleLootTableItem { itemName = "riflebody", displayName = "", skinID = 0, dropChance = 40, minAmount = 1, maxAmount = 3 });
itemsList.Add(new SimpleLootTableItem { itemName = "semibody", displayName = "", skinID = 0, dropChance = 50, minAmount = 2, maxAmount = 4 });
itemsList.Add(new SimpleLootTableItem { itemName = "explosives", displayName = "", skinID = 0, dropChance = 50, minAmount = 10, maxAmount = 50 });
itemsList.Add(new SimpleLootTableItem { itemName = "explosive.satchel", displayName = "", skinID = 0, dropChance = 30, minAmount = 2, maxAmount = 5 });
itemsList.Add(new SimpleLootTableItem { itemName = "explosive.timed", displayName = "", skinID = 0, dropChance = 10, minAmount = 1, maxAmount = 2 });
itemsList.Add(new SimpleLootTableItem { itemName = "ammo.rocket.basic", displayName = "", skinID = 0, dropChance = 20, minAmount = 2, maxAmount = 4 });
itemsList.Add(new SimpleLootTableItem { itemName = "metal.facemask", displayName = "", skinID = 0, dropChance = 10, minAmount = 1, maxAmount = 1 });
itemsList.Add(new SimpleLootTableItem { itemName = "metal.plate.torso", displayName = "", skinID = 0, dropChance = 10, minAmount = 1, maxAmount = 1 });
itemsList.Add(new SimpleLootTableItem { itemName = "metalpipe", displayName = "", skinID = 0, dropChance = 80, minAmount = 2, maxAmount = 6 });
itemsList.Add(new SimpleLootTableItem { itemName = "metalspring", displayName = "", skinID = 0, dropChance = 80, minAmount = 2, maxAmount = 5 });
itemsList.Add(new SimpleLootTableItem { itemName = "rope", displayName = "", skinID = 0, dropChance = 80, minAmount = 2, maxAmount = 6 });
itemsList.Add(new SimpleLootTableItem { itemName = "smgbody", displayName = "", skinID = 0, dropChance = 40, minAmount = 2, maxAmount = 3 });
itemsList.Add(new SimpleLootTableItem { itemName = "sulfur", displayName = "", skinID = 0, dropChance = 60, minAmount = 1000, maxAmount = 3000 });
itemsList.Add(new SimpleLootTableItem { itemName = "rifle.ak", displayName = "Top gun", skinID = 809190373, dropChance = 5, minAmount = 1, maxAmount = 1 });
exampleTable.Clear();
for (int i = 0; i < itemsList.Count; i++)
{
exampleTable[i.ToString(), "itemName"] = itemsList[i].itemName;
exampleTable[i.ToString(), "displayName"] = itemsList[i].displayName;
exampleTable[i.ToString(), "skinID"] = itemsList[i].skinID;
exampleTable[i.ToString(), "dropChance"] = itemsList[i].dropChance;
exampleTable[i.ToString(), "minAmount"] = itemsList[i].minAmount;
exampleTable[i.ToString(), "maxAmount"] = itemsList[i].maxAmount;
}
exampleTable.Save();
}
}
private void LoadAllTables()
{
DynamicConfigFile newFile;
SimpleLootTableItem newItem;
SimpleLootTableList newTableList;
string[] filesList = Interface.Oxide.DataFileSystem.GetFiles("SimpleLootTable");
for (int i = 0; i < filesList.Length; i++)
{
newTableList = new SimpleLootTableList { name = filesList[i], table = new List<SimpleLootTableItem>() };
newFile = Interface.Oxide.DataFileSystem.GetDatafile(filesList[i].ToString().Replace(".json", ""));
foreach (var item in newFile)
{
newItem = new SimpleLootTableItem
{
itemName = newFile[item.Key.ToString(), "itemName"].ToString(),
displayName = newFile[item.Key.ToString(), "displayName"].ToString(),
skinID = Convert.ToUInt32(newFile[item.Key.ToString(), "skinID"]),
dropChance = Convert.ToSingle(newFile[item.Key.ToString(), "dropChance"]),
minAmount = (int)newFile[item.Key.ToString(), "minAmount"],
maxAmount = (int)newFile[item.Key.ToString(), "maxAmount"],
};
newTableList.table.Add(newItem);
}
tablesList.Add(newTableList);
}
}
private void GiveItem(StorageContainer container, string itemName, string displayName, int min, int max, ulong skinID, float multiplier)
{
int amount = Mathf.Max(1, (int)(UnityEngine.Random.Range(min, max) * multiplier));
Item item = ItemManager.CreateByName(itemName, amount, skinID);
if (item == null)
{
PrintWarning($"In the config file there is an error in the name of the item - {itemName}!");
return;
}
if (!string.IsNullOrEmpty(displayName))
item.name = displayName;
item.MoveToContainer(container.inventory);
}
private void GiveItemCorpse(ItemContainer container, string itemName, string displayName, int min, int max, ulong skinID, float multiplier)
{
int amount = Mathf.Max(1, (int)(UnityEngine.Random.Range(min, max) * multiplier));
Item item = ItemManager.CreateByName(itemName, amount, skinID);
if (item == null)
{
PrintWarning($"In the config file there is an error in the name of the item - {itemName}!");
return;
}
if (!string.IsNullOrEmpty(displayName))
item.name = displayName;
item.MoveToContainer(container);
}
private void GetSetItems(BaseEntity entity, string tableName, int minAmount, int maxAmount, float multiplier, bool clear = true)
{
if (!entity) return;
StorageContainer container = entity.GetComponent<StorageContainer>();
ItemContainer corpseContainer = null;
LootableCorpse lootableCorpse = entity.GetComponentInParent<LootableCorpse>();
if (lootableCorpse)
corpseContainer = lootableCorpse.containers[0];
if (!container && corpseContainer == null)
{
PrintWarning("Components 'StorageContainer' or 'ItemContainer' not found");
return;
}
int amount = UnityEngine.Random.Range(minAmount, maxAmount + 1);
int index;
float chance;
List<SimpleLootTableItem> selectedItems = new List<SimpleLootTableItem>();
List<SimpleLootTableItem> tempList = new List<SimpleLootTableItem>();
List<SimpleLootTableItem> doneList = new List<SimpleLootTableItem>();
SimpleLootTableList table = tablesList.Find(item => item.name.Contains(tableName + ".json"));
if (container)
{
if (container is HackableLockedCrate crate) crate.inventory.onItemAddedRemoved = null;
if (clear)
container.inventory.Clear();
if (container.inventory.capacity < maxAmount)
container.inventory.capacity = maxAmount;
}
if (corpseContainer != null)
{
if (clear)
corpseContainer.Clear();
if (corpseContainer.capacity < maxAmount)
corpseContainer.capacity = maxAmount;
}
if (table != null)
selectedItems = table.table;
else
{
PrintWarning("No table found with name '" + tableName + "'!");
return;
}
for (int i = 0; i < selectedItems.Count; i++)
tempList.Add(selectedItems[i]);
for (int i = 0; i < selectedItems.Count; i++)
if (selectedItems[i].dropChance >= 100)
{
if (amount < 1)
{
PrintWarning("The number of items with a 100% drop chance exceeds the maximum number of slots!");
break;
}
amount--;
if (corpseContainer != null)
GiveItemCorpse(corpseContainer, selectedItems[i].itemName, selectedItems[i].displayName, selectedItems[i].minAmount, selectedItems[i].maxAmount + 1, selectedItems[i].skinID, multiplier);
else
GiveItem(container, selectedItems[i].itemName, selectedItems[i].displayName, selectedItems[i].minAmount, selectedItems[i].maxAmount + 1, selectedItems[i].skinID, multiplier);
doneList.Add(selectedItems[i]);
tempList.Remove(selectedItems[i]);
}
while (amount > 0)
{
if (tempList.Count == 0)
{
amount = 0;
break;
}
index = UnityEngine.Random.Range(0, tempList.Count);
chance = UnityEngine.Random.Range(0f, 100f);
if (chance < tempList[index].dropChance)
{
amount--;
if (corpseContainer != null)
GiveItemCorpse(corpseContainer, tempList[index].itemName, tempList[index].displayName, tempList[index].minAmount, tempList[index].maxAmount + 1, tempList[index].skinID, multiplier);
else
GiveItem(container, tempList[index].itemName, tempList[index].displayName, tempList[index].minAmount, tempList[index].maxAmount + 1, tempList[index].skinID, multiplier);
tempList.Remove(tempList[index]);
}
}
}
[Command("simplt_refresh")]
private void simplt_refresh(IPlayer iplayer)
{
if (iplayer.IsAdmin)
foreach (var container in containersList)
OnEntitySpawned(container);
}
}
}