C#:
// Все права принадлежат дискорд сообществу https://discord.gg/VgNHPpNrz6
using System;
using System.Collections.Generic;
using Oxide.Core;
using Oxide.Core.Configuration;
using Oxide.Core.Plugins;
using UnityEngine;
namespace Oxide.Plugins {
[Info("RadShrinkZone", "vaalberith", "1.0.6", ResourceId = 1828)]
class RadShrinkZone : RustPlugin {
//DEFAULT VALUES
Vector3 target = new Vector3(0, 0, 0);
float saferadius = 10;
float saferadiusmin = 5;
float eventradius = 40;
float radpower = 50;
float step = 1;
float period = 20;
//float drawtime = 5;
//string drawmode = "both";
string permissionrad = "RadShrinkZone.can";
bool breaking = true;
bool ok = true;
//INITIALISATION\DECLARATION
List<Vector3> position = new List<Vector3>();
readonly DynamicConfigFile dataFile = Interface.Oxide.DataFileSystem.GetFile("RadShrinkZoneDefault");
Dictionary<string, List<string>> radzonedata = new Dictionary<string, List<string>>();
//LOCALIZATION
#region Localization
string GetMessage(string key, string steamId = null) => lang.GetMessage(key, this, steamId);
void LoadDefaultMessages() {
var messagesEn = new Dictionary<string, string> {
{
"EventStart", "Radiation is coming! Run to the centre to safe your life! ( {0} : {1} )"
}
, {
"RadiusDecreased", "Radius of safezone decreased!"
}
, {
"SafezoneRadiusReachedMin", "Radius of safezone reached its minimum!"
}
, {
"EventStopped", "Event stopped!"
}
, {
"NoPerm", "No permission!"
}
, {
"Help", "Type /rad for usage help"
}
, {
"Helplong", "<color=red>Config:</color>\n/rad saferad (m)\n /rad saferadmin (m)\n/rad eventrad (m)\n/rad radpower (%)\n/rad step (num)\n/rad period (seconds)\n/rad x y z\n/rad me (uses your position as target)\n<color=red>Manager:</color>\n/rad start\n/rad stop (stops decrease)\n/rad clear (close event and remove zones)"
}
, {
"Erased", "Erased all event rad zones"
}
}
;
lang.RegisterMessages(messagesEn, this);
var messagesRu = new Dictionary<string, string> {
{
"EventStart", "Радиация появляется! Беги в центр, чтобы выжить! ( {0} : {1} )"
}
, {
"RadiusDecreased", "Радиус безопасной зоны уменьшился!"
}
, {
"SafezoneRadiusReachedMin", "Радиус безопасной зоны достиг минимума!"
}
, {
"EventStopped", "Ивент закончился!"
}
, {
"NoPerm", "Нет прав!"
}
, {
"Help", "Напиши /rad для подсказки"
}
, {
"Helplong", "<color=red>Config:</color>\n/rad saferad (m)\n /rad saferadmin (m)\n/rad eventrad (m)\n/rad radpower (%)\n/rad step (num)\n/rad period (seconds)\n/rad x y z\n/rad me (uses your position as target)\n<color=red>Manager:</color>\n/rad start\n/rad stop (stops decrease)\n/rad clear (close event and remove zones)"
}
, {
"Erased", "Все ивент-зоны очищены"
}
}
;
lang.RegisterMessages(messagesRu, this, "ru");
}
#endregion
//CONFIG
//PLUGIN REFERENCE AND HOOKS
[PluginReference]
Plugin ZoneManager;
void OnServerInitialized() {
LoadDefaultMessages();
if (plugins.Exists("ZoneManager")) ok = true;
else {
PrintWarning("Install ZoneManager!");
ok = false;
}
radzonedata = dataFile.ReadObject<Dictionary<string, List<string>>>();
List<string> pos;
if (!radzonedata.TryGetValue("Position", out pos)) {
//first datafile creating ("position" does not exist)
safecfg();
Puts("BattleRoyale RadZone created for first time.");
}
else Puts("BattleRoyale RadZone datafile loaded.");
execcfg();
}
void execcfg() {
radzonedata = dataFile.ReadObject<Dictionary<string, List<string>>>();
List<string> value;
if (radzonedata.TryGetValue("Position", out value)) target.x = Convert.ToSingle(value[0]);
target.y = Convert.ToSingle(value[1]);
target.z = Convert.ToSingle(value[2]);
if (radzonedata.TryGetValue("SafeRadius", out value)) saferadius = Convert.ToSingle(value[0]);
if (radzonedata.TryGetValue("SafeRadiusMinimum", out value)) saferadiusmin = Convert.ToSingle(value[0]);
if (radzonedata.TryGetValue("EventRadius", out value)) eventradius = Convert.ToSingle(value[0]);
if (radzonedata.TryGetValue("RadiationPower", out value)) radpower = Convert.ToSingle(value[0]);
if (radzonedata.TryGetValue("DecreaseStep", out value)) step = Convert.ToSingle(value[0]);
if (radzonedata.TryGetValue("DecreasePeriod", out value)) period = Convert.ToSingle(value[0]);
/*if (radzonedata.TryGetValue("DrawTime", out value))
drawtime=Convert.ToSingle(value[0]);
if (radzonedata.TryGetValue("DrawMode", out value))
drawmode=value[0];*/
}
void safecfg() {
radzonedata["Position"] = new List<string> {
target.x.ToString(), target.y.ToString(), target.z.ToString()
}
;
radzonedata["SafeRadius"] = new List<string> {
saferadius.ToString()
}
;
radzonedata["SafeRadiusMinimum"] = new List<string> {
saferadiusmin.ToString()
}
;
radzonedata["EventRadius"] = new List<string> {
eventradius.ToString()
}
;
radzonedata["RadiationPower"] = new List<string> {
radpower.ToString()
}
;
radzonedata["DecreaseStep"] = new List<string> {
step.ToString()
}
;
radzonedata["DecreasePeriod"] = new List<string> {
period.ToString()
}
;
/*radzonedata["DrawTime"] = new List<string>(){drawtime.ToString()};
radzonedata["DrawMode"] = new List<string>(){drawmode};*/
dataFile.WriteObject(radzonedata);
}
void Unload() {
DestroyAllSpheres();
DelPos();
}
void Loaded() {
permission.RegisterPermission(permissionrad, this);
}
/*void OnEnterZone(string ZoneID, BasePlayer player)
{
if (breaking) return;
if (!ZoneID.Contains("radshrink_pos_")) return;
if (drawmode=="rad" || drawmode=="both")
{
Regex regex = new Regex(@"\d+");
Match match = regex.Match(ZoneID);
if (match.Success)
{
float sphereradius = (eventradius-saferadius)/2;
player.SendConsoleCommand("ddraw.sphere", drawtime, Color.red, position[Convert.ToInt32(match.Value, 16)], sphereradius);
}
}
if (drawmode=="safe"|| drawmode=="both") player.SendConsoleCommand("ddraw.sphere", drawtime, Color.green, target, saferadius);
}*/
//MAIN FUNCTIONS
private List<BaseEntity> Spheres = new List<BaseEntity>();
private const string SphereEnt = "assets/prefabs/visualization/sphere.prefab";
private void CreateSphere(Vector3 position, float radius) {
BaseEntity sphere = GameManager.server.CreateEntity(SphereEnt, position, new Quaternion(), true);
SphereEntity ent = sphere.GetComponent<SphereEntity>();
ent.currentRadius = radius * 2;
ent.lerpSpeed = 0f;
sphere.Spawn();
Spheres.Add(sphere);
}
private void DestroyAllSpheres() {
foreach (var sphere in Spheres) if (sphere != null) sphere.KillMessage();
}
private void createZone(string zoneID, Vector3 pos, float radius, float rads) {
List<string> build = new List<string>();
build.Add("radius");
build.Add(radius.ToString());
build.Add("radiation");
build.Add(rads.ToString());
string[] zoneArgs = build.ToArray();
ZoneManager?.Call("CreateOrUpdateZone", zoneID, zoneArgs, pos);
}
private void eraseZone(string zoneID) {
ZoneManager.Call("EraseZone", zoneID);
}
private void CalcPos(Vector3 pos) {
if (breaking) return;
position.Clear();
float centerline = (eventradius + saferadius) / 2;
float sphereradius = (eventradius - saferadius) / 2;
float corn = centerline * 0.71f;
Vector3 SW = new Vector3(pos.x - corn, pos.y, pos.z - corn);
position.Add(SW);
Vector3 W = new Vector3(pos.x - centerline, pos.y, pos.z);
position.Add(W);
Vector3 NW = new Vector3(pos.x - corn, pos.y, pos.z + corn);
position.Add(NW);
Vector3 N = new Vector3(pos.x, pos.y, pos.z + centerline);
position.Add(N);
Vector3 NE = new Vector3(pos.x + corn, pos.y, pos.z + corn);
position.Add(NE);
Vector3 E = new Vector3(pos.x + centerline, pos.y, pos.z);
position.Add(E);
Vector3 SE = new Vector3(pos.x + corn, pos.y, pos.z - corn);
position.Add(SE);
Vector3 S = new Vector3(pos.x, pos.y, pos.z - centerline);
position.Add(S);
int i = 0;
foreach (Vector3 elem in position) {
createZone("radshrink_pos_" + i, elem, sphereradius, radpower);
i++;
}
}
private void DelPos() {
stop();
int i = 0;
foreach (Vector3 elem in position) {
eraseZone("radshrink_pos_" + i);
i++;
}
position.Clear();
if (i > 0) Puts(GetMessage("Erased"));
}
private void started() {
ConVar.Server.radiation = true;
breaking = false;
execcfg();
PrintToChat(GetMessage("EventStart"), target.x, target.z);
Puts(GetMessage("EventStart"), target.x, target.z);
StartZoneShrink();
}
private void stop() {
breaking = true;
PrintToChat(GetMessage("EventStopped"));
Puts(GetMessage("EventStopped"));
ConVar.Server.radiation = true;
}
private void StartZoneShrink() {
DestroyAllSpheres();
if (breaking) return;
CreateSphere(target, saferadius);
timer.In(period, () => Shrink());
}
private void Shrink() {
if (breaking) return;
if (saferadius <= saferadiusmin) {
PrintToChat(GetMessage("SafezoneRadiusReachedMin"));
Puts(GetMessage("SafezoneRadiusReachedMin"));
return;
}
CalcPos(target);
saferadius = saferadius - step;
Puts(GetMessage("RadiusDecreased"));
PrintToChat(GetMessage("RadiusDecreased"));
StartZoneShrink();
}
bool IsAllowed(BasePlayer player, string perm) {
if (permission.UserHasPermission(player.userID.ToString(), perm)) return true;
return false;
}
// INTERFACE, COMMANDS
[ChatCommand("rad")]
void radchat(BasePlayer player, string cmd, string[] args) {
if (!ok) return;
if (player != null) {
if (!IsAllowed(player, permissionrad)) {
SendReply(player, GetMessage("NoPerm", player.UserIDString));
return;
}
}
if (args.Length == 1) {
if (args[0] == "start") {
started();
}
else if (args[0] == "stop") {
stop();
}
else if (args[0] == "clear") {
DelPos();
}
else if (args[0] == "me") {
if (player == null) return;
target = player.transform.position;
safecfg();
}
else if (player != null) SendReply(player, GetMessage("Help", player.UserIDString));
return;
}
if (args.Length == 2) {
/*if (args[0]=="drawmod")
{
if (args[1] == "safe" || args[1] == "rad" || args[1] == "both" || args[1] == "none")
{
drawmode=args[1];
}
else if (player !=null) SendReply(player, GetMessage("Help", player.UserIDString));
}
else if (args[0]=="drawtime")
{
drawtime=Convert.ToSingle(args[1]);
}
else*/
if (args[0] == "saferad") {
saferadius = Convert.ToSingle(args[1]);
}
else if (args[0] == "saferadmin") {
saferadiusmin = Convert.ToSingle(args[1]);
}
else if (args[0] == "eventrad") {
eventradius = Convert.ToSingle(args[1]);
}
else if (args[0] == "radpower") {
radpower = Convert.ToSingle(args[1]);
}
else if (args[0] == "step") {
step = Convert.ToSingle(args[1]);
}
else if (args[0] == "period") {
period = Convert.ToSingle(args[1]);
}
else if (player != null) SendReply(player, GetMessage("Help", player.UserIDString));
safecfg();
return;
}
if (args.Length == 3) {
target.x = Convert.ToSingle(args[0]);
target.y = Convert.ToSingle(args[1]);
target.z = Convert.ToSingle(args[2]);
safecfg();
}
else if (player != null) SendReply(player, GetMessage("Helplong", player.UserIDString));
}
[ConsoleCommand("rad")]
void radconsole(ConsoleSystem.Arg arg) {
if (arg.Args == null) return;
string[] args = arg.Args;
if (arg.Connection != null) {
BasePlayer player = arg.Connection.player as BasePlayer;
if (!IsAllowed(player, permissionrad)) {
PrintToChat(player, GetMessage("NoPerm", player.UserIDString));
return;
}
radchat(player, "rad", args);
}
radchat(null, "rad", args);
}
}
}