C#:
using System.Collections.Generic;
using System.Linq;
using Newtonsoft.Json;
using Oxide.Core;
using Oxide.Core.Plugins;
namespace Oxide.Plugins
{
[Info("NewComponents", "https://topplugin.ru/", "1.0.1")]
public class NewComponents : RustPlugin
{
#region Hooks
private ComponentInfo FindItemInfo(Item item)
{
ComponentList componentList;
if (!_config.items.TryGetValue(item.info.displayName.english, out componentList))
{
return null;
}
var itemData = componentList.components.FirstOrDefault(itemInfo => itemInfo.name == item.name);
return itemData;
}
object CanRecycle(Recycler recycler, Item item)
{
var itemInfo = FindItemInfo(item);
if (itemInfo?.RecycleInfos == null || itemInfo.RecycleInfos.Length == 0)
{
return null;
}
return true;
}
object OnRecycleItem(Recycler recycler, Item item)
{
var itemInfo = FindItemInfo(item);
if (itemInfo?.RecycleInfos == null || itemInfo.RecycleInfos.Length == 0)
{
return null;
}
item.UseItem();
foreach (var recycleItemInfo in itemInfo.RecycleInfos)
{
recycler.MoveItemToOutput(ItemManager.CreateByName(recycleItemInfo.shortname, recycleItemInfo.amount));
}
return true;
}
object OnItemAction(Item item, string action, BasePlayer player)
{
var itemData = FindItemInfo(item);
if (itemData == null)
{
return null;
}
ActionInfo act;
if (!itemData.actions.TryGetValue(action, out act))
{
return null;
}
if (!string.IsNullOrEmpty(act.command) && !string.IsNullOrEmpty(act.commandType))
{
if (act.commandType=="console")
{
player.SendConsoleCommand(act.command);
}
else
{
var cmd = act.command.Replace("{steamid}", player.UserIDString).Replace("%STEAMID%", player.UserIDString);
Server.Command(cmd);
}
if (!string.IsNullOrEmpty(act.chatText)) SendReply(player,act.chatText);
}
Interface.Oxide.CallHook("OnNewComponentsItemUse", player, item);
if (act.useItem)
{
item.UseItem(act.useItemCount);
}
if (act.drops != null && act.drops.Count != 0)
{
foreach (var drop in act.drops)
{
Item dropItem = ItemManager.CreateByItemID(drop.itemId, drop.amount, drop.skin);
dropItem.name = drop.name;
player.GiveItem(dropItem);
}
}
return false;
}
private void OnLootSpawn(LootContainer lootContainer)
{
UpdateContainer(lootContainer);
}
object CanStackItem(Item item, Item item2) => CanStack(item, item2);
object CanCombineDroppedItem(DroppedItem item, DroppedItem item2) => CanStack(item.item, item2.item);
object OnItemSplit(Item item, int amount)
{
var configItem = FindItemInfo(item);
if (configItem == null) return null;
item.amount -= amount;
var byItem = ItemManager.Create(item.info, amount, item.skin);
byItem.name = configItem.name;
item.name = configItem.name;
item.MarkDirty();
return byItem;
}
void OnServerInitialized()
{
var c = 0;
foreach (var container in BaseNetworkable.serverEntities.OfType<LootContainer>())
{
if (container.ShortPrefabName.Contains("elite")) continue;
UpdateContainer(container);
c++;
}
PrintError($"Было обновлено {c} контейнеров");
}
#endregion
#region Methods
private void UpdateContainer(LootContainer container)
{
if (container == null || container.inventory == null) return;
NextTick(() =>
{
Item newItem = null;
foreach (var item in _config.items)
{
foreach (var component in item.Value.components)
{
if (component==null) continue;
if (component.chanceSpawn.ContainsKey(container.ShortPrefabName))
{
if (component.chanceSpawn[container.ShortPrefabName] >
UnityEngine.Random.RandomRange(0f, 1f))
{
newItem = ItemManager.CreateByItemID(component.itemID, 1, component.skinID);
if (newItem==null) continue;
if (!string.IsNullOrEmpty(component.name)) newItem.name = component.name;
if (component.flags.Placeholder) newItem.SetFlag(global::Item.Flag.Placeholder, true);
if (component.flags.IsOn) newItem.SetFlag(global::Item.Flag.IsOn, true);
if (component.flags.OnFire) newItem.SetFlag(global::Item.Flag.OnFire, true);
if (component.flags.IsLocked) newItem.SetFlag(global::Item.Flag.IsLocked, true);
if (component.flags.Cooking) newItem.SetFlag(global::Item.Flag.Cooking, true);
}
}
}
}
if (newItem == null) return;
newItem.MoveToContainer(container.inventory);
});
}
[HookMethod("GetPng")]
public string GetPng(string name, string displayName)
{
if (!_config.items.ContainsKey(name))
return string.Empty;
var item = _config.items[name].components.First(x => x.name.Equals(displayName));
return item?.image ?? string.Empty;
}
object CanStack(Item item, Item item2)
{
if (item.info.displayName.english == item2.info.displayName.english)
{
if (_config.items.ContainsKey(item.info.displayName.english))
{
if (item.skin == item2.skin) return null;
return false;
}
}
return null;
}
public Dictionary<string, double> getChance()
{
Dictionary<string, double> chances = new Dictionary<string, double>();
foreach (var container in BaseNetworkable.serverEntities.OfType<LootContainer>())
{
if (chances.ContainsKey(container.ShortPrefabName)) continue;
chances.Add(container.ShortPrefabName, 0.5);
}
return chances;
}
#endregion
#region Commands
[ChatCommand("testitem")]
void chatCmdTestItem(BasePlayer player, string command, string[] args)
{
if (!player.IsAdmin) return;
int i=0;
foreach (var cfgItem in _config.items)
{
i++;
if (cfgItem.Value==null) {
continue;
}
int j=0;
foreach (var itemData in cfgItem.Value.components)
{
j++;
Item item = ItemManager.CreateByItemID(itemData.itemID, 10);
if (item==null) {
PrintError("Не удалось создать предмет {itemData.itemID}");
continue;
}
item.skin = itemData.skinID;
item.name = itemData.name;
if (itemData.flags.Placeholder) item.SetFlag(global::Item.Flag.Placeholder, true);
if (itemData.flags.IsOn) item.SetFlag(global::Item.Flag.IsOn, true);
if (itemData.flags.OnFire) item.SetFlag(global::Item.Flag.OnFire, true);
if (itemData.flags.IsLocked) item.SetFlag(global::Item.Flag.IsLocked, true);
if (itemData.flags.Cooking) item.SetFlag(global::Item.Flag.Cooking, true);
player.GiveItem(item);
}
}
SendReply(player, "Предметы выданы!");
}
[ChatCommand("ncd")]
void chatCmdNCD(BasePlayer player, string command, string[] args)
{
if (!player.IsAdmin) return;
var activeItem = player.GetActiveItem();
var activeItemInfo = FindItemInfo(activeItem);
if (activeItemInfo == null)
return;
activeItemInfo.actions["unwrap"].drops.Clear();
foreach (var item in player.inventory.containerMain.itemList)
{
activeItemInfo.actions["unwrap"].drops.Add(new DropItem()
{
itemId = item.info.itemid,
amount = item.amount,
skin = item.skin,
name = item.name
});
}
SendReply(player, "Добавили");
SaveConfig();
}
[ChatCommand("nc")]
void chatCmdNC(BasePlayer player, string command, string[] args)
{
if (!player.IsAdmin) return;
var activeItem = player.GetActiveItem();
if (!_config.items.ContainsKey(activeItem.info.displayName.english))
{
_config.items.Add(activeItem.info.displayName.english, new ComponentList());
_config.items[activeItem.info.displayName.english].components.Add(new ComponentInfo()
{
name = activeItem.info.displayName.english,
itemID = activeItem.info.itemid,
shortname = activeItem.info.shortname,
skinID = activeItem.skin,
chanceSpawn = getChance(),
actions = new Dictionary<string, ActionInfo>()
{
{"unwrap", new ActionInfo()
{
command = "",
commandType = "",
useItemCount = 1,
drops = new List<DropItem>()
}}
}
});
}
else
{
_config.items[activeItem.info.displayName.english].components.Add(new ComponentInfo()
{
name = activeItem.info.displayName.english,
itemID = activeItem.info.itemid,
shortname = activeItem.info.shortname,
skinID = activeItem.skin,
chanceSpawn = getChance(),
});
}
SaveConfig();
SendReply(player, $"Предмет {activeItem.info.displayName.english} успешно добавлен в конфиг!");
}
#endregion
#region Config
protected override void SaveConfig()
{
Config.WriteObject(_config);
}
protected override void LoadConfig()
{
base.LoadConfig();
_config = Config.ReadObject<Configuration>();
if (_config==null) LoadDefaultConfig();
SaveConfig();
}
protected override void LoadDefaultConfig()
{
_config = new Configuration()
{
items = new Dictionary<string, ComponentList>(){
["Glue"] = new ComponentList(){
components = new List<ComponentInfo>(){
new ComponentInfo()
{
name = "Золото",
itemID = -1899491405,
shortname = "glue",
skinID = 1707233455,
chanceSpawn = getChance(),
actions = new Dictionary<string, ActionInfo>()
{
{"unwrap", new ActionInfo()
{
command = "",
commandType = "",
useItemCount = 1,
drops = new List<DropItem>(),
chatText = ""
}
}
},
RecycleInfos = new RecycleInfo[]{
new RecycleInfo(){
shortname = "metal.refined",
amount = 10
},
new RecycleInfo(){
shortname = "techparts",
amount = 2
},
new RecycleInfo(){
shortname = "scrap",
amount = 20
}
}
}
}
},
["Large Loot Bag"] = new ComponentList(){
components = new List<ComponentInfo>(){
new ComponentInfo()
{
name = "Кейс с дождем и золотом",
itemID = 479292118,
shortname = "halloween.lootbag.large",
skinID = 0,
chanceSpawn = getChance(),
actions = new Dictionary<string, ActionInfo>()
{
{"unwrap", new ActionInfo()
{
command = "rain 1",
commandType = "server",
useItemCount = 1,
drops = new List<DropItem>(){
new DropItem(){
itemId = -1899491405,
amount = 100,
skin = 1707233455,
name = "Золото"
}
},
chatText = "И начался дождь..."
}
}
},
RecycleInfos = new RecycleInfo[]{
new RecycleInfo(){
shortname = "metal.refined",
amount = 100
},
new RecycleInfo(){
shortname = "techparts",
amount = 20
},
new RecycleInfo(){
shortname = "scrap",
amount = 200
}
}
}
}
}
}
};
SaveConfig();
}
public Configuration _config;
public class Configuration
{
public Dictionary<string, ComponentList> items = new Dictionary<string, ComponentList>();
}
public class DropItem
{
[JsonProperty("Айди предмета")] public int itemId;
[JsonProperty("Количество предметов")] public int amount;
[JsonProperty("Скинид")] public ulong skin;
[JsonProperty("Название предмета")] public string name = "";
}
public class ActionInfo
{
[JsonProperty("Выполняемая команда")]
public string command = "";
[JsonProperty("Тип команды (console - консольная команда; server - серверная команда)")]
public string commandType = "";
[JsonProperty("Использовать предмет")] public bool useItem = true;
[JsonProperty("Выпадаемые предметы")] public List<DropItem> drops = new List<DropItem>();
[JsonProperty("Количество использованного предмета")]
public int useItemCount = 1;
[JsonProperty("Текст для отправки сообщения в чат")]
public string chatText = "";
}
public class ComponentList
{
public List<ComponentInfo> components = new List<ComponentInfo>();
}
public class TFlags{
public bool Placeholder = false;
public bool IsOn = false;
public bool OnFire = false;
public bool IsLocked = false;
public bool Cooking = false;
}
public class ComponentInfo
{
[JsonProperty("Айди предмета")] public int itemID = 0;
[JsonProperty("Скинид предмета")] public ulong skinID = 0U;
[JsonProperty("Шортнейм")] public string shortname = "";
[JsonProperty("Изображение предмета")] public string image = "";
[JsonProperty("Название предмета")] public string name = "";
[JsonProperty("Шанс спавна")]
public Dictionary<string, double> chanceSpawn = new Dictionary<string, double>();
[JsonProperty("Действия")]
public Dictionary<string, ActionInfo> actions = new Dictionary<string, ActionInfo>();
[JsonProperty("Переработка")]
public RecycleInfo[] RecycleInfos = new RecycleInfo[0];
[JsonProperty("Системный флаг (будьте остарожны при установке")]
public TFlags flags = new TFlags();
}
public class RecycleInfo
{
[JsonProperty("Шортнейм")] public string shortname = "";
[JsonProperty("Количество")] public int amount = 0;
}
#endregion
}
}