C#:
using System;
using System.Collections.Generic;
using System.Linq;
using Newtonsoft.Json;
using Oxide.Core;
using Oxide.Core.Plugins;
using Oxide.Game.Rust.Cui;
using UnityEngine;
namespace Oxide.Plugins {
[Info ("kryCrafts", "xkrystalll", "1.0.0")]
class kryCrafts : RustPlugin {
[PluginReference]
Plugin ImageLibrary;
#region CuiBuilder
protected CuiElement Panel (string name, string anMin, string anMax, string parent, string png, bool cursor) {
var Element = new CuiElement () {
Name = name, Parent = parent, Components = {
new CuiRawImageComponent {
Png = png
}
, new CuiRectTransformComponent {
AnchorMin = anMin, AnchorMax = anMax
}
}
}
;
if (cursor) {
Element.Components.Add (new CuiNeedsCursorComponent ());
}
return Element;
}
protected CuiElement transparent (string name, string parent, bool cursor) {
var Element = new CuiElement () {
Name = name, Parent = parent, Components = {
new CuiImageComponent {
Sprite = "assets/content/ui/ui.background.tile.psd", Color = "0 0 0 0"
}
, new CuiRectTransformComponent {
AnchorMin = "0 0", AnchorMax = "1 1"
}
}
}
;
if (cursor) {
Element.Components.Add (new CuiNeedsCursorComponent ());
}
return Element;
}
protected CuiElement Text (string name, string parent, string color, string text, TextAnchor pos, int fsize, string anMin, string anMax, float fadein, float fadeout, string fname = "robotocondensed-bold.ttf") {
var Element = new CuiElement () {
Name = name, Parent = parent, FadeOut = fadeout, Components = {
new CuiTextComponent () {
FadeIn = fadein, Color = color, Text = text, Align = pos, Font = fname, FontSize = fsize
}
, new CuiRectTransformComponent {
AnchorMin = anMin, AnchorMax = anMax
}
}
}
;
return Element;
}
protected CuiElement Button (string name, string parent, string command, string color, string anMin, string anMax) {
var Element = new CuiElement () {
Name = name, Parent = parent, Components = {
new CuiButtonComponent {
Command = command, Color = color
}
, new CuiRectTransformComponent {
AnchorMin = anMin, AnchorMax = anMax
}
}
}
;
return Element;
}
#endregion
#region Configuration
public static ConfigData cfg;
public class ConfigData {
[JsonProperty("Крафты")]
public Dictionary<string, CraftInfo> CraftPrice = new Dictionary<string, CraftInfo> ();
}
protected override void LoadDefaultConfig() {
var config = new ConfigData() {
CraftPrice = {
["testakcraft"]
= new CraftInfo(new Dictionary<string, int>() {
{
"metalspring", 4
}
, {
"riflebody", 1
}
}
, null, false, "", "rifle.ak", 887494035), ["testlrcraft"] = new CraftInfo(new Dictionary<string, int>() {
{
"metalspring", 4
}
, {
"riflebody", 1
}
}
, null, false, "", "rifle.lr300", 0), ["testitem"] = new CraftInfo(new Dictionary<string, int>() {
{
"metalspring", 4
}
, {
"riflebody", 1
}
}
, null, true, "giveweapon %CRAFTER% aktest", "rifle.ak", 0), ["testitem1"] = new CraftInfo(new Dictionary<string, int>() {
{
"metalspring", 4
}
, {
"riflebody", 1
}
}
, "https://media.discordapp.net/attachments/771661902190215171/794834849369161769/syringe1.png", true, "giveheal armysteampack 1 %CRAFTER%", "lmg.m249", 0)
}
}
;
SaveConfig(config);
}
void LoadConfig () {
cfg = Config.ReadObject<ConfigData>();
}
void SaveConfig (object config) => Config.WriteObject (config, true);
#endregion
#region Fields
public class CraftInfo {
public CraftInfo (Dictionary<string, int> price, string craftURL, bool CraftIsCommand, string CommandForCraft, string shortname, ulong skin) {
this.shortname = shortname;
this.craftURL = craftURL;
this.price = price;
this.CommandForCraft = CommandForCraft;
this.CraftIsCommand = CraftIsCommand;
this.skin = skin;
}
[JsonProperty("shortname предмета")]
public string shortname;
[JsonProperty ("Предметы для крафта")]
public Dictionary<string, int> price;
[JsonProperty ("Иконка для крафта (url)")]
public string craftURL;
[JsonProperty("Это команда?")]
public bool CraftIsCommand;
[JsonProperty("Команда для крафта")]
public string CommandForCraft;
[JsonProperty("Скин для предмета")]
public ulong skin;
}
public const double defaultMinX = 0.02564071;
public const double defaultMaxX = 0.2403845;
public List<ulong> OpenedUIs = new List<ulong> ();
public Dictionary<ulong, short> pages = new Dictionary<ulong, short> ();
#endregion
#region Hooks
void Unload() {
foreach (var i in BasePlayer.activePlayerList) {
UI_UnloadAllUIs(i);
}
}
void OnPlayerDisconnected (BasePlayer player, string reason) => OpenedUIs.Remove (player.userID);
void OnServerInitialized () {
this.LoadConfig ();
if (!plugins.Exists ("ImageLibrary")) {
PrintWarning ("DOWNLOAD 'ImageLibrary'! Plugin kryCrafts has closed...");
Interface.Oxide.UnloadPlugin ("ImageLibrary");
return;
}
for (int i = 0; i < cfg.CraftPrice.Count ();
i++) {
if (cfg.CraftPrice.Keys.ToList()[i] == null) {
continue;
}
ImageLibrary.Call ("AddImage", cfg.CraftPrice.Values.ToList()[i].craftURL, cfg.CraftPrice.Keys.ToList()[i]);
}
ImageLibrary.Call ("AddImage", "https://media.discordapp.net/attachments/771661902190215171/793865474428764180/craft.png", "bg_AllowCraft");
ImageLibrary.Call ("AddImage", "https://media.discordapp.net/attachments/771661902190215171/793867475749961759/craft_notresourses.png", "bg_NotResourses");
ImageLibrary.Call ("AddImage", "https://media.discordapp.net/attachments/771661902190215171/793923590386352168/arrowleft.png", "arrowleft");
ImageLibrary.Call ("AddImage", "https://media.discordapp.net/attachments/771661902190215171/793923635680903198/arrowright.png", "arrowright");
ImageLibrary.Call ("AddImage", "https://media.discordapp.net/attachments/771661902190215171/793935440674947072/closebtn.png", "closebtn");
ImageLibrary.Call ("AddImage", "https://media.discordapp.net/attachments/771661902190215171/793938242255716362/craftsnotfound.png", "emptyPanel");
ImageLibrary.Call("AddImage", "https://media.discordapp.net/attachments/771661902190215171/794652099833102386/focusedcraft.png", "focusedmenu_available");
ImageLibrary.Call("AddImage", "https://media.discordapp.net/attachments/771661902190215171/794652963511599114/focusedcraftnonavailable.png", "focusedmenu_nonavailable");
}
#endregion
#region Main
void UI_DrawMain (BasePlayer p) {
short page = pages.GetValueOrDefault (p.userID);
CuiElementContainer c = new CuiElementContainer ();
c.Add(transparent("kryCrafts.bg", "Overlay", true));
if (page > 0)c.Add (Panel ("kryCrafts.bg.backbtn", "0.004375003 0.2311112", "0.055625 0.7777778", "kryCrafts.bg", (string) ImageLibrary.Call ("GetImage", "arrowleft"), false));
if (page < AllPages()) c.Add (Panel ("kryCrafts.bg.nextbtn", "0.94375 0.2311112", "0.9949999 0.7777778", "kryCrafts.bg", (string) ImageLibrary.Call ("GetImage", "arrowright"), false));
c.Add (Panel ("kryCrafts.bg.close", "0.34 0.1155556", "0.64375 0.1866667", "kryCrafts.bg", (string) ImageLibrary.Call ("GetImage", "closebtn"), false));
c.Add (Button ("kryCrafts.bg.close.btn", "kryCrafts.bg.close", "UI_CloseCraft", "0 0 0 0", "0 0", "1 1"));
if (page < AllPages())c.Add (Button ("kryCrafts.bg.nextbtn.btn", "kryCrafts.bg.nextbtn", "UI_NextPage", "0 0 0 0", "0 0", "1 1"));
if (page > 0) c.Add (Button ("kryCrafts.bg.backbtn.btn", "kryCrafts.bg.backbtn", "UI_BackPage", "0 0 0 0", "0 0", "1 1"));
int j = page * 5;
double AnMinX = 0.06312537;
double AnMaxX = 0.229375;
if (cfg.CraftPrice.ToList ().Count <= 0) {
c.Add (Panel ("kryCrafts.bg.empty", "0.3368748 0.5022222", "0.6425003 0.6133333", "kryCrafts.bg", (string) ImageLibrary.Call ("GetImage", "emptyPanel"), true));
}
for (int i = j; i < j + 5; i++) {
if (i >= cfg.CraftPrice.ToList ().Count ()) {
break;
}
c.Add (Panel ($"kryCrafts.bg.{i}", $"{AnMinX} 0.2311112", $"{AnMaxX} 0.7777778", "kryCrafts.bg", HaveItemsToCraft (i, p) == null ? (string) ImageLibrary.Call ("GetImage", "bg_AllowCraft") : (string) ImageLibrary.Call ("GetImage", "bg_NotResourses"), true));
c.Add (Button ($"kryCrafts.bg.{i}.items", $"kryCrafts.bg.{i}", $"craftitem price {cfg.CraftPrice.Keys.ToList()[i]}", "0 0 0 0", "0 0.1527495", "1 0.2443992"));
c.Add(Panel($"kryCrafts.bg.{i}.icon", "0.04135123 0.4521385", "0.9586465 0.9775967", $"kryCrafts.bg.{i}", (string)ImageLibrary.Call("GetImage", cfg.CraftPrice.Values.ToList()[i].craftURL == null ? cfg.CraftPrice.Values.ToList()[i].shortname : cfg.CraftPrice.Keys.ToList()[i]), false));
if (HaveItemsToCraft (i, p) == null) {
c.Add (Button ($"kryCrafts.bg.{i}.craft", $"kryCrafts.bg.{i}", $"craftitem craft {cfg.CraftPrice.Keys.ToList()[i]}", "0 0 0 0", "0 0", "1 0.1547862"));
}
AnMinX += 0.17375003;
AnMaxX += 0.17375003;
}
if (!OpenedUIs.Contains(p.userID)) OpenedUIs.Add(p.userID);
CuiHelper.AddUi(p, c);
}
Dictionary<string, int> HaveItemsToCraft (int index, BasePlayer p) {
var item = cfg.CraftPrice.Values.ToList () [index];
int remains = item.price.Count ();
Dictionary<string, int> itemsnothave = new Dictionary<string, int>();
for (int i = 0; i < item.price.Count ();
i++) {
if (p.inventory.GetAmount(ItemManager.FindItemDefinition (item.price.Keys.ToList()[i]).itemid) >= item.price.Values.ToList()[i]) {
remains--;
}
else {
int nothave = item.price.Values.ToList()[i] - p.inventory.GetAmount(ItemManager.FindItemDefinition (item.price.Keys.ToList()[i]).itemid);
itemsnothave.Add(ItemManager.FindItemDefinition (item.price.Keys.ToList()[i]).displayName.translated, nothave);
}
}
if (remains <= 0) {
return null;
}
else {
return itemsnothave;
}
}
private int AllPages () {
return (int) Math.Floor (Convert.ToDecimal (cfg.CraftPrice.Keys.Count) / 5);
}
void UI_RefreshItems (BasePlayer p, short page) {
CuiHelper.DestroyUi(p, "kryCrafts.bg.backbtn");
CuiHelper.DestroyUi(p, "kryCrafts.bg.nextbtn");
CuiElementContainer c = new CuiElementContainer ();
if (page > 0)c.Add (Panel ("kryCrafts.bg.backbtn", "0.004375003 0.2311112", "0.055625 0.7777778", "kryCrafts.bg", (string) ImageLibrary.Call ("GetImage", "arrowleft"), false));
if (page < AllPages()) c.Add (Panel ("kryCrafts.bg.nextbtn", "0.94375 0.2311112", "0.9949999 0.7777778", "kryCrafts.bg", (string) ImageLibrary.Call ("GetImage", "arrowright"), false));
if (page < AllPages())c.Add (Button ("kryCrafts.bg.nextbtn.btn", "kryCrafts.bg.nextbtn", "UI_NextPage", "0 0 0 0", "0 0", "1 1"));
if (page > 0) c.Add (Button ("kryCrafts.bg.backbtn.btn", "kryCrafts.bg.backbtn", "UI_BackPage", "0 0 0 0", "0 0", "1 1"));
int j = page * 5;
double AnMinX = 0.06312537;
double AnMaxX = 0.229375;
for (int i = j; i < j + 5; i++) {
if (i >= cfg.CraftPrice.ToList ().Count ()) {
break;
}
c.Add (Panel ($"kryCrafts.bg.{i}", $"{AnMinX} 0.2311112", $"{AnMaxX} 0.7777778", "kryCrafts.bg", HaveItemsToCraft (i, p) == null ? (string) ImageLibrary.Call ("GetImage", "bg_AllowCraft") : (string) ImageLibrary.Call ("GetImage", "bg_NotResourses"), true));
c.Add (Button ($"kryCrafts.bg.{i}.items", $"kryCrafts.bg.{i}", $"craftitem price {cfg.CraftPrice.Keys.ToList()[i]}", "0 0 0 0", "0 0.1527495", "1 0.2443992"));
c.Add(Panel($"kryCrafts.bg.{i}.icon", "0.04135123 0.4521385", "0.9586465 0.9775967", $"kryCrafts.bg.{i}", (string)ImageLibrary.Call("GetImage", cfg.CraftPrice.Values.ToList()[i].craftURL == null ? cfg.CraftPrice.Values.ToList()[i].shortname : cfg.CraftPrice.Values.ToList()[i].craftURL), false));
if (HaveItemsToCraft (i, p) == null) {
c.Add (Button ($"kryCrafts.bg.{i}.craft", $"kryCrafts.bg.{i}", $"craftitem craft {cfg.CraftPrice.Keys.ToList()[i]}", "0 0 0 0", "0 0", "1 0.1547861"));
}
AnMinX += 0.17375003;
AnMaxX += 0.17375003;
}
CuiHelper.AddUi(p, c);
}
private void removeItems(Dictionary<string, int> itemsRem, BasePlayer p) {
for (int i = 0; i < itemsRem.Keys.Count; i++) {
p.inventory.Take(null, ItemManager.FindItemDefinition(itemsRem.Keys.ToList()[i]).itemid, itemsRem.Values.ToList()[i]);
}
}
private void ChangeItemSkin(Item item, ulong targetSkin) {
item.skin = targetSkin;
item.MarkDirty();
BaseEntity heldEntity = item.GetHeldEntity();
if (heldEntity != null) {
heldEntity.skinID = targetSkin;
heldEntity.SendNetworkUpdate(BasePlayer.NetworkQueue.Update);
}
}
void CraftItem(short index, BasePlayer p) {
if (p == null) {
return;
}
if (HaveItemsToCraft(index, p) != null) {
SendNeededItems(p, HaveItemsToCraft(index, p));
return;
}
removeItems(cfg.CraftPrice.Values.ToList()[index].price, p);
if (cfg.CraftPrice.Values.ToList()[index].CraftIsCommand) {
Server.Command(cfg.CraftPrice.Values.ToList()[index].CommandForCraft.Replace("%CRAFTER%", p.UserIDString));
return;
}
Item item = ItemManager.Create(ItemManager.FindItemDefinition(cfg.CraftPrice.Values.ToList()[index].shortname), 1, cfg.CraftPrice.Values.ToList()[index].skin);
p.GiveItem(item, BaseEntity.GiveItemReason.PickedUp);
if (cfg.CraftPrice.Values.ToList()[index].skin != 0) {
ChangeItemSkin(item, cfg.CraftPrice.Values.ToList()[index].skin);
}
}
void SendNeededItems(BasePlayer p, Dictionary<string, int> items) {
string str = "<size=18>Предметы, которых не хватает для крафта:</size>\n";
for (int i = 0; i < items.Count();
i++) {
str += $"{items.Keys.ToList()[i]}: {items.Values.ToList()[i]}шт.\n";
}
p.ChatMessage(str);
}
private void UI_FocusItem(BasePlayer p, List<string> args) {
CuiHelper.DestroyUi(p, "kryCrafts.bg");
CuiElementContainer c = new CuiElementContainer();
var index = cfg.CraftPrice.Keys.ToList().IndexOf(args[1]);
if (index == -1) {
PrintError("-1 INDEX ON LINE 238");
return;
}
var items = cfg.CraftPrice.Values.ToList()[index].price;
c.Add(Panel("kryCrafts.price.bg", "0.3937501 0.2322222", "0.5887499 0.7777771", "Overlay", HaveItemsToCraft(index, p) == null ? (string)ImageLibrary.Call("GetImage", "focusedmenu_available") : (string)ImageLibrary.Call("GetImage", "focusedmenu_nonavailable"), true));
if (HaveItemsToCraft(index, p) == null) {
c.Add(Button("kryCrafts.price.bg.craft", "kryCrafts.price.bg", $"craftitem craft {cfg.CraftPrice.Keys.ToList()[index]}", "0 0 0 0", "0.5 0", "1 0.0855398"));
}
c.Add(Button("kryCrafts.price.bg.back", "kryCrafts.price.bg", $"UI_BackToChoice {index}", "0 0 0 0", "0 0", HaveItemsToCraft(index, p) == null ? "0.5 0.0855398" : "1 0.0855398"));
double AnMinX = defaultMinX;
// 0.2724359
double AnMaxX = defaultMaxX;
// 0.4871796
double AnMinY = 0.8431783;
// 0.6843186
double AnMaxY = 0.9816713;
// 0.8228115
for (int i = 0; i < items.Count();
i++) {
if (i % 5 == 0 && i > 0) {
AnMinY -= 0.1588597;
AnMaxY -= 0.1588598;
AnMinX = defaultMinX;
AnMaxX = defaultMaxX;
}
c.Add(Panel($"kryCrafts.price.bg.{i}", $"{AnMinX} {AnMinY}", $"{AnMaxX} {AnMaxY}", "kryCrafts.price.bg", (string)ImageLibrary.Call("GetImage", $"{items.Keys.ToList()[i]}"), false));
if (items.Values.ToList()[i] > 1) {
c.Add(Text($"kryCrafts.price.bg.{i}.count", $"kryCrafts.price.bg.{i}", "0 0 0 0.7", $"{items.Values.ToList()[i]}", TextAnchor.LowerRight, 12, "0 0", "0.9552216 0.3970594", 0f, 0f));
}
AnMinX += 0.24679519;
AnMaxX += 0.24679520;
}
CuiHelper.AddUi(p, c);
}
void UI_UnloadAllUIs(BasePlayer p) {
CuiHelper.DestroyUi(p, "kryCrafts.bg");
CuiHelper.DestroyUi(p, "kryCrafts.price.bg");
}
#endregion
#region Commands
[ConsoleCommand("craftitem")]
void cmd_craftitem(ConsoleSystem.Arg arg) {
if (arg.Args.Count() < 2) {
return;
}
var index = cfg.CraftPrice.Keys.ToList().IndexOf(arg.Args[1]);
var p = arg.Player();
switch(arg.Args[0]) {
case "craft" : CraftItem((short)index, p);
break;
case "price" : UI_FocusItem(p, arg.Args.ToList());
break;
default : return;
}
}
[ConsoleCommand("UI_BackToChoice")]
void cmd_BackToChoice(ConsoleSystem.Arg arg) {
if (!OpenedUIs.Contains(arg.Player().userID)) {
return;
}
CuiHelper.DestroyUi(arg.Player(), "kryCrafts.price.bg");
UI_DrawMain(arg.Player());
}
[ChatCommand ("craft")]
void cmd_Craft (BasePlayer p) {
if (!pages.ContainsKey (p.userID)) {
pages.Add (p.userID, 0);
}
if (OpenedUIs.Contains(p.userID)) {
return;
}
UI_DrawMain (p);
}
[ConsoleCommand ("UI_BackPage")]
void cmd_backPage (ConsoleSystem.Arg arg) {
var p = arg?.Player ();
if (!OpenedUIs.Contains (p.userID)) {
return;
}
int pagecur = pages.GetValueOrDefault(p.userID);
int page = pages.GetValueOrDefault (p.userID) - 1;
if (page < 0) {
page = 0;
}
int j = pagecur * 5;
for (int i = pagecur * 5; i < j + 5; i++) {
CuiHelper.DestroyUi (p, $"kryCrafts.bg.{i}");
}
pages[p.userID] = (short) page;
UI_RefreshItems (p, (short) page);
}
[ConsoleCommand ("UI_NextPage")]
void UI_Next_Page (ConsoleSystem.Arg arg) {
var p = arg?.Player ();
if (!OpenedUIs.Contains (p.userID)) {
return;
}
int pagecur = pages.GetValueOrDefault(p.userID);
int page = pages.GetValueOrDefault (p.userID) + 1;
if (page > AllPages ()) {
page--;
}
int j = pagecur * 5;
for (int i = pagecur * 5; i < j + 5; i++) {
CuiHelper.DestroyUi (p, $"kryCrafts.bg.{i}");
}
pages[p.userID] = (short) page;
UI_RefreshItems (p, (short) page);
}
[ConsoleCommand ("UI_CloseCraft")]
void cmd_CloseCraft (ConsoleSystem.Arg arg) {
var p = arg.Player ();
CuiHelper.DestroyUi(p, "kryCrafts.bg");
OpenedUIs.Remove (p.userID);
}
[ConsoleCommand("UI_FocusItem")]
void cmd_FocusItem(ConsoleSystem.Arg arg) {
var p = arg.Player();
if (!OpenedUIs.Contains(p.userID)) {
return;
}
if (arg.Args?.Count() <= 0) {
return;
}
CuiHelper.DestroyUi(p, "kryCrafts.bg");
short page = pages.GetValueOrDefault (p.userID);
UI_FocusItem(p, arg.Args.ToList());
}
#endregion
}
}