C#:
using System.Text;
using Oxide.Game.Rust.Cui;
using System.Linq;
using UnityEngine.UI;
using System.Collections.Generic;
using Object = System.Object;
using Oxide.Core.Plugins;
using System;
using ConVar;
using UnityEngine;
using Newtonsoft.Json;
namespace Oxide.Plugins
{
[Info("IQSkipNight", "Mercury", "2.0.2")]
[Description("Ночь? Зачем она нужна - ПРОПУСТИТЬ!")]
class IQSkipNight : RustPlugin
{
private const String layerSkipNight = "UI_IQSKIPNIGHT_PANEL";
protected override void LoadConfig()
{
base.LoadConfig();
try
{
config = Config.ReadObject<Configuration>();
if (config == null) LoadDefaultConfig();
}
catch
{
PrintWarning(LanguageEn
? "Error #334332143" + $"read configuration 'oxide/config/{Name}', create a new configuration!!"
: "Ошибка #334343" + $"чтения конфигурации 'oxide/config/{Name}', создаём новую конфигурацию!!");
LoadDefaultConfig();
}
NextTick(SaveConfig);
}
protected override void LoadDefaultConfig() => config = Configuration.GetNewConfiguration();
[ConsoleCommand("vote.send")]
private void VoteSendConsoleCommand(ConsoleSystem.Arg arg)
{
BasePlayer player = arg.Player();
if (!player) return;
if (playersVoted.ContainsKey(player.userID)) return;
Boolean statusVote = Boolean.Parse(arg.Args[0]);
playersVoted.Add(player.userID, statusVote);
UpdateButtonsClient(player, statusVote);
if (config.V1orV2)
UpdateGlobalProgress_V1();
else UpdateGlobalProgress_V2();
}
private Int32 announcedDay = -1;
private void UpdateGlobalProgress_V1()
{
Int32 totalVotes = playersVoted.Count;
Int32 votesFor = playersVoted.Values.Count(vote => vote);
Int32 votesAgainst = totalVotes - votesFor;
Double percentageFor = (votesFor / (Double)totalVotes) * 100;
Double percentageAgainst = (votesAgainst / (Double)totalVotes) * 100;
Double lineForOffsetMax = (percentageFor / 100) * 380;
Double lineAgainstOffsetMin = lineForOffsetMax - 380;
foreach (BasePlayer player in BasePlayer.allPlayerList)
{
CuiElementContainer container = new CuiElementContainer();
container.Add(new CuiElement
{
Parent = "BUTTON_YES_SKIP",
Name = "BUTTON_YES_TITLE",
Update = true,
Components = { new CuiTextComponent { Text = GetLang("TITILE_YES_BUTTON", player.UserIDString, $"{percentageFor:F2}") }, }
});
container.Add(new CuiElement
{
Parent = "BUTTON_NO_SKIP",
Name = "BUTTON_NO_TITLE",
Update = true,
Components = { new CuiTextComponent { Text = GetLang("TITILE_NO_BUTTON", player.UserIDString, $"{percentageAgainst:F2}") }, }
});
container.Add(new CuiElement
{
Parent = layerSkipNight,
Name = "PROGRESS_BAR_YES",
Update = true,
Components = { new CuiRectTransformComponent { OffsetMax = $"{lineForOffsetMax} -10.5" } }
});
container.Add(new CuiElement
{
Parent = layerSkipNight,
Name = "PROGRESS_BAR_NO",
Update = true,
Components = { new CuiRectTransformComponent { OffsetMin = $"{lineAgainstOffsetMin} -16.5" } }
});
AddUI(player, container.ToJson());
}
}
private static StringBuilder sb = new StringBuilder();
private const String colorYes = "0.451 0.553 0.271 1";
private static void AddUI(BasePlayer player, String json) => CommunityEntity.ServerInstance.ClientRPC<String>(RpcTarget.Player("AddUI", player.net.connection), json);
private void CheckTimeServer()
{
if (!config.IsNight())
{
announcedNotEnoughPlayers = false;
announcedDay = -1;
return;
}
Int32 currentDay = TOD_Sky.Instance.Cycle.Day;
if (announcedDay != currentDay)
{
announcedNotEnoughPlayers = false;
announcedDay = currentDay;
}
if (config.noVoteAllSkip)
{
dayVote = currentDay;
TOD_Sky.Instance.Cycle.Day++;
TOD_Sky.Instance.Cycle.Hour = config.fastSkipController.timeDay;
foreach (BasePlayer player in BasePlayer.activePlayerList)
SendChat(GetLang("MESSAGE_AUTO_SKIP", player.UserIDString), player);
Puts(LanguageEn ? "" : "На сервере была автоматически пропущена ночь");
announcedNotEnoughPlayers = false;
return;
}
playersVoted.Clear();
Int32 countPlayers = BasePlayer.activePlayerList.Count;
Int32 countAmountMin = config.voteController.amountPlayers;
if (countPlayers < countAmountMin)
{
if (!announcedNotEnoughPlayers)
{
foreach (BasePlayer player in BasePlayer.activePlayerList)
SendChat(GetLang("MESSAGE_VOTE_FAILED", player.UserIDString), player);
Puts(LanguageEn ? $"" : $"Голосование о пропуске ночи не было запущено. Недостаточно игроков на сервере ({countPlayers} < {countAmountMin})");
announcedNotEnoughPlayers = true;
announcedDay = currentDay;
}
return;
}
announcedNotEnoughPlayers = false;
Puts(LanguageEn ? "" : "Запущено голосование за пропуск ночи на сервере");
foreach (BasePlayer player in BasePlayer.activePlayerList)
{
if (config.V1orV2)
DrawUI_V1(player);
else DrawUI_V2(player);
SendChat(GetLang("MESSAGE_START_VOTE", player.UserIDString), player);
}
timerProcessNight = timer.Once(config.voteController.secondsVote, StopNightVote);
}
private void UpdateGlobalProgress_V2()
{
Int32 totalVotes = playersVoted.Count;
Int32 votesFor = playersVoted.Values.Count(vote => vote);
Int32 votesAgainst = totalVotes - votesFor;
Double percentageFor = (votesFor / (Double)totalVotes) * 100;
Double percentageAgainst = (votesAgainst / (Double)totalVotes) * 100;
Double offsetForMinY = -29.5 + ((percentageFor / 100) * ( -82 - (-29.5) ));
Double offsetAgainstMaxY = 0 + ((percentageAgainst / 100) * (52.5 - 0));
foreach (BasePlayer player in BasePlayer.allPlayerList)
{
CuiElementContainer container = new CuiElementContainer();
container.Add(new CuiElement
{
Parent = "BUTTON_YES_SKIP",
Name = "BUTTON_YES_TITLE",
Update = true,
Components = { new CuiTextComponent { Text = GetLang("TITILE_YES_BUTTON", player.UserIDString, $"{percentageFor:F2}") }, }
});
container.Add(new CuiElement
{
Parent = "BUTTON_NO_SKIP",
Name = "BUTTON_NO_TITLE",
Update = true,
Components = { new CuiTextComponent { Text = GetLang("TITILE_NO_BUTTON", player.UserIDString, $"{percentageAgainst:F2}") }, }
});
container.Add(new CuiElement
{
Parent = layerSkipNight,
Name = "PROGRESS_BAR_YES",
Update = true,
Components = { new CuiRectTransformComponent { OffsetMin = $"56 {offsetForMinY:F2}" } }
});
container.Add(new CuiElement
{
Parent = layerSkipNight,
Name = "PROGRESS_BAR_NO",
Update = true,
Components = { new CuiRectTransformComponent { OffsetMax = $"62 {offsetAgainstMaxY:F2}" } }
});
AddUI(player, container.ToJson());
}
}
//TODO: Таймер с обратным отсчетом до окончания голосования
[PluginReference] Plugin IQChat;
private void StopNightVote()
{
if (timerProcessNight is { Destroyed: false })
{
timerProcessNight.Destroy();
timerProcessNight = null;
}
Int32 totalVotes = playersVoted.Count;
Int32 votesFor = playersVoted.Values.Count(vote => vote);
Int32 votesAgainst = totalVotes - votesFor;
Int32 votesNone = BasePlayer.activePlayerList.Count - totalVotes;
Double percentageFor = (votesFor / (Double)totalVotes) * 100;
Boolean resultVoted = percentageFor >= config.voteController.percentVote;
foreach (BasePlayer player in BasePlayer.activePlayerList)
{
DestroyUI(player, layerSkipNight);
String resultMessage = GetLang("MESSAGE_VOTE_COMPLETE", player.UserIDString,
GetLang($"RESULT_{resultVoted.ToString().ToUpper()}", player.UserIDString), votesFor, votesAgainst, votesNone);
SendChat(resultMessage, player);
}
dayVote = TOD_Sky.Instance.Cycle.Day;
if (resultVoted)
{
TOD_Sky.Instance.Cycle.Day++;
TOD_Sky.Instance.Cycle.Hour = config.voteController.timeDay;
}
Puts(LanguageEn ? "" : $"Голосование за пропуск ночи заверешно, результат : {(resultVoted ? "ночь пропущена" : "ночь не пропущена")}");
}
private void UpdateButtonsClient(BasePlayer player, Boolean voteStatus)
{
CuiElementContainer container = new CuiElementContainer();
Int32 totalVotes = playersVoted.Count;
Int32 votesFor = playersVoted.Values.Count(vote => vote);
Int32 votesAgainst = totalVotes - votesFor;
container.Add(new CuiElement
{
Parent = layerSkipNight,
Name = "BUTTON_YES_SKIP",
Update = true,
Components = { new CuiButtonComponent { Command = String.Empty }, }
});
container.Add(new CuiElement
{
Parent = layerSkipNight,
Name = "BUTTON_NO_SKIP",
Update = true,
Components = { new CuiButtonComponent { Command = String.Empty }, }
});
if (!voteStatus)
{
Double percentageAgainst = (votesAgainst / (Double)totalVotes) * 100;
container.Add(new CuiElement
{
Parent = "BUTTON_NO_SKIP",
Name = "BUTTON_SLIDE_SCROLL_NO",
DestroyUi = "BUTTON_SLIDE_SCROLL_NO",
Components =
{
new CuiScrollViewComponent
{
MovementType = ScrollRect.MovementType.Elastic,
Horizontal = true,
Elasticity = 0.2f,
Inertia = true,
ScrollSensitivity = 0.3f,
ContentTransform = new CuiRectTransformComponent
{
AnchorMin = "-80 1",
AnchorMax = "-80 1",
OffsetMax = "0 0",
Pivot = "0.5 1"
},
},
new CuiImageComponent { Color = "0 0 0 0" },
new CuiRectTransformComponent
{
AnchorMin = "0.5 0.5", AnchorMax = "0.5 0.5", OffsetMin = "-52 -11.5",
OffsetMax = "52 11.5"
}
}
});
container.Add(new CuiElement
{
Parent = "BUTTON_SLIDE_SCROLL_NO",
Name = "BUTTON_NO_TITLE",
DestroyUi = "BUTTON_NO_TITLE",
Components =
{
new CuiTextComponent { Text = GetLang("TITILE_NO_BUTTON", player.UserIDString, $"{percentageAgainst:F2}"), Font = "robotocondensed-bold.ttf", FontSize = 12, Color = colorText, Align = TextAnchor.MiddleCenter },
new CuiRectTransformComponent { AnchorMin = "0 1", AnchorMax = "0 1", OffsetMin = "-52 -23", OffsetMax = "52 0" }
}
});
}
else
{
Double percentageFor = (votesFor / (Double)totalVotes) * 100;
container.Add(new CuiElement
{
Parent = "BUTTON_YES_SKIP",
Name = "BUTTON_SLIDE_SCROLL_YES",
DestroyUi = "BUTTON_SLIDE_SCROLL_YES",
Components =
{
new CuiScrollViewComponent
{
MovementType = ScrollRect.MovementType.Elastic,
Horizontal = true,
Elasticity = 0.2f,
Inertia = true,
ScrollSensitivity = 0.3f,
ContentTransform = new CuiRectTransformComponent
{
AnchorMin = "80 1",
AnchorMax = "80 1",
OffsetMax = "0 0",
Pivot = "0.5 1",
},
},
new CuiImageComponent { Color = "0 0 0 0" },
new CuiRectTransformComponent
{
AnchorMin = "0.5 0.5", AnchorMax = "0.5 0.5", OffsetMin = "-52 -11.5",
OffsetMax = "52 11.5"
}
}
});
container.Add(new CuiElement
{
Parent = "BUTTON_SLIDE_SCROLL_YES",
Name = "BUTTON_YES_TITLE",
DestroyUi = "BUTTON_YES_TITLE",
Components = {
new CuiTextComponent { Text = GetLang("TITILE_YES_BUTTON", player.UserIDString, $"{percentageFor:F2}"), Font = "robotocondensed-bold.ttf", FontSize = 12, Color = colorText, Align = TextAnchor.MiddleCenter },
new CuiRectTransformComponent { AnchorMin = "0 1", AnchorMax = "0 1", OffsetMin = "-52 -23", OffsetMax = "52 0" }
}
});
}
AddUI(player, container.ToJson());
}
private const String colorNo = "0.569 0.18 0.122 1";
private Dictionary<UInt64, Boolean> playersVoted = new Dictionary<UInt64, Boolean>();
protected override void SaveConfig() => Config.WriteObject(config);
private static IQSkipNight _;
private static void DestroyUI(BasePlayer player, String elementName) => CommunityEntity.ServerInstance.ClientRPC<String>(RpcTarget.Player("DestroyUI", player.net.connection), elementName);
private const String material = "assets/content/ui/uibackgroundblur-ingamemenu.mat";
private void Init() => _ = this;
private void SendChat(String Message, BasePlayer player, Chat.ChatChannel channel = Chat.ChatChannel.Global)
{
if (IQChat && config.referencePlugins.iqchatReference.useIQChat)
IQChat.Call("API_ALERT_PLAYER", player, Message, config.referencePlugins.iqchatReference.prefixChat, config.referencePlugins.iqchatReference.customAvatar);
else player.SendConsoleCommand("chat.add", channel, 0, Message);
}
private void DrawUI_V1(BasePlayer player)
{
CuiElementContainer container = new CuiElementContainer();
container.Add(new CuiElement
{
Parent = "Overlay",
Name = layerSkipNight,
DestroyUi = layerSkipNight,
Components = {
new CuiImageComponent { Color = "0 0 0 0" },
new CuiRectTransformComponent { AnchorMin = "0.5 0", AnchorMax = "0.5 0", OffsetMin = "-199.78 81.3", OffsetMax = "180.22 114.3" }
}
});
container.Add(new CuiElement
{
Parent = layerSkipNight,
Name = "TITLE_PANEL",
DestroyUi = "TITLE_PANEL",
Components = {
new CuiImageComponent { Color = colorPanel, Material = material },
new CuiRectTransformComponent { AnchorMin = "0.5 0.5", AnchorMax = "0.5 0.5", OffsetMin = "-190 -6.5", OffsetMax = "-26 16.5" }
}
});
container.Add(new CuiElement
{
Parent = "TITLE_PANEL",
Name = "TITLE_PANEL_TEXT",
DestroyUi = "TITLE_PANEL_TEXT",
Components = {
new CuiTextComponent { Text = GetLang("TITILE_PANEL", player.UserIDString), Font = "robotocondensed-bold.ttf", FontSize = 12, Color = colorText, Align = TextAnchor.MiddleLeft },
new CuiRectTransformComponent { AnchorMin = "0.5 0.5", AnchorMax = "0.5 0.5", OffsetMin = "-73 -11.5", OffsetMax = "82 11.5" }
}
});
container.Add(new CuiElement
{
Parent = layerSkipNight,
Name = "BUTTON_YES_SKIP",
DestroyUi = "BUTTON_YES_SKIP",
Components = {
new CuiButtonComponent { Command = "vote.send true", Color = colorYes, Material = material },
new CuiRectTransformComponent { AnchorMin = "0.5 0.5", AnchorMax = "0.5 0.5", OffsetMin = "-22 -6.5", OffsetMax = "82 16.5" }
}
});
container.Add(new CuiElement
{
Parent = "BUTTON_YES_SKIP",
Name = "BUTTON_YES_TITLE",
DestroyUi = "BUTTON_YES_TITLE",
Components = {
new CuiTextComponent { Text = GetLang("TITILE_YES_BUTTON", player.UserIDString, 0.00), Font = "robotocondensed-bold.ttf", FontSize = 12, Color = colorText, Align = TextAnchor.MiddleCenter },
new CuiRectTransformComponent { AnchorMin = "0 0", AnchorMax = "1 1" }
}
});
container.Add(new CuiElement
{
Parent = layerSkipNight,
Name = "BUTTON_NO_SKIP",
DestroyUi = "BUTTON_NO_SKIP",
Components = {
new CuiButtonComponent { Command = "vote.send false", Color = colorNo, Material = material },
new CuiRectTransformComponent { AnchorMin = "0.5 0.5", AnchorMax = "0.5 0.5", OffsetMin = "86 -6.5", OffsetMax = "190 16.5" }
}
});
container.Add(new CuiElement
{
Parent = "BUTTON_NO_SKIP",
Name = "BUTTON_NO_TITLE",
DestroyUi = "BUTTON_NO_TITLE",
Components = {
new CuiTextComponent { Text = GetLang("TITILE_NO_BUTTON", player.UserIDString, 0.00), Font = "robotocondensed-bold.ttf", FontSize = 12, Color = colorText, Align = TextAnchor.MiddleCenter },
new CuiRectTransformComponent { AnchorMin = "0 0", AnchorMax = "1 1" }
}
});
container.Add(new CuiElement
{
Parent = layerSkipNight,
Name = "PROGRESS_BAR_YES",
DestroyUi = "PROGRESS_BAR_YES",
Components = {
new CuiImageComponent { Color = colorYes, Material = material },
new CuiRectTransformComponent { AnchorMin = "0 0.5", AnchorMax = "0 0.5", OffsetMin = "0 -16.5", OffsetMax = "380 -10.5" }
}
});
container.Add(new CuiElement
{
Parent = layerSkipNight,
Name = "PROGRESS_BAR_NO",
DestroyUi = "PROGRESS_BAR_NO",
Components = {
new CuiImageComponent { Color = colorNo, Material = material },
new CuiRectTransformComponent { AnchorMin = "1 0.5", AnchorMax = "1 0.5", OffsetMin = "-380 -16.5", OffsetMax = "0 -10.5" }
}
});
AddUI(player, container.ToJson());
}
private static Configuration config = new Configuration();
private void Unload()
{
if (_ == null) return;
if (timerCheckNight is { Destroyed: false })
{
timerCheckNight.Destroy();
timerCheckNight = null;
}
foreach (BasePlayer player in BasePlayer.allPlayerList)
DestroyUI(player, layerSkipNight);
playersVoted.Clear();
playersVoted = null;
_ = null;
}
private Timer timerCheckNight;
private String GetLang(String LangKey, String userID = null, params Object[] args)
{
sb.Clear();
if (args != null)
{
sb.AppendFormat(lang.GetMessage(LangKey, this, userID), args);
return sb.ToString();
}
return lang.GetMessage(LangKey, this, userID);
}
private void DrawUI_V2(BasePlayer player)
{
CuiElementContainer container = new CuiElementContainer();
container.Add(new CuiElement
{
Parent = "Overlay",
Name = layerSkipNight,
DestroyUi = layerSkipNight,
Components = {
new CuiImageComponent { Color = "0 0 0 0" },
new CuiRectTransformComponent { AnchorMin = "0.5 0", AnchorMax = "0.5 0", OffsetMin = "-328 16.19", OffsetMax = "-204 98.19" }
}
});
container.Add(new CuiElement
{
Parent = layerSkipNight,
Name = "TITLE_PANEL",
DestroyUi = "TITLE_PANEL",
Components = {
new CuiImageComponent { Color = colorPanel, Material = material },
new CuiRectTransformComponent { AnchorMin = "0.5 0.5", AnchorMax = "0.5 0.5", OffsetMin = "-62 18", OffsetMax = "62 41" }
}
});
container.Add(new CuiElement
{
Parent = "TITLE_PANEL",
Name = "TITLE_PANEL_TEXT",
DestroyUi = "TITLE_PANEL_TEXT",
Components = {
new CuiTextComponent { Text = GetLang("TITILE_PANEL", player.UserIDString), Font = "robotocondensed-bold.ttf", FontSize = 12, Color = colorText, Align = TextAnchor.MiddleCenter },
new CuiRectTransformComponent { AnchorMin = "0 0", AnchorMax = "1 1" }
}
});
container.Add(new CuiElement
{
Parent = layerSkipNight,
Name = "BUTTON_YES_SKIP",
DestroyUi = "BUTTON_YES_SKIP",
Components = {
new CuiButtonComponent { Command = "vote.send true", Color = colorYes, Material = material },
new CuiRectTransformComponent { AnchorMin = "0.5 0.5", AnchorMax = "0.5 0.5", OffsetMin = "-62 -11.5", OffsetMax = "52 11.5" }
}
});
container.Add(new CuiElement
{
Parent = "BUTTON_YES_SKIP",
Name = "BUTTON_YES_TITLE",
DestroyUi = "BUTTON_YES_TITLE",
Components = {
new CuiTextComponent { Text = GetLang("TITILE_YES_BUTTON", player.UserIDString, 0.00), Font = "robotocondensed-bold.ttf", FontSize = 12, Color = colorText, Align = TextAnchor.MiddleCenter },
new CuiRectTransformComponent { AnchorMin = "0 0", AnchorMax = "1 1" }
}
});
container.Add(new CuiElement
{
Parent = layerSkipNight,
Name = "BUTTON_NO_SKIP",
DestroyUi = "BUTTON_NO_SKIP",
Components = {
new CuiButtonComponent { Command = "vote.send false", Color = colorNo, Material = material },
new CuiRectTransformComponent { AnchorMin = "0.5 0.5", AnchorMax = "0.5 0.5", OffsetMin = "-62 -41", OffsetMax = "52 -18" }
}
});
container.Add(new CuiElement
{
Parent = "BUTTON_NO_SKIP",
Name = "BUTTON_NO_TITLE",
DestroyUi = "BUTTON_NO_TITLE",
Components = {
new CuiTextComponent { Text = GetLang("TITILE_NO_BUTTON", player.UserIDString, 0.00), Font = "robotocondensed-bold.ttf", FontSize = 12, Color = colorText, Align = TextAnchor.MiddleCenter },
new CuiRectTransformComponent { AnchorMin = "0 0", AnchorMax = "1 1" }
}
});
container.Add(new CuiElement
{
Parent = layerSkipNight,
Name = "PROGRESS_BAR_YES",
DestroyUi = "PROGRESS_BAR_YES",
Components = {
new CuiImageComponent { Color = colorYes, Material = material },
new CuiRectTransformComponent { AnchorMin = "0.5 1", AnchorMax = "0.5 1", OffsetMin = "56 -82", OffsetMax = "62 -29.5" }
}
});
container.Add(new CuiElement
{
Parent = layerSkipNight,
Name = "PROGRESS_BAR_NO",
DestroyUi = "PROGRESS_BAR_NO",
Components = {
new CuiImageComponent { Color = colorNo, Material = material },
new CuiRectTransformComponent { AnchorMin = "0.5 0", AnchorMax = "0.5 0", OffsetMin = "56 0", OffsetMax = "62 52.5" }
}
});
AddUI(player, container.ToJson());
}
private new void LoadDefaultMessages()
{
lang.RegisterMessages(new Dictionary<String, String>
{
["MESSAGE_START_VOTE"] = "A vote to skip the night has started!\nDon’t stay on the sidelines – cast your vote!",
["MESSAGE_AUTO_SKIP"] = "The night was automatically skipped",
["MESSAGE_VOTE_FAILED"] = "Vote to skip the night failed – not enough players to vote",
["MESSAGE_VOTE_COMPLETE"] = "Vote to skip the night has concluded!\nResult: {0}\nYes: {1}\nNo: {2}\nAbstained: {3}\nGet involved – don’t stay on the sidelines!",
["RESULT_TRUE"] = "the night will be skipped",
["RESULT_FALSE"] = "the night will not be skipped",
["TITILE_YES_BUTTON"] = "YES ({0}%)",
["TITILE_NO_BUTTON"] = "NO ({0}%)",
["TITILE_PANEL"] = "SKIP NIGHT",
}, this);
lang.RegisterMessages(new Dictionary<String, String>
{
["MESSAGE_START_VOTE"] = "Голосование за пропуск ночи запущено!\nНе оставайся в стороне - проголосуй!",
["MESSAGE_AUTO_SKIP"] = "Ночь была автоматически пропущена",
["MESSAGE_VOTE_FAILED"] = "Голосование за пропуск ночи пропущено, недостаточно игроков для голосования",
["MESSAGE_VOTE_COMPLETE"] = "Голосование за пропуск ночи заверешено!\nРезультат : {0}\nПроголосовало за : {1}\nПроголосовало против : {2}\nВоздержалось : {3}\nПринимайте участие, не оставайтесь в стороне!",
["RESULT_TRUE"] = "ночь будет пропущена",
["RESULT_FALSE"] = "ночь не будет пропущена",
["TITILE_YES_BUTTON"] = "ЗА ({0}%)",
["TITILE_NO_BUTTON"] = "ПРОТИВ ({0}%)",
["TITILE_PANEL"] = "ПРОПУСК НОЧИ",
}, this, "ru");
}
private Timer timerProcessNight;
private Int32 dayVote;
private const String colorText = "0.89485151 0.854902 0.8196079 1";
private Boolean announcedNotEnoughPlayers;
private const String colorPanel = "0.325 0.325 0.325 0.6";
private void OnServerInitialized()
{
timerCheckNight = timer.Every(30f, CheckTimeServer);
config.voteController.secondsVote = config.voteController.timeVote * 60;
}
private const Boolean LanguageEn = false;
private class Configuration
{
[JsonProperty(LanguageEn ? "Automatically skip night without voting [true - yes / false - no]" : "Пропускать ночь автоматически, без голосования [true - да / false - нет]")]
public Boolean noVoteAllSkip;
internal class VoteController
{
[JsonProperty(LanguageEn ? "Minimum number of players online to start voting" : "Минимальное количество игроков онлайн для начала голосования")]
public Int32 amountPlayers;
[JsonProperty(LanguageEn ? "Time to start voting (in-game hour, e.g., 20 means 20:00)" : "Время начала голосования (в игровых часах, например, 20 — это 20:00)")]
public Int32 timeStartSkip;
[JsonProperty(LanguageEn ? "Time to set after skipping night (in-game hour, e.g., 8 means 08:00)" : "Время, которое устанавливается после пропуска ночи (в игровых часах, например, 8 — это 08:00)")]
public Int32 timeDay;
[JsonProperty(LanguageEn ? "Required percentage of 'YES' votes to skip night (e.g., 60 means 60% must vote yes)" : "Процент голосов 'ДА' для успешного пропуска (например, 60 означает, что 60% игроков должно проголосовать за)")]
public Int32 percentVote;
[JsonProperty(LanguageEn ? "Duration of voting in minutes" : "Длительность голосования в минутах")]
public Int32 timeVote;
[JsonIgnore] public Int32 secondsVote;
}
[JsonProperty(LanguageEn ? "" : "Настройка поддерживаемых плагинов")]
public ReferencePlugins referencePlugins = new ReferencePlugins();
internal class ReferencePlugins
{
internal class IQChat
{
[JsonProperty(LanguageEn ? "Prefix for IQChat" : "Префикс для IQChat")]
public String prefixChat;
[JsonProperty(LanguageEn ? "Use IQChat" : "Использовать IQChat")]
public Boolean useIQChat;
[JsonProperty(LanguageEn ? "Avatar for IQChat [Steam64ID]" : "Аватарка для IQChat [Steam64ID]")]
public String customAvatar;
}
[JsonProperty(LanguageEn ? "IQChat settings" : "Настройка IQChat")]
public IQChat iqchatReference = new IQChat();
}
[JsonProperty(LanguageEn ? "Night skip voting settings" : "Настройка голосования за пропуск ночи")]
public VoteController voteController = new VoteController();
public static Configuration GetNewConfiguration()
{
return new Configuration
{
noVoteAllSkip = false,
V1orV2 = true,
voteController = new VoteController
{
amountPlayers = 0,
timeStartSkip = 19,
timeDay = 12,
percentVote = 20,
timeVote = 3,
},
fastSkipController = new FastSkipNight
{
timeStartSkip = 19,
timeDay = 12
},
referencePlugins = new ReferencePlugins()
{
iqchatReference = new ReferencePlugins.IQChat
{
useIQChat = false,
customAvatar = "0",
prefixChat = LanguageEn ? "[SkipNight]\n" : "[Пропуск ночи]\n"
}
}
};
}
internal class FastSkipNight
{
[JsonProperty(LanguageEn ? "Time to skip night (in in-game hours, e.g., 20 means 20:00)" : "Время для пропуска ночи (в игровых часах, например, 20 — это 20:00)")]
public Int32 timeStartSkip;
[JsonProperty(LanguageEn ? "Time to set after skipping night (in-game hour, e.g., 8 means 08:00)" : "Время, которое устанавливается после пропуска ночи (в игровых часах, например, 8 — это 08:00)")]
public Int32 timeDay;
}
[JsonProperty(LanguageEn ? "Instant night skip setting" : "Настройка моментального пропуска ночи")]
public FastSkipNight fastSkipController = new FastSkipNight();
[JsonProperty(LanguageEn ? "" : "Тип интерфейса. V1 - true, V2 - false")]
public Boolean V1orV2;
public Boolean IsNight()
{
if (_.timerProcessNight is { Destroyed: false }) return false;
if (_.dayVote == TOD_Sky.Instance.Cycle.Day) return false;
Int32 hourRounded = (Int32)Math.Round(TOD_Sky.Instance.Cycle.Hour);
if (noVoteAllSkip)
return hourRounded >= fastSkipController.timeStartSkip;
return hourRounded >= voteController.timeStartSkip;
}
}
}
}