Иконка ресурса

FREE DynamicPVP : 3.2.4 3.2.4

Нет прав для скачивания
C#:
// Все права принадлежат дискорд сообществу https://discord.gg/VgNHPpNrz6
using System;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using Oxide.Core.Plugins;
using Newtonsoft.Json;
using Oxide.Core;

namespace Oxide.Plugins
{
    [Info("DynamicPVP", "CatMeat", "3.2.4", ResourceId = 2728)]
    [Description("Create temporary PVP zones around SupplyDrops, LockedCrates, APC and/or Heli")]

    public class DynamicPVP : RustPlugin
    {
        #region References
        [PluginReference]
        Plugin ZoneManager, TruePVE, ZoneDomes, BotSpawn;
        #endregion

        #region Declarations
        ConfigFileStructure Settings = new ConfigFileStructure();
        DataProfile BotSpawnProfileSettings = new DataProfile();

        Dictionary<BaseEntity, Vector3> activeSupplySignals = new Dictionary<BaseEntity, Vector3>();
        Dictionary<string, Vector3> ActiveDynamicZones = new Dictionary<string, Vector3>();
        Dictionary<ulong, Timer> PVPDelay = new Dictionary<ulong, Timer>();

        bool starting = true;
        bool validcommand;

        float zoneRadius;
        float zoneDuration;

        string botProfile;
        string msg;
        static string PluginVersion;
        string debugfilename = "debug";
        string BotSpawnProfileName = "DynamicPVP";

        ConsoleSystem.Arg arguments;
        #endregion

        #region Commands
        [ChatCommand("dynpvp")]
        private void CmdChatCommand(BasePlayer player, string command, string[] args)
        {
            if (player?.net?.connection != null && player.net.connection.authLevel > 0)
                if (args.Count() > 0) ProcessCommand(player, args);
        }

        [ConsoleCommand("dynpvp")]
        private void CmdConsoleCommand(ConsoleSystem.Arg arg)
        {
            arguments = arg; //save for responding later
            if (arg.IsAdmin)
                if (arg.Args.Count() > 0) ProcessCommand(null, arg.Args);
        }

        private void ProcessCommand(BasePlayer player, string[] args)
        {
            var command = args[0];
            var value = "";

            if (args.Count() > 1) value = args[1];

            var commandToLower = command.Trim().ToLower();
            var valueToLower = value.Trim().ToLower();
            float numberValue;
            var number = Single.TryParse(value, out numberValue);

            validcommand = true;

            switch (commandToLower)
            {
                case "debug":
                    switch (valueToLower)
                    {
                        case "true":
                            Settings.Global.DebugEnabled = true;
                            break;
                        case "false":
                            Settings.Global.DebugEnabled = false;
                            break;
                        default:
                            validcommand = false;
                            break;
                    }
                    if (validcommand) SaveConfig(Settings);
                    break;
                default:
                    validcommand = false;
                    break;
            }
            if (validcommand)
            {
                msg = "DynamicPVP: " + command + " set to: " + value;
                arguments.ReplyWith(msg);
            }
            else
            {
                msg = "Syntax error! (" + command + ":" + value;
                arguments.ReplyWith(msg);
            }
        }
        #endregion

        #region OxideHooks
        void Init()
        {
            PluginVersion = Version.ToString();
            LoadConfigVariables();
        }

        void Unload()
        {
            List<string> keys = new List<string>(ActiveDynamicZones.Keys);

            if (keys.Count > 0) DebugPrint($"Deleting {keys.Count} ActiveZones", false);
            foreach (string key in keys) DeleteDynZone(key);
        }

        object CanEntityTakeDamage(BaseCombatEntity entity, HitInfo hitinfo)
        {
            if (!Settings.Global.PVPDelayEnabled) return null;
            if (entity is BasePlayer)
            {
                var player = entity as BasePlayer;

                if (PVPDelay.ContainsKey(player.userID)) return true; // force allow damage
            }
            return null; //allow default behavior
        }

        void OnServerInitialized()
        {
            starting = false;
            if (BotSpawnAllowed()) BotSpawnProfileCreate();
            DeleteOldZones();
            DeleteOldMappings();
            DeleteOldDomes();
        }

        void OnEntitySpawned(BaseNetworkable entity)
        {
            if (!Settings.Global.PluginEnabled || starting || entity == null || entity.IsDestroyed) return;
            switch (entity.ShortPrefabName)
            {
                case "supply_drop":
                    SupplyDropEvent(entity);
                    break;
                case "codelockedhackablecrate":
                    LockedCrateEvent(entity);
                    break;
                default:
                    return;
            }
        }

        void OnEntityDeath(BaseCombatEntity entity, HitInfo info)
        {
            if (!Settings.Global.PluginEnabled || starting || entity == null || entity.IsDestroyed) return;
            switch (entity.ShortPrefabName)
            {
                case "patrolhelicopter":
                    PatrolHelicopterEvent(entity);
                    break;
                case "bradleyapc":
                    BradleyApcEvent(entity);
                    break;
                default:
                    return;
            }
        }

        void OnExplosiveThrown(BasePlayer player, BaseEntity entity)
        {
            if (entity == null || !(entity is SupplySignal))
                return;
            if (entity.net == null)
                entity.net = Network.Net.sv.CreateNetworkable();

            Vector3 position = entity.transform.position;

            if (activeSupplySignals.ContainsKey(entity))
                return;
            SupplyThrown(player, entity, position);
            return;
        }

        void OnExplosiveDropped(BasePlayer player, BaseEntity entity)
        {
            if (entity == null || !(entity is SupplySignal)) return;
            if (activeSupplySignals.ContainsKey(entity)) return;

            Vector3 position = entity.transform.position;
            SupplyThrown(player, entity, position);
            return;
        }
        #endregion

        #region Entity Testing and Tracking
        bool IsProbablySupplySignal(Vector3 landingposition)
        {
            // potential issues with signals thrown near each other (<40m)
            // definite issues with modifications that create more than one supply drop per cargo plane.// potential issues with player moving while throwing signal.DebugPrint($"Checking {activeSupplySignals.Count()} active supply signals", false);
            //if (!Settings.Events.SupplySignal.Enabled) return false;
            if (activeSupplySignals.Count() > 0)
            {
                foreach (var supplysignal in activeSupplySignals.ToList())
                {
                    if (supplysignal.Key == null)
                    {
                        activeSupplySignals.Remove(supplysignal.Key);

                        continue;
                    }

                    var thrownposition = supplysignal.Value;
                    thrownposition.y = 0;
                    landingposition.y = 0;
                    var distance = Vector3.Distance(thrownposition, landingposition);
                    DebugPrint($"Found SupplySignal at {supplysignal.Value} located {distance}m away.", false);

                    if (distance < Settings.Global.CompareRadius)
                    {
                        //activeSupplySignals.Remove(supplysignal.Key);
                        timer.Once(10, () => {
                            if (activeSupplySignals.ContainsKey(supplysignal.Key))
                            {
                                activeSupplySignals.Remove(supplysignal.Key);
                                DebugPrint($"Removing Supply signal from active list", false);
                            }
                        });

                        DebugPrint("Found matching SupplySignal.", false);
                        DebugPrint($"Active supply signals remaining: {activeSupplySignals.Count()}", false);
                        return true;
                    }
                }
                DebugPrint($"No matches found, probably from a timed event cargo_plane", false);
                return false;
            }
            DebugPrint($"No active signals, must be from a timed event cargo_plane", false);
            return false;
        }

        void SupplyThrown(BasePlayer player, BaseEntity entity, Vector3 position)
        {
            //Vector3 thrownposition = entity.transform.position;

            timer.Once(2.0f, () =>
            {
                if (entity == null)
                {
                    activeSupplySignals.Remove(entity);
                    return;
                }
            });

            timer.Once(2.3f, () =>
            {
                if (entity == null) return;
                activeSupplySignals.Add(entity, position);
                DebugPrint($"SupplySignal thrown at position of {position}", false);
            });
        }
        #endregion

        #region Events
        private void SupplyDropEvent(BaseNetworkable entity)
        {
            DebugPrint($"Supply drop spawned at {entity.transform.position}", false);
            bool IsFromSupplySignal = IsProbablySupplySignal(entity.transform.position);

            DebugPrint($"IsFromSupplySignal: {IsFromSupplySignal}", false);
            if (IsFromSupplySignal)
            {
                DebugPrint($"Settings.Events.SupplySignal.Enabled: {Settings.Events.SupplySignal.Enabled}", false);
                if (!Settings.Events.SupplySignal.Enabled)
                {
                    DebugPrint($"PVP for Supply Signals disabled: Skipping zone creation", false);
                    return;
                }
                CreateDynZone("Signal",
                    entity.transform.position,
                    Settings.Events.SupplySignal.Radius,
                    Settings.Events.SupplySignal.Duration,
                    Settings.Events.SupplySignal.BotProfile
                    );
            }
            else
            {
                if (!Settings.Events.TimedDrop.Enabled) return;
                CreateDynZone("AirDrop",
                    entity.transform.position,
                    Settings.Events.TimedDrop.Radius,
                    Settings.Events.TimedDrop.Duration,
                    Settings.Events.TimedDrop.BotProfile
                    );
            }
        }

        private void LockedCrateEvent(BaseNetworkable entity)
        {
            if (!Settings.Events.TimedCrate.Enabled) return;
            CreateDynZone("Crate",
                entity.transform.position,
                Settings.Events.TimedCrate.Radius,
                Settings.Events.TimedCrate.Duration,
                Settings.Events.TimedCrate.BotProfile
                );
        }

        private void PatrolHelicopterEvent(BaseCombatEntity entity)
        {
            if (!Settings.Events.PatrolHelicopter.Enabled) return;
            CreateDynZone("Heli",
                entity.transform.position,
                Settings.Events.PatrolHelicopter.Radius,
                Settings.Events.PatrolHelicopter.Duration,
                Settings.Events.PatrolHelicopter.BotProfile
                );
        }

        private void BradleyApcEvent(BaseCombatEntity entity)
        {
            if (!Settings.Events.BradleyAPC.Enabled) return;
            CreateDynZone("APC",
                entity.transform.position,
                Settings.Events.BradleyAPC.Radius,
                Settings.Events.BradleyAPC.Duration,
                Settings.Events.BradleyAPC.BotProfile
                );
        }
        #endregion

        #region ZoneHandling
        void CreateDynZone(string EventID, Vector3 DynPosition, float _radius, float _duration, string _profile)
        {
            DynPosition.y = TerrainMeta.HeightMap.GetHeight(DynPosition);

            if (ZoneCreateAllowed())
            {
                string DynZoneID = DateTime.Now.ToString("HHmmssff");

                List<string> DynArgs = new List<string>
                {
                    "name",
                    "DynamicPVP",
                    "radius",
                    _radius.ToString(),
                    "enter_message",
                    "Entering a PVP area!",
                    "leave_message",
                    "Leaving a PVP area.",
                    "undestr",
                    "true"
                };

                if (Settings.Global.BlockTeleport)
                {
                    DynArgs.Add("notp");
                    DynArgs.Add("true");
                }
                if (!String.IsNullOrEmpty(Settings.Global.ExtraZoneFlags))
                {
                    List<string> _xtraArgs = Settings.Global.ExtraZoneFlags.Split(' ').ToList();

                    foreach (var _arg in _xtraArgs)
                    {
                        DynArgs.Add(_arg);
                    }
                }

                string[] DynZoneArgs = DynArgs.ToArray();
                DebugPrint($"EventID {DynZoneID} {EventID}{DynPosition} {_radius.ToString()}m {_duration.ToString()}s", false);
                bool ZoneAdded = AddZone(DynZoneID, DynZoneArgs, DynPosition);

                if (ZoneAdded)
                {
                    string successString = "";
                    ActiveDynamicZones.Add(DynZoneID, DynPosition);
                    bool MappingAdded = AddMapping(DynZoneID);

                    if (!MappingAdded) DebugPrint("ERROR: PVP Mapping failed.", true);
                    else successString = successString + " Mapping,";
                    if (DomeCreateAllowed())
                    {
                        bool DomeAdded = AddDome(DynZoneID);

                        if (!DomeAdded) DebugPrint("ERROR: Dome NOT added for Zone: " + DynZoneID, true);
                        else successString = successString + " Dome,";
                    }
                    if (BotSpawnAllowed())
                    {
                        bool botsSpawned = SpawnBots(DynPosition, _profile, DynZoneID);

                        if (botsSpawned) successString = successString + " Bots,";
                    }
                    timer.Once(_duration, () => { DeleteDynZone(DynZoneID); });
                    if (successString.EndsWith(",")) successString = successString.Substring(0, successString.Length - 1);
                    DebugPrint($"Created Zone {DynZoneID} ({successString.Trim()})", false);
                }
                else DebugPrint("ERROR: Zone creation failed.", true);
            }
        }

        bool DeleteDynZone(string DynZoneID)
        {
            if (ZoneCreateAllowed())
            {
                string successString = "";

                if (String.IsNullOrEmpty(DynZoneID))
                {
                    DebugPrint("Invalid ZoneID", false);
                    return false;
                }
                if (BotSpawnAllowed())
                {
                    DebugPrint("Calling RemoveBots", false);

                    bool botsRemoved = RemoveBots(DynZoneID);

                    if (botsRemoved) successString = successString + " Bots,";
                }
                if (DomeCreateAllowed())
                {
                    DebugPrint("Calling RemoveDome", false);

                    bool DomeRemoved = RemoveDome(DynZoneID);

                    if (!DomeRemoved) DebugPrint("ERROR: Dome NOT removed for Zone: " + DynZoneID, true);
                    else successString = successString + " Dome,";
                }
                DebugPrint("Calling RemoveMapping", false);

                bool MappingRemoved = RemoveMapping(DynZoneID);

                if (!MappingRemoved) DebugPrint("ERROR: PVP NOT disabled for Zone: " + DynZoneID, true);
                else successString = successString + " Mapping,";

                DebugPrint("Calling RemoveZone", false);

                bool ZoneRemoved = RemoveZone(DynZoneID);

                if (!ZoneRemoved) DebugPrint("ERROR: Zone removal failed.", true);
                else
                {
                    if (successString.EndsWith(",")) successString = successString.Substring(0, successString.Length - 1);
                    DebugPrint($"Deleted Zone {DynZoneID} ({successString.Trim()})", false);
                    ActiveDynamicZones.Remove(DynZoneID);
                    return true;
                }
            }
            return false;
        }
        #endregion

        #region ZoneDome Integration
        bool AddDome(string zoneID) => (bool)ZoneDomes?.Call("AddNewDome", null, zoneID);

        bool RemoveDome(string zoneID) => (bool)ZoneDomes?.Call("RemoveExistingDome", null, zoneID);

        private void DeleteOldDomes()
        {
        }

        private bool DomeCreateAllowed()
        {
            Plugin ZoneDomes = (Plugin)plugins.Find("ZoneDomes");

            if (ZoneDomes != null && Settings.Global.DomesEnabled) return true;
            return false;
        }
        #endregion

        #region TruePVE Integration
        bool AddMapping(string zoneID) => (bool)TruePVE?.Call("AddOrUpdateMapping", zoneID, "exclude");

        bool RemoveMapping(string zoneID) => (bool)TruePVE?.Call("RemoveMapping", zoneID);

        private void DeleteOldMappings()
        {
        }
        #endregion

        #region BotSpawn Integration
        bool SpawnBots(Vector3 zoneLocation, string zoneProfile, string zoneGroupID)
        {
            if (!String.IsNullOrEmpty(zoneProfile))
            {
                string[] result = (string[])BotSpawn?.CallHook("AddGroupSpawn", zoneLocation, zoneProfile, zoneGroupID);

                if (result == null || result.Length < 2)
                {
                    DebugPrint("AddGroupSpawn returned invalid response.", false);
                    return false;
                }

                switch (result[0])
                {
                    case "true":
                        return true;
                    case "false":
                        return false;
                    case "error":
                        DebugPrint($"ERROR: AddGroupSpawn failed: {result[1]}", true);
                        return false;
                    default:
                        return false;
                }
            }
            return false;
        }

        bool RemoveBots(string zoneGroupID)
        {
            string[] result = (string[])BotSpawn?.CallHook("RemoveGroupSpawn", zoneGroupID);

            if (result == null || result.Length < 2)
            {
                DebugPrint("RemoveGroupSpawn returned invalid response.", false);
                return false;
            }
            else if (result[0] == "error")
            {
                DebugPrint($"ERROR: RemoveGroupSpawn failed: {result[1]}", true);
                return false;
            }
            else return true;
        }

        string[] CheckProfile(string profile) => (string[])BotSpawn?.CallHook("ProfileExists", profile);

        string[] AddProfile(DataProfile profile) => (string[])BotSpawn?.CallHook("CreateNewProfile", "DynamicPVP", profile);

        private void DeleteOldBots()
        {
        }

        private bool BotSpawnAllowed()
        {
            Plugin BotSpawn = (Plugin)plugins.Find("BotSpawn");

            if (BotSpawn != null && Settings.Global.BotsEnabled) return true;
            return false;
        }
        #endregion

        #region ZoneManager Integration
        private bool ZoneCreateAllowed()
        {
            Plugin ZoneManager = (Plugin)plugins.Find("ZoneManager");
            Plugin TruePVE = (Plugin)plugins.Find("TruePVE");

            if ((TruePVE != null) && (ZoneManager != null))
                if (Settings.Global.PluginEnabled)
                    return true;
            return false;
        }

        private void DeleteOldZones()
        {
            int _attempts = 0;
            int _sucesses = 0;
            string[] ZoneIDs = (string[])ZoneManager?.Call("GetZoneIDs");

            if (ZoneIDs != null)
            {
                for (int i = 0; i < ZoneIDs.Length; i++)
                {
                    string zoneName = (string)ZoneManager?.Call("GetZoneName", ZoneIDs[i]);

                    if (zoneName == "DynamicPVP")
                    {
                        _attempts++;

                        bool _success = DeleteDynZone(ZoneIDs[i]);

                        if (_success) _sucesses++;
                    }
                }
                DebugPrint($"Deleted {_sucesses} of {_attempts} existing DynamicPVP zones", true);
            }
        }

        bool AddZone(string zoneID, string[] zoneArgs, Vector3 zoneLocation) => (bool)ZoneManager?.Call("CreateOrUpdateZone", zoneID, zoneArgs, zoneLocation);

        bool RemoveZone(string zoneID) => (bool)ZoneManager?.Call("EraseZone", zoneID);

        private void OnEnterZone(string zoneID, BasePlayer player)
        {
            string zoneName = (string)ZoneManager?.Call("GetZoneName", zoneID);

            if (zoneName == "DynamicPVP")
            {
                var _name = GetPlayerName(player);

                if (_name != null) DebugPrint($"{_name} has entered PVP Zone {zoneID}.", true);
            }
        }

        private void OnExitZone(string zoneID, BasePlayer player)
        {
            if (!Settings.Global.PVPDelayEnabled) return;

            string zoneName = (string)ZoneManager?.Call("GetZoneName", zoneID);

            if (zoneName != "DynamicPVP" || player is NPCPlayer) return;
            if (player.userID < 76560000000000000L) return;
            if (!player.userID.IsSteamId()) return;

            var _name = GetPlayerName(player);

            if (_name == null) return;
            DebugPrint($"{_name} has left a PVP Zone {zoneID}.", true);

            if (!PVPDelay.ContainsKey(player.userID))
            {
                var time = Settings.Global.PVPDelayTime;
                DebugPrint($"Adding {player.displayName} to PVPDelay.", true);
                PVPDelay.Add(player.userID, timer.Repeat(1, time, () =>
                {
                    time--;
                    if (time == 0)
                    {
                        DebugPrint($"Remove {player.displayName} from PVPDelay.", true);
                        PVPDelay.Remove(player.userID);
                    }
                }));
            }
        }
        #endregion

        #region Messaging
        void DebugPrint(string msg, bool warning)
        {
            if (Settings.Global.DebugEnabled)
            {
                switch (warning)
                {
                    case true:
                        PrintWarning(msg);
                        break;
                    case false:
                        Puts(msg);
                        break;
                }
            }

            LogToFile(debugfilename, "[" + DateTime.Now.ToString() + "] | " + msg, this, true);
        }

        void RespondWith(BasePlayer player, string msg)
        {
            if (player == null)
                arguments.ReplyWith(msg);
            else
                SendReply(player, msg);
            return;
        }
        #endregion

        #region Classes
        private class ActiveZone
        {
            public string DynZoneID { get; set; }
        }

        private void BotSpawnProfileCreate()
        {
            string[] result = (string[])BotSpawn?.CallHook("ProfileExists", "DynamicPVP");

            if (true)
            //if (result[0] == "false")
            {
                //DebugPrint("BotsSpawn Does not contain custom profile `DynamicPVP`.", true);

                var _profile = JsonConvert.SerializeObject(new DataProfile());

                result = (string[])BotSpawn?.CallHook("CreateNewProfile", BotSpawnProfileName, _profile);
                if (result[0] == "false") DebugPrint($"BotsSpawn failed to add/update `DynamicPVP`.\n{result[1]}", true);
                else
                {
                    result = (string[])BotSpawn?.CallHook("ProfileExists", "DynamicPVP");

                    if (result[0] == "false") DebugPrint($"Added but failed show `DynamicPVP`.\n{result[1]}", true);
                    else DebugPrint("Succesfully updated custom profile `DynamicPVP`.", true);
                }
            }
            else DebugPrint("Custom profile `DynamicPVP` already exists.", true);
        }

        public class DataProfile
        {
            public bool AutoSpawn = false;
            public bool Murderer = false;
            public int Bots = 2;
            public int BotHealth = 100;
            public int Radius = 20;
            public List<string> Kit = new List<string>();
            public string BotNamePrefix = "Sgt.";
            public List<string> BotNames = new List<string>();
            public int Bot_Accuracy = 4;
            public float Bot_Damage = 0.4f;
            public bool Disable_Radio = false;
            public int Roam_Range = 20;
            public bool Peace_Keeper = true;
            public int Peace_Keeper_Cool_Down = 5;
            public bool Weapon_Drop = true;
            public bool Keep_Default_Loadout = false;
            public bool Wipe_Belt = false;
            public bool Wipe_Clothing = false;
            public bool Allow_Rust_Loot = true;
            public int Suicide_Timer = 1200;
            public bool Chute = false;
            public int Long_Attack_Distance = 120;
            public int Respawn_Timer = 0;
            public float LocationX;
            public float LocationY;
            public float LocationZ;
            public string Parent_Monument = "";
        }

        #endregion

        #region NewConfig

        private void LoadConfigVariables()
        {
            Settings = Config.ReadObject<ConfigFileStructure>();
            SaveConfig(Settings);
        }

        protected override void LoadDefaultConfig()
        {
            Puts("Creating new config file.");

            var config = new ConfigFileStructure();
            SaveConfig(config);
        }

        void SaveConfig(ConfigFileStructure config)
        {
            Config.WriteObject(config, true);
        }

        public class ConfigFileStructure
        {
            public GlobalOptions Global = new GlobalOptions() { };
            public SpecificEventOptions Events = new SpecificEventOptions() { };
        }

        public class GlobalOptions
        {
            public string ConfigVersion = "3.2.4";
            public bool PluginEnabled = true;
            public bool DebugEnabled = false;
            public float CompareRadius = 100;

            public string ExtraZoneFlags = "";
            public string MsgEnter = "Entering a PVP area!";
            public string MsgLeave = "Leaving a PVP area.";

            public bool BlockTeleport = true;
            public bool BotsEnabled = true;
            public bool DomesEnabled = true;

            public bool PVPDelayEnabled = true;
            public int PVPDelayTime = 10;
        }

        public class SpecificEventOptions
        {
            public StandardEventOptions BradleyAPC = new StandardEventOptions() { };
            public StandardEventOptions PatrolHelicopter = new StandardEventOptions() { };
            public StandardEventOptions SupplySignal = new StandardEventOptions() { Enabled = false };
            public StandardEventOptions TimedCrate = new StandardEventOptions() { Duration = 1200 };
            public StandardEventOptions TimedDrop = new StandardEventOptions() { };
        }

        public class StandardEventOptions
        {
            public string BotProfile = "DynamicPVP";
            public float Duration = 600;
            public bool Enabled = true;
            public float Radius = 100;
        }

        #endregion

        #region Helper Methods
        public string GetPlayerName(BasePlayer player)
        {
            if (player.displayName == "")
            {
                if (player.name == "")
                {
                    return null;
                }
                else return player.name;
            }
            else return player.displayName;
        }
        #endregion
    }
}

Автор
15FPS
Скачиваний
0
Просмотры
1
Первый выпуск
Обновление
Оценка
0.00 звёзд 0 оценок
Сверху