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

FREE PookEvent : 1.3.5 1.3.5

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

namespace Oxide.Plugins
{
    [Info("PookEvent", "SinKohh", "1.3.5")]
    [Description("Unleash chaos and reap rewards with Pookie and it's Decoy!")]
    class PookEvent : RustPlugin
    {
        #region Declarations
        private const float GroundOffset = 0.1f;
        private BaseEntity pookie;
        private BaseEntity pookieDecoy;
        private BaseEntity decoyLan;
        private BaseEntity pookieLan;
        private Timer eventTimer;
        private bool eventActive = false;
        List<string> gridList = new List<string>();
        List<Vector3> decoyPositions = new List<Vector3>(); // Create a list to store decoy positions
        private readonly List<Collider> colliders = new List<Collider>();
        private MapMarkerGenericRadius pookieMarker { get; set; }
        private Dictionary<string, MapMarkerGenericRadius> pookieMarkers = new Dictionary<string, MapMarkerGenericRadius>();
        private List<NetworkableId> pookieEntName = new List<NetworkableId>();
        Vector3 newPositionDecoy = Vector3.zero;
        string decoyGrid = "";
        string spawnGrid = "";
        string pookGrids = "";
        string gridOne = "";
        string gridTwo = "";

        private const string worlItem_Prefab = "assets/prefabs/misc/burlap sack/generic_world.prefab";
        private static PookEvent Instance;

        [PluginReference]
        private Plugin Economics;

        [PluginReference]
        private Plugin ServerRewards;

        [PluginReference]
        private Plugin EntityScaleManager;

        #endregion

        #region Config
        private Configuration config;

        private class Configuration
        {
            [JsonProperty("Enable Special Event? (Holiday themed Pookie)")]
            public bool specialEvent { get; set; }

            [JsonProperty("Event Interval (in minutes)")]
            public int IntervalMinutes { get; set; }

            [JsonProperty("Event Length (in minutes)")]
            public int EventLength { get; set; }

            [JsonProperty("Minimum players online for event to start.")]
            public int minPlayers { get; set; }

            [JsonProperty("How many decoys should spawn?")]
            public int decoyCount { get; set; }

            [JsonProperty("Item to spawn next to Pookies")]
            public string pookieObject { get; set; }

            [JsonProperty("Broadcast grids they spawn in?")]
            public bool BroadcastGrid { get; set; }

            [JsonProperty("Show map markers when they spawn?")]
            public bool pookieMapMarkers { get; set; }

            [JsonProperty("Color of Map Marker")]
            public string MapMarkerColor { get; set; }

            [JsonProperty("Map Marker Radius")]
            public float MapMarkerSize { get; set; }

            [JsonProperty("Name color for decoy killer.")]
            public string DecoyKiller { get; set; }

            [JsonProperty("Name color for pookie killer.")]
            public string PookieKiller { get; set; }

            [JsonProperty("Enable custom HP for Pookie and Decoy?")]
            public bool customHeatlh { get; set; }

            [JsonProperty("Custom Pookie HP Amount")]
            public int pookieHP { get; set; }

            [JsonProperty("Custom Decoy HP Amount")]
            public int decoyHP { get; set; }

            [JsonProperty("Enable Negative Effects?")]
            public bool EnableNegativeEffects { get; set; }

            [JsonProperty("Enable Negative Effect Commands?")]
            public bool EnableNegativeEffectCommand { get; set; }

            [JsonProperty("Give Reward Item AND Currency?")]
            public bool enableDualReward { get; set; }

            [JsonProperty("Use ServerRewards?")]
            public bool srvrRewards { get; set; }

            [JsonProperty("ServerRewards Amount to give per kill.")]
            public int srAmount { get; set; }

            [JsonProperty("Use Economics?")]
            public bool ecoUse { get; set; }

            [JsonProperty("Economics Amount to give per kill.")]
            public int ecoAmount { get; set; }

            [JsonProperty("Reward Items (Item Shortname, Quantity)")]
            public List<Rewards> RewardItems { get; set; }

            [JsonProperty("Negative Effects (Executes on player for killing Decoy)")]
            public List<NegativeEffect> NegativeEffects { get; set; }

            [JsonProperty("Negative Effect Commands (When using commands, put %steamid% where the player ID would be used in the command)")]
            public List<NegativeEffectCommands> NegativeEffectCommands { get; set; }
        }

        private class NegativeEffect
        {
            [JsonProperty("Effect Name")]
            public string EffectName { get; set; }

            [JsonProperty("Effect Description")]
            public string EffectDesc { get; set; }

            [JsonProperty("Enabled")]
            public bool EffectEnabled { get; set; }

            [JsonProperty("Amount")]
            public int effectAmt { get; set; }
        }

        private class NegativeEffectCommands
        {
            [JsonProperty("Command")]
            public string effectCommand { get; set; }

            [JsonProperty("Command Chat Message")]
            public string effectCommandMsg { get; set; }

            [JsonProperty("Enabled")]
            public bool CommandEffectEnabled { get; set; }
        }

        private class Rewards
        {
            [JsonProperty("Item Shortname")]
            public string itemShortname { get; set; }

            [JsonProperty("Item Skin")]
            public ulong itemSkin { get; set; }

            [JsonProperty("Item Name")]
            public string itemName { get; set; }

            [JsonProperty("Minimum Quantity")]
            public int minQty { get; set; }

            [JsonProperty("Maximum Quantity")]
            public int maxQty { get; set; }

        }

        protected override void LoadDefaultConfig()
        {
            var defaultConfig = new Configuration
            {
                specialEvent = false,
                IntervalMinutes = 60,
                EventLength = 20,
                minPlayers = 1,
                decoyCount = 1,
                pookieObject = "assets/prefabs/deployable/lantern/lantern.deployed.prefab",
                BroadcastGrid = true,
                pookieMapMarkers = false,
                MapMarkerColor = "#00FF00",
                MapMarkerSize = 0.25f,
                PookieKiller = "green",
                DecoyKiller = "orange",
                customHeatlh = false,
                pookieHP = 100,
                decoyHP = 100,
                EnableNegativeEffects = true,
                EnableNegativeEffectCommand = false,
                enableDualReward = false,
                srvrRewards = false,
                srAmount = 0,
                ecoUse = false,
                ecoAmount = 0,
                RewardItems = new List<Rewards>
                {
                    new Rewards {itemShortname = "ammo.rifle", itemSkin = 0, itemName = "", minQty = 1, maxQty = 5},
                    new Rewards {itemShortname = "apple", itemSkin = 0, itemName = "", minQty = 2, maxQty = 3},
                    new Rewards {itemShortname = "bandage", itemSkin = 0, itemName = "", minQty = 7, maxQty = 11},
                },
                NegativeEffects = new List<NegativeEffect>
                {
                    new NegativeEffect {EffectName = "Health",EffectDesc = "Subtracts amount from players health.(If players health is less than amount, they will die!)",EffectEnabled = true,effectAmt = 25},
                    new NegativeEffect {EffectName = "Dehydration",EffectDesc = "Sets players hydration to the value given.",EffectEnabled = true,effectAmt = 25},
                    new NegativeEffect {EffectName = "Hunger",EffectDesc = "Sets players hunger to the value given.",EffectEnabled = true,effectAmt = 25},
                    new NegativeEffect {EffectName = "Radiation",EffectDesc = "Amount of radiation poisoning you want to give the player.",EffectEnabled = true,effectAmt = 25},
                    new NegativeEffect {EffectName = "Bleeding",EffectDesc = "Bleeding amount you want applied to the player.",EffectEnabled = true,effectAmt = 25},
                    new NegativeEffect {EffectName = "Spawn Bears",EffectDesc = "Number of bears you want spawned around the player.",EffectEnabled = true,effectAmt = 1},
                    new NegativeEffect {EffectName = "Spawn Wolves",EffectDesc = "Number of wolves you want spawned around the player.",EffectEnabled = true,effectAmt = 1},
                    new NegativeEffect {EffectName = "Spawn Boar",EffectDesc = "Number of boar you want spawned around the player.",EffectEnabled = true,effectAmt = 1},
                    new NegativeEffect {EffectName = "Drop Inventory",EffectDesc = "Drops the players inventory on the ground.(1 = Hot Bar, 2 = Armor, 3 = Main Inventory, 4 = All)",EffectEnabled = true,effectAmt = 1},
                    new NegativeEffect {EffectName = "Spikes",EffectDesc = "Spawn a ring of spike traps around a player for x secs.(e.g.Amount = 10 is 10 seconds.)",EffectEnabled = true,effectAmt = 10},
                },
                NegativeEffectCommands = new List<NegativeEffectCommands>
                {
                    new NegativeEffectCommands {effectCommand = "killplayer %steamid%", effectCommandMsg = "Message to send to player", CommandEffectEnabled = false },
                    new NegativeEffectCommands {effectCommand = "killplayer %steamid%", effectCommandMsg = "Message to send to player", CommandEffectEnabled = false },
                    new NegativeEffectCommands {effectCommand = "killplayer %steamid%", effectCommandMsg = "Message to send to player", CommandEffectEnabled = false },
                }
            };

            Config.WriteObject(defaultConfig, true);
        }

        protected override void LoadConfig()
        {
            base.LoadConfig();
            config = Config.ReadObject<Configuration>();
            SaveConfig();

            if (config == null)
            {
                Puts("Configuration file not found, generating default configuration...");
                LoadDefaultConfig();
            }
        }

        protected override void SaveConfig()
        {
            Config.WriteObject(config);
        }
        #endregion

        #region Admin Commands/Cleanup
        [ChatCommand("spawnpookie")]
        private void SpawnPookieCommand(BasePlayer player, string command, string[] args)
        {
            if (eventActive)
            {
                gridList.Clear();
                decoyPositions.Clear();
                decoyGrid = "";
                RemoveEntitiesByNames(pookieEntName);
            }
            if (!player.IsAdmin)
                return;
            SpawnPookieEvent();

        }

        private void KillMapMarkerByName()
        {
            MapMarkerGenericRadius[] markers = UnityEngine.Object.FindObjectsOfType<MapMarkerGenericRadius>();

            foreach (var marker in markers)
            {
                marker.Kill();
            }
        }

        [ChatCommand("clearpookie")]
        private void RemoveEntitiesCommand(BasePlayer player, string command, string[] args)
        {
            if (!player.IsAdmin)
                return;

            RemoveEntitiesByNames(pookieEntName);
            eventActive = false;
            EndEvent();
        }

        [ChatCommand("pg")]
        private void locatePookie(BasePlayer player, string command, string[] args)
        {
            if (!eventActive)
            {
                player.ChatMessage("Event not active!");
                return;
            }
            if (config.BroadcastGrid)
            {
                if (config.decoyCount > 1)
                {
                    player.ChatMessage($"Grids are: {pookGrids}");
                }
                else
                {
                    player.ChatMessage($"Grids are: {gridOne},{gridTwo}");
                }
            }
        }

        private void RemoveEntitiesByNames(List<NetworkableId> entityNames)
        {
            List<BaseEntity> entitiesToRemove = new List<BaseEntity>();

            foreach (var entity in BaseNetworkable.serverEntities)
            {
                BaseEntity baseEntity = entity as BaseEntity;
                if (baseEntity != null)
                {
                    foreach (var name in entityNames)
                    {
                        if (baseEntity.name.Equals(name))
                        {
                            entitiesToRemove.Add(baseEntity);
                            break;
                        }
                    }
                }
            }

            foreach (var entity in entitiesToRemove)
            {
                entity.Kill();
            }
            Puts("Entities removed successfully.");
        }


        #endregion

        #region Hooks
        void Init()
        {
            Instance = this;
            LoadConfig();
            timer.Every(config.IntervalMinutes * 60, SpawnPookieEvent);
            Puts($"The first event will start in {config.IntervalMinutes} minutes!");
            Subscribe(nameof(OnEntityDeath));
            Subscribe(nameof(Unload));
        }

        void Unload()
        {
            if (eventActive) { EndEvent(); }
            Instance = null;
            Unsubscribe(nameof(OnEntityDeath));
            Unsubscribe(nameof(Unload));
            foreach (var pookieMarker in pookieMarkers.Values)
            {
                if (pookieMarker != null && !pookieMarker.IsDestroyed)
                {
                    pookieMarker.Kill();
                }
            }

            pookieMarkers.Clear();
        }
        object OnEntityTakeDamage(BaseCombatEntity entity, HitInfo info)
        {
            if (entity.name == "pumpkinhead" || entity.name == "Pookie Lantern")
            { return true; }
            return null;
        }

        private void OnEntityDeath(BaseCombatEntity entity, HitInfo hitInfo)
        {
            if (hitInfo == null || hitInfo.InitiatorPlayer == null)
                return;

            if (pookieEntName.Count > 0)
            {
                if (entity.name == "Pookie Bear")
                {
                    PrintToChat(GetMessage("pookiekiller", hitInfo.InitiatorPlayer.displayName, config.PookieKiller));
                    pookieEntName.Remove(entity.net.ID);
                    FindAndKillDecoys();
                    Effect.server.Run("assets/prefabs/misc/halloween/lootbag/effects/gold_open.prefab", entity, 0, new Vector3(0, 1.5f, 0), new Vector3());
                    if (eventTimer != null && eventTimer.Destroyed == false)
                    {
                        eventTimer.Destroy();
                    }

                    pookie = null;
                    EndEvent();
                    var pookID = entity.net.ID;

                    MapMarkerGenericRadius pookieMarker;
                    if (pookieMarkers.TryGetValue(pookID.ToString(), out pookieMarker))
                    {
                        pookieMarker.Kill();
                        pookieMarkers.Remove(pookID.ToString());
                    }

                    if (config.RewardItems != null && config.RewardItems.Count > 0)
                    {
                        ulong skin = 0;
                        string name = "";
                        int randomIndex = Random.Range(0, config.RewardItems.Count);
                        var rewardItem = config.RewardItems[randomIndex];
                        int quantity = Random.Range(rewardItem.minQty, rewardItem.maxQty + 1);
                        var item = FindItemDefinition(rewardItem.itemShortname);

                        if (rewardItem.itemSkin != 0)
                        {
                            skin = rewardItem.itemSkin;
                        }
                        if (rewardItem.itemName != "")
                        {
                            name = rewardItem.itemName;
                        }
                        GivePlayerItem(hitInfo.InitiatorPlayer, rewardItem.itemShortname, quantity, name, skin);
                    }

                }
                else if (entity.name.ToLower().Contains("pookie decoy"))
                {
                    pookieEntName.Remove(entity.net.ID);
                    PrintToChat(GetMessage("decoykiller", hitInfo.InitiatorPlayer.displayName, config.DecoyKiller));
                    Effect.server.Run("assets/prefabs/misc/halloween/pumpkin_bucket/effects/eggexplosion.prefab", entity, 0, new Vector3(0, 1.5f, 0), new Vector3());
                    if (decoyLan != null)
                    {
                        decoyLan.Kill();
                        decoyLan = null;
                    }
                    var pookID = entity.net.ID;

                    // Check if the pookID exists in the dictionary and retrieve the associated map marker
                    MapMarkerGenericRadius pookieMarker;
                    if (pookieMarkers.TryGetValue(pookID.ToString(), out pookieMarker))
                    {
                        // Remove the map marker
                        pookieMarker.Kill();
                        pookieMarkers.Remove(pookID.ToString()); // Remove the reference from the dictionary
                    }


                    if (!config.EnableNegativeEffects && config.EnableNegativeEffectCommand && config.NegativeEffectCommands != null && config.NegativeEffectCommands.Count > 0)
                    {
                        List<NegativeEffectCommands> enabledCommands = config.NegativeEffectCommands.Where(command => command.CommandEffectEnabled).ToList();
                        if (enabledCommands.Count > 0)
                        {
                            int randomIndex = Random.Range(0, enabledCommands.Count);
                            NegativeEffectCommands nEffect = enabledCommands[randomIndex];
                            ExecuteNegativeCommand(hitInfo.InitiatorPlayer, nEffect, nEffect.effectCommandMsg);
                            return;
                        }
                    }

                    if (!config.EnableNegativeEffectCommand && config.EnableNegativeEffects && config.NegativeEffects != null && config.NegativeEffects.Count > 0)
                    {
                        List<NegativeEffect> enabledEffects = config.NegativeEffects.Where(effect => effect.EffectEnabled).ToList();
                        if (enabledEffects.Count > 0)
                        {
                            int randomIndex = Random.Range(0, enabledEffects.Count);
                            NegativeEffect effect = enabledEffects[randomIndex];

                            ApplyNegativeEffect(hitInfo.InitiatorPlayer, effect);
                            return;
                        }
                    }


                    if (config.EnableNegativeEffects && config.NegativeEffects != null && config.NegativeEffects.Count > 0 &&
                    config.EnableNegativeEffectCommand && config.NegativeEffectCommands != null && config.NegativeEffectCommands.Count > 0)
                    {
                        List<NegativeEffect> enabledEffects = config.NegativeEffects.Where(effect => effect.EffectEnabled).ToList();
                        List<NegativeEffectCommands> enabledCommands = config.NegativeEffectCommands.Where(command => command.CommandEffectEnabled).ToList();

                        bool applyEffect = Random.Range(0, 2) == 0; // Randomly choose between 0 and 1

                        if ((applyEffect && enabledEffects.Count > 0) || (!applyEffect && enabledCommands.Count > 0))
                        {
                            if (applyEffect)
                            {
                                int randomIndex = Random.Range(0, enabledEffects.Count);
                                NegativeEffect effect = enabledEffects[randomIndex];
                                ApplyNegativeEffect(hitInfo.InitiatorPlayer, effect);
                                return;
                            }
                            else
                            {
                                int randomIndex = Random.Range(0, enabledCommands.Count);
                                NegativeEffectCommands nEffect = enabledCommands[randomIndex];
                                ExecuteNegativeCommand(hitInfo.InitiatorPlayer, nEffect, nEffect.effectCommandMsg);
                                return;
                            }
                        }
                    }


                }
            }
        }

        private void FindAndKillDecoys()
        {
            foreach (NetworkableId decoyID in pookieEntName.ToList())
            {
                NetworkableId netID = decoyID;

                var networkable = BaseNetworkable.serverEntities.Find(netID);
                var entity = networkable as BaseEntity;
                if (entity != null)
                {
                    entity.Kill();
                }
            }
        }

        private object CanPickupEntity(BasePlayer player, BaseEntity entity)
        {
            foreach (NetworkableId decoyID in pookieEntName.ToList())
            {
                if (entity.net.ID == decoyID || entity.name == "Pookie Lantern")
                {
                    player.ChatMessage("You can't pick that up!");
                    return false;
                }
            }

            return null;
        }
        #endregion

        #region MapMarkers

        private void CreatePookieMarker(Vector3 location, string pookID)
        {

            pookieMarker = GameManager.server.CreateEntity(StringPool.Get(2849728229), location) as MapMarkerGenericRadius;

            if (pookieMarker != null)
            {
                pookieMarker.alpha = 0.75f;
                pookieMarker.name = pookID;
                pookieMarker.color1 = MarkerColor();
                pookieMarker.color2 = MarkerColor();
                pookieMarker.radius = Mathf.Min(2.5f, config.MapMarkerSize);
                pookieMarker.Spawn();
                pookieMarker.SendUpdate();

                pookieMarkers[pookID] = pookieMarker;
            }

        }

        private Color MarkerColor()
        {
            Color color;
            return TryParseHtmlString(config.MapMarkerColor, out color) ? color : Color.green;
        }

        private bool TryParseHtmlString(string value, out Color color)
        {
            return ColorUtility.TryParseHtmlString(value.StartsWith("#") ? value : $"#{value}", out color);
        }

        #endregion

        #region Event Handlers
        private void SpawnPookieEvent()
        {
            foreach (var pookieMarker in pookieMarkers.Values)
            {
                if (pookieMarker != null && !pookieMarker.IsDestroyed)
                {
                    pookieMarker.Kill();
                }
            }

            pookieMarkers.Clear();

            if (BasePlayer.activePlayerList.Count < config.minPlayers)
            {
                PrintToChat($"There must be at least {config.minPlayers} players online for the event to start.");
                return;
            }

            eventActive = true;
            pookGrids = "";
            gridOne = "";
            gridTwo = "";
            decoyGrid = "";
            gridList.Clear();
            decoyPositions.Clear();
            RemoveEntitiesByNames(pookieEntName);
            float spawnThreshold = 180f;

            Vector3 bLoc = BanditLoc();
            Vector3 oLoc = GetOutpostLoc();
            if (eventTimer != null) { EndEvent(); }
            Vector3 spawnPosition = GetRandomSpawnPosition();
            Vector3 spawnPositionDecoy = GetRandomSpawnPosition();

            // Check if the spawn positions are outside the safe zone
            if (AreVectorsClose(bLoc, spawnPosition, spawnThreshold) || AreVectorsClose(oLoc, spawnPosition, spawnThreshold) || AreVectorsClose(bLoc, spawnPositionDecoy, spawnThreshold) || AreVectorsClose(oLoc, spawnPositionDecoy, spawnThreshold))
            {
                Puts("Pookie cannot spawn in a safe zone.Trying again...");
                SpawnPookieEvent(); // Try again until a valid spawn position is found
                return;
            }
            SpawnPookieBear(spawnPosition);
            if (config.decoyCount > 1)
            {
                for (int i = 0; i < config.decoyCount; i++)
                {
                    Vector3 newPositionDecoy = GetRandomSpawnPosition();
                    while (AreVectorsClose(bLoc, newPositionDecoy, spawnThreshold) || AreVectorsClose(oLoc, newPositionDecoy, spawnThreshold))
                    {
                        // If the new position is too close to bLoc or oLoc, generate a new random position
                        newPositionDecoy = GetRandomSpawnPosition();
                    }
                    SpawnPookieBearDecoy(newPositionDecoy, i);

                    //Add new position to list and then write a for each to get coordinates and append a string.decoyPositions.Add(newPositionDecoy);
                }
            }
            else
            {
                SpawnPookieBearDecoy(spawnPositionDecoy, 0);
            }
            if (config.BroadcastGrid)
            {
                if (config.decoyCount > 1)
                {
                    foreach (Vector3 position in decoyPositions)
                    {
                        decoyGrid = decoyGrid + PhoneController.PositionToGridCoord(position) + ", ";
                    }
                    string spawnGrid = PhoneController.PositionToGridCoord(spawnPosition);
                    pookGrids = decoyGrid + spawnGrid;
                    PrintToChat(GetMessage("spawnedgridmulti", pookGrids));

                    decoyPositions.Clear(); // Clear the decoy list for the next event
                }
                else if (config.decoyCount == 1)
                {
                    string spawnGrid = PhoneController.PositionToGridCoord(spawnPosition);
                    string decoyGrid = PhoneController.PositionToGridCoord(spawnPositionDecoy);
                    if (spawnGrid == "N19") { spawnGrid = "N-19"; }
                    if (decoyGrid == "N19") { decoyGrid = "N-19"; }

                    //Put grid locations in a list and randomly select them.This prevents knowing which grid location will always be the pookie and not the decoy.gridList.Add(spawnGrid);
                    gridList.Add(decoyGrid);
                    int randomIndex = UnityEngine.Random.Range(0, gridList.Count);
                    gridOne = gridList[randomIndex];
                    gridList.RemoveAt(randomIndex);
                    gridTwo = gridList[0];

                    PrintToChat(GetMessage("spawnedgrid", gridOne, gridTwo));
                    gridList.Clear(); // Clear the list for the next event
                }
            }
            else { PrintToChat(GetMessage("spawned")); }
            eventTimer = timer.Once(config.EventLength * 60, EndEvent);
        }

        private bool AreVectorsClose(Vector3 a, Vector3 b, float distanceThreshold)
        {
            float distance = Vector3.Distance(a, b);
            if (distance <= distanceThreshold)
            {
                return true;
            }
            return false;
        }

        private Vector3 GetOutpostLoc()
        {
            var monuments = UnityEngine.Object.FindObjectsOfType<MonumentInfo>();

            foreach (var monument in monuments)
            {
                if (monument.displayPhrase.english == "Outpost")
                {
                    return monument.transform.position + monument.transform.rotation * new Vector3(-30.62f, 1.87f, 20.95f);
                }
            }
            return Vector3.zero;
        }

        private Vector3 BanditLoc()
        {
            var monuments = UnityEngine.Object.FindObjectsOfType<MonumentInfo>();

            foreach (var monument in monuments)
            {
                if (monument.displayPhrase.english == "Bandit Camp")
                {
                    return monument.transform.position + monument.transform.rotation * new Vector3(-30.62f, 1.87f, 20.95f);
                }
            }
            return Vector3.zero;
        }

        void ClearItemList()
        {
            gridList.Clear();
            decoyPositions.Clear();
            decoyGrid = "";
            pookieEntName.Clear();
        }

        private void EndEvent()
        {
            FindAndKillDecoys();
            eventActive = false;
            if (pookie != null && !pookie.IsDestroyed)
            {
                pookie.Kill();
                pookie = null;
                PrintToChat(GetMessage("notfound"));
                ClearItemList();
            }
            else
            { pookie = null; }
            if (pookieDecoy != null && !pookieDecoy.IsDestroyed)
            {
                pookieDecoy.Kill();
                pookieDecoy = null;

                ClearItemList();
            }

            if (decoyLan != null && !decoyLan.IsDestroyed)
            {
                decoyLan.Kill();
                decoyLan = null;

                ClearItemList();
            }

            if (pookieLan != null && !pookieLan.IsDestroyed)
            {
                pookieLan.Kill();
                pookieLan = null;

                ClearItemList();
            }
            foreach (var pookieMarker in pookieMarkers.Values)
            {
                if (pookieMarker != null && !pookieMarker.IsDestroyed)
                {
                    pookieMarker.Kill();
                }
            }

            // Clear the pookieMarkers dictionary after killing the map markers
            pookieMarkers.Clear();
            eventTimer = null;

            ClearItemList();


        }

        private Vector3 GetRandomSpawnPosition()
        {
            float mapSize = TerrainMeta.Size.x / 2f;
            Vector3 randomPosition = new Vector3(Random.Range(-mapSize, mapSize), 0f, Random.Range(-mapSize, mapSize));
            float y = TerrainMeta.HeightMap.GetHeight(randomPosition);
            Vector3 spawnPosition = new Vector3(randomPosition.x, y + GroundOffset, randomPosition.z);

            if (!TestPos(spawnPosition) || IsNearToolCupboard(spawnPosition) || !IsPositionValid(spawnPosition))
            {
                return GetRandomSpawnPosition();
            }

            return spawnPosition;
        }

        private string GetGridLocation(Vector3 position)
        {
            int gridX = Mathf.FloorToInt(position.x / 146.3f);
            int gridZ = Mathf.FloorToInt(position.z / 146.3f);
            char gridLetter = (char)(gridX + 'A');
            string gridLocation = $"{gridLetter}{gridZ + 1}";
            return gridLocation;
        }

        private bool IsNearToolCupboard(Vector3 position)
        {
            Collider[] colliders = Physics.OverlapSphere(position, 10f, LayerMask.GetMask("Construction"));
            foreach (Collider collider in colliders)
            {
                BuildingPrivlidge privilege = collider.GetComponentInParent<BuildingPrivlidge>();
                if (privilege != null)
                {
                    return true;
                }
            }
            return false;
        }

        private bool IsPositionValid(Vector3 position)
        {
            float terrainHeight = TerrainMeta.HeightMap.GetHeight(position);
            if (position.y - GroundOffset < terrainHeight)
            {
                return false;
            }

            Collider[] colliders = Physics.OverlapSphere(position, 1f, LayerMask.GetMask("Construction", "Deployed"));
            if (colliders.Length > 0)
            {
                return false;
            }

            if (position.y - GroundOffset <= WaterSystem.OceanLevel)
            {
                return false;
            }

            NavMeshHit hit;
            if (!NavMesh.SamplePosition(position, out hit, 1f, NavMesh.AllAreas))
            {
                return false;
            }

            RaycastHit rockHit;
            if (Physics.Raycast(position, Vector3.down, out rockHit, 10f, LayerMask.GetMask("Terrain", "World")))
            {
                string rock = rockHit.collider.sharedMaterial.name;
                if (rockHit.collider.sharedMaterial.name.Contains("Rock") || rockHit.collider.sharedMaterial.name.ToLower().Contains("mountain") || rockHit.collider.sharedMaterial.name.ToLower().Contains("Cliff"))
                {
                    return false;
                }
                if (rock == "Rock")
                {
                    return false;
                }
            }

            return true;
        }

        #region New Pos Spawns

        private bool TestPos(Vector3 randomPos)
        {
            RaycastHit hitInfo;
            if (!Physics.Raycast(randomPos + Vector3.up * 300f, Vector3.down, out hitInfo, 400f, Layers.Solid) ||
                hitInfo.GetEntity() != null)
            {
                return false;
            }

            randomPos.y = hitInfo.point.y;

            var topology = TerrainMeta.TopologyMap.GetTopology(randomPos);
            if (topology == TerrainTopology.CLIFF || topology == TerrainTopology.CLIFFSIDE || topology == TerrainTopology.MONUMENT)
            {
                return false;
            }

            if (AntiHack.TestInsideTerrain(randomPos))
            {
                return false;
            }

            if (!ValidBounds.Test(randomPos))
            {
                return false;
            }
            return TestPosAgain(randomPos);
        }

        private bool TestPosAgain(Vector3 spawnPos)
        {
            if (WaterLevel.Test(spawnPos, true, true))
            {
                return false;
            }

            colliders.Clear();
            Vis.Colliders(spawnPos, 3f, colliders);
            foreach (var collider in colliders)
            {
                switch (collider.gameObject.layer)
                {
                    case (int)Layer.Prevent_Building:
                        return false;

                    case (int)Layer.Vehicle_Large:
                    case (int)Layer.Vehicle_World:
                    case (int)Layer.Vehicle_Detailed:
                        return false;
                }

                if (collider.name.Contains("zonemanager", CompareOptions.IgnoreCase))
                {
                    return false;
                }

                if (collider.name.Contains("radiation", CompareOptions.IgnoreCase))
                {
                    return false;
                }

                if (collider.name.Contains("fireball", CompareOptions.IgnoreCase) ||
                    collider.name.Contains("iceberg", CompareOptions.IgnoreCase) ||
                    collider.name.Contains("ice_sheet", CompareOptions.IgnoreCase))
                {
                    return false;
                }
            }

            return true;
        }

        #endregion
        private static TerrainTopology.Enum GetPosTopology(Vector3 position) => (TerrainTopology.Enum)TerrainMeta.TopologyMap.GetTopology(position);

        private void SpawnPookieBear(Vector3 position)
        {
            Vector3 newPos = new Vector3(0, 0.01f, 0);
            if (config.specialEvent && EntityScaleManager != null)
            {
                position = position + newPos;
            }

            Quaternion rotation = Quaternion.Euler(0, 90, 0);

            BaseEntity pookiePrefab = GameManager.server.CreateEntity("assets/prefabs/misc/xmas/pookie/pookie_deployed.prefab", position, rotation);

            if (pookiePrefab != null)
            {
                BaseCombatEntity entity = pookiePrefab as BaseCombatEntity;
                entity.Spawn();
                if (config.customHeatlh)
                {
                    entity.InitializeHealth(config.pookieHP, config.pookieHP);
                }
                if (config.pookieMapMarkers)
                {
                    CreatePookieMarker(position, entity.net.ID.ToString());
                }
                entity.name = "Pookie Bear";
                pookieEntName.Add(entity.net.ID);
                pookie = entity;
                AddMarkerToPook(entity);
                if (config.specialEvent)
                {
                    if (EntityScaleManager == null)
                    {
                        Puts("You need to download Entity Scale Manager by WhiteThunder for the event to work!");
                        Puts("https://umod.org/plugins/entity-scale-manager");
                    }
                    else
                    {
                        AddEventToPook(entity);
                    }
                }
            }
        }

        private void SpawnPookieBearDecoy(Vector3 position, int decNum)
        {
            Vector3 newPos = new Vector3(0, 0.01f, 0);
            if (config.specialEvent && EntityScaleManager != null)
            {
                position = position + newPos;
            }

            Quaternion rotation = Quaternion.Euler(0, 90, 0);
            BaseEntity pookiePrefab = GameManager.server.CreateEntity("assets/prefabs/misc/xmas/pookie/pookie_deployed.prefab", position, rotation);
            if (pookiePrefab != null)
            {
                BaseCombatEntity entity = pookiePrefab as BaseCombatEntity;
                entity.Spawn();
                if (config.customHeatlh)
                {
                    entity.InitializeHealth(config.decoyHP, config.decoyHP);
                }
                if (config.pookieMapMarkers)
                {
                    CreatePookieMarker(position, entity.net.ID.ToString());
                }
                entity.name = "Pookie Decoy" + decNum.ToString();
                pookieEntName.Add(entity.net.ID);
                pookieDecoy = entity;
                AddMarkerToPook(entity);
                if (config.specialEvent)
                {
                    if (EntityScaleManager == null)
                    {
                        Puts("You need to download Entity Scale Manager by WhiteThunder for the event to work!");
                        Puts("https://umod.org/plugins/entity-scale-manager");
                    }
                    else
                    {
                        AddEventToPook(entity);
                    }
                }
            }
        }

        void AddMarkerToPook(BaseEntity marker)
        {
            BaseEntity lantern = GameManager.server.CreateEntity(config.pookieObject, new Vector3(-1f, 0, 0));
            lantern.SetFlag(BaseEntity.Flags.On, true);
            lantern.name = "Pookie Lantern";
            lantern.SetParent(marker);
            lantern.Spawn();
        }

        void AddEventToPook(BaseEntity marker)
        {
            BaseEntity lantern = GameManager.server.CreateEntity("assets/prefabs/misc/xmas/sled/sled.deployed.prefab", new Vector3(0f, -0.10f, 0f));
            lantern.SetFlag(BaseEntity.Flags.On, true);
            lantern.name = "pumpkinhead";
            lantern.SetParent(marker);
            lantern.SetFlag(BaseEntity.Flags.InUse, true);
            lantern.SetFlag(BaseEntity.Flags.Busy, true, true);
            lantern.Spawn();
            EntityScaleManager.Call("API_ScaleEntity", lantern, 0.35f);
            var rigidBody = lantern.GetComponent<Rigidbody>();
            if (rigidBody != null)
                rigidBody.isKinematic = true;

            SpawnLights(lantern);
        }
        void SpawnLights(BaseEntity marker)
        {
            Quaternion newRot = Quaternion.Euler(90, 0, 90);
            Quaternion newRotTwo = Quaternion.Euler(-90, 0, -90);
            BaseEntity lightOne = GameManager.server.CreateEntity("assets/prefabs/misc/xmas/christmas_lights/xmas.lightstring.deployed.prefab", new Vector3(0.40f, 0.55f, -0.22f), newRot);
            BaseEntity lightTwo = GameManager.server.CreateEntity("assets/prefabs/misc/xmas/christmas_lights/xmas.lightstring.deployed.prefab", new Vector3(-0.40f, 0.55f, -0.22f), newRotTwo);

            lightOne.SetFlag(BaseEntity.Flags.On, true);
            lightTwo.SetFlag(BaseEntity.Flags.On, true);
            lightOne.name = "pumpkinhead";
            lightTwo.name = "pumpkinhead";
            lightOne.SetParent(marker);
            lightTwo.SetParent(marker);
            lightOne.Spawn();
            lightTwo.Spawn();
           // CreateWorldObject(-1622660759, "pumpkinhead", marker, false);
            EntityScaleManager.Call("API_ScaleEntity", lightOne, 0.35f);
            EntityScaleManager.Call("API_ScaleEntity", lightTwo, 0.35f);
        }

        //private DroppedItem CreatePresentItem(string name, BaseEntity parent, Vector3 localPosition, Vector3 localRotation, bool canPickup = true)
        //{
        //    DroppedItem presentItem = CreatePresentItem(name, parent.transform.position);

        //    presentItem.SetParent(parent);
        //    presentItem.transform.localPosition = localPosition;
        //    presentItem.transform.rotation = Quaternion.Euler(localRotation);

        //    return presentItem;
        //}

        //private DroppedItem CreatePresentItem(string name, Vector3 position, bool canPickup = true)
        //{
        //    BaseEntity presentEntity = CreateWorldObject(-1622660759, name, position, canPickup);

        //    Rigidbody rb = presentEntity.GetComponent<Rigidbody>();
        //    rb.isKinematic = true;

        //    UnityEngine.Object.Destroy(presentEntity.GetComponent<EntityCollisionMessage>());
        //    UnityEngine.Object.Destroy(presentEntity.GetComponent<PhysicsEffects>());

        //    return presentEntity as DroppedItem;
        //}

        //private BaseEntity CreateWorldObject(int itemId, string name, BaseEntity marker, bool canPickup)
        //{
        //    Item item = ItemManager.CreateByItemID(itemId);

        //    if (!string.IsNullOrEmpty(name))
        //        item.name = name;

        //    BaseEntity worldEntity = GameManager.server.CreateEntity(worlItem_Prefab, new Vector3(-0.40f, 0.55f, -0.22f));

        //    WorldItem worldItem = worldEntity as WorldItem;
        //    if (worldItem != null)
        //        worldItem.InitializeItem(item);

        //    worldEntity.Invoke(() =>
        //    {
        //        (worldEntity as DroppedItem).CancelInvoke((worldEntity as DroppedItem).IdleDestroy);
        //    }, 1f);


        //    worldItem.enableSaving = false;
        //    worldItem.allowPickup = true;

        //    worldItem.SetParent(marker);

        //    worldEntity.Spawn();

        //    item.SetWorldEntity(worldEntity);

        //    return worldEntity;
        //}

        private ItemDefinition FindItemDefinition(string shortname)
        {
            foreach (var itemDefinition in ItemManager.itemList)
            {
                if (itemDefinition.shortname == shortname)
                    return itemDefinition;
            }
            return null;
        }

        #endregion

        #region Rewards/Punishments
        private void GivePlayerItem(BasePlayer player, string itemName, int quantity, string name, ulong skin)
        {
            Item item = null;
            if (!config.enableDualReward)
            {
                if (config.srvrRewards)
                {
                    //Use ServerRewards
                    ServerRewards?.Call("AddPoints", player.userID, config.srAmount);
                    player.ChatMessage($"You have received {config.srAmount} RP for killing pookie!");
                    return;
                }
                if (config.ecoUse)
                {
                    //Use Economics
                    Economics?.Call("Deposit", player.userID, (double)config.ecoAmount);
                    player.ChatMessage($"{config.ecoAmount} has been added to your balance for killing pookie!");
                    return;
                }

                if (skin != 0)
                {
                    item = ItemManager.CreateByItemID(ItemManager.FindItemDefinition(itemName).itemid, quantity, skin);
                }
                else
                {
                    item = ItemManager.CreateByItemID(ItemManager.FindItemDefinition(itemName).itemid, quantity);
                }

                if (name != "")
                {
                    item.name = name;
                }

                if (item != null)
                {
                    if (!player.inventory.GiveItem(item, player.inventory.containerMain))
                    {
                        float dropHeight = 5f; // You can adjust this value as needed to set the drop height.Vector3 dropPosition = player.transform.position + Vector3.up * dropHeight;
                        item.Drop(dropPosition, player.transform.forward * 2);
                        player.ChatMessage($"Your inventory was full so {quantity}x {item.info.displayName.translated} were dropped on the ground!!");

                    }
                    else
                    {
                        player.ChatMessage($"You have received {quantity}x {item.info.displayName.translated} for finding Pookie!");
                    }

                }
            }
            else
            {
                if (config.srvrRewards)
                {
                    //Use ServerRewards
                    ServerRewards?.Call("AddPoints", player.userID, config.srAmount);
                    player.ChatMessage($"You have received {config.srAmount} RP for killing pookie!");
                }
                if (config.ecoUse)
                {
                    //Use Economics
                    Economics?.Call("Deposit", player.userID, (double)config.ecoAmount);
                    player.ChatMessage($"{config.ecoAmount} has been added to your balance for killing pookie!");
                }

                if (skin != 0)
                {
                    item = ItemManager.CreateByItemID(ItemManager.FindItemDefinition(itemName).itemid, quantity, skin);
                }
                else
                {
                    item = ItemManager.CreateByItemID(ItemManager.FindItemDefinition(itemName).itemid, quantity);
                }

                if (name != "")
                {
                    item.name = name;
                    item.info.displayName = name;
                }

                if (item != null)
                {
                    if (!player.inventory.GiveItem(item, player.inventory.containerMain))
                    {
                        float dropHeight = 5f; // You can adjust this value as needed to set the drop height.Vector3 dropPosition = player.transform.position + Vector3.up * dropHeight;
                        item.Drop(dropPosition, player.transform.forward * 2);
                        player.ChatMessage($"Your inventory was full so {quantity}x {item.info.displayName.translated} were dropped on the ground!!");

                    }
                    else
                    {
                        player.ChatMessage($"You have received {quantity}x {item.info.displayName.translated} for findi
// ... [Code preview truncated due to length. Full source in attached file] ...

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