C#:
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Reflection;
using Facepunch;
using Newtonsoft.Json;
using Oxide.Core;
using Oxide.Core.Plugins;
using Oxide.Game.Rust.Cui;
using Rust;
using UnityEngine;
namespace Oxide.Plugins {
[Info("FightZ", "XAVIER", "1.0.0")]
public class FightZ : RustPlugin {
#region Var
private static FieldInfo hookSubscriptions = typeof(PluginManager).GetField("hookSubscriptions", (BindingFlags.Instance | BindingFlags.NonPublic));
[PluginReference]
private Plugin ImageLibrary, Clans;
public Timer TimerEvent;
private static FightZ _ins;
private ZoneComponent _activeEvent;
private static string Layer = "UI_MaskFightLayer";
public Dictionary<ulong, int> _playerKill = new Dictionary<ulong, int>();
static SpawnFilter filter = new SpawnFilter();
static List<Vector3> monuments = new List<Vector3>();
static 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
}
;
static int blockedMask = LayerMask.GetMask(new[] {
"Player (Server)", "Trigger", "Prevent Building"
}
);
#endregion
#region Generate Position
public static Vector3 RandomDropPosition() {
var vector = Vector3.zero;
float num = 100f, x = TerrainMeta.Size.x / 3;
do {
vector = Vector3Ex.Range(-x, x);
}
while (filter.GetFactor(vector) == 0f && (num -= 1f) > 0f);
float max = TerrainMeta.Size.x / 2;
float height = TerrainMeta.HeightMap.GetHeight(vector);
vector.y = height;
return vector;
}
public Vector3 GetSafeDropPosition(Vector3 position) {
RaycastHit hit;
position.y += 200f;
if (Physics.Raycast(position, Vector3.down, out hit)) {
if (hit.collider?.gameObject == null) return Vector3.zero;
string ColName = hit.collider.name;
if (!BlockedLayers.Contains(hit.collider.gameObject.layer) && ColName != "MeshColliderBatch" && ColName != "iceberg_3" && ColName != "iceberg_2" && !ColName.Contains("rock_cliff")) {
position.y = Mathf.Max(hit.point.y, TerrainMeta.HeightMap.GetHeight(position));
var colliders = Pool.GetList<Collider>();
Vis.Colliders(position, 1, colliders, blockedMask, QueryTriggerInteraction.Collide);
bool blocked = colliders.Count > 0;
Pool.FreeList<Collider>(ref colliders);
if (!blocked) return position;
}
}
return Vector3.zero;
}
public Vector3 GetEventPosition() {
var eventPos = Vector3.zero;
int maxRetries = 100;
monuments = UnityEngine.Object.FindObjectsOfType<MonumentInfo>().Select(monument => monument.transform.position).ToList();
do {
eventPos = GetSafeDropPosition(RandomDropPosition());
foreach (var monument in monuments) {
if (Vector3.Distance(eventPos, monument) < 150f) {
eventPos = Vector3.zero;
break;
}
}
}
while (eventPos == Vector3.zero && --maxRetries > 0);
return eventPos;
}
private List<Vector3> PositionListed = new List<Vector3>();
private void FindPositions() {
List<Vector3> NewListed = new List<Vector3>();
for (int i = 0; i < 100; i++) {
var position = TryFindPosition();
if (position != null) NewListed.Add(position.Value);
}
PositionListed = NewListed;
Puts($"Найдено {PositionListed.Count} позиций");
GetEventTime();
}
private Vector3? TryFindPosition() {
var position = GetEventPosition();
var height = TerrainMeta.HeightMap.GetHeight(position);
if (height > 0) position.y = height;
else return null;
return CheckBadBuilding(position) ? (Vector3?)null : position;
}
private bool CheckBadBuilding(Vector3 position) {
var buildings = new List<BuildingBlock>();
Vis.Entities(position, 150, buildings, Layers.Construction);
return buildings.Count > 0;
}
private Vector3 FindPosition() {
Vector3 position = PositionListed.GetRandom();
if (position != null) {
PositionListed.Remove(position);
return position;
}
return new Vector3();
}
#endregion
#region Hooks
void OnServerInitialized() {
_ins = this;
try {
_playerKill = Interface.GetMod().DataFileSystem.ReadObject<Dictionary<ulong, int>>(Name);
if (_playerKill == null) _playerKill = new Dictionary<ulong, int>();
}
catch {
_playerKill = new Dictionary<ulong, int>();
}
foreach (var keyRatePerm in config._Settings._ratePerms) {
if (!permission.PermissionExists(keyRatePerm.Key, this)) permission.RegisterPermission(keyRatePerm.Key, this);
}
SubscribeInternalHook("IOnBasePlayerHurt");
ImageLibrary?.CallHook("AddImage", config._Settings.IconNotification, config._Settings.IconNotification);
ImageLibrary?.CallHook("AddImage", "https://i.imgur.com/pYGyLH8.png", "close");
FindPositions();
}
void OnPlayerConnected(BasePlayer player) {
if (_activeEvent != null) _activeEvent.StartUI(player);
}
object CanBuild(Planner planner, Construction prefab, Construction.Target target) {
var player = planner.GetOwnerPlayer();
if (player == null) return null;
if (_activeEvent == null) return null;
if (_activeEvent != null && _activeEvent.IsFightZone(player)) {
var shortname = prefab.hierachyName.Substring(prefab.hierachyName.IndexOf("/") + 1);
if (config._Settings.WhiteEntity.Contains(shortname)) {
return null;
}
return false;
}
return null;
}
void Unload() {
if (_activeEvent != null) {
_activeEvent.Kill();
_activeEvent = null;
}
if (TimerEvent != null) TimerEvent.Destroy();
_ins = null;
config = null;
}
private object IOnBasePlayerHurt(BasePlayer player, HitInfo info) {
if (_activeEvent == null) return null;
if (player == null || player is NPCPlayer || info?.Initiator == null) return null;
var initiator = info?.Initiator.ToPlayer();
if (initiator == null || initiator is NPCPlayer) return null;
if (player == initiator) return null;
if (_activeEvent.IsFightZone(player) && !_activeEvent.IsFightZone(initiator)) {
DisableDamage(info);
return false;
}
return null;
}
object OnPlayerDeath(BasePlayer player, HitInfo info) {
if (_activeEvent == null) return null;
if (player == null || info == null) return null;
var initiator = info.InitiatorPlayer;
if (initiator == null) return null;
if (_activeEvent.IsFightZone(info.InitiatorPlayer)) {
if (player != initiator) {
Clans?.CallHook("AddPoints", info.InitiatorPlayer.userID, config._ClanSupport.AddPointKill);
if (!_playerKill.ContainsKey(info.InitiatorPlayer.userID)) _playerKill.Add(info.InitiatorPlayer.userID, 1);
else _playerKill[info.InitiatorPlayer.userID]++;
}
}
if (_activeEvent.IsFightZone(player)) {
Clans?.CallHook("RemovePoints", player.userID, config._ClanSupport.RemovePointKill);
_activeEvent.RemoveZone(player);
}
return null;
}
public float GetRate(BasePlayer player) {
float rate = config._Settings.DefaultRate;
foreach (var key in config._Settings._ratePerms) {
if (permission.UserHasPermission(player.UserIDString, key.Key)) rate = key.Value;
}
return rate;
}
object OnDispenserBonus(ResourceDispenser dispenser, BasePlayer player, Item item) {
if (player == null) return null;
if (_activeEvent == null) return null;
if (_activeEvent.IsFightZone(player)) {
_activeEvent.RemoveStone(dispenser.GetComponent<BaseEntity>().net.ID.Value);
var count = Math.Round(item.amount * GetRate(player));
item.amount = (int)count;
}
return null;
}
void OnDispenserGather(ResourceDispenser dispenser, BaseEntity entity, Item item) {
if (dispenser == null || entity == null || item == null) return;
BasePlayer player = entity.ToPlayer();
if (player == null) return;
if (_activeEvent == null) return;
if (_activeEvent.IsFightZone(player)) {
var count = Math.Round(item.amount * GetRate(player));
item.amount = (int)count;
}
}
#endregion
#region Timer
public void GetEventTime() {
if (TimerEvent != null) TimerEvent.Destroy();
TimerEvent = timer.Once(UnityEngine.Random.Range(config._Settings.MinIventTime, config._Settings.MaxIventTime), () => {
GenerateSphere();
}
);
}
#endregion
#region GenerateSphere
public bool GenerateSphere() {
if (BasePlayer.activePlayerList.Count < config._Settings.MinPlayer) {
PrintWarning("Ивент 'FIGHT ZONE' Не запущен. Причина: Недостаточно игроков для проведения ивента");
GetEventTime();
return false;
}
if (_activeEvent != null) {
PrintWarning("Ивент 'FIGHT ZONE' Не запущен. Причина: Ивент уже активен");
GetEventTime();
return false;
}
Vector3 position = FindPosition();
if (position == new Vector3()) {
PrintWarning("Ивент 'FIGHT ZONE' Не запущен. Причина: Позиция спавна неккоретная. Рекомендую перезагрузить плагин");
GetEventTime();
return false;
}
_activeEvent = new GameObject().AddComponent<ZoneComponent>().Init(position);
foreach (var target in BasePlayer.activePlayerList) {
Effect z = new Effect("assets/bundled/prefabs/fx/invite_notice.prefab", target, 0, new Vector3(), new Vector3());
EffectNetwork.Send(z, target.Connection);
}
return true;
}
#endregion
#region Functional
private void DisableDamage(HitInfo info) {
info.damageTypes = new DamageTypeList();
info.DidHit = false;
info.HitEntity = null;
info.Initiator = null;
info.DoHitEffects = false;
info.HitMaterial = 0;
}
private void SubscribeInternalHook(string hook) {
var hookSubscriptions_ = hookSubscriptions.GetValue(Interface.Oxide.RootPluginManager) as IDictionary<string, IList<Plugin>>;
IList<Plugin> plugins;
if (!hookSubscriptions_.TryGetValue(hook, out plugins)) {
plugins = new List<Plugin>();
hookSubscriptions_.Add(hook, plugins);
}
if (!plugins.Contains(this)) plugins.Add(this);
}
#endregion
#region Console && Chat Command
[ConsoleCommand("FightZHandler")]
void FightZHandler(ConsoleSystem.Arg args) {
BasePlayer player = args.Player();
if (_activeEvent == null) return;
if (_activeEvent._openPlayerButton.Contains(player.userID)) {
_activeEvent._openPlayerButton.Remove(player.userID);
_activeEvent.StartUI(player);
}
else {
_activeEvent._openPlayerButton.Add(player.userID);
_activeEvent.StartUI(player);
}
}
[ChatCommand("fz")]
void CommandHandlerFightZ(BasePlayer player, string command, string[] args) {
if (!player.IsAdmin) {
if (args.Length > 0) return;
string topPoint = "Топ 5 игроков по убийствам в FZ:\n";
int iss = 1;
foreach (var value in _playerKill.OrderByDescending(p => p.Value).Take(5)) {
string name = null;
if (covalence.Players.FindPlayer(value.Key.ToString()) != null) {
name = covalence.Players.FindPlayer(value.Key.ToString()).Name;
}
if (name == null) name = "Неизвестный";
int amounts = value.Value;
topPoint = topPoint + $"{iss.ToString()}" + ". " + $"{name} : " + $"{amounts.ToString()}" + "\n";
iss++;
if (iss > 5) break;
}
player.ChatMessage(topPoint);
}
else {
if (args.Length == 0) {
player.ChatMessage("Доступные команды:" + "\n/fz start - Запустить ивент" + "\n/fz stop - Окончить ивент");
return;
}
if (args[0] == "start") {
if (!GenerateSphere()) player.ChatMessage("Ивент не был запущен! Причина в консоли");
else player.ChatMessage("Вы успешно запустили ивент");
}
else if (args[0] == "stop") {
if (_activeEvent == null) {
player.ChatMessage("Ошибка! Ивент уже неактивен. Пропишите /fz start для запуска ивента");
return;
}
_activeEvent.Kill();
_activeEvent = null;
player.ChatMessage("Вы успешно остановили ивент!");
}
}
}
#endregion
#region Component
public class ZoneComponent : MonoBehaviour {
public List<SphereEntity> _SphereEntities = new List<SphereEntity>();
public List<BasePlayer> _playerList = new List<BasePlayer>();
public List<ulong> _openPlayerButton = new List<ulong>();
public List<ulong> _stonesList = new List<ulong>(_ins.config._Settings.MaxStone);
// max spawn
public MapMarkerGenericRadius mapMarker;
public VendingMachineMapMarker vendingMarker;
public double StartTime = 0;
public double EventLength = 0;
public double StartTimeStones = 0;
public double StonesLength = 0;
public int Radius = 0;
public string Image = string.Empty;
private void Awake() {
gameObject.layer = (int)Rust.Layer.Reserved1;
gameObject.name = "FightZone";
enabled = false;
}
public ZoneComponent Init(Vector3 position) {
Radius = _ins.config._Settings.SphereRadius;
EventLength = _ins.config._Settings.FightLength;
StonesLength = _ins.config._Settings.InvokeUpdateStone;
StartTimeStones = _ins.config._Settings.InvokeUpdateStone;
Image = _ins.config._Settings.IconNotification;
var collider = gameObject.GetComponent<SphereCollider>() ?? gameObject.AddComponent<SphereCollider>();
collider.radius = Radius;
collider.isTrigger = true;
collider.enabled = true;
collider.gameObject.layer = (int)Rust.Layer.Reserved1;
_stonesList.Capacity = _ins.config._Settings.MaxStone;
for (int i = 0; i < 5; i++) {
var entity = GameManager.server.CreateEntity("assets/prefabs/visualization/sphere.prefab", position) as SphereEntity;
entity.currentRadius = 1f;
entity.Spawn();
entity.LerpRadiusTo((Radius * 2f) + 1f, 5f);
_SphereEntities.Add(entity);
}
transform.position = position;
gameObject.SetActive(true);
enabled = true;
foreach (var target in BasePlayer.activePlayerList) {
//target.StopAllCoroutines();
StartUI(target);
}
if (_ins.config._MarkerSettings.isMapGame) {
RemoveMarker();
UpdateMarker();
}
InvokeRepeating("UpdateTime", 0f, 1f);
return this;
}
private void RemoveMarker() {
if (mapMarker != null && !mapMarker.IsDestroyed) mapMarker.Kill();
if (vendingMarker != null && !vendingMarker.IsDestroyed) vendingMarker.Kill();
}
public void UpdateMarker() {
RemoveMarker();
mapMarker = GameManager.server.CreateEntity("assets/prefabs/tools/map/genericradiusmarker.prefab", transform.position) as MapMarkerGenericRadius;
mapMarker.enableSaving = false;
mapMarker.Spawn();
mapMarker.radius = _ins.config._MarkerSettings.RadiusMarker;
mapMarker.alpha = 0.9f;
mapMarker.color1 = ConvertToColor(_ins.config._MarkerSettings.MarkerC);
mapMarker.SendUpdate();
mapMarker.SendNetworkUpdate();
vendingMarker = GameManager.server.CreateEntity("assets/prefabs/deployable/vendingmachine/vending_mapmarker.prefab", transform.position).GetComponent<VendingMachineMapMarker>();
vendingMarker.markerShopName = _ins.config._MarkerSettings.NameMarker;
vendingMarker.Spawn();
}
private Color ConvertToColor(string color) {
if (color.StartsWith("#")) color = color.Substring(1);
int red = int.Parse(color.Substring(0, 2), NumberStyles.AllowHexSpecifier);
int green = int.Parse(color.Substring(2, 2), NumberStyles.AllowHexSpecifier);
int blue = int.Parse(color.Substring(4, 2), NumberStyles.AllowHexSpecifier);
return new Color((float)red / 255, (float)green / 255, (float)blue / 255);
}
public void UpdateTime() {
UpdatePlayer();
StartTime++;
foreach (var player in BasePlayer.activePlayerList) {
UpdateProgress(player);
// стыдно че пиздец
}
if (StartTime >= EventLength) {
Kill();
}
else {
StartTimeStones++;
if (StartTimeStones >= StonesLength) {
UpdateStones();
StartTimeStones = 0;
}
}
}
#region Stones
public List<string> _stonesPrefab = new List<string>() {
{
"assets/bundled/prefabs/autospawn/resource/ores/sulfur-ore.prefab"
}
, {
"assets/bundled/prefabs/autospawn/resource/ores/metal-ore.prefab"
}
, {
"assets/bundled/prefabs/autospawn/resource/ores/stone-ore.prefab"
}
}
;
public int RandomRange() {
return UnityEngine.Random.Range(2, (int)_ins.config._Settings.SphereRadius - 5);
}
void UpdateStones() {
int spawnCount = _stonesList.Capacity - _stonesList.Count;
if (spawnCount > 0) {
for (int i = 0; i < spawnCount; i++) {
string stonePrefab = _stonesPrefab.GetRandom();
var entity = GameManager.server.CreateEntity(stonePrefab, RandomCircle(transform.position, RandomRange()));
if (entity == null) continue;
entity.OwnerID = 48674;
entity.Spawn();
_stonesList.Add(entity.net.ID.Value);
}
}
}
static Vector3 RandomCircle(Vector3 center, float radius = 2) {
float ang = UnityEngine.Random.value * 360;
Vector3 pos = Vector3.zero;
pos.x = center.x + radius * Mathf.Sin(ang * Mathf.Deg2Rad);
pos.z = center.z + radius * Mathf.Cos(ang * Mathf.Deg2Rad);
pos.y = TerrainMeta.HeightMap.GetHeight(pos);
return pos;
}
#endregion
public void UpdatePlayer() {
foreach (var key in _playerList) {
if (key == null) {
RemoveZone(key);
continue;
}
if (Vector3.Distance(key.transform.position, transform.position) > Radius) {
RemoveZone(key);
continue;
}
}
}
void OnTriggerEnter(Collider col) {
var player = col.ToBaseEntity() as BasePlayer;
if (!player || player.IsNpc || !player.userID.IsSteamId()) return;
if (!_playerList.Contains(player)) _playerList.Add(player);
}
void OnTriggerExit(Collider col) {
var player = col.ToBaseEntity() as BasePlayer;
if (!player || player.IsNpc || !player.userID.IsSteamId()) return;
if (_playerList.Contains(player)) _playerList.Remove(player);
}
public void Kill() {
_ins.GetEventTime();
DestroyImmediate(this);
}
private void OnDestroy() {
CancelInvoke();
RemoveMarker();
if (_SphereEntities.Count > 0) {
foreach (var entity in _SphereEntities) {
if (entity != null && !entity.IsDestroyed) entity.Kill();
}
}
foreach (var key in _stonesList) {
var ent = BaseNetworkable.serverEntities.Find(new NetworkableId(key));
if (ent != null && !ent.IsDestroyed) ent.Kill();
}
foreach (var target in BasePlayer.activePlayerList) {
DestroyUI(target);
}
_ins._activeEvent = null;
_SphereEntities = null;
}
public bool IsFightZone(BasePlayer player) => _playerList.Contains(player);
public void RemoveZone(BasePlayer player) {
if (_playerList.Contains(player)) _playerList.Remove(player);
}
public void RemoveStone(ulong netID) {
if (_stonesList.Contains(netID)) _stonesList.Remove(netID);
}
#region UI
public void DestroyUI(BasePlayer player) => CuiHelper.DestroyUi(player, Layer);
public void StartUI(BasePlayer player) {
CuiHelper.DestroyUi(player, Layer);
var container = new CuiElementContainer();
container.Add(new CuiPanel {
RectTransform = {
AnchorMin = "1 0", AnchorMax = "1 0", OffsetMin = $"-220 340", OffsetMax = $"-4 380"
}
, Image = {
Color = "0 0 0 0"
}
}
, "Overlay", Layer);
container.Add(new CuiButton {
RectTransform = {
AnchorMin = "0.8148147 0", AnchorMax = "1 1"
}
, Button = {
Color = HexToCuiColor("#fffdfc", 20), Command = "FightZHandler"
}
, Text = {
Text = ""
}
}
, Layer, ".GetPanel");
container.Add(new CuiElement {
Parent = Layer, Components = {
new CuiRawImageComponent {
FadeIn = 0.3f, Png = (string)_ins.ImageLibrary.Call("GetImage", Image)
}
, new CuiRectTransformComponent {
AnchorMin = "0.8395064 0.1500004", AnchorMax = "0.9722222 0.8666668"
}
, new CuiOutlineComponent {
Color = "0 0 0 1", Distance = "0.6 0.6"
}
,
}
}
);
container.Add(new CuiPanel {
RectTransform = {
AnchorMin = "0 0", AnchorMax = $"{(float) (EventLength - StartTime) / EventLength} 0.02000013"
}
, Image = {
Color = "",
}
}
, ".GetPanel", Layer + ".ProgressUpdate");
container.Add(new CuiButton {
RectTransform = {
AnchorMin = "0 0", AnchorMax = "1 1"
}
, Button = {
Color = HexToCuiColor("#fffdfc", 20), Command = "FightZHandler"
}
, Text = {
Text = ""
}
}
, ".GetPanel");
if (_openPlayerButton.Contains(player.userID)) {
container.Add(new CuiPanel {
RectTransform = {
AnchorMin = "0 0", AnchorMax = "0.8055556 1"
}
, Image = {
Color = HexToCuiColor("#fffdfc", 20),
}
}
, Layer);
container.Add(new CuiElement() {
Parent = Layer, Name = Layer + ".TextUpdate", Components = {
new CuiTextComponent {
Color = HexToCuiColor("#FCF7F6"), Text = $"<b>ИВЕНТ “FIGHT ZONE” [{GetFormatTime(TimeSpan.FromSeconds(EventLength - StartTime))}]</b>\n<size=10>На карте ( G ) отмечено маркером место, где происходит данный ивент. В данном месте увеличенный спавн камней и рейтов.</size>", Align = TextAnchor.UpperLeft, FontSize = 12, Font = "robotocondensed-regular.ttf"
}
, new CuiRectTransformComponent {
AnchorMin = "0.0216046 0", AnchorMax = "0.7546528 1"
}
, new CuiOutlineComponent {
Color = "0 0 0 1", Distance = "0.3 0.3"
}
,
}
}
);
container.Add(new CuiButton {
RectTransform = {
AnchorMin = "0.7499998 0.7000008", AnchorMax = "0.8055556 1"
}
, Button = {
Command = $"FightZHandler", Color = HexToCuiColor("#ac555c")
}
, Text = {
Text = "", Color = HexToCuiColor($"#e1d6cc"), Align = TextAnchor.MiddleCenter, FontSize = 13, Font = "robotocondensed-bold.ttf"
}
}
, Layer, ".Close");
container.Add(new CuiElement {
Parent = ".Close", Components = {
new CuiRawImageComponent {
FadeIn = 0.3f, Png = (string)_ins.ImageLibrary.Call("GetImage", "close")
}
, new CuiRectTransformComponent {
AnchorMin = "0 0", AnchorMax = "1 1", OffsetMin = "3 3", OffsetMax = "-3 -3"
}
}
}
);
}
CuiHelper.AddUi(player, container);
}
public void UpdateProgress(BasePlayer player) {
var container = new CuiElementContainer();
CuiHelper.DestroyUi(player, Layer + ".ProgressUpdate");
container.Add(new CuiPanel {
RectTransform = {
AnchorMin = "0 0", AnchorMax = $"{(float) (EventLength - StartTime) / EventLength} 0.02000013"
}
, Image = {
Color = "",
}
}
, ".GetPanel", Layer + ".ProgressUpdate");
if (_openPlayerButton.Contains(player.userID)) {
CuiHelper.DestroyUi(player, Layer + ".TextUpdate");
container.Add(new CuiElement() {
Parent = Layer, Name = Layer + ".TextUpdate", Components = {
new CuiTextComponent {
Color = HexToCuiColor("#FCF7F6"), Text = $"<b>ИВЕНТ “FIGHT ZONE” [{GetFormatTime(TimeSpan.FromSeconds(EventLength - StartTime))}]</b>\n<size=10>На карте ( G ) отмечено маркером место, где происходит данный ивент. В данном месте увеличенный спавн камней и рейтов.</size>", Align = TextAnchor.UpperLeft, FontSize = 12, Font = "robotocondensed-regular.ttf"
}
, new CuiRectTransformComponent {
AnchorMin = "0.0216046 0", AnchorMax = "0.7546528 1"
}
, new CuiOutlineComponent {
Color = "0 0 0 1", Distance = "0.3 0.3"
}
,
}
}
);
}
CuiHelper.AddUi(player, container);
}
public string HexToCuiColor(string HEX, float Alpha = 100) {
if (string.IsNullOrEmpty(HEX)) HEX = "#FFFFFF";
var str = HEX.Trim('#');
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);
return $"{(double) r / 255} {(double) g / 255} {(double) b / 255} {Alpha / 100}";
}
private string GetFormatTime(TimeSpan timespan) {
return string.Format(timespan.TotalHours >= 1 ? "{2:00}:{0:00}:{1:00}" : "{0:00}:{1:00}", timespan.Minutes, timespan.Seconds, System.Math.Floor(timespan.TotalHours));
}
#endregion
}
#endregion
#region Configuration
private PluginConfig config;
protected override void LoadDefaultConfig() {
config = PluginConfig.DefaultConfig();
}
protected override void LoadConfig() {
base.LoadConfig();
config = Config.ReadObject<PluginConfig>();
if (config.PluginVersion < Version) UpdateConfigValues();
Config.WriteObject(config, true);
}
private void UpdateConfigValues() {
PluginConfig baseConfig = PluginConfig.DefaultConfig();
if (config.PluginVersion < new VersionNumber(1, 0, 0)) {
PrintWarning("Config update detected! Updating config values...");
PrintWarning("Config update completed!");
}
config.PluginVersion = Version;
}
protected override void SaveConfig() {
Config.WriteObject(config);
}
public class MainSettings {
[JsonProperty("Минимальное количество игроков для запуска")]
public int MinPlayer;
[JsonProperty("Минимальное время до начала ивента ( в секундах )")]
public int MinIventTime;
[JsonProperty("Максимальное время до начала ивента ( в секундах )")]
public int MaxIventTime;
[JsonProperty("Радиус сферы")]
public int SphereRadius;
[JsonProperty("Длительность ивента")]
public double FightLength;
[JsonProperty("Максимальное количество камней, которые будут заспавнены в зоне")]
public int MaxStone;
[JsonProperty("Циклическое обновление камней ( в секундах )")]
public int InvokeUpdateStone;
[JsonProperty("Иконка оповещения ( 43x43 )")]
public string IconNotification;
[JsonProperty("Дефолтные рейты в зоне сферы")]
public float DefaultRate;
[JsonProperty("Рейты в зависимости от привилегии ( permission => rate )")]
public Dictionary<string, float> _ratePerms = new Dictionary<string, float>();
[JsonProperty("Объекты, которые можно устанавливать в сфере")]
public List<string> WhiteEntity = new List<string>();
}
public class ClanSupport {
[JsonProperty("Добавить поддержку Clans ?")]
public bool ClansSupport;
[JsonProperty("Сколько добавлять очков при убийстве игрока в зоне")]
public int AddPointKill;
[JsonProperty("Сколько снимать очков при смерти игрока в зоне")]
public int RemovePointKill;
}
public class MarkerSettings {
[JsonProperty("Добавить маркер и радиус на карту G ?")]
public bool isMapGame;
[JsonProperty("Отображаемое имя на марке")]
public string NameMarker;
[JsonProperty("Цвет радиуса")]
public string MarkerC;
[JsonProperty("Радиус маркера")]
public float RadiusMarker;
}
private class PluginConfig {
[JsonProperty("Основная настройка плагина")]
public MainSettings _Settings = new MainSettings();
[JsonProperty("Настройка маркера")]
public MarkerSettings _MarkerSettings = new MarkerSettings();
[JsonProperty("Настройка поддержки плагина Clans")]
public ClanSupport _ClanSupport = new ClanSupport();
[JsonProperty("Версия конфигурации")]
public VersionNumber PluginVersion = new VersionNumber();
public static PluginConfig DefaultConfig() {
return new PluginConfig() {
_Settings = new MainSettings() {
MinPlayer = 1, MinIventTime = 3600, MaxIventTime = 7200, SphereRadius = 30, FightLength = 600, IconNotification = "https://i.imgur.com/r4NXdOn.png", DefaultRate = 10.0f, MaxStone = 20, InvokeUpdateStone = 120, _ratePerms = new Dictionary<string, float>() {
["fightz.use50"]
= 50.0f, ["fightz.use30"] = 30.0f, ["fightz.use15"] = 15.0f,
}
, WhiteEntity = new List<string>() {
"wall.external.high.stone", "barricade.metal", "sleepingbag"
}
}
, _MarkerSettings = new MarkerSettings() {
isMapGame = true, NameMarker = "FIGHT ZONE", MarkerC = "#ffb700", RadiusMarker = 1f,
}
, _ClanSupport = new ClanSupport() {
ClansSupport = true, AddPointKill = 20, RemovePointKill = 30,
}
, PluginVersion = new VersionNumber(),
}
;
}
}
#endregion
}
}