C#:
// Все права принадлежат дискорд сообществу https://discord.gg/VgNHPpNrz6
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Globalization;
using Newtonsoft.Json;
using Oxide.Game.Rust.Cui;
using UnityEngine;
namespace Oxide.Plugins
{
[Info("Research Unlocked", "MJSU", "1.0.2")]
[Description("Displays a ui if you have already unlocked the item placed in a research table")]
public class ResearchUnlocked : RustPlugin
{
#region Class Fields
private PluginConfig _pluginConfig; //Plugin Config
private const string UsePermission = "researchunlocked.use";
private readonly Hash<ResearchTable, List<BasePlayer>> _lootingPlayers = new Hash<ResearchTable, List<BasePlayer>>();
private string _notLearnedColor;
private string _learnedColor;
#endregion
#region Setup & Loading
private void Init()
{
permission.RegisterPermission(UsePermission, this);
Unsubscribe(nameof(OnItemAddedToContainer));
}
protected override void LoadDefaultMessages()
{
lang.RegisterMessages(new Dictionary<string, string>
{
[LangKeys.AlreadyLearned] = "Already Learned",
[LangKeys.NotLearned] = "Not Learned"
}, this);
}
protected override void LoadDefaultConfig()
{
PrintWarning("Loading Default Config");
}
protected override void LoadConfig()
{
base.LoadConfig();
Config.Settings.DefaultValueHandling = DefaultValueHandling.Populate;
_pluginConfig = AdditionalConfig(Config.ReadObject<PluginConfig>());
Config.WriteObject(_pluginConfig);
}
private PluginConfig AdditionalConfig(PluginConfig config)
{
config.Pos = config.Pos ?? new UiPosition(0.86525f, 0.8025f, 0.86525f + 0.08f, 0.8025f + 0.03f);
return config;
}
private void OnServerInitialized()
{
_notLearnedColor = Ui.Color(_pluginConfig.NotLearnedColor);
_learnedColor = Ui.Color(_pluginConfig.LearnedColor);
Subscribe(nameof(OnItemAddedToContainer));
foreach (BasePlayer player in BasePlayer.activePlayerList)
{
ResearchTable table = player.inventory.loot.entitySource as ResearchTable;
if (table != null)
{
OnLootEntity(player, table);
}
}
}
private void Unload()
{
foreach (BasePlayer player in BasePlayer.activePlayerList)
{
DestroyAllUi(player);
}
}
#endregion
#region uMod Hooks
private void OnLootEntity(BasePlayer player, ResearchTable table)
{
if (!HasPermission(player, UsePermission) && !player.IsAdmin)
{
return;
}
if (!_lootingPlayers.ContainsKey(table))
{
_lootingPlayers[table] = new List<BasePlayer>();
}
_lootingPlayers[table].Add(player);
Item item = table.GetTargetItem();
if (item == null)
{
return;
}
if (!table.IsItemResearchable(item))
{
return;
}
CreateUnlockedUi(player, player.blueprints.HasUnlocked(item.info));
}
private void OnLootEntityEnd(BasePlayer player, ResearchTable table)
{
if (!_lootingPlayers.ContainsKey(table))
{
return;
}
_lootingPlayers[table].RemoveAll(p => p.userID == player.userID);
if (_lootingPlayers[table].Count == 0)
{
_lootingPlayers.Remove(table);
}
DestroyAllUi(player);
}
private void OnItemAddedToContainer(ItemContainer container, Item item)
{
NextTick(() =>
{
if (item.position != 0)
{
return;
}
ResearchTable table = container.entityOwner as ResearchTable;
if (table == null)
{
return;
}
if (!_lootingPlayers.ContainsKey(table))
{
return;
}
if (!table.IsItemResearchable(item))
{
foreach (BasePlayer player in _lootingPlayers[table])
{
DestroyAllUi(player);
}
return;
}
foreach (BasePlayer player in _lootingPlayers[table])
{
CreateUnlockedUi(player, player.blueprints.HasUnlocked(item.info));
}
});
}
private void OnItemRemovedFromContainer(ItemContainer container, Item item)
{
NextTick(() =>
{
ResearchTable table = container.entityOwner as ResearchTable;
if (table == null)
{
return;
}
if (!_lootingPlayers.ContainsKey(table))
{
return;
}
if (!table.IsItemResearchable(item))
{
return;
}
foreach (BasePlayer player in _lootingPlayers[table])
{
DestroyAllUi(player);
}
});
}
#endregion
#region Helpers
private bool HasPermission(BasePlayer player, string perm) => permission.UserHasPermission(player.UserIDString, perm);
private string Lang(string key, BasePlayer player = null, params object[] args)
{
try
{
return string.Format(lang.GetMessage(key, this, player?.UserIDString), args);
}
catch(Exception ex)
{
PrintError($"Lang Key '{key}' threw exception\n:{ex}");
throw;
}
}
#endregion
#region Classes
private class PluginConfig
{
[DefaultValue("##00CC00FF")]
[JsonProperty(PropertyName = "Learned Color")]
public string LearnedColor { get; set; }
[DefaultValue("#CC0000FF")]
[JsonProperty(PropertyName = "Not Learned Color")]
public string NotLearnedColor { get; set; }
[JsonProperty(PropertyName = "Ui Position")]
public UiPosition Pos { get; set; }
}
private class LangKeys
{
public const string AlreadyLearned = "AlreadyLearned";
public const string NotLearned = "NotLearned";
}
#endregion
#region UI
private const string UiPanelName = "ResearchUnlocked_UI";
private static class Ui
{
private static string UiPanel { get; set; }
public static CuiElementContainer Container(string color, UiPosition pos, bool useCursor, string panel, string parent = "Hud.Menu")
{
UiPanel = panel;
return new CuiElementContainer
{
{
new CuiPanel
{
Image = {Color = color},
RectTransform = {AnchorMin = pos.GetMin(), AnchorMax = pos.GetMax()},
CursorEnabled = useCursor
},
new CuiElement().Parent = parent,
panel
}
};
}
public static void Panel(ref CuiElementContainer container, string color, UiPosition pos, bool cursor = false)
{
container.Add(new CuiPanel
{
Image = { Color = color },
RectTransform = { AnchorMin = pos.GetMin(), AnchorMax = pos.GetMax() },
CursorEnabled = cursor
},
UiPanel);
}
public static void Label(ref CuiElementContainer container, string text, int size, UiPosition pos, TextAnchor align = TextAnchor.MiddleCenter)
{
container.Add(new CuiLabel
{
Text = { FontSize = size, Align = align, Text = text },
RectTransform = { AnchorMin = pos.GetMin(), AnchorMax = pos.GetMax() }
},
UiPanel);
}
public static string Color(string hexColor)
{
hexColor = hexColor.TrimStart('#');
int red = int.Parse(hexColor.Substring(0, 2), NumberStyles.AllowHexSpecifier);
int green = int.Parse(hexColor.Substring(2, 2), NumberStyles.AllowHexSpecifier);
int blue = int.Parse(hexColor.Substring(4, 2), NumberStyles.AllowHexSpecifier);
int alpha = 255;
if (hexColor.Length == 8)
{
alpha = int.Parse(hexColor.Substring(6, 2), NumberStyles.AllowHexSpecifier);
}
return $"{red / 255.0} {green / 255.0} {blue / 255.0} {alpha / 255}";
}
}
private class UiPosition
{
public float XMin { get; set; }
public float YMin { get; set; }
public float XMax { get; set; }
public float YMax { get; set; }
public UiPosition(float xMin, float yMin, float xMax, float yMax)
{
XMin = xMin;
YMin = yMin;
XMax = xMax;
YMax = yMax;
}
public string GetMin() => $"{XMin} {YMin}";
public string GetMax() => $"{XMax} {YMax}";
public override string ToString()
{
return $"{XMin} {YMin} {XMax} {YMax}";
}
}
private void DestroyAllUi(BasePlayer player)
{
CuiHelper.DestroyUi(player, UiPanelName);
}
#endregion
#region UI Variables
private readonly string _clear = Ui.Color("#00000000");
private readonly UiPosition _fullArea = new UiPosition(0, 0, 1, 1);
#endregion
#region UI Creation
private void CreateUnlockedUi(BasePlayer player, bool unlocked)
{
CuiElementContainer container = Ui.Container(_clear, _pluginConfig.Pos, false, UiPanelName, "Overlay");
string key = unlocked ? LangKeys.AlreadyLearned : LangKeys.NotLearned;
Ui.Panel(ref container, unlocked ? _notLearnedColor : _learnedColor, _fullArea);
Ui.Label(ref container, Lang(key, player), 14, _fullArea);
CuiHelper.DestroyUi(player, UiPanelName);
CuiHelper.AddUi(player, container);
}
#endregion
}
}