C#:
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using Facepunch;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using Oxide.Core;
using Oxide.Core.Libraries.Covalence;
using Oxide.Core.Plugins;
using Oxide.Game.Rust.Cui;
using Rust;
using UnityEngine;
using VLB;
using WebSocketSharp;
using Random = UnityEngine.Random;
namespace Oxide.Plugins {
[Info("Crafts", "Mevent", "1.11.0")]
public class Crafts : RustPlugin {
//TODO: Добавить время крафта
#region Fields
[PluginReference]
private Plugin ImageLibrary;
private const string Layer = "UI.Crafts";
private static Crafts _instance;
private readonly List<int> _blockedLayers = new List<int> {
(int) Rust.Layer.Water, (int) Rust.Layer.Construction, (int) Rust.Layer.Trigger, (int) Rust.Layer.Prevent_Building, (int) Rust.Layer.Deployed, (int) Rust.Layer.Tree
}
;
private enum WorkbenchLevel {
None = 0, One = 1, Two = 2, Three = 3
}
private enum CraftType {
Команда, Транспорт, Предмет, Переработчик
}
#endregion
#region Config
private static Configuration _config;
private class Configuration {
[JsonProperty(PropertyName = "Цвет кнопки когда все предметы присутствуют")]
public string GreenColor = "#80FF8080";
[JsonProperty(PropertyName = "Комманда меню крафта")]
public string Command = "craft";
[JsonProperty(PropertyName = "Включить дебаг?")]
public bool useDebug = true;
[JsonProperty(PropertyName = "Настройка цветов верстаков", ObjectCreationHandling = ObjectCreationHandling.Replace)]
public Dictionary<WorkbenchLevel, WorkbenchConfig> Workbenchs = new Dictionary<WorkbenchLevel, WorkbenchConfig> {
[WorkbenchLevel.None]
= new WorkbenchConfig("#00000080", "Верстак не требуется"), [WorkbenchLevel.One] = new WorkbenchConfig("#80400080", "Верстак 1 уровня"), [WorkbenchLevel.Two] = new WorkbenchConfig("#0080FF80", "Верстак 2 уровня"), [WorkbenchLevel.Three] = new WorkbenchConfig("#FF000080", "Верстак 3 уровня")
}
;
[JsonProperty(PropertyName = "Настройка крафтов", ObjectCreationHandling = ObjectCreationHandling.Replace)]
public List<CraftConfig> CraftsList = new List<CraftConfig> {
new CraftConfig {
Enabled = true, ImageURL = "https://i.imgur.com/YXjADeE.png", Description = new List<string> {
"Для создания требуется:", "- Шестерни (5 шт)", "- Дорожные знаки (5 шт)", "- Металл (2000 шт)"
}
, Command = "givecopter", Permission = "crafts.all", DisplayName = "Миникоптер", ShortName = "electric.flasherlight", SkinID = 2080145158, Type = CraftType.Транспорт, Prefab = "assets/content/vehicles/minicopter/minicopter.entity.prefab", Level = WorkbenchLevel.One, UseDistance = true, Distance = 1.5f, GiveCommand = string.Empty, Ground = true, Structure = true, Items = new List<ItemForCraft> {
new ItemForCraft("gears", 5, 0), new ItemForCraft("roadsigns", 5, 0), new ItemForCraft("metal.fragments", 2000, 0)
}
}
, new CraftConfig {
Enabled = true, ImageURL = "https://i.imgur.com/dmWQOm6.png", Description = new List<string> {
"Для создания требуется:", "- Шестерни (5 шт)", "- Дорожные знаки (5 шт)", "- Металл (2000 шт)"
}
, Command = "giverowboat", Permission = "crafts.all", DisplayName = "Деревянная лодка", ShortName = "coffin.storage", SkinID = 2080150023, Type = CraftType.Транспорт, Prefab = "assets/content/vehicles/boats/rowboat/rowboat.prefab", Level = WorkbenchLevel.Two, UseDistance = true, Distance = 1.5f, GiveCommand = string.Empty, Ground = true, Structure = true, Items = new List<ItemForCraft> {
new ItemForCraft("gears", 5, 0), new ItemForCraft("roadsigns", 5, 0), new ItemForCraft("metal.fragments", 2000, 0)
}
}
, new CraftConfig {
Enabled = true, ImageURL = "https://i.imgur.com/CgpVw2j.png", Description = new List<string> {
"Для создания требуется:", "- Шестерни (5 шт)", "- Дорожные знаки (5 шт)", "- Металл (2000 шт)"
}
, Command = "giverhibboat", Permission = "crafts.all", DisplayName = "Военная лодка", ShortName = "electric.sirenlight", SkinID = 2080150770, Type = CraftType.Транспорт, GiveCommand = string.Empty, Prefab = "assets/content/vehicles/boats/rhib/rhib.prefab", Level = WorkbenchLevel.Three, UseDistance = true, Distance = 1.5f, Ground = true, Structure = true, Items = new List<ItemForCraft> {
new ItemForCraft("gears", 5, 0), new ItemForCraft("roadsigns", 5, 0), new ItemForCraft("metal.fragments", 2000, 0)
}
}
, new CraftConfig {
Enabled = true, ImageURL = "https://i.imgur.com/eioxlvK.png", Description = new List<string> {
"Для создания требуется:", "- Шестерни (5 шт)", "- Дорожные знаки (5 шт)", "- Металл (2000 шт)"
}
, Command = "givesedan", Permission = "crafts.all", DisplayName = "Машина", ShortName = "woodcross", SkinID = 2080151780, Type = CraftType.Транспорт, GiveCommand = string.Empty, Prefab = "assets/content/vehicles/sedan_a/sedantest.entity.prefab", Level = WorkbenchLevel.Two, UseDistance = true, Distance = 1.5f, Ground = true, Structure = true, Items = new List<ItemForCraft> {
new ItemForCraft("gears", 5, 0), new ItemForCraft("roadsigns", 5, 0), new ItemForCraft("metal.fragments", 2000, 0)
}
}
, new CraftConfig {
Enabled = true, ImageURL = "https://i.imgur.com/cp2Xx2A.png", Description = new List<string> {
"Для создания требуется:", "- Шестерни (5 шт)", "- Дорожные знаки (5 шт)", "- Металл (2000 шт)"
}
, Command = "givehotair", Permission = "crafts.all", DisplayName = "Воздушный шар", ShortName = "box.repair.bench", SkinID = 2080152635, Type = CraftType.Транспорт, GiveCommand = string.Empty, Prefab = "assets/prefabs/deployable/hot air balloon/hotairballoon.prefab", Level = WorkbenchLevel.Three, UseDistance = true, Distance = 1.5f, Ground = true, Structure = true, Items = new List<ItemForCraft> {
new ItemForCraft("gears", 5, 0), new ItemForCraft("roadsigns", 5, 0), new ItemForCraft("metal.fragments", 2000, 0)
}
}
, new CraftConfig {
Enabled = true, ImageURL = "https://i.imgur.com/7JZE0Lr.png", Description = new List<string> {
"Для создания требуется:", "- Шестерни (5 шт)", "- Дорожные знаки (5 шт)", "- Металл (2000 шт)"
}
, Command = "givescrapheli", Permission = "crafts.all", DisplayName = "Грузовой вертолёт", ShortName = "lantern", SkinID = 2080154394, Type = CraftType.Транспорт, GiveCommand = string.Empty, Prefab = "assets/content/vehicles/scrap heli carrier/scraptransporthelicopter.prefab", Level = WorkbenchLevel.Three, UseDistance = true, Distance = 1.5f, Ground = true, Structure = true, Items = new List<ItemForCraft> {
new ItemForCraft("gears", 5, 0), new ItemForCraft("roadsigns", 5, 0), new ItemForCraft("metal.fragments", 2000, 0)
}
}
, new CraftConfig {
Enabled = true, ImageURL = "https://i.imgur.com/LLB2AVi.png", Description = new List<string> {
"Для создания требуется:", "- Шестерни (5 шт)", "- Дорожные знаки (5 шт)", "- Металл (2000 шт)"
}
, Command = "giverecycler", Permission = "crafts.all", DisplayName = "Домашний Переработчик", ShortName = "research.table", SkinID = 2186833264, Type = CraftType.Переработчик, Prefab = "assets/bundled/prefabs/static/recycler_static.prefab", GiveCommand = string.Empty, Level = WorkbenchLevel.Two, UseDistance = true, Distance = 1.5f, Ground = true, Structure = true, Items = new List<ItemForCraft> {
new ItemForCraft("gears", 5, 0), new ItemForCraft("roadsigns", 5, 0), new ItemForCraft("metal.fragments", 2000, 0)
}
}
, new CraftConfig {
Enabled = true, ImageURL = "https://i.imgur.com/mw1T17x.png", Description = new List<string> {
"Для создания требуется:", "- Шестерни (5 шт)", "- Дорожные знаки (5 шт)", "- Металл (2000 шт)"
}
, Command = "givelr300", Permission = "crafts.all", DisplayName = string.Empty, ShortName = "rifle.lr300", SkinID = 0, Type = CraftType.Предмет, Prefab = string.Empty, GiveCommand = string.Empty, Level = WorkbenchLevel.None, UseDistance = true, Distance = 1.5f, Ground = true, Structure = true, Items = new List<ItemForCraft> {
new ItemForCraft("gears", 5, 0), new ItemForCraft("roadsigns", 5, 0), new ItemForCraft("metal.fragments", 2000, 0)
}
}
}
;
[JsonProperty(PropertyName = "Настройка переработчика")]
public RecyclerConfig Recycler = new RecyclerConfig {
Speed = 5f, Radius = 7.5f, Text = "<size=19>ПЕРЕРАБОТЧИК</size>\n<size=15>{0}/{1}</size>", Color = "#C5D0E6", Delay = 0.75f, Available = true, Owner = true, Amounts = new[] {
0.9f, 0, 0, 0, 0, 0.5f, 0, 0, 0, 0.9f, 0.5f, 0.5f, 0, 1, 1, 0.5f, 0, 0, 0, 0, 0, 1, 1
}
, Scale = 0.5f, DDraw = true, Building = true
}
;
[JsonProperty(PropertyName = "Настройка машины")]
public CarConfig Car = new CarConfig {
ActiveItems = new ActiveItemOptions {
Disable = true, BlackList = new[] {
"explosive.timed", "rocket.launcher", "surveycharge", "explosive.satchel"
}
}
, Radius = 7.5f, Text = "<size=15>{0}/{1}</size>", Color = "#C5D0E6", Delay = 0.75f,
}
;
}
private class CarConfig {
[JsonProperty(PropertyName = "Активные предметы (которые в руки)")]
public ActiveItemOptions ActiveItems;
[JsonProperty(PropertyName = "Радиус в котором будет показан текст на машине")]
public float Radius;
[JsonProperty(PropertyName = "Текст на машине")]
public string Text;
[JsonProperty(PropertyName = "Цвет текста на машине")]
public string Color;
[JsonProperty(PropertyName = "Время показа текста на машине (сек)")]
public float Delay;
}
public class ActiveItemOptions {
[JsonProperty(PropertyName = "Запретить держать все предметы")]
public bool Disable;
[JsonProperty(PropertyName = "Список запрещённых к держанию предметов (shortname)", ObjectCreationHandling = ObjectCreationHandling.Replace)]
public string[] BlackList;
}
private class RecyclerConfig {
[JsonProperty(PropertyName = "Скорость переработки")]
public float Speed;
[JsonProperty(PropertyName = "Радиус в котором будет показан текст на переработчике")]
public float Radius;
[JsonProperty(PropertyName = "Показывать дамаг на переработчике")]
public bool DDraw;
[JsonProperty(PropertyName = "Текст на переработчике")]
public string Text;
[JsonProperty(PropertyName = "Цвет текста на переработчике")]
public string Color;
[JsonProperty(PropertyName = "Время показа текста на переработчике (сек)")]
public float Delay;
[JsonProperty(PropertyName = "Можно ли подбирать переработчик")]
public bool Available;
[JsonProperty(PropertyName = "Подбор только владельцем?")]
public bool Owner;
[JsonProperty(PropertyName = "Право на постройку для подбора")]
public bool Building;
[JsonProperty(PropertyName = "Настройка BaseProtection", ObjectCreationHandling = ObjectCreationHandling.Replace)]
public float[] Amounts;
[JsonProperty(PropertyName = "Множитель урона по переработчику")]
public float Scale;
}
private class WorkbenchConfig {
[JsonProperty(PropertyName = "Цвет")]
public string Color;
[JsonProperty(PropertyName = "Надпись")]
public string Title;
public WorkbenchConfig(string color, string title) {
Color = color;
Title = title;
}
}
private class CraftConfig {
[JsonProperty(PropertyName = "Включить крафт?")]
public bool Enabled;
[JsonProperty(PropertyName = "Картинка")]
public string ImageURL;
[JsonProperty(PropertyName = "Описание")]
public List<string> Description;
[JsonProperty(PropertyName = "Команда для получения")]
public string Command;
[JsonProperty(PropertyName = "Право на крафт")]
public string Permission;
[JsonProperty(PropertyName = "Отображаемое имя заменяемого предмета")]
public string DisplayName;
[JsonProperty(PropertyName = "Shortname заменяемого предмета")]
public string ShortName;
[JsonProperty(PropertyName = "Скин заменяемого предмета")]
public ulong SkinID;
[JsonProperty(PropertyName = "Тип предмета (Предмет/Команда/Транспорт)")]
[JsonConverter(typeof(StringEnumConverter))]
public CraftType Type;
[JsonProperty(PropertyName = "Префаб (для транспорта)")]
public string Prefab;
[JsonProperty(PropertyName = "Команда при получении")]
public string GiveCommand;
[JsonProperty(PropertyName = "Уровень верстака")]
public WorkbenchLevel Level;
[JsonProperty(PropertyName = "Включить проверку на дистанцию?")]
public bool UseDistance;
[JsonProperty(PropertyName = "Дистанция")]
public float Distance;
[JsonProperty(PropertyName = "Установка на землю")]
public bool Ground;
[JsonProperty(PropertyName = "Установка на строения")]
public bool Structure;
[JsonProperty(PropertyName = "Настройка предметов для крафта", ObjectCreationHandling = ObjectCreationHandling.Replace)]
public List<ItemForCraft> Items;
public Item ToItem() {
var newItem = ItemManager.CreateByName(ShortName, 1, SkinID);
if (newItem == null) {
Debug.LogError($"Error creating item with ShortName: '{ShortName}'");
return null;
}
if (!DisplayName.IsNullOrEmpty()) newItem.name = DisplayName;
return newItem;
}
public void Give(BasePlayer player) {
if (player == null) return;
var item = ToItem();
if (item == null) return;
player.GiveItem(item, BaseEntity.GiveItemReason.PickedUp);
}
}
private class ItemForCraft {
[JsonProperty(PropertyName = "Shortname")]
public string ShortName;
[JsonProperty(PropertyName = "Количество")]
public int Amount;
[JsonProperty(PropertyName = "Скин")]
public ulong SkinID;
public ItemForCraft(string shortname, int amount, ulong skin) {
ShortName = shortname;
Amount = amount;
SkinID = skin;
}
}
protected override void LoadConfig() {
base.LoadConfig();
try {
_config = Config.ReadObject<Configuration>();
if (_config == null) throw new Exception();
SaveConfig();
}
catch {
PrintError("Your configuration file contains an error.Using default configuration values.");
LoadDefaultConfig();
}
}
protected override void SaveConfig() {
Config.WriteObject(_config);
}
protected override void LoadDefaultConfig() {
_config = new Configuration();
}
#endregion
#region Hooks
private void OnServerInitialized() {
_instance = this;
if (!ImageLibrary) PrintWarning("IMAGE LIBRARY IS NOT INSTALLED.");
foreach (var item in _config.CraftsList) {
if (!item.ImageURL.IsNullOrEmpty()) ImageLibrary?.Call("AddImage", item.ImageURL, item.ImageURL);
if (!item.Command.IsNullOrEmpty()) AddCovalenceCommand(item.Command, nameof(CmdGiveItem));
if (!item.Permission.IsNullOrEmpty() && !permission.PermissionExists(item.Permission)) permission.RegisterPermission(item.Permission, this);
}
foreach (var ent in BaseNetworkable.serverEntities) {
OnEntitySpawned(ent as BaseEntity);
}
cmd.AddChatCommand(_config.Command, this, nameof(CmdChatOpenUI));
}
private void Unload() {
foreach (var player in BasePlayer.activePlayerList) CuiHelper.DestroyUi(player, Layer);
foreach (var component in UnityEngine.Object.FindObjectsOfType<RecyclerComponent>()) if (component != null) component.Kill();
foreach (var component in UnityEngine.Object.FindObjectsOfType<CarController>()) if (component != null) component.Kill();
_config = null;
_instance = null;
}
private void OnEntityBuilt(Planner held, GameObject go) {
if (held == null || go == null) return;
var player = held.GetOwnerPlayer();
if (player == null) return;
var entity = go.ToBaseEntity();
if (entity == null || entity.skinID == 0) return;
var craft = _config.CraftsList.FirstOrDefault(x => (x.Type == CraftType.Транспорт || x.Type == CraftType.Переработчик) && x.SkinID == entity.skinID);
if (craft == null) return;
var transform = entity.transform;
var itemName = !string.IsNullOrEmpty(craft.DisplayName) ? craft.DisplayName : ItemManager.FindItemDefinition(craft.ShortName)?.displayName.translated ?? "ITEM";
NextTick(() => {
if (entity != null) entity.Kill();
}
);
RaycastHit rHit;
if (Physics.Raycast(transform.position + new Vector3(0, 0.1f, 0), Vector3.down, out rHit, 4f, LayerMask.GetMask("Construction")) && rHit.GetEntity() != null) {
if (!craft.Structure) {
Reply(player, OnStruct, itemName);
GiveCraft(player, craft);
return;
}
}
else {
if (!craft.Ground) {
Reply(player, OnGround, itemName);
GiveCraft(player, craft);
return;
}
}
SpawnVehicle(craft.Prefab, player.userID, craft.SkinID, transform.position, transform.rotation);
}
private object CanResearchItem(BasePlayer player, Item item) {
if (player == null || item == null || !_config.CraftsList.Exists(x => x.Type == CraftType.Транспорт && x.SkinID == item.skin)) return null;
return false;
}
private void OnEntitySpawned(BaseEntity entity) {
if (entity == null) return;
if (entity is Recycler) entity.gameObject.AddComponent<RecyclerComponent>();
if (entity is BasicCar) entity.gameObject.AddComponent<CarController>();
}
private void OnEntityTakeDamage(BaseCombatEntity entity, HitInfo info) {
if (entity == null || entity.OwnerID == 0) return;
var recycler = entity.GetComponent<RecyclerComponent>();
if (recycler != null) {
info.damageTypes.ScaleAll(_config.Recycler.Scale);
recycler.DDraw();
}
var car = entity.GetComponent<CarController>();
if (car != null) {
car.ManageDamage(info);
car.DDraw();
}
}
private object OnRecyclerToggle(Recycler recycler, BasePlayer player) {
if (recycler == null || player == null) return null;
var component = recycler.GetComponent<RecyclerComponent>();
if (component == null) return null;
if (!recycler.IsOn()) {
foreach (var obj in recycler.inventory.itemList) obj.CollectedForCrafting(player);
component.StartRecycling();
}
else {
component.StopRecycling();
}
return false;
}
private void OnHammerHit(BasePlayer player, HitInfo info) {
if (player == null || info == null) return;
var entity = info.HitEntity;
if (entity == null) return;
var component = entity.GetComponent<RecyclerComponent>();
if (component == null) return;
if (!_config.Recycler.Available) {
Reply(player, NotTake);
return;
}
component.TryPickup(player);
}
#endregion
#region Commands
[ConsoleCommand("UI_Crafts")]
private void CmdConsoleCraft(ConsoleSystem.Arg arg) {
var player = arg.Player();
if (player == null) return;
if (!arg.HasArgs()) {
DrawUI(player, isFirst : true);
return;
}
switch (arg.Args[0].ToLower()) {
case "page" : {
var page = 0;
if (!arg.HasArgs(2) || !int.TryParse(arg.Args[1], out page)) return;
DrawUI(player, page);
break;
}
case "craft" : {
int itemid;
if (!arg.HasArgs(2) || !int.TryParse(arg.Args[1], out itemid) || !(itemid >= 0 && _config.CraftsList.Count > itemid)) return;
var craftItem = _config.CraftsList[itemid];
if (craftItem == null) return;
if (!HasWorkbench(player, craftItem.Level)) {
Reply(player, "NOT WORKBENCH");
return;
}
var playerItems = player.inventory.AllItems();
if (!HasAllItems(playerItems, craftItem)) {
Reply(player, "NOT.RESOURCES");
return;
}
for (var i = 0; i < craftItem.Items.Count; i++) {
var item = craftItem.Items[i];
if (item == null) continue;
Take(playerItems, item.ShortName, item.SkinID, item.Amount);
}
GiveCraft(player, craftItem);
//CraftItem(player, craftItem);
Reply(player, "GIVED CRAFT", !string.IsNullOrEmpty(craftItem.DisplayName) ? craftItem.DisplayName : ItemManager.FindItemDefinition(craftItem.ShortName).displayName.translated);
break;
}
}
}
private void CmdGiveItem(IPlayer iPlayer, string cmd, string[] args) {
if (args.Length == 0) return;
var player = BasePlayer.Find(args[0]);
if (player == null) {
Reply(iPlayer, "PLAYER NOT FOUND", args[0]);
return;
}
var craftItem = _config.CraftsList.FirstOrDefault(x => x.Command == cmd);
if (craftItem == null) {
iPlayer.Reply("COMMAND NOT FOUND", cmd);
return;
}
var item = craftItem.ToItem();
if (item == null) return;
var itemName = !string.IsNullOrEmpty(craftItem.DisplayName) ? craftItem.DisplayName : item.info.displayName.translated;
player.GiveItem(item, BaseEntity.GiveItemReason.PickedUp);
Reply(player, "GIVED CRAFT", itemName);
if (_config.useDebug) Reply(iPlayer, "GIVE.DEBUG", player.displayName, player.UserIDString, itemName);
}
private void CmdChatOpenUI(BasePlayer player, string cmd, string[] args) {
DrawUI(player, isFirst : true);
}
#endregion
#region Interface
private void DrawUI(BasePlayer player, int page = 0, bool isFirst = false) {
var container = new CuiElementContainer();
var playerItems = player.inventory.AllItems();
#region First
if (isFirst) {
CuiHelper.DestroyUi(player, Layer);
#region BG
container.Add(new CuiPanel {
RectTransform = {
AnchorMin = "0 0", AnchorMax = "1 1"
}
, Image = {
Color = "0.1 0.1 0.05 0.75", Sprite = "assets/content/ui/ui.background.transparent.radial.psd", Material = "assets/content/ui/uibackgroundblur-ingamemenu.mat"
}
, CursorEnabled = true
}
, "Overlay", Layer);
#endregion
#region Title
container.Add(new CuiLabel {
RectTransform = {
AnchorMin = "0.5 0.5", AnchorMax = "0.5 0.5", OffsetMin = "-200 200", OffsetMax = "200 300"
}
, Text = {
Text = lang.GetMessage("Title", this, player.UserIDString), Align = TextAnchor.MiddleCenter, FontSize = 28
}
}
, Layer);
#endregion
}
#endregion
#region Main
container.Add(new CuiPanel {
RectTransform = {
AnchorMin = "0 0", AnchorMax = "1 1"
}
, Image = {
Color = "0 0 0 0"
}
}
, Layer, Layer + ".Main");
container.Add(new CuiButton {
RectTransform = {
AnchorMin = "1 1", AnchorMax = "1 1", OffsetMin = "-45 -45", OffsetMax = "-5 -5"
}
, Text = {
Text = "✕", Align = TextAnchor.MiddleCenter, FontSize = 28, Color = "1 1 1 1"
}
, Button = {
Color = "0 0 0 0", Close = Layer
}
}
, Layer + ".Main");
#region Items
var list = GetPlayerCrafts(player, page);
if (list.Count > 0) {
var xSwitch = -(220 * list.Count + 40 * (list.Count - 1)) / 2;
for (var i = 0; i < list.Count; i++) {
var craft = list[i];
container.Add(new CuiPanel {
RectTransform = {
AnchorMin = "0.5 0.5", AnchorMax = "0.5 0.5", OffsetMin = $"{xSwitch} -100", OffsetMax = $"{xSwitch + 220} 200"
}
, Image = {
Color = "0 0 0 0.5", Material = "assets/content/ui/uibackgroundblur-ingamemenu.mat"
}
}
, Layer + ".Main", Layer + $".Craft.{xSwitch}");
container.Add(new CuiElement {
Parent = Layer + $".Craft.{xSwitch}", Components = {
new CuiRawImageComponent {
Png = ImageLibrary.Call<string>("GetImage", craft.ImageURL)
}
, new CuiRectTransformComponent {
AnchorMin = "0.5 0.5", AnchorMax = "0.5 0.5", OffsetMin = "-70 0", OffsetMax = "70 140"
}
}
}
);
container.Add(new CuiPanel {
RectTransform = {
AnchorMin = "0.5 0.5", AnchorMax = "0.5 0.5", OffsetMin = "-85 -10", OffsetMax = "85 -5"
}
, Image = {
Color = "1 1 1 1", Sprite = "assets/content/ui/gameui/compass/alpha_mask.png"
}
}
, Layer + $".Craft.{xSwitch}");
container.Add(new CuiLabel {
RectTransform = {
AnchorMin = "0 0.5", AnchorMax = "1 0.5", OffsetMin = "0 -130", OffsetMax = "0 -25"
}
, Text = {
Text = string.Join("\n", craft.Description), Align = TextAnchor.UpperCenter, FontSize = 14
}
}
, Layer + $".Craft.{xSwitch}");
container.Add(new CuiPanel {
RectTransform = {
AnchorMin = "0 0", AnchorMax = "1 0", OffsetMin = "0 -50", OffsetMax = "0 -5"
}
, Image = {
Color = HexToCuiColor(_config.Workbenchs[craft.Level].Color), Material = "assets/content/ui/uibackgroundblur-ingamemenu.mat"
}
}
, Layer + $".Craft.{xSwitch}", Layer + $".Craft.{xSwitch}.Workbench");
container.Add(new CuiLabel {
RectTransform = {
AnchorMin = "0 0", AnchorMax = "1 1"
}
, Text = {
Text = _config.Workbenchs[craft.Level].Title, Align = TextAnchor.MiddleCenter, FontSize = 14
}
}
, Layer + $".Craft.{xSwitch}.Workbench");
var active = HasAllItems(playerItems, craft) && HasWorkbench(player, craft.Level);
container.Add(new CuiButton {
RectTransform = {
AnchorMin = "0 0", AnchorMax = "1 0", OffsetMin = "0 -105", OffsetMax = "0 -55"
}
, Button = {
Command = active ? $"UI_Crafts craft {_config.CraftsList.IndexOf(craft)}" : "", Color = active ? HexToCuiColor(_config.GreenColor) : "0 0 0 0.5", Material = "assets/content/ui/uibackgroundblur-ingamemenu.mat", Close = active ? Layer : ""
}
, Text = {
Text = lang.GetMessage("CREATE", this, player.UserIDString), Align = TextAnchor.MiddleCenter, FontSize = 24
}
}
, Layer + $".Craft.{xSwitch}");
xSwitch += 260;
}
}
else {
container.Add(new CuiLabel {
RectTransform = {
AnchorMin = "0.5 0.5", AnchorMax = "0.5 0.5", OffsetMin = "-250 -150", OffsetMax = "250 150"
}
, Text = {
Text = lang.GetMessage("NOT CRAFTS", this, player.UserIDString), Align = TextAnchor.MiddleCenter, FontSize = 34
}
}
, Layer + ".Main");
}
#endregion
#region Pages
if (list.Count > 0) {
container.Add(new CuiButton {
RectTransform = {
AnchorMin = "0 0.5", AnchorMax = "0 0.5", OffsetMin = "5 -25", OffsetMax = "55 25"
}
, Button = {
Command = page > 0 ? $"UI_Crafts page {page - 1}" : "", Color = "0 0 0 0"
}
, Text = {
Text = "<", Align = TextAnchor.MiddleCenter, FontSize = 40, Color = page > 0 ? "1 1 1 1" : "1 1 1 0.5"
}
}
, Layer + ".Main");
var count = _config.CraftsList.Count(craft => craft.Enabled && (string.IsNullOrEmpty(craft.Permission) || permission.UserHasPermission(player.UserIDString, craft.Permission)));
container.Add(new CuiButton {
RectTransform = {
AnchorMin = "1 0.5", AnchorMax = "1 0.5", OffsetMin = "-55 -25", OffsetMax = "-5 25"
}
, Button = {
Command = count > (page + 1) * 3 ? $"UI_Crafts page {page + 1}" : "", Color = "0 0 0 0"
}
, Text = {
Text = ">", Align = TextAnchor.MiddleCenter, FontSize = 40, Color = count > (page + 1) * 3 ? "1 1 1 1" : "1 1 1 0.5"
}
}
, Layer + ".Main");
}
#endregion
#endregion
CuiHelper.DestroyUi(player, Layer + ".Main");
CuiHelper.AddUi(player, container);
}
#endregion
#region Utils
private void GiveCraft(BasePlayer player, CraftConfig cfg) {
switch (cfg.Type) {
case CraftType.Команда : {
var command = cfg.GiveCommand.Replace("\n", "|").Replace("%steamid%", player.UserIDString, StringComparison.OrdinalIgnoreCase).Replace("%username%", player.displayName, StringComparison.OrdinalIgnoreCase);
foreach (var check in command.Split('|')) Server.Command(check);
break;
}
default : {
cfg.Give(player);
break;
}
}
}
private void CraftItem(BasePlayer player, CraftConfig item) {
var defenition = ItemManager.FindItemDefinition(item.ShortName);
var task = Pool.Get<ItemCraftTask>();
task.blueprint = defenition.Blueprint;
task.endTime = 0.0f;
task.taskUID = player.inventory.crafting.taskUID + 1;
task.owner = player;
task.instanceData = null;
if (task.instanceData != null) task.instanceData.ShouldPool = false;
task.amount = 1;
task.skinID = (int) item.SkinID;
player.inventory.crafting.queue.AddLast(task);
if (task.owner != null) task.owner.Command("note.craft_add", (object) task.taskUID, (object) task.blueprint.targetItem.itemid, (object) 1, (object) task.skinID);
}
private static bool HasWorkbench(BasePlayer player, WorkbenchLevel level) {
return level == WorkbenchLevel.Three ? player.HasPlayerFlag(BasePlayer.PlayerFlags.Workbench3) : level == WorkbenchLevel.Two ? player.HasPlayerFlag(BasePlayer.PlayerFlags.Workbench3) || player.HasPlayerFlag(BasePlayer.PlayerFlags.Workbench2) : level == WorkbenchLevel.One ? player.HasPlayerFlag(BasePlayer.PlayerFlags.Workbench3) || player.HasPlayerFlag(BasePlayer.PlayerFlags.Workbench2) || player.HasPlayerFlag(BasePlayer.PlayerFlags.Workbench1) : level == WorkbenchLevel.None;
}
private static bool HasAllItems(IReadOnlyList<Item> items, CraftConfig craftConfig) {
for (var i = 0; i < craftConfig.Items.Count; i++) {
var itemForCraft = craftConfig.Items[i];
if (ItemCount(items, itemForCraft.ShortName, itemForCraft.SkinID) < itemForCraft.Amount) return false;
}
return true;
}
private static int ItemCount(IReadOnlyList<Item> items, string shortname, ulong skin) {
var result = 0;
for (var i = 0; i < items.Count; i++) {
var item = items[i];
if (item.info.shortname == shortname && (skin == 0 || item.skin == skin)) result += item.amount;
}
return result;
}
private void Take(IEnumerable<Item> itemList, string shortname, ulong skinId, int iAmount) {
var num1 = 0;
if (iAmount == 0) return;
var list = Pool.GetList<Item>();
foreach (var item in itemList) {
if (item.info.shortname != shortname || skinId != 0 && item.skin != skinId) continue;
var num2 = iAmount - num1;
if (num2 <= 0) continue;
if (item.amount > num2) {
item.MarkDirty();
item.amount -= num2;
num1 += num2;
break;
}
if (item.amount <= num2) {
num1 += item.amount;
list.Add(item);
}
if (num1 == iAmount) break;
}
foreach (var obj in list) obj.RemoveFromContainer();
Pool.FreeList(ref list);
}
private void SpawnVehicle(string prefab, ulong owner, ulong skin, Vector3 position, Quaternion rotation) {
var entity = GameManager.server.CreateEntity(prefab, position, rotation);
if (entity == null) return;
entity.skinID = skin;
entity.OwnerID = owner;
entity.Spawn();
}
private static string HexToCuiColor(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);
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}";
}
private List<CraftConfig> GetPlayerCrafts(BasePlayer player, int page, int count = 3) {
var result = new List<CraftConfig>();
var skipCount = page * count;
for (var i = 0; i < _config.CraftsList.Count; i++) {
var craft = _config.CraftsList[i];
if (i < skipCount) continue;
if (craft.Enabled && (string.IsNullOrEmpty(craft.Permission) || permission.UserHasPermission(player.UserIDString, craft.Permission))) result.Add(craft);
if (result.Count >= count) break;
}
return result;
}
private static Color HexToUnityColor(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);
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;
}
private static void SetPlayerFlag(BasePlayer player, BasePlayer.PlayerFlags f, bool b) {
if (b) {
if (player.HasPlayerFlag(f)) return;
player.playerFlags |= f;
}
else {
if (!player.HasPlayerFlag(f)) return;
player.playerFlags &= ~f;
}
player.SendNetworkUpdateImmediate();
}
#endregion
#region Recycler Component
private class RecyclerComponent : FacepunchBehaviour {
private Recycler recycler;
private GroundWatch groundWatch;
private DestroyOnGroundMissing groundMissing;
[NonSerialized]
private readonly BaseEntity[] SensesResults = new BaseEntity[64];
private void Awake() {
recycler = GetComponent<Recycler>();
if (recycler.OwnerID != 0) {
recycler.baseProtection = ScriptableObject.CreateInstance<ProtectionProperties>();
recycler.baseProtection.amounts = _config.Recycler.Amounts;
groundWatch = recycler.GetOrAddComponent<GroundWatch>();
groundMissing = recycler.GetOrAddComponent<DestroyOnGroundMissing>();
}
}
public void DDraw() {
if (recycler == null) {
Kill();
return;
}
if (recycler.OwnerID == 0 || !_config.Recycler.DDraw) return;
var inSphere = BaseEntity.Query.Server.GetInSphere(recycler.transform.position, _config.Recycler.Radius, SensesResults, entity => entity is BasePlayer);
if (inSphere == 0) return;
for (var i = 0; i < inSphere; i++) {
var user = SensesResults[i] as BasePlayer;
if (user == null || user.IsDestroyed || !user.IsConnected || user.IsNpc || !user.userID.IsSteamId()) continue;
if (user.Connection.authLevel < 2) SetPlayerFlag(user, BasePlayer.PlayerFlags.IsAdmin, true);
user.SendConsoleCommand("ddraw.text", _config.Recycler.Delay, HexToUnityColor(_config.Recycler.Color), recycler.transform.position + new Vector3(0.25f, 1, 0), string.Format(_config.Recycler.Text, recycler.health, recycler._maxHealth));
if (user.Connection.authLevel < 2) SetPlayerFlag(user, BasePlayer.PlayerFlags.IsAdmin, false);
}
}
#region Methods
public void StartRecycling() {
if (recycler.IsOn()) return;
InvokeRepeating(RecycleThink, _config.Recycler.Speed, _config.Recycler.Speed);
Effect.server.Run(recycler.startSound.resourcePath, recycler, 0U, Vector3.zero, Vector3.zero);
recycler.SetFlag(BaseEntity.Flags.On, true);
recycler.SendNetworkUpdateImmediate();
}
public void StopRecycling() {
CancelInvoke(RecycleThink);
if (!recycler.IsOn()) return;
Effect.server.Run(recycler.stopSound.resourcePath, recycler, 0U, Vector3.zero, Vector3.zero);
recycler.SetFlag(BaseEntity.Flags.On, false
// ... [Code preview truncated due to length. Full source in attached file] ...