C#:
using Newtonsoft.Json;
using Oxide.Core;
using Oxide.Game.Rust.Cui;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UnityEngine;
namespace Oxide.Plugins {
[Info("Custom Craft System", "Rosty", "2.0.0")]
[Description("")]
public class CustomCraft : RustPlugin {
#region - Fields & Hooks -
private PluginConfig _config;
private readonly Dictionary<ulong, int> _playerPages = new Dictionary<ulong, int>();
private const int ItemsPerPage = 3;
private void OnServerInitialized() {
if (!string.IsNullOrEmpty(_config.Permission)) {
permission.RegisterPermission(_config.Permission, this);
}
}
#endregion
#region - Configuration -
private class PluginConfig {
[JsonProperty("Permission to use the craft menu (leave empty to disable)")]
public string Permission {
get;
set;
}
= "customcraft.use";
[JsonProperty("Craftable Items")]
public List<CraftableItem> CraftableItems {
get;
set;
}
}
private class CraftableItem {
[JsonProperty("Display Name")]
public string DisplayName {
get;
set;
}
[JsonProperty("Item Shortname")]
public string Shortname {
get;
set;
}
[JsonProperty("Amount to craft")]
public int Amount {
get;
set;
}
[JsonProperty("Skin ID (0 for default)")]
public ulong SkinID {
get;
set;
}
[JsonProperty("Ingredients (item shortname and amount)")]
public List<Ingredient> Ingredients {
get;
set;
}
}
private class Ingredient {
[JsonProperty("Item Shortname")]
public string Shortname {
get;
set;
}
[JsonProperty("Amount")]
public int Amount {
get;
set;
}
}
protected override void LoadDefaultConfig() {
_config = new PluginConfig {
Permission = "customcraft.use", CraftableItems = new List<CraftableItem> {
new CraftableItem {
DisplayName = "First aid kit", Shortname = "syringe.medical", Amount = 5, SkinID = 0, Ingredients = new List<Ingredient> {
new Ingredient {
Shortname = "cloth", Amount = 100
}
, new Ingredient {
Shortname = "lowgradefuel", Amount = 50
}
}
}
, new CraftableItem {
DisplayName = "rifle.ak", Shortname = "rifle.ak", Amount = 1, SkinID = 824209221, Ingredients = new List<Ingredient> {
new Ingredient {
Shortname = "metal.fragments", Amount = 2500
}
, new Ingredient {
Shortname = "metal.refined", Amount = 100
}
, new Ingredient {
Shortname = "wood", Amount = 500
}
}
}
, new CraftableItem {
DisplayName = "Fuel", Shortname = "lowgradefuel", Amount = 250, SkinID = 0, Ingredients = new List<Ingredient> {
new Ingredient {
Shortname = "fat.animal", Amount = 100
}
, new Ingredient {
Shortname = "cloth", Amount = 50
}
}
}
, new CraftableItem {
DisplayName = "pickaxe", Shortname = "pickaxe", Amount = 1, SkinID = 0, Ingredients = new List<Ingredient> {
new Ingredient {
Shortname = "metal.fragments", Amount = 500
}
, new Ingredient {
Shortname = "wood", Amount = 1000
}
}
}
}
}
;
}
protected override void SaveConfig() => Config.WriteObject(_config);
protected override void LoadConfig() {
base.LoadConfig();
_config = Config.ReadObject<PluginConfig>();
if (_config == null) LoadDefaultConfig();
}
#endregion
#region - Localization -
protected override void LoadDefaultMessages() {
lang.RegisterMessages(new Dictionary<string, string> {
["NoPermission"]
= "You do not have permission to use this command.", ["NotEnoughResources"] = "You don't have enough resources for crafting. <color=#FFD700>{0}</color>.", ["CraftSuccess"] = "You have successfully crafted <color=#FFD700>{0} x{1}</color>.", ["InventoryFull"] = "Your inventory is full! An item was dropped near you.", ["Recipe"] = "<color=#FFD700>{0}</color> - Required Resources:", ["RecipeIngredient"] = "• <color=#ADD8E6>{0}</color>: <color=#FFFFFF>{1}</color>"
}
, this);
}
private string _(string key, ulong playerId = 0, params object[] args) => string.Format(lang.GetMessage(key, this, playerId == 0 ? null : playerId.ToString()), args);
#endregion
#region - Commands -
[ChatCommand("craft")]
private void ChatCmdCraft(BasePlayer player) {
if (!string.IsNullOrEmpty(_config.Permission) && !permission.UserHasPermission(player.UserIDString, _config.Permission)) {
player.ChatMessage(_("NoPermission", player.userID));
return;
}
_playerPages[player.userID] = 0;
DrawCraftUI(player, 0);
}
[ConsoleCommand("craftsystem.close")]
private void ConsoleCmdClose(ConsoleSystem.Arg arg) {
var p = arg.Player();
if (p) CuiHelper.DestroyUi(p, "CraftSystem");
}
[ConsoleCommand("craftsystem.page")]
private void ConsoleCmdPage(ConsoleSystem.Arg arg) {
var p = arg.Player();
if (!p || !arg.HasArgs(1)) return;
_playerPages.TryGetValue(p.userID, out int page);
page += arg.GetString(0) == "next" ? 1 : -1;
_playerPages[p.userID] = page;
DrawCraftUI(p, page);
}
[ConsoleCommand("craftsystem.showinfo")]
private void ConsoleCmdShowInfo(ConsoleSystem.Arg arg) {
var p = arg.Player();
if (!p || !arg.HasArgs(1) || !int.TryParse(arg.GetString(0), out int i) || i < 0 || i >= _config.CraftableItems.Count) return;
var item = _config.CraftableItems[i];
var sb = new StringBuilder();
sb.AppendLine(_("Recipe", p.userID, item.DisplayName));
foreach (var ing in item.Ingredients) {
var def = ItemManager.FindItemDefinition(ing.Shortname);
sb.AppendLine(_("RecipeIngredient", p.userID, def?.displayName?.translated ?? ing.Shortname, ing.Amount));
}
p.ChatMessage(sb.ToString());
}
[ConsoleCommand("craftsystem.craft")]
private void ConsoleCmdCraft(ConsoleSystem.Arg arg) {
var p = arg.Player();
if (!p || !arg.HasArgs(1) || !int.TryParse(arg.GetString(0), out int i) || i < 0 || i >= _config.CraftableItems.Count) return;
var item = _config.CraftableItems[i];
if (HasAllIngredients(p, item.Ingredients)) {
foreach (var ing in item.Ingredients) p.inventory.Take(null, ItemManager.FindItemDefinition(ing.Shortname).itemid, ing.Amount);
var created = ItemManager.CreateByName(item.Shortname, item.Amount, item.SkinID);
if (created != null) {
if (!p.inventory.GiveItem(created)) {
created.Drop(p.GetDropPosition(), p.GetDropVelocity());
p.ChatMessage(_("InventoryFull", p.userID));
}
p.ChatMessage(_("CraftSuccess", p.userID, item.DisplayName, item.Amount));
}
_playerPages.TryGetValue(p.userID, out int page);
DrawCraftUI(p, page);
}
else p.ChatMessage(_("NotEnoughResources", p.userID, item.DisplayName));
}
private bool HasAllIngredients(BasePlayer p, List<Ingredient> ings) {
foreach (var ing in ings) {
var def = ItemManager.FindItemDefinition(ing.Shortname);
if (def == null) return false;
if (p.inventory.GetAmount(def.itemid) < ing.Amount) return false;
}
return true;
}
#endregion
#region - UI Drawing (Your Original Layout) -
private void DrawCraftUI(BasePlayer player, int page) {
var container = new CuiElementContainer();
CuiHelper.DestroyUi(player, "CraftSystem");
container.Add(new CuiPanel {
CursorEnabled = true, Image = {
Color = "0 0 0 0.5882353", Material = "assets/content/ui/uibackgroundblur.mat"
}
, RectTransform = {
AnchorMin = "0.5 0.5", AnchorMax = "0.5 0.5", OffsetMin = "-640 -360", OffsetMax = "640 360"
}
}
, "Overlay", "CraftSystem");
container.Add(new CuiPanel {
Image = {
Color = "0.3568628 0.3372549 0.3372549 0.6392157"
}
, RectTransform = {
AnchorMin = "0.5 0.5", AnchorMax = "0.5 0.5", OffsetMin = "-254.174 108.49", OffsetMax = "190.916 145.23"
}
}
, "CraftSystem", "HeaderPanel");
container.Add(new CuiLabel {
Text = {
Text = "Craft System", Font = "robotocondensed-bold.ttf", FontSize = 24, Align = TextAnchor.MiddleCenter, Color = "1 1 1 1"
}
, RectTransform = {
AnchorMin = "0.5 0.5", AnchorMax = "0.5 0.5", OffsetMin = "-254.174 105.091", OffsetMax = "190.916 145.234"
}
}
, "CraftSystem");
container.Add(new CuiButton {
Button = {
Command = "craftsystem.close", Color = "0.6415094 0.190032 0.190032 0.6392157"
}
, RectTransform = {
AnchorMin = "0.5 0.5", AnchorMax = "0.5 0.5", OffsetMin = "195.407 108.492", OffsetMax = "240.173 145.229"
}
, Text = {
Text = "X", Font = "robotocondensed-bold.ttf", FontSize = 26, Align = TextAnchor.MiddleCenter
}
}
, "CraftSystem");
string[] itemPanelOffsets = {
"-254.174 -97.091 -91.826 105.091", "-88.174 -97.091 74.174 105.091", "77.826 -97.091 240.174 105.091"
}
;
string[] craftButtonOffsets = {
"-254.18 -129.501 -125.7 -100.499", "-88.179 -129.501 40.301 -100.499", "77.825 -129.501 206.295 -100.499"
}
;
string[] infoButtonOffsets = {
"-121.332 -129.501 -91.822 -100.499", "44.664 -129.501 74.174 -100.499", "210.665 -129.501 240.175 -100.499"
}
;
var itemsToShow = _config.CraftableItems.Skip(page * ItemsPerPage).Take(ItemsPerPage).ToList();
for (int i = 0; i < itemsToShow.Count; i++) {
var item = itemsToShow[i];
var itemIndexInConfig = _config.CraftableItems.IndexOf(item);
var itemDef = ItemManager.FindItemDefinition(item.Shortname);
string itemSlotPanel = container.Add(new CuiPanel {
Image = {
Color = "0.3568628 0.3372549 0.3372549 0.6392157"
}
, RectTransform = {
AnchorMin = "0.5 0.5", AnchorMax = "0.5 0.5", OffsetMin = itemPanelOffsets[i].Split(' ')[0] + " " + itemPanelOffsets[i].Split(' ')[1], OffsetMax = itemPanelOffsets[i].Split(' ')[2] + " " + itemPanelOffsets[i].Split(' ')[3]
}
}
, "CraftSystem");
if (itemDef != null) {
container.Add(new CuiElement {
Parent = itemSlotPanel, Components = {
new CuiRawImageComponent {
Url = $"https://rustlabs.com/img/items180/{itemDef.shortname}.png", Sprite = "assets/content/textures/generic/fulltransparent.tga"
}
, new CuiRectTransformComponent {
AnchorMin = "0.1 0.1", AnchorMax = "0.9 0.9"
}
}
}
);
container.Add(new CuiLabel {
Text = {
Text = item.DisplayName.ToUpper(), Align = TextAnchor.LowerCenter, FontSize = 14
}
, RectTransform = {
AnchorMin = "0 0", AnchorMax = "1 0.2"
}
}
, itemSlotPanel);
}
container.Add(new CuiButton {
Button = {
Command = $"craftsystem.craft {itemIndexInConfig}", Color = "0.3568628 0.3372549 0.3372549 0.6392157"
}
, RectTransform = {
AnchorMin = "0.5 0.5", AnchorMax = "0.5 0.5", OffsetMin = craftButtonOffsets[i].Split(' ')[0] + " " + craftButtonOffsets[i].Split(' ')[1], OffsetMax = craftButtonOffsets[i].Split(' ')[2] + " " + craftButtonOffsets[i].Split(' ')[3]
}
, Text = {
Text = "CRAFT", Font = "robotocondensed-bold.ttf", FontSize = 21, Align = TextAnchor.MiddleCenter
}
}
, "CraftSystem");
container.Add(new CuiButton {
Button = {
Command = $"craftsystem.showinfo {itemIndexInConfig}", Color = "0.3568628 0.3372549 0.3372549 0.6392157"
}
, RectTransform = {
AnchorMin = "0.5 0.5", AnchorMax = "0.5 0.5", OffsetMin = infoButtonOffsets[i].Split(' ')[0] + " " + infoButtonOffsets[i].Split(' ')[1], OffsetMax = infoButtonOffsets[i].Split(' ')[2] + " " + infoButtonOffsets[i].Split(' ')[3]
}
, Text = {
Text = "?", Font = "robotocondensed-bold.ttf", FontSize = 21, Align = TextAnchor.MiddleCenter
}
}
, "CraftSystem");
}
if (page > 0) container.Add(new CuiButton {
Button = {
Command = "craftsystem.page prev", Color = "0.3568628 0.3372549 0.3372549 0.6392157"
}
, RectTransform = {
AnchorMin = "0.5 0.5", AnchorMax = "0.5 0.5", OffsetMin = "-295.446 -14.501", OffsetMax = "-264.954 14.501"
}
, Text = {
Text = "<", Font = "robotocondensed-bold.ttf", FontSize = 21, Align = TextAnchor.MiddleCenter
}
}
, "CraftSystem");
if ((page + 1) * ItemsPerPage < _config.CraftableItems.Count) container.Add(new CuiButton {
Button = {
Command = "craftsystem.page next", Color = "0.3568628 0.3372549 0.3372549 0.6392157"
}
, RectTransform = {
AnchorMin = "0.5 0.5", AnchorMax = "0.5 0.5", OffsetMin = "250.954 -14.501", OffsetMax = "281.446 14.501"
}
, Text = {
Text = ">", Font = "robotocondensed-bold.ttf", FontSize = 21, Align = TextAnchor.MiddleCenter
}
}
, "CraftSystem");
CuiHelper.AddUi(player, container);
}
#endregion
}
}