C#:
// Все права принадлежат дискорд сообществу https://discord.gg/VgNHPpNrz6
using Oxide.Game.Rust.Cui;
using UnityEngine;
using System;
using Rust;
using System.Collections.Generic;
using Oxide.Core;
using Newtonsoft.Json;
using System.Globalization;
using System.Linq;
using System.Text.RegularExpressions;
namespace Oxide.Plugins {
[Info("Chill Diving", "Thisha", "1.4.0")]
[Description("Audiovisual support for divers")]
public class ChillDiving : RustPlugin {
private const string inviteNoticeMsg = "assets/bundled/prefabs/fx/invite_notice.prefab";
private const string divingTankShortName = "diving.tank";
private const string defaultPictureURL = "https://i.imgur.com/z8JqhRB.png";
private float pictureOffset = 0.022f;
public DateTime lastCleanUp;
public enum ShowValues {
All, Bar, Value
}
;
public enum DivingColor {
AliceBlue = 28, AntiqueWhite = 29, Aqua = 30, Aquamarine = 31, Azure = 32, Beige = 33, Bisque = 34, Black = 35, BlanchedAlmond = 36, Blue = 37, BlueViolet = 38, Brown = 39, BurlyWood = 40, CadetBlue = 41, Chartreuse = 42, Chocolate = 43, Coral = 44, CornflowerBlue = 45, Cornsilk = 46, Crimson = 47, Cyan = 48, DarkBlue = 49, DarkCyan = 50, DarkGoldenrod = 51, DarkGray = 52, DarkGreen = 53, DarkKhaki = 54, DarkMagenta = 55, DarkOliveGreen = 56, DarkOrange = 57, DarkOrchid = 58, DarkRed = 59, DarkSalmon = 60, DarkSeaGreen = 61, DarkSlateBlue = 62, DarkSlateGray = 63, DarkTurquoise = 64, DarkViolet = 65, DeepPink = 66, DeepSkyBlue = 67, DimGray = 68, DodgerBlue = 69, Firebrick = 70, FloralWhite = 71, ForestGreen = 72, Fuchsia = 73, Gainsboro = 74, GhostWhite = 75, Gold = 76, Goldenrod = 77, Gray = 78, Green = 79, GreenYellow = 80, Honeydew = 81, HotPink = 82, IndianRed = 83, Indigo = 84, Ivory = 85, Khaki = 86, Lavender = 87, LavenderBlush = 88, LawnGreen = 89, LemonChiffon = 90, LightBlue = 91, LightCoral = 92, LightCyan = 93, LightGoldenrodYellow = 94, LightGray = 95, LightGreen = 96, LightPink = 97, LightSalmon = 98, LightSeaGreen = 99, LightSkyBlue = 100, LightSlateGray = 101, LightSteelBlue = 102, LightYellow = 103, Lime = 104, LimeGreen = 105, Linen = 106, Magenta = 107, Maroon = 108, MediumAquamarine = 109, MediumBlue = 110, MediumOrchid = 111, MediumPurple = 112, MediumSeaGreen = 113, MediumSlateBlue = 114, MediumSpringGreen = 115, MediumTurquoise = 116, MediumVioletRed = 117, MidnightBlue = 118, MintCream = 119, MistyRose = 120, Moccasin = 121, NavajoWhite = 122, Navy = 123, OldLace = 124, Olive = 125, OliveDrab = 126, Orange = 127, OrangeRed = 128, Orchid = 129, PaleGoldenrod = 130, PaleGreen = 131, PaleTurquoise = 132, PaleVioletRed = 133, PapayaWhip = 134, PeachPuff = 135, Peru = 136, Pink = 137, Plum = 138, PowderBlue = 139, Purple = 140, Red = 141, RosyBrown = 142, RoyalBlue = 143, SaddleBrown = 144, Salmon = 145, SandyBrown = 146, SeaGreen = 147, SeaShell = 148, Sienna = 149, Silver = 150, SkyBlue = 151, SlateBlue = 152, SlateGray = 153, Snow = 154, SpringGreen = 155, SteelBlue = 156, Tan = 157, Teal = 158, Thistle = 159, Tomato = 160, Turquoise = 161, Violet = 162, Wheat = 163, White = 164, WhiteSmoke = 165, Yellow = 166, YellowGreen = 167,
}
#region localization
private new void LoadDefaultMessages() {
lang.RegisterMessages(new Dictionary<string, string> {
["HelpInfo"]
= "Use \"/diving <on|off>\" to show hide the diving panel.", ["HelpShow"] = "Use \"/diving show <alerts|ranges>\" to see your active alerts/colors.", ["HelpView"] = "Use \"/diving view <bar|value|all>\" to switch view.", ["HelpColor"] = "Use \"/diving colors help\" to show more info about color usage.", ["HelpColorList"] = "Use \"/diving colors list\" to see a list of the available color names.", ["HelpAlertAdd"] = "Use \"/diving add alert <number>\" to add or update a normal alert, add * for a continuous one (eg.20*)", ["HelpRangeAdd"] = "Use \"/diving add range <number> <barcolor> <fontcolor>\" to add or update a color range.", ["HelpDelete"] = "Use \"/diving remove <alert|range> <number>\" to delete a certain alert or range", ["HelpReset"] = "Use \"/diving reset\" to reset your settings to defaults.", ["NoUsePermission"] = "You do not have permission to use the diving information.", ["NoModifyPermission"] = "You do not have permission to modify diving settings.", ["InvalidAlert"] = "Invalid alert value.", ["InvalidColor"] = "Invalid color value.", ["InvalidRGB"] = "Invalid RGB value.", ["InvalidNumberValue"] = "Invalid number value", ["NoAlerts"] = "You don't have any active alerts.", ["AlertAdded"] = "The alert has been added.", ["AlertUpdated"] = "The alert has been updated.", ["AlertRemoved"] = "The alert has been removed.", ["AlertDoesNotExists"] = "The alert does not exist.", ["NoRanges"] = "You don't have any color ranges.", ["RangeAdded"] = "The color range has been added.", ["RangeUpdated"] = "The color range has been updated.", ["RangeRemoved"] = "The color range has been removed.", ["RangeDoesNotExists"] = "The color range does not exist.", ["MaxAlerts"] = "You have reached the maximum number of alerts.", ["DataReset"] = "Your data has been reset to defaults.", ["ColorUsage"] = "Colors can be defined by a hexadecimal value, for example #FC03F0.\nTransparancy from FF (none) to 00 (full) can be added, for example FC03F0FF.\nColors can be defined by name too (case-sensitive), use \"/diving colors list\" to view them.\nWhen using color names, the transparancy will be default.", ["ServerDefaults"] = "Server defaults", ["NoServerAlerts"] = "No alerts",
}
, this);
}
#endregion localization
#region data
private Dictionary<ulong, PlayerData> playerData = new Dictionary<ulong, PlayerData>();
private class PlayerData {
public bool Enabled;
public string ShowInfo = string.Empty;
public DateTime LastChange = DateTime.Today;
public DateTime LastOnline = DateTime.Today;
public Dictionary<uint, SimpleRangeData> ColorRanges = new Dictionary<uint, SimpleRangeData>();
public Dictionary<uint, bool> Alerts = new Dictionary<uint, bool>();
public PlayerData() {
}
}
#endregion data
#region config
private ConfigData config;
class ConfigData {
[JsonProperty(PropertyName = "Lower Range Color Value")]
public SimpleRangeData LowerRange = new SimpleRangeData {
BarColorValue = "#996633", FontColorValue = "#FFFFFFFF"
}
;
[JsonProperty(PropertyName = "Middle Range")]
public FullRangeData MiddleRange = new FullRangeData {
BarColorValue = "#FFFF00E4", StartValue = 100, FontColorValue = "#FFFFFFFF"
}
;
[JsonProperty(PropertyName = "Higher Range")]
public FullRangeData HigherRange = new FullRangeData {
BarColorValue = "#669933E4", StartValue = 300, FontColorValue = "#FFFFFFFF"
}
;
[JsonProperty(PropertyName = "Alert 1")]
public uint Alert1 = 100;
[JsonProperty(PropertyName = "Alert 2")]
public uint Alert2 = 0;
[JsonProperty(PropertyName = "Continous alert")]
public uint ContAlert = 15;
[JsonProperty(PropertyName = "Show picture")]
public bool ShowPicture = false;
[JsonProperty(PropertyName = "Picture URL")]
public string PictureURL = "https://i.imgur.com/z8JqhRB.png";
[JsonProperty(PropertyName = "Show info (All, Bar, Value)")]
public string ShowInfo = ShowValues.All.ToString();
[JsonProperty(PropertyName = "Postition")]
public AnchorPosition Position = new AnchorPosition {
XAxis = 0.035f, YAxis = 0.007f
}
;
[JsonProperty(PropertyName = "Maximum Player Alerts")]
public uint MaxAlerts = 6;
[JsonProperty(PropertyName = "Remove after offline days")]
public uint OffDays = 0;
}
private class FullRangeData {
[JsonProperty(PropertyName = "Starting Value")]
public uint StartValue = 0;
[JsonProperty(PropertyName = "Bar Color")]
public string BarColorValue = "#00000000";
[JsonProperty(PropertyName = "Font Color")]
public string FontColorValue = "#00000000";
}
private class AnchorPosition {
[JsonProperty(PropertyName = "X-axis")]
public float XAxis = 0;
[JsonProperty(PropertyName = "Y-axis")]
public float YAxis = 0;
}
private class SimpleRangeData {
[JsonProperty(PropertyName = "Bar Color")]
public string BarColorValue = "#00000000";
[JsonProperty(PropertyName = "Font Color")]
public string FontColorValue = "#00000000";
public SimpleRangeData() {
}
public SimpleRangeData(string barcolor, string fontcolor) {
BarColorValue = barcolor;
FontColorValue = fontcolor;
}
}
protected override void LoadDefaultConfig() {
config = new ConfigData();
}
protected override void LoadConfig() {
base.LoadConfig();
try {
config = Config.ReadObject<ConfigData>();
if (config == null) throw new Exception();
SaveConfig();
}
catch {
LoadDefaultConfig();
}
}
#endregion config
#region commands
[ChatCommand("Diving")]
void HandleChatcommand(BasePlayer player, string command, string[] args) {
bool doUpdate = false;
if (!permission.UserHasPermission(player.UserIDString, "chilldiving.use")) {
PrintToChat(player, Lang("NoUsePermission", player.UserIDString));
return;
}
switch (args.Length) {
case 1 : {
switch (args[0].ToLower()) {
case "on" : {
ShowOxygen(player);
break;
}
case "off" : {
HideOxygen(player);
break;
}
case "reset" : {
if (!permission.UserHasPermission(player.UserIDString, "chilldiving.modify")) {
PrintToChat(player, Lang("NoModifyPermission", player.UserIDString));
return;
}
InitPlayer(player.userID, true);
player.ChatMessage(Lang("DataReset", player.UserIDString));
Item item;
if (IsWearingdivingTank(player, out item)) UpdatePanels(player, item.condition, item.maxCondition, true);
break;
}
default : {
ShowCommandHelp(player);
break;
}
}
break;
}
case 2 : {
switch (args[0].ToLower()) {
case "show" : {
switch (args[1].ToLower()) {
case "alerts" : {
}
player.ChatMessage(GetAlerts(player.userID));
break;
case "ranges" : {
player.ChatMessage(GetRanges(player.userID));
break;
}
default : {
PrintToChat(player, Lang("HelpShow", player.UserIDString));
break;
}
}
break;
}
case "view" : {
if (!permission.UserHasPermission(player.UserIDString, "chilldiving.modify")) {
PrintToChat(player, Lang("NoModifyPermission", player.UserIDString));
return;
}
switch (args[1].ToLower()) {
case "bar" : {
ChangeView(player.userID, args[1], out doUpdate);
break;
}
case "value" : {
ChangeView(player.userID, args[1], out doUpdate);
break;
}
case "all" : {
ChangeView(player.userID, args[1], out doUpdate);
break;
}
default : {
PrintToChat(player, Lang("HelpView", player.UserIDString));
break;
}
}
break;
}
case "colors" : {
switch (args[1].ToLower()) {
case "help" : {
PrintToChat(player, Lang("ColorUsage", player.UserIDString));
break;
}
case "list" : {
PrintToChat(player, ColorList());
break;
}
default : {
PrintToChat(player, Lang("HelpColor", player.UserIDString));
break;
}
}
break;
}
default : ShowCommandHelp(player);
break;
}
break;
}
case 3 : {
if (!permission.UserHasPermission(player.UserIDString, "chilldiving.modify")) {
PrintToChat(player, Lang("NoModifyPermission", player.UserIDString));
return;
}
switch (args[0].ToLower()) {
case "add" : {
switch (args[1].ToLower()) {
case "alert" : {
player.ChatMessage(Lang(AddAlert(player.userID, args[2])));
break;
}
default : {
ShowCommandHelp(player);
break;
}
}
break;
}
case "remove" : {
switch (args[1].ToLower()) {
case "alert" : {
player.ChatMessage(Lang(RemoveAlert(player.userID, args[2])));
break;
}
case "range" : {
player.ChatMessage(Lang(RemoveRange(player.userID, args[2], out doUpdate)));
break;
}
default : {
ShowCommandHelp(player);
break;
}
}
break;
}
default : ShowCommandHelp(player);
break;
}
break;
}
case 5 : {
if (!permission.UserHasPermission(player.UserIDString, "chilldiving.modify")) {
PrintToChat(player, Lang("NoModifyPermission", player.UserIDString));
return;
}
switch (args[0].ToLower()) {
case "add" : {
switch (args[1].ToLower()) {
case "range" : {
string[] pars = new string[3] {
args[2], args[3], args[4]
}
;
player.ChatMessage(Lang(AddRange(player.userID, pars, out doUpdate)));
break;
}
default : {
ShowCommandHelp(player);
break;
}
}
break;
}
default : {
ShowCommandHelp(player);
break;
}
}
break;
}
default : {
ShowCommandHelp(player);
break;
}
}
;
if (doUpdate) {
Item item;
if (PlayerSignedUp(player)) if (IsWearingdivingTank(player, out item)) UpdatePanels(player, item.condition, item.maxCondition, true);
}
}
#endregion commands
#region hooks
private void Init() {
permission.RegisterPermission("chilldiving.use", this);
permission.RegisterPermission("chilldiving.modify", this);
LoadData();
}
void OnServerInitialized() {
foreach (BasePlayer player in BasePlayer.activePlayerList) {
if (!PlayerSignedUp(player)) continue;
if (!player.IsAlive()) continue;
Item item;
if (IsWearingdivingTank(player, out item)) {
UpdatePanels(player, item.condition, item.maxCondition, true);
}
}
}
void OnServerSave() {
RemoveOldData();
}
private void Unload() {
foreach (BasePlayer player in BasePlayer.activePlayerList) {
if (PlayerSignedUp(player)) DestroyUI(player, true);
}
}
void OnPlayerConnected(BasePlayer player) {
if (playerData.ContainsKey(player.userID)) {
playerData[player.userID].LastOnline = DateTime.Today;
SaveData();
}
}
private void OnPlayerSleepEnded(BasePlayer player) {
if (!PlayerSignedUp(player)) return;
Item item;
if (IsWearingdivingTank(player, out item)) UpdatePanels(player, item.condition, item.maxCondition, true);
}
void OnPlayerDeath(BasePlayer player, ref HitInfo info) {
if (!PlayerSignedUp(player)) return;
Item item2;
if (IsWearingdivingTank(player, out item2)) DestroyUI(player, true);
}
void OnItemAddedToContainer(ItemContainer cont, Item item) {
if (ShouldHandleUI(cont, item)) UpdatePanels(cont.playerOwner, item.condition, item.maxCondition, true);
}
void OnItemRemovedFromContainer(ItemContainer cont, Item item) {
if (ShouldHandleUI(cont, item)) DestroyUI(cont.GetOwnerPlayer(), true);
}
void OnEntityTakeDamage(BasePlayer player, ref HitInfo info) {
if (info.damageTypes.Get(DamageType.Drowned) <= 0f) return;
if (!PlayerSignedUp(player)) return;
if (!player.IsAlive()) return;
Item item;
if (IsWearingdivingTank(player, out item)) {
UpdatePanels(player, item.condition, item.maxCondition, true);
}
}
void OnLoseCondition(Item item, ref float amount) {
if (!item.info.shortname.Equals(divingTankShortName)) return;
BasePlayer player = item.GetOwnerPlayer();
if (!PlayerSignedUp(player)) return;
UpdatePanels(player, item.condition - 3f, item.maxCondition, false);
}
void OnItemAction(Item item, string action, BasePlayer player) {
if (!action.ToUpper().Contains("REFILL")) return;
Item item2;
if ((item.info.shortname.Equals(divingTankShortName)) && (IsWearingdivingTank(player, out item2))) {
float maxLossFraction = 0.05f;
float tempMax = 0;
float single = 1f - item.condition / item.maxCondition;
maxLossFraction = Mathf.Clamp(maxLossFraction, 0f, item.maxCondition);
tempMax = (float)Math.Floor(item.maxCondition * (1f - maxLossFraction * single));
UpdatePanels(player, tempMax, tempMax, false);
}
}
#endregion hooks
#region functions
#region general
void RemoveOldData() {
if (lastCleanUp >= DateTime.Today) return;
if (config.OffDays <= 0) return;
List<ulong> ToDelete = new List<ulong>();
for (int i = 0; i < playerData.Count; i++) {
if ((DateTime.Today - playerData.ElementAt(i).Value.LastOnline).TotalDays > config.OffDays) {
ToDelete.Add(playerData.ElementAt(i).Key);
}
}
if (ToDelete.Count > 0) {
for (int i = 0; i < ToDelete.Count; i++) playerData.Remove(ToDelete[i]);
}
SaveData();
//catch save of new player data lastonline
lastCleanUp = DateTime.Today;
}
void InitPlayer(ulong userID, bool reset) {
if (reset) {
playerData.Remove(userID);
SaveData();
return;
}
PlayerData data = new PlayerData();
data.Enabled = true;
data.ShowInfo = config.ShowInfo;
data.ColorRanges.Add(0, config.LowerRange);
data.ColorRanges.Add(config.MiddleRange.StartValue, new SimpleRangeData(config.MiddleRange.BarColorValue, config.MiddleRange.FontColorValue));
data.ColorRanges.Add(config.HigherRange.StartValue, new SimpleRangeData(config.HigherRange.BarColorValue, config.HigherRange.FontColorValue));
if (config.ContAlert > 0) data.Alerts.Add(config.ContAlert, true);
if (config.Alert1 > 0) data.Alerts.Add(config.Alert1, false);
if (config.Alert2 > 0) data.Alerts.Add(config.Alert2, false);
playerData[userID] = data;
SaveData();
}
void HideOxygen(BasePlayer player) {
if (!playerData.ContainsKey(player.userID)) InitPlayer(player.userID, false);
playerData[player.userID].Enabled = false;
playerData[player.userID].LastChange = DateTime.Today;
SaveData();
DestroyUI(player, true);
}
void ShowOxygen(BasePlayer player) {
PlayerData info;
if (!playerData.TryGetValue(player.userID, out info)) {
InitPlayer(player.userID, false);
}
else {
info.Enabled = true;
playerData[player.userID].LastChange = DateTime.Today;
SaveData();
Item item;
if (IsWearingdivingTank(player, out item)) UpdatePanels(player, item.condition, item.maxCondition, true);
}
}
#endregion general
#region alerts
string GetAlerts(ulong userID) {
string alerts = string.Empty;
if (playerData.ContainsKey(userID)) {
if (playerData[userID].Alerts.Count > 0) {
foreach (var alert in playerData[userID].Alerts.OrderBy(x => x.Key)) {
if (alerts.Length > 0) alerts = alerts + ", " + alert.Key.ToString();
else alerts = alert.Key.ToString();
if (alert.Value == true) alerts = alerts + "*";
}
}
if (alerts.Length == 0) {
alerts = Lang("NoAlerts", userID.ToString());
}
}
else {
alerts = Lang("NoAlerts", userID.ToString()) + '\n' + GetDefaultAlerts();
}
return alerts;
}
string GetDefaultAlerts() {
string alerts = string.Empty;
if (config.ContAlert > 0) alerts = config.ContAlert.ToString() + "*";
if (config.Alert1 > 0) alerts = (alerts + ", " + config.Alert1.ToString()).TrimStart(' ', ',');
if (config.Alert2 > 0) alerts = (alerts + ", " + config.Alert2.ToString()).TrimStart(' ', ',');
if (alerts.Length > 0) return (Lang("ServerDefaults") + ": " + alerts);
else return (Lang("ServerDefaults") + ": " + Lang("NoServerAlerts"));
}
string AddAlert(ulong userID, string args) {
string result = String.Empty;
bool continuous = args.Substring(args.Length - 1) == "*";
if (continuous) {
args = args.Remove(args.Length - 1);
}
uint condition;
if (uint.TryParse(args, out condition)) {
bool oldContinuous;
if (!playerData.ContainsKey(userID)) InitPlayer(userID, false);
if (!playerData[userID].Alerts.TryGetValue(condition, out oldContinuous)) {
if ((playerData[userID].Alerts.Count < config.MaxAlerts) || (config.MaxAlerts == 0)) {
playerData[userID].Alerts.Add(condition, continuous);
playerData[userID].LastChange = DateTime.Today;
SaveData();
result = "AlertAdded";
}
else {
result = "MaxAlerts";
}
}
else {
playerData[userID].Alerts[condition] = continuous;
playerData[userID].LastChange = DateTime.Today;
SaveData();
result = "AlertUpdated";
}
}
else {
result = "InvalidAlert";
}
return (result);
}
string RemoveAlert(ulong userID, string args) {
string result = string.Empty;
uint condition;
if (uint.TryParse(args, out condition)) {
if (playerData[userID].Alerts.Remove(condition)) {
playerData[userID].LastChange = DateTime.Today;
SaveData();
result = "AlertRemoved";
}
else {
result = "AlertDoesNotExists";
}
}
else {
result = "InvalidAlert";
}
;
return result;
}
bool MustDoEffect(float condition, ulong userID) {
uint alert = 0;
if (playerData.ContainsKey(userID)) {
alert = playerData[userID].Alerts.Where(x => x.Key >= condition).OrderBy(x => x.Key).FirstOrDefault().Key;
if (alert > 0) {
if (playerData[userID].Alerts[alert] == false) return (condition >= alert - 3) && (condition <= alert);
else return true;
}
else {
return false;
}
}
else {
return (((config.Alert1 > 0) && (condition >= config.Alert1 - 3) && (condition <= config.Alert1)) || ((config.Alert2 > 0) && (condition >= config.Alert2 - 3) && (condition <= config.Alert2)) || ((config.ContAlert > 0) && (condition <= config.ContAlert)));
}
}
#endregion alerts
#region ranges
string GetRanges(ulong userID) {
string ranges = string.Empty;
if (playerData.ContainsKey(userID)) {
if (playerData[userID].ColorRanges.Count > 0) {
foreach (var range in playerData[userID].ColorRanges.OrderBy(x => x.Key)) {
if (ranges.Length > 0) ranges = ranges + "\n" + range.Key.ToString() + " B: " + range.Value.BarColorValue + " F: " + range.Value.FontColorValue;
else ranges = range.Key.ToString() + " B: " + range.Value.BarColorValue + " F: " + range.Value.FontColorValue;
}
}
}
if (ranges.Length == 0) {
ranges = Lang("NoRanges", userID.ToString()) + '\n' + Lang("ServerDefaults") + ": " + '\n' + GetDefaultRanges();
}
return ranges;
}
string GetDefaultRanges() {
return ("0 " + "B: " + config.LowerRange.BarColorValue + " F: " + config.LowerRange.FontColorValue + '\n' + config.MiddleRange.StartValue.ToString() + " B: " + config.MiddleRange.BarColorValue + " F: " + config.LowerRange.FontColorValue + '\n' + config.HigherRange.StartValue.ToString() + " B: " + config.HigherRange.BarColorValue + " F: " + config.HigherRange.FontColorValue);
}
string AddRange(ulong userID, string[] args, out bool doUpdate) {
string result = string.Empty;
string barRGB = string.Empty;
string fontRGB = string.Empty;
uint startCond = 0;
doUpdate = false;
if (IsValidColor(args[1], out barRGB)) {
if (IsValidColor(args[2], out fontRGB)) {
if (uint.TryParse(args[0], out startCond)) {
if (!playerData.ContainsKey(userID)) InitPlayer(userID, false);
SimpleRangeData range;
if (!playerData[userID].ColorRanges.TryGetValue(startCond, out range)) {
playerData[userID].ColorRanges.Add(startCond, new SimpleRangeData(args[1], args[2]));
playerData[userID].LastChange = DateTime.Today;
SaveData();
result = "RangeAdded";
}
else {
playerData[userID].ColorRanges[startCond].BarColorValue = args[1];
playerData[userID].ColorRanges[startCond].FontColorValue = args[2];
playerData[userID].LastChange = DateTime.Today;
SaveData();
result = "RangeUpdated";
}
doUpdate = true;
}
else result = "InvalidNumberValue";
}
else result = "InvalidColor";
}
else result = "InvalidColor";
return result;
}
string RemoveRange(ulong userID, string args, out bool doUpdate) {
string result = string.Empty;
uint condition;
doUpdate = false;
if (uint.TryParse(args, out condition)) {
if (playerData[userID].ColorRanges.Remove(condition)) {
playerData[userID].LastChange = DateTime.Today;
SaveData();
result = "RangeRemoved";
doUpdate = true;
}
else {
result = "RangeDoesNotExists";
}
}
else {
result = "InvalidNumberValue";
}
;
return result;
}
void GetRGBValues(ulong userID, uint condition, out string barRGB, out string fontRGB) {
barRGB = string.Empty;
fontRGB = string.Empty;
bool getFromconfig = true;
uint startCond = 0;
SimpleRangeData range;
if (playerData.ContainsKey(userID)) {
startCond = playerData[userID].ColorRanges.Where(x => x.Key <= condition).OrderBy(x => x.Key).LastOrDefault().Key;
if (playerData[userID].ColorRanges.TryGetValue(startCond, out range)) {
barRGB = range.BarColorValue;
fontRGB = range.FontColorValue;
getFromconfig = false;
}
}
if (getFromconfig) {
if (condition < config.MiddleRange.StartValue) {
barRGB = config.LowerRange.BarColorValue;
fontRGB = config.LowerRange.FontColorValue;
}
else if ((condition >= config.MiddleRange.StartValue) && (condition < config.HigherRange.StartValue)) {
barRGB = config.MiddleRange.BarColorValue;
fontRGB = config.MiddleRange.FontColorValue;
}
else {
barRGB = config.HigherRange.BarColorValue;
fontRGB = config.HigherRange.FontColorValue;
}
}
if (barRGB[0] != '#') barRGB = ColorToRGB(barRGB);
if (fontRGB[0] != '#') fontRGB = ColorToRGB(fontRGB);
}
#endregion ranges
#region UI
void ChangeView(ulong userID, string show, out bool doUpdate) {
doUpdate = false;
if (!playerData.ContainsKey(userID)) InitPlayer(userID, false);
if (playerData[userID].ShowInfo != show) {
playerData[userID].ShowInfo = show;
playerData[userID].LastChange = DateTime.Today;
SaveData();
doUpdate = true;
}
}
bool ShouldHandleUI(ItemContainer cont, Item item) {
if (!item.info.shortname.Equals(divingTankShortName)) return false;
if (cont.playerOwner == null) return false;
if (!cont.playerOwner.IsAlive()) return false;
if (!PlayerSignedUp(cont.playerOwner)) return false;
if (IsWearablesContainer(cont)) return true;
return false;
}
void UpdatePanels(BasePlayer player, float condition, float maxCondition, bool doPicture) {
if (!permission.UserHasPermission(player.UserIDString, "chilldiving.use")) return;
string barColor;
string fontColor;
string valueText;
string barText;
if (condition < 0) condition = 0;
GetRGBValues(player.userID, (uint)Math.Floor(condition), out barColor, out fontColor);
double lifepct = condition / maxCondition * 1000;
if (MustDoEffect(condition, player.userID)) Effect.server.Run(inviteNoticeMsg, player.transform.position);
int counter = 0;
int numberofchars = (int)Math.Round(lifepct);
counter = Convert.ToInt32(config.Position.XAxis * 10000);
if (condition != 0) counter = counter + numberofchars;
if (MustShowValue(player.userID)) counter = counter + 150;
if (config.ShowPicture) counter = counter + 220;
barText = "0." + counter.ToString("".PadLeft(4, '0')) + " " + (config.Position.YAxis + 0.023f).ToString();
valueText = ((int)Math.Round(condition, 0)).ToString();
DestroyUI(player, doPicture);
DrawUI(player, ColorFromHex(barColor, 228), valueText, barText, ColorFromHex(fontColor, 255), doPicture);
}
void DestroyUI(BasePlayer player, bool updatePicture) {
if (player == null) return;
CuiHelper.DestroyUi(player, "divingPanel");
CuiHelper.DestroyUi(player, "divingBar");
if (updatePicture) CuiHelper.DestroyUi(player, "divingPicture");
}
void DrawUI(BasePlayer player, string color, string valueText, string barText, string fontColor, bool updatePicture) {
CuiHelper.AddUi(player, Generate_Menu(player, color, valueText, barText, fontColor, updatePicture));
}
private bool MustShowBar(ulong userID) {
if (playerData.ContainsKey(userID)) return (playerData[userID].ShowInfo.ToLower() == ShowValues.All.ToString().ToLower()) || (playerData[userID].ShowInfo.ToLower() == ShowValues.Bar.ToString().ToLower());
else return (config.ShowInfo.ToLower() == ShowValues.All.ToString().ToLower()) || (config.ShowInfo.ToLower() == ShowValues.Bar.ToString().ToLower());
}
private bool MustShowValue(ulong userID) {
if (playerData.ContainsKey(userID)) return (playerData[userID].ShowInfo.ToLower() == ShowValues.All.ToString().ToLower()) || (playerData[userID].ShowInfo.ToLower() == ShowValues.Value.ToString().ToLower());
else return (config.ShowInfo.ToLower() == ShowValues.All.ToString().ToLower()) || (config.ShowInfo.ToLower() == ShowValues.Value.ToString().ToLower());
}
private string GetAnchorMax(ulong userID) {
float X = config.Position.XAxis;
if (config.ShowPicture) X = X + pictureOffset;
float Y = config.Position.YAxis;
if (MustShowBar(userID)) X = X + 0.116f;
else X = X + 0.013f;
if (!MustShowValue(userID)) X = X - 0.015f;
Y = Y + 0.025f;
return X.ToString() + " " + Y.ToString();
}
CuiElementContainer Generate_Menu(BasePlayer player, string barColor, string valueText, string barText, string fontColor, bool updatePicture) {
var elements = new CuiElementContainer();
string contMin = config.Position.XAxis.ToString() + " " + config.Position.YAxis.ToString();
if (config.ShowPicture) contMin = (config.Position.XAxis + pictureOffset).ToString() + " " + config.Position.YAxis.ToString();
var panel = elements.Add(new CuiPanel {
Image = {
Color = "0.60 0.60 0.60 0.27"
}
, RectTransform = {
AnchorMin = contMin, AnchorMax = GetAnchorMax(player.userID)
}
, CursorEnabled = false
}
, "Hud", "divingPanel");
if (updatePicture) {
if (config.ShowPicture) {
var logo = new CuiElementContainer();
logo.Add(new CuiElement {
Name = "divingPicture", Components = {
new CuiRawImageComponent {
Color = "1 1 1 1", Url = (config.PictureURL != "") ? config.PictureURL : "https://i.imgur.com/z8JqhRB.png"
}
, new CuiRectTransformComponent {
AnchorMin = config.Position.XAxis.ToString() + " " + (config.Position.YAxis + 0.004f).ToString(), AnchorMax = (config.Position.XAxis + 0.019f).ToString() + " " + (config.Position.YAxis + 0.027f).ToString()
}
}
}
);
CuiHelper.AddUi(player, logo);
}
}
if (MustShowValue(player.userID)) {
var message01 = elements.Add(new CuiLabel {
Text = {
Text = valueText, Color = fontColor, FontSize = 12, Align = TextAnchor.MiddleLeft
}
, RectTransform = {
AnchorMin = "0.02 0", AnchorMax = "0.8 1"
}
,
}
, panel);
}
if ((MustShowBar(player.userID)) && (valueText != "0")) {
float anchorMin = config.Position.XAxis;
if (config.ShowPicture) anchorMin = anchorMin + pictureOffset;
if (MustShowValue(player.userID)) anchorMin = anchorMin + 0.015f;
var panel2 = elements.Add(new CuiPanel {
Image = {
Color = barColor
}
, RectTransform = {
AnchorMin = anchorMin.ToString() + " " + (config.Position.YAxis + 0.002f).ToString(), AnchorMax = barText
}
, CursorEnabled = false
}
, "Hud", "divingBar");
}
return elements;
}
#endregion UI
void LoadData() {
try {
playerData = Interface.Oxide.DataFileSystem.ReadObject<Dictionary<ulong, PlayerData>>("ChillDiving");
}
catch {
playerData = new Dictionary<ulong, PlayerData>();
}
}
void SaveData() => Interface.Oxide.DataFileSystem.WriteObject("ChillDiving", playerData);
protected override void SaveConfig() => Config.WriteObject(config);
#endregion functions
#region helpers
private static string ColorFromHex(string hexColor, int alpha) {
hexColor = hexColor.TrimStart('#');
if (hexColor.Length != 6 && hexColor.Length != 8) {
hexColor = "000000";
}
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);
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.0}";
}
private string Lang(string key, string userId = null, params object[] args) => string.Format(lang.GetMessage(key, this, userId), args);
private bool IsWearablesContainer(ItemContainer cont) {
return (cont.HasFlag(ItemContainer.Flag.Clothing) && (cont.HasFlag(ItemContainer.Flag.IsPlayer)));
}
private bool IsWearingdivingTank(BasePlayer player, out Item item) {
foreach (Item contItem in player.inventory.containerWear.itemList) {
if (contItem.info.shortname.Equals(divingTankShortName)) {
item = contItem;
return true;
}
}
item = null;
return false;
}
private bool PlayerSignedUp(BasePlayer player) {
PlayerData info;
if (playerData.TryGetValue(player.userID, out info)) return info.Enabled;
else return true;
}
private bool IsValidColor(string value, out string RGB) {
RGB = string.Empty;
if (value[0] == '#') {
if (IsValidRGBValue(value)) {
RGB = value;
return true;
}
else return false;
}
else {
if (Enum.IsDefined(typeof(DivingColor), value)) {
RGB = ColorToRGB(value);
return true;
}
else return false;
}
}
private bool IsValidRGBValue(string value) {
if (value.Length <= 7) return Regex.IsMatch(value, "^#([A-Fa-f0-9]{6})$");
else return Regex.IsMatch(value, "^#([A-Fa-f0-9]{8})$");
}
void ShowCommandHelp(BasePlayer player) {
player.ChatMessage(Lang("HelpInfo", player.UserIDString) + "\n\n" + Lang("HelpView", player.userID.ToString()) + "\n" + Lang("HelpShow", player.userID.ToString()) + "\n\n" + Lang("HelpAlertAdd", player.userID.ToString()) + "\n" + Lang("HelpRangeAdd", player.userID.ToString()) + "\n" + Lang("HelpDelete", player.userID.ToString()) + "\n\n" + Lang("HelpView", player.userID.ToString()) + "\n\n" + Lang("HelpColor", player.userID.ToString()));
}
string ColorList() {
string colors = string.Empty;
foreach (string value in Enum.GetNames(typeof(DivingColor))) {
colors = colors + ", " + value;
}
colors = colors.TrimStart(',', ' ');
return (colors);
}
string ColorToRGB(string namedColor) {
System.Drawing.Color color = System.Drawing.Color.FromName(namedColor);
return ("#" + color.R.ToString("X2") + color.G.ToString("X2") + color.B.ToString("X2"));
}
#endregion helpers
}
}