C#:
// Все права принадлежат дискорд сообществу https://discord.gg/VgNHPpNrz6
// Requires: ImageLibrary
using System;
using System.Collections.Generic;
using Newtonsoft.Json;
using Oxide.Core.Plugins;
using Oxide.Game.Rust.Cui;
using System.Globalization;
using Oxide.Core;
using UnityEngine;
using Color = UnityEngine.Color;
namespace Oxide.Plugins {
[Info("Gesture Wheel", "Tricky & Mevent", "0.1.3")]
[Description("Convenient wheel that provides the ability to use gestures")]
public class GestureWheel : RustPlugin {
#region Plugin References
[PluginReference]
private Plugin ImageLibrary;
#endregion
#region Config
Configuration config;
public class Configuration {
[JsonProperty(PropertyName = "Command")]
public string Command = "gestures";
[JsonProperty(PropertyName = "Use Permission")]
public bool UsePermission = false;
[JsonProperty(PropertyName = "Button Radius")]
public int ButtonRadius = 100;
[JsonProperty(PropertyName = "Close Button Color")]
public string CloseButtonColor = "#FFB6B3DE";
[JsonProperty(PropertyName = "Gesture Button Color")]
public string GestureButtonColor = "#FF6666DE";
[JsonProperty(PropertyName = "Gesture Button Size")]
public int GestureButtonSize = 50;
[JsonProperty(PropertyName = "Gestures", ObjectCreationHandling = ObjectCreationHandling.Replace)]
public List<Gesture> Gestures = new List<Gesture> {
new Gesture {
Name = "wave", Image = "https://i.imgur.com/pB3iZer.png"
}
, new Gesture {
Name = "victory", Image = "https://i.imgur.com/PLbSgED.png"
}
, new Gesture {
Name = "shrug", Image = "https://i.imgur.com/A3hHcgV.png"
}
, new Gesture {
Name = "thumbsup", Image = "https://i.imgur.com/yWuhCMu.png"
}
, new Gesture {
Name = "chicken", Image = "https://i.imgur.com/Qxhjf6N.png"
}
, new Gesture {
Name = "hurry", Image = "https://i.imgur.com/vVKVeha.png"
}
, new Gesture {
Name = "whoa", Image = "https://i.imgur.com/AFeGOrK.png"
}
}
;
public class Gesture {
[JsonProperty(PropertyName = "Gesture Name")]
public string Name;
[JsonProperty(PropertyName = "Image")]
public string Image;
}
}
protected override void LoadConfig() {
base.LoadConfig();
try {
config = Config.ReadObject<Configuration>();
if (config == null) throw new Exception();
}
catch {
Config.WriteObject(config, false, $"{Interface.Oxide.ConfigDirectory}/{Name}.jsonError");
PrintError("The configuration file contains an error and has been replaced with a default config.\n" + "The error configuration file was saved in the.jsonError extension");
LoadDefaultConfig();
}
SaveConfig();
}
protected override void LoadDefaultConfig() => config = new Configuration();
protected override void SaveConfig() => Config.WriteObject(config);
#endregion
#region Stored Data
private readonly string Layer = "UI_Emotions";
private readonly string Perm = "gestures.use";
List<ulong> Players = new List<ulong>();
#endregion
#region Oxide Hooks
private void Init() {
permission.RegisterPermission(Perm, this);
cmd.AddChatCommand(config.Command, this, nameof(GesturesCommand));
cmd.AddConsoleCommand("gestures.close", this, nameof(GesturesCloseCommand));
}
private void OnServerInitialized() {
if (ImageLibrary == null) {
PrintError("Image Library is not loaded, get it at https://umod.org/plugins/image-library");
return;
}
ImageLibrary.Call("AddImage", "https://i.imgur.com/D40FoBT.png", "CloseImage");
ImageLibrary.Call("AddImage", "https://i.imgur.com/2fjUdcJ.png", "EmotionImage");
for (int i = 0; i < config.Gestures.Count; i++) ImageLibrary.Call("AddImage", config.Gestures[i].Image, config.Gestures[i].Name);
}
#endregion
#region Commands
private void GesturesCommand(BasePlayer player, string command, string[] args) {
if (config.UsePermission && !player.IPlayer.HasPermission(Perm)) return;
if (!Players.Contains(player.userID)) {
UI_DrawInterface(player);
Players.Add(player.userID);
}
else {
CuiHelper.DestroyUi(player, Layer);
Players.Remove(player.userID);
}
}
private void GesturesCloseCommand(ConsoleSystem.Arg arg) {
var player = arg.Player();
if (player == null) return;
Players.Remove(player.userID);
}
#endregion
#region User Interface
private void UI_DrawInterface(BasePlayer player) {
var container = new CuiElementContainer();
container.Add(new CuiPanel {
CursorEnabled = true, Image = {
Color = "0 0 0 0"
}
, RectTransform = {
AnchorMin = "0.5 0.5", AnchorMax = "0.5 0.5"
}
}
, "Overlay", Layer);
LoadImage(ref container, Layer, Layer + ".Img", "CloseImage", oMin : "-30 -30", oMax : "30 30", color : HexToRustFormat(config.CloseButtonColor));
container.Add(new CuiButton {
Button = {
Command = "gestures.close", Color = "0 0 0 0", Close = Layer
}
, Text = {
Text = ""
}
, RectTransform = {
AnchorMin = "0 0", AnchorMax = "1 1"
}
}
, Layer + ".Img");
for (int i = 0; i < config.Gestures.Count; i++) {
var emotion = config.Gestures[i];
int r = config.Gestures.Count * 10 + config.ButtonRadius;
var c = (double) config.Gestures.Count / 2;
var pos = i / c * Math.PI;
var x = r * Math.Sin(pos);
var y = r * Math.Cos(pos);
LoadImage(ref container, Layer, $"EmoButton.{i}", "EmotionImage", aMin : $"{x - config.GestureButtonSize} {y - config.GestureButtonSize}", aMax : $"{x + config.GestureButtonSize} {y + config.GestureButtonSize}", color : HexToRustFormat(config.GestureButtonColor));
LoadImage(ref container, $"EmoButton.{i}", $"EmoButton.{i}.Img", emotion.Name, aMin : "0.5 0.5", aMax : "0.5 0.5", oMin : "-30 -30", oMax : "30 30");
container.Add(new CuiButton {
RectTransform = {
AnchorMin = "0 0", AnchorMax = "1 1"
}
, Button = {
Color = "0 0 0 0", Command = $"gesture {emotion.Name}"
}
, Text = {
Text = ""
}
}
, $"EmoButton.{i}");
}
CuiHelper.DestroyUi(player, Layer);
CuiHelper.AddUi(player, container);
}
public void LoadImage(ref CuiElementContainer container, string parent, string name, string image, string aMin = "0 0", string aMax = "1 1", string oMin = "0 0", string oMax = "0 0", string color = "1 1 1 1") {
container.Add(new CuiElement {
Name = name, Parent = parent, Components = {
new CuiRawImageComponent {
Png = (string) ImageLibrary.Call("GetImage", image), Color = color
}
, new CuiRectTransformComponent {
AnchorMin = aMin, AnchorMax = aMax, OffsetMin = oMin, OffsetMax = oMax
}
,
}
}
);
}
#endregion
#region Helpers
private static string HexToRustFormat(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 string.Format("{0:F2} {1:F2} {2:F2} {3:F2}", color.r, color.g, color.b, color.a);
}
#endregion
}
}