C#:
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using Newtonsoft.Json;
using Oxide.Core;
using Oxide.Game.Rust.Cui;
using UnityEngine;
namespace Oxide.Plugins
{
[Info("CraftSystem", "https://topplugin.ru/", "1.0.2")]
public class CraftSystem : RustPlugin
{
public string Layer = "UI.CraftSystem";
#region Hooks
void Loaded()
{
foreach (var craftitem in _config.items){
if (!string.IsNullOrEmpty(craftitem.png)) AddImage(craftitem.png,"CraftSystem_item_"+Translit(craftitem.png));
foreach (var item in craftitem.items)
if (!string.IsNullOrEmpty(item.png)) AddImage(item.png,"CraftSystem_item_"+Translit(item.png));
}
AddImage("https://i.ibb.co/J2btPkW/arrow.png","CraftSystem_arrow");
AddImage("https://i.ibb.co/z6R6pQn/exit.png","CraftSystem_exit_img");
}
void Unload()
{
foreach (var player in BasePlayer.activePlayerList) CuiHelper.DestroyUi(player, Layer);
}
#endregion
#region Command
[ChatCommand(("craft"))]
void chatCmdCraft(BasePlayer player, string command, string[] args)
{
CuiHelper.DestroyUi(player, Layer);
var container = new CuiElementContainer();
container.Add(new CuiPanel
{
CursorEnabled = true,
Image =
{
FadeIn = 0.2f,
Sprite = "assets/content/ui/ui.background.transparent.radial.psd",
Color = "0 0 0 1"
}
}, "Overlay", Layer);
container.Add(new CuiPanel
{
Image =
{
FadeIn = 0.2f,
Color = "0.2 0.2 0.17 0.7",
Material = "assets/content/ui/uibackgroundblur.mat"
}
}, Layer);
container.Add(new CuiLabel
{
Text = { Text = "КРАФТ", Align = TextAnchor.UpperCenter, FontSize = 40, Font = "robotocondensed-bold.ttf" },
RectTransform = { AnchorMin = "0.3 1", AnchorMax = "0.7 1", OffsetMin = "0 -145", OffsetMax = "0 -81.6" }
}, Layer);
container.Add(new CuiLabel
{
Text = { Text = "Создание уникальных предметов", Align = TextAnchor.UpperCenter, FontSize = 18, Font = "robotocondensed-regular.ttf" },
RectTransform = { AnchorMin = "0 1", AnchorMax = "1 1", OffsetMin = "0 -145", OffsetMax = "0 -123" }
}, Layer);
container.Add(new CuiElement
{
Parent = Layer,
Components =
{
GetImageComponent("https://i.ibb.co/z6R6pQn/exit.png","CraftSystem_exit_img"),
new CuiRectTransformComponent {AnchorMin = "1 0", AnchorMax = "1 0", OffsetMin = "-73.9 20", OffsetMax = "-28.6 80"},
}
});
container.Add(new CuiElement
{
Parent = Layer,
Components =
{
new CuiImageComponent {Color = "0.33 0.87 0.59 0.6"},
new CuiRectTransformComponent {AnchorMin = "1 0", AnchorMax = "1 0", OffsetMin = "-291.3 22.6", OffsetMax = "-108 25.2"}
}
});
container.Add(new CuiButton
{
Button =
{
Color = "0 0 0 0",
Command = "UI_Craft close",
Close = Layer
},
Text = { Text = "Покинуть страницу", Align = TextAnchor.UpperCenter, FontSize = 18 },
RectTransform = { AnchorMin = "1 0", AnchorMax = "1 0", OffsetMin = "-291.3 22.6", OffsetMax = "-108 49.2" },
}, Layer);
container.Add(new CuiButton
{
Button =
{
Color = "0 0 0 0",
Command = "UI_Craft close",
Close = Layer
},
Text = { Text = "" },
RectTransform = { AnchorMin = "0 0", AnchorMax = "1 1" },
}, Layer);
var itemSize = 165.3f;
var itemSepX = 38f;
var buttomSepY = 4f;
var buttomSizeY = 39.3f;
var items = new Dictionary<string, List<string[]>>();
foreach (var item in _config.items)
{
List<string[]> list;
if (!items.TryGetValue(item.shortname, out list)) list = items[item.shortname] = new List<string[]>();
list.Add(new[] { item.png, item.name });
}
var itemCount = items.Count;
var posX = -(itemSize * itemCount + itemSepX * (itemCount - 1)) / 2f;
var posY = 0f;
var itemId = 0;
foreach (var p in items)
{
container.Add(new CuiPanel
{
RectTransform = { AnchorMin = "0.5 0.7", AnchorMax = "0.5 0.7", OffsetMin = $"{posX} {posY - itemSize}", OffsetMax = $"{posX + itemSize} {posY}" },
Image = { Color = "0 0 0 0.6" }
}, Layer, Layer + $".Item{itemId}");
container.Add(new CuiElement
{
Parent = Layer + $".Item{itemId}",
Components =
{
GetImageComponent(p.Value[0][0], "CraftSystem_item_"+Translit(p.Value[0][0])),
new CuiRectTransformComponent { AnchorMin = "0 0", AnchorMax = "1 1" },
}
});
var buttonPosY = posY - itemSize - buttomSepY;
for (var i = 0; i < p.Value.Count; i++)
{
var item = p.Value[i];
container.Add(new CuiButton
{
RectTransform = { AnchorMin = "0.5 0.7", AnchorMax = "0.5 0.7", OffsetMin = $"{posX} {buttonPosY - buttomSizeY}", OffsetMax = $"{posX + itemSize} {buttonPosY}" },
Button =
{
Color = "0.33 0.87 0.59 0.6",
Command = $"UI_Craft opencraftinfo {item[1]}",
},
Text = { Text = p.Value.Count > 1 ? $"{i+1} УРОВЕНЬ" : "ОТКРЫТЬ КРАФТ", Align = TextAnchor.MiddleCenter, FontSize = 18 }
}, Layer);
buttonPosY -= buttomSizeY + buttomSepY;
}
posX += itemSize + itemSepX;
}
CuiHelper.AddUi(player, container);
}
[ConsoleCommand("UI_Craft")]
void consoleCmdCraft(ConsoleSystem.Arg arg)
{
var player = arg.Connection?.player as BasePlayer;
if (player == null) return;
var name = "";
foreach (var args in arg.Args)
{
if (args == "opencraftinfo" || args == "close" || args == "craftitem") continue;
if (name.Length == 0)
{
name += args;
}
else name += $" {args}";
}
Items craftItem = null;
if (arg.GetString(0) != "close" && arg.GetString(0) != "prev")
{
craftItem = _config.items.First(x => x.name == name);
}
switch (arg.GetString(0))
{
case "prev":
{
chatCmdCraft(player, "", new string[0]);
break;
}
case "opencraftinfo":
{
CuiHelper.DestroyUi(player, Layer);
var container = new CuiElementContainer();
container.Add(new CuiPanel
{
CursorEnabled = true,
Image =
{
FadeIn = 0.2f,
Sprite = "assets/content/ui/ui.background.transparent.radial.psd",
Color = "0 0 0 1"
}
}, "Overlay", Layer);
container.Add(new CuiPanel
{
Image =
{
FadeIn = 0.2f,
Color = "0.2 0.2 0.17 0.7",
Material = "assets/content/ui/uibackgroundblur.mat"
}
}, Layer);
container.Add(new CuiLabel
{
Text = { Text = craftItem.name.ToUpper(), Align = TextAnchor.UpperCenter, FontSize = 40, Font = "robotocondensed-bold.ttf" },
RectTransform = { AnchorMin = "0.3 1", AnchorMax = "0.7 1", OffsetMin = "0 -145", OffsetMax = "0 -81.6" }
}, Layer);
container.Add(new CuiElement
{
Parent = Layer,
Components =
{
GetImageComponent("https://i.ibb.co/z6R6pQn/exit.png","CraftSystem_exit_img"),
new CuiRectTransformComponent {AnchorMin = "1 0", AnchorMax = "1 0", OffsetMin = "-73.9 20", OffsetMax = "-28.6 80"},
}
});
container.Add(new CuiElement
{
Parent = Layer,
Components =
{
new CuiImageComponent {Color = "0.33 0.87 0.59 0.6"},
new CuiRectTransformComponent {AnchorMin = "1 0", AnchorMax = "1 0", OffsetMin = "-291.3 22.6", OffsetMax = "-108 25.2"}
}
});
container.Add(new CuiButton
{
Button =
{
Color = "0 0 0 0",
Command = "UI_Craft prev",
Close = Layer
},
Text = { Text = "Вернуться назад", Align = TextAnchor.UpperCenter, FontSize = 18 },
RectTransform = { AnchorMin = "1 0", AnchorMax = "1 0", OffsetMin = "-291.3 22.6", OffsetMax = "-108 49.2" },
}, Layer);
container.Add(new CuiButton
{
Button =
{
Color = "0 0 0 0",
Command = "UI_Craft prev",
Close = Layer
},
Text = { Text = "" },
RectTransform = { AnchorMin = "0 0", AnchorMax = "1 1" },
}, Layer);
container.Add(new CuiElement
{
Parent = Layer,
Name = Layer + ".Image",
Components =
{
GetImageComponent("https://i.ibb.co/J2btPkW/arrow.png","CraftSystem_arrow"),
new CuiRectTransformComponent { AnchorMin = "0.5 0.5", AnchorMax = "0.5 0.5", OffsetMin = "-78.3 -15", OffsetMax = "78.3 15" },
}
});
container.Add(new CuiElement
{
Parent = Layer,
Name = Layer + ".Image",
Components =
{
GetImageComponent(craftItem.png,"CraftSystem_item_"+Translit(craftItem.png)),
new CuiRectTransformComponent { AnchorMin = "0.5 0.5", AnchorMax = "0.5 0.5", OffsetMin = "106.6 -88.7", OffsetMax = "339.9 144.6" },
}
});
container.Add(new CuiButton()
{
RectTransform = { AnchorMin = "0.5 0.5", AnchorMax = "0.5 0.5", OffsetMin = "128.6 -144", OffsetMax = "317.9 -108"},
Button =
{
Color = "0.33 0.87 0.59 0.6",
Command = $"UI_Craft craftitem {craftItem.name}",
},
Text = { Text = "СКРАФТИТЬ", Align = TextAnchor.MiddleCenter, FontSize = 20 }
}, Layer);
var itemSize = 89.3f;
var itemSep = 10.6f;
var posX = -128f;
var posYstart = 144.6f;
var posY = posYstart;
var itemCount = 0;
foreach (var dropItem in craftItem.items)
{
itemCount += 1;
var haveItem = HaveItem(player, dropItem.idItem, dropItem.skinID, dropItem.amount);
container.Add(new CuiPanel
{
Image = { Color = haveItem ? "0 0 0 0.6" : "0.6 0 0 0.6" },
RectTransform = { AnchorMin = "0.5 0.5", AnchorMax = "0.5 0.5", OffsetMin = $"{posX - itemSize} {posY - itemSize}", OffsetMax = $"{posX} {posY}"}
}, Layer, Layer + $".Item{dropItem.name}");
container.Add(new CuiElement
{
Parent = Layer + $".Item{dropItem.name}",
Components =
{
string.IsNullOrEmpty(dropItem.png)
? GetItemImageComponent(dropItem.shortname)
: GetImageComponent(dropItem.png,"CraftSystem_item_"+Translit(dropItem.png)),
new CuiRectTransformComponent { AnchorMin = "0 0", AnchorMax = "1 1", OffsetMin = "2 2", OffsetMax = "-2 -2" },
}
});
container.Add(new CuiLabel()
{
Text = { Text = $"x{dropItem.amount}", Align = TextAnchor.LowerRight, FontSize = 12 },
RectTransform = { AnchorMin = "0 0", AnchorMax = "1 1", OffsetMax = "-3 -3" }
}, Layer + $".Item{dropItem.name}");
if (itemCount % 3 == 0)
{
posY = posYstart;
posX -= itemSize + itemSep;
}
else posY -= itemSize + itemSep;
}
CuiHelper.AddUi(player, container);
break;
}
case "close":
{
CuiHelper.DestroyUi(player, Layer);
break;
}
case "craftitem":
{
var container = new CuiElementContainer();
CuiHelper.DestroyUi(player, Layer + "Status");
var items = new Dictionary<Item, int>();
foreach (var craftedItem in craftItem.items)
{
var haveItem = HaveItem(player, craftedItem.idItem, craftedItem.skinID, craftedItem.amount);
if (!haveItem)
{
container.Add(new CuiLabel
{
Text = { Text = "Вы не можете скрафтить предмет! Не хватает ингредиента!", Align = TextAnchor.LowerCenter, FontSize = 18, Font = "robotocondensed-bold.ttf" },
RectTransform = { AnchorMin = "0.5 0", AnchorMax = "0.5 0", OffsetMin = "-250 104", OffsetMax = "250 130" }
}, Layer, Layer + "Status");
CuiHelper.AddUi(player, container);
return;
}
items.Add(FindItem(player, craftedItem.idItem, craftedItem.skinID, craftedItem.amount), craftedItem.amount);
}
foreach (var itemPair in items) itemPair.Key.UseItem(itemPair.Value);
CuiHelper.DestroyUi(player, Layer);
var craft = ItemManager.CreateByName(craftItem.shortname, craftItem.amount, craftItem.skinID);
craft.name = craftItem.name;
Interface.Oxide.CallHook("OnCraftSystemCraft", player, craft);
player.GiveItem(craft);
break;
}
}
}
[ChatCommand("newcraft")]
void chatCmdNewCraft(BasePlayer player, string command, string[] args)
{
if (!player.IsAdmin) return;
var craftItem = player.GetActiveItem();
var craftedItems = player.inventory.containerMain.itemList;
_config.items.Add(new Items()
{
name = craftItem.name,
amount = craftItem.amount,
png = "https://upload.wikimedia.org/wikipedia/ru/3/3f/%D0%93%D1%83%D0%B1%D0%BA%D0%B0_%D0%91%D0%BE%D0%B1_%D0%BF%D0%B5%D1%80%D1%81%D0%BE%D0%BD%D0%B0%D0%B6.png",
shortname = craftItem.info.shortname,
skinID = craftItem.skin,
});
foreach (var item in craftedItems)
{
var newItem = ItemManager.CreateByItemID(item.info.itemid, 1);
_config.items.First(x => x.name == craftItem.name).items.Add(new CraftItems()
{
name = item.name,
shortname = item.info.shortname,
skinID = item.skin,
png = "",
amount = item.amount,
idItem = item.info.itemid
});
}
SaveConfig();
}
#endregion
#region Methods
public Item FindItem(BasePlayer player, int itemID, ulong skinID, int amount)
{
Item item = null;
if (skinID == 0U)
{
if (player.inventory.FindItemID(itemID) != null && player.inventory.FindItemID(itemID).amount >= amount)
return player.inventory.FindItemID(itemID);
}
else
{
List<Item> items = new List<Item>();
items.AddRange(player.inventory.FindItemIDs(itemID));
foreach (var findItem in items)
{
if (findItem.skin == skinID && findItem.amount >= amount)
{
return findItem;
}
}
}
return item;
}
public bool HaveItem(BasePlayer player, int itemID, ulong skinID, int amount)
{
if (skinID == 0U)
{
if (player.inventory.FindItemID(itemID) != null &&
player.inventory.FindItemID(itemID).amount >= amount) return true;
return false;
}
else
{
List<Item> items = new List<Item>();
items.AddRange(player.inventory.FindItemIDs(itemID));
foreach (var item in items)
{
if (item.skin == skinID && item.amount >= amount)
{
return true;
}
}
}
return false;
}
private static string HexToRGB(string hex)
{
if (string.IsNullOrEmpty(hex))
{
hex = "#FFFFFFFF";
}
var str = hex.Trim('#');
if (str.Length == 6)
str += "FF";
if (str.Length != 8)
{
throw new Exception(hex);
throw new InvalidOperationException("Cannot convert a wrong format.");
}
var r = byte.Parse(str.Substring(0, 2), NumberStyles.HexNumber);
var g = byte.Parse(str.Substring(2, 2), NumberStyles.HexNumber);
var b = byte.Parse(str.Substring(4, 2), NumberStyles.HexNumber);
var a = byte.Parse(str.Substring(6, 2), NumberStyles.HexNumber);
Color color = new Color32(r, g, b, a);
return $"{color.r:F2} {color.g:F2} {color.b:F2} {color.a:F2}";
}
#endregion
#region Data
#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 List<Items>(){
new Items(){
name="Маленький рюкзак",
shortname="burlap.gloves.new",
amount=1,
png="https://static.moscow.ovh/images/games/rust//plugins/ultimate_ui/craftsystem/backpack_1.png",
skinID=1591970438,
items=new List<CraftItems>(){
new CraftItems{
name=null,
shortname="leather",
amount=100,
skinID=0,
idItem=1381010055,
png=""
},
new CraftItems{
name=null,
shortname="cloth",
amount=200,
skinID=0,
idItem=-858312878,
png=""
},
new CraftItems{
name=null,
shortname="rope",
amount=10,
skinID=0,
idItem=1414245522,
png=""
},
new CraftItems{
name=null,
shortname="sewingkit",
amount=5,
skinID=0,
idItem=1234880403,
png=""
},
new CraftItems{
name=null,
shortname="metal.fragments",
amount=500,
skinID=0,
idItem=69511070,
png=""
},
new CraftItems{
name=null,
shortname="metal.refined",
amount=20,
skinID=0,
idItem=317398316,
png=""
}
}
},
new Items(){
name="Верстак",
shortname="workbench1",
amount=1,
png="https://rustlabs.com/img/items180/workbench1.png",
skinID=0,
items=new List<CraftItems>(){
new CraftItems{
name=null,
shortname="metal.fragments",
amount=100,
skinID=0,
idItem=69511070,
png=""
},
new CraftItems{
name=null,
shortname="wood",
amount=500,
skinID=0,
idItem=-151838493,
png=""
}
}
}
}
};
}
public Configuration _config;
public class Configuration
{
[JsonProperty("Предметы на крафт")] public List<Items> items = new List<Items>();
}
public class Items
{
[JsonProperty("Название предмета")] public string name = "";
[JsonProperty("Шортнейм")] public string shortname = "";
[JsonProperty("Количество")] public int amount = 1;
[JsonProperty("PNG")] public string png = "";
[JsonProperty("Скинид")] public ulong skinID = 0U;
[JsonProperty("Необходимые для крафта предметы")]
public List<CraftItems> items = new List<CraftItems>();
}
public class CraftItems
{
[JsonProperty("Название предмета")] public string name = "";
[JsonProperty("Шортнейм")] public string shortname = "";
[JsonProperty("Количество")] public int amount = 0;
[JsonProperty("СкинИД")] public ulong skinID = 0U;
[JsonProperty("Айди предмета")] public int idItem = 0;
[JsonProperty("ПНГ")] public string png = "";
}
#endregion
public CuiRawImageComponent GetAvatarImageComponent(ulong user_id, string color = "1.0 1.0 1.0 1.0"){
if (plugins.Find("ImageLoader")) return plugins.Find("ImageLoader").Call("BuildAvatarImageComponent",user_id) as CuiRawImageComponent;
if (plugins.Find("ImageLibrary")) {
return new CuiRawImageComponent { Png = (string)plugins.Find("ImageLibrary").Call("GetImage", user_id.ToString()), Color = color, Sprite = "assets/content/textures/generic/fulltransparent.tga" };
}
return new CuiRawImageComponent {Url = "https://image.flaticon.com/icons/png/512/37/37943.png", Color = color, Sprite = "assets/content/textures/generic/fulltransparent.tga"};
}
public CuiRawImageComponent GetImageComponent(string url, string shortName="", string color = "1.0 1.0 1.0 1.0"){
if (plugins.Find("ImageLoader")) return plugins.Find("ImageLoader").Call("BuildImageComponent",url) as CuiRawImageComponent;
if (plugins.Find("ImageLibrary")) {
if (!string.IsNullOrEmpty(shortName)) url = shortName;
return new CuiRawImageComponent { Png = (string)plugins.Find("ImageLibrary").Call("GetImage", url), Color = color, Sprite = "assets/content/textures/generic/fulltransparent.tga"};
}
return new CuiRawImageComponent {Url = url, Color = color, Sprite = "assets/content/textures/generic/fulltransparent.tga"};
}
public CuiRawImageComponent GetItemImageComponent(string shortName){
string itemUrl = shortName;
if (plugins.Find("ImageLoader")) {itemUrl = $"https://static.moscow.ovh/images/games/rust/icons/{shortName}.png";}
return GetImageComponent(itemUrl, shortName);
}
public bool AddImage(string url,string shortName=""){
if (plugins.Find("ImageLoader")){
plugins.Find("ImageLoader").Call("CheckCachedOrCache", url);
return true;
}else
if (plugins.Find("ImageLibrary")){
if (string.IsNullOrEmpty(shortName)) shortName=url;
plugins.Find("ImageLibrary").Call("AddImage", url, shortName);
return true;
}
return false;
}
public static string Translit(string str)
{
str = str.Replace("б", "b");
str = str.Replace("Б", "B");
str = str.Replace("в", "v");
str = str.Replace("В", "V");
str = str.Replace("г", "h");
str = str.Replace("Г", "H");
str = str.Replace("ґ", "g");
str = str.Replace("Ґ", "G");
str = str.Replace("д", "d");
str = str.Replace("Д", "D");
str = str.Replace("є", "ye");
str = str.Replace("Э", "Ye");
str = str.Replace("ж", "zh");
str = str.Replace("Ж", "Zh");
str = str.Replace("з", "z");
str = str.Replace("З", "Z");
str = str.Replace("и", "y");
str = str.Replace("И", "Y");
str = str.Replace("ї", "yi");
str = str.Replace("Ї", "YI");
str = str.Replace("й", "j");
str = str.Replace("Й", "J");
str = str.Replace("к", "k");
str = str.Replace("К", "K");
str = str.Replace("л", "l");
str = str.Replace("Л", "L");
str = str.Replace("м", "m");
str = str.Replace("М", "M");
str = str.Replace("н", "n");
str = str.Replace("Н", "N");
str = str.Replace("п", "p");
str = str.Replace("П", "P");
str = str.Replace("р", "r");
str = str.Replace("Р", "R");
str = str.Replace("с", "s");
str = str.Replace("С", "S");
str = str.Replace("ч", "ch");
str = str.Replace("Ч", "CH");
str = str.Replace("ш", "sh");
str = str.Replace("Щ", "SHH");
str = str.Replace("ю", "yu");
str = str.Replace("Ю", "YU");
str = str.Replace("Я", "YA");
str = str.Replace("я", "ya");
str = str.Replace("ь", "");
str = str.Replace("Ь", "");
str = str.Replace('т', 't');
str = str.Replace("Т", "T");
str = str.Replace('ц', 'c');
str = str.Replace("Ц", "C");
str = str.Replace('о', 'o');
str = str.Replace("О", "O");
str = str.Replace('е', 'e');
str = str.Replace("Е", "E");
str = str.Replace('а', 'a');
str = str.Replace("А", "A");
str = str.Replace('ф', 'f');
str = str.Replace("Ф", "F");
str = str.Replace('і', 'i');
str = str.Replace("І", "I");
str = str.Replace('У', 'U');
str = str.Replace("у", "u");
str = str.Replace('х', 'x');
str = str.Replace("Х", "X");
str = str.Replace(" ", "_");
str = str.Replace("~", "_");
str = str.Replace("/", "");
str = str.Replace("\\", "");
str = str.Replace(":", "");
str = str.Replace(".", "_");
str = str.Replace("'", "_");
str = str.Replace("&", "");
str = str.Replace("?", "");
str = str.Replace(">", "_");
str = str.Replace("<", "_");
return str;
}
}
}