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

FREE SharkBait : 1.0.4 1.0.4

Нет прав для скачивания
C#:
using System;
using System.Collections;
using Network;
using System.Collections.Generic;
using UnityEngine;
using Facepunch;
using Rust;
using System.Linq;

namespace Oxide.Plugins
{
    [Info("SharkBait", "Colon Blow", "1.0.4")]
    class SharkBait : RustPlugin
    {
        // Fix for shark parts now spawning to see them

        #region Load

        void Loaded()
        {
            LoadVariables();
            LoadMessages();
            permission.RegisterPermission("sharkbait.admin", this);
        }

        void OnServerInitialized()
        {
            timer.In(10, RespawnAllSharks);
        }

        #endregion

        #region Configuration

        static ulong GWFin = 1407588505;
        static ulong GWFront = 1407587906;
        static ulong GWBack = 1407587156;

        static ulong HHFin = 1403745229;
        static ulong HHFront = 1403174634;
        static ulong HHBack = 1403180514;

        bool EnableAutoSpawn = true;
        bool EnableSpawnAtRockFormations = true;
        bool EnableSpawnAtDiveSites = true;
        bool EnableSpawnAtFloatingLoot = true;

        static float SpawnActivationRadius = 50f;
        static float SharkAggroRadius = 20f;
        static float SharkBiteRange = 2f;
        static float SharkDespawnTime = 500f;
        static float SharkSwimSpeed = 6f;
        static float SharkDamageToPlayer = 20f;
        int SharkSpawnChance = 30;
        static bool SharksCanAttackBoats = true;
        static bool SharksCanAttackPlayers = true;

        bool Changed;

        void LoadVariables()
        {
            LoadConfigVariables();
            SaveConfig();
        }

        void LoadDefaultConfig()
        {
            Puts("Creating a new config file");
            Config.Clear();
            LoadVariables();
        }

        void LoadConfigVariables()
        {
            CheckCfgUlong("Skin ID - Great White Front", ref GWFront);
            CheckCfgUlong("Skin ID - Great White Back", ref GWBack);
            CheckCfgUlong("Skin ID - Great White Fin", ref GWFin);

            CheckCfgUlong("Skin ID - HammerHead Front", ref HHFront);
            CheckCfgUlong("Skin ID - HammerHead Back", ref HHBack);
            CheckCfgUlong("Skin ID - HammerHead Fin", ref HHFin);

            CheckCfg("Chance Roll - chances a loot or dive site will have a shark spawner : ", ref SharkSpawnChance);

            CheckCfg("Global - Sharks can attack Boats ? ", ref SharksCanAttackBoats);
            CheckCfg("Global - Sharks can attack Players ? ", ref SharksCanAttackPlayers);

            CheckCfg("Autospawn - Enable the Autospawn feature ? ", ref EnableAutoSpawn);
            CheckCfg("Autospawn - Enable autospawn at Rock Formations ? ", ref EnableSpawnAtRockFormations);
            CheckCfg("Autospawn - Enable autospawn at Dive Sites ? ", ref EnableSpawnAtDiveSites);
            CheckCfg("Autospawn - Enable autospawn at Floating Water Loot Sites ? ", ref EnableSpawnAtFloatingLoot);

            CheckCfgFloat("Shark Spawner - player detection radius : ", ref SpawnActivationRadius);

            CheckCfgFloat("Shark - aggro radius of shark to players or boats : ", ref SharkAggroRadius);
            CheckCfgFloat("Shark - bite range radius of shark : ", ref SharkBiteRange);
            CheckCfgFloat("Shark - despawn time of shark after spawn with no interaction : ", ref SharkDespawnTime);
            CheckCfgFloat("Shark - swim speed of shark : ", ref SharkSwimSpeed);
            CheckCfgFloat("Shark - damage done to player when shark attacks : ", ref SharkDamageToPlayer);
        }

        void CheckCfg<T>(string Key, ref T var)
        {
            if (Config[Key] is T)
                var = (T)Config[Key];
            else
                Config[Key] = var;
        }

        void CheckCfgFloat(string Key, ref float var)
        {

            if (Config[Key] != null)
                var = System.Convert.ToSingle(Config[Key]);
            else
                Config[Key] = var;
        }

        void CheckCfgUlong(string Key, ref ulong var)
        {

            if (Config[Key] != null)
                var = Convert.ToUInt64(Config[Key]);
            else
                Config[Key] = var;
        }

        #endregion

        #region Localization

        private void LoadMessages()
        {
            lang.RegisterMessages(new Dictionary<string, string>
            {
                ["noperms"] = "You don't have permission to use this command.",
                ["sharkhasspawned"] = "There is a shark in the water !!!!",
                ["sharkhasdied"] = "You have killed a shark..good job !!",
            }, this);
        }

        #endregion

        #region Commands

        [ChatCommand("sharkbait")]
        void chatSharkBait(BasePlayer player, string command, string[] args)
        {
            if (permission.UserHasPermission(player.UserIDString, "sharkbait.admin"))
                AddSharkEntity(player.transform.position);
            else
                PrintToChat(player, lang.GetMessage("noperms", this, player.UserIDString));
        }

        [ChatCommand("sharkbait.respawn")]
        void chatSharkBaitRespawn(BasePlayer player, string command, string[] args)
        {
            if (permission.UserHasPermission(player.UserIDString, "sharkbait.admin"))
                RespawnAllSharks();
            else
                PrintToChat(player, lang.GetMessage("noperms", this, player.UserIDString));
        }

        [ConsoleCommand("sharkbait.respawn")]
        void cmdConsoleSharkBaitRespawn(ConsoleSystem.Arg arg)
        {
            var player = arg.Player() ?? null;
            if (player == null) { RespawnAllSharks(); return; }
            if (player != null)
            {
                if (permission.UserHasPermission(player.UserIDString, "sharkbait.admin"))
                    RespawnAllSharks();
                else
                    PrintToChat(player, lang.GetMessage("noperms", this, player.UserIDString));
            }
        }

        [ChatCommand("sharkbait.killall")]
        void chatSharkBaitKillAll(BasePlayer player, string command, string[] args)
        {
            if (permission.UserHasPermission(player.UserIDString, "sharkbait.admin"))
                RemoveAllSharks();
            else
                PrintToChat(player, lang.GetMessage("noperms", this, player.UserIDString));
        }

        #endregion

        #region Hooks

        private void RemoveAllSharks()
        {
            DestroyAll<SharkEntity>();
            DestroyAll<SharkSpawnController>();
            List<BaseEntity> findspawns = new List<BaseEntity>();
            Vis.Entities<BaseEntity>(new Vector3(0f, 0f, 0f), ((ConVar.Server.worldsize) / 2) + 1000f, findspawns);
            foreach (BaseEntity obj in findspawns)
            {
                if (obj.name.Contains("rug/rug.deployed"))
                {
                    if (obj.skinID == GWFront || obj.skinID == HHFront || obj.skinID == GWFin || obj.skinID == HHFin || obj.skinID == GWFront || obj.skinID == HHFront)
                    {
                        if (obj != null && !obj.IsDestroyed)
                        {
                            obj.gameObject.ToBaseEntity().Kill(BaseNetworkable.DestroyMode.None);
                        }
                    }
                }
            }
        }

        void OnEntitySpawned(BaseEntity entity, UnityEngine.GameObject gameObject)
        {
            if (!EnableAutoSpawn) return;
            if (gameObject == null) return;

            if (gameObject.name.Contains("rockformation_underwater") && EnableSpawnAtRockFormations)
            {
                RespawnHandler(gameObject);
            }
            if (gameObject.name.Contains("junkpile_water") && EnableSpawnAtFloatingLoot)
            {
                RespawnHandler(gameObject);
            }
            if (gameObject.name.Contains("divesite") && EnableSpawnAtDiveSites)
            {
                RespawnHandler(gameObject);
            }
        }

        void RespawnAllSharks()
        {
            if (!EnableAutoSpawn) return;
            RemoveAllSharks();

            var allobjects = UnityEngine.Object.FindObjectsOfType<GameObject>();
            foreach (var gobject in allobjects)
            {
                if (gobject.name.Contains("rockformation_underwater") && EnableSpawnAtRockFormations)
                {
                    RespawnHandler(gobject);
                }
                if (gobject.name.Contains("junkpile_water") && EnableSpawnAtFloatingLoot)
                {
                    RespawnHandler(gobject);
                }
                if (gobject.name.Contains("divesite") && EnableSpawnAtDiveSites)
                {
                    RespawnHandler(gobject);
                }
            }
            PrintWarning("Respawn of Shark Population has been completed.");
        }

        public void RespawnHandler(GameObject gobject)
        {
            var pos = gobject.transform.position;

            int roll = UnityEngine.Random.Range(0, 100);
            if (roll < SharkSpawnChance)
            {
                var hascontroller = gobject.GetComponent<SharkSpawnController>() ?? null;
                if (hascontroller != null) GameObject.Destroy(hascontroller);

                gobject.AddComponent<SharkSpawnController>();
            }
        }

        public void AddSharkEntity(Vector3 pos)
        {

            List<BaseEntity> nearshark = new List<BaseEntity>();
            Vis.Entities<BaseEntity>(pos, 30f, nearshark);
            foreach (BaseEntity shark in nearshark)
            {
                if (shark.GetComponentInParent<SharkEntity>())
                {
                    return;
                }
            }
            SpawnShark(pos);
        }

        void SpawnShark(Vector3 pos)
        {
            string prefabsharkfin = "assets/prefabs/misc/orebonus/orebonus_generic.prefab";
            var groundy = TerrainMeta.HeightMap.GetHeight(pos);
            if (pos.y < groundy) pos.y = groundy + 2f;
            if (pos.y > -0.5f) pos.y = -0.5f;
            var sharkent = GameManager.server.CreateEntity(prefabsharkfin, new Vector3(pos.x, pos.y, pos.z), Quaternion.identity, true);
            sharkent.enableSaving = false;
            sharkent.Spawn();
            var addentity = sharkent.gameObject.AddComponent<SharkEntity>();
        }

        void Unload()
        {
            RemoveAllSharks();
        }

        void DestroyAll<T>()
        {
            var objects = GameObject.FindObjectsOfType(typeof(T));
            if (objects != null)
                foreach (var gameObj in objects)
                {
                    GameObject.Destroy(gameObj);
                }
        }

        #endregion

        #region Shark Spawn Controller

        class SharkSpawnController : MonoBehaviour
        {
            SharkBait _instance;
            SphereCollider detectionradius;
            Vector3 spawnlocation;
            bool doactivation;
            Timer mytimer;

            void Awake()
            {
                _instance = new SharkBait();
                detectionradius = gameObject.AddComponent<SphereCollider>();
                detectionradius.gameObject.layer = (int)Layer.Reserved1;
                detectionradius.isTrigger = true;
                detectionradius.radius = SpawnActivationRadius;
                spawnlocation = detectionradius.transform.position;
            }

            private void OnTriggerEnter(Collider col)
            {
                if (col == null || doactivation) return;
                var target = col.GetComponentInParent<BasePlayer>() ?? null;
                if (target != null)
                {
                    doactivation = true;
                    _instance.AddSharkEntity(spawnlocation);
                    ToggleTrigger();
                }
            }

            void ToggleTrigger()
            {
                mytimer = _instance.timer.Once(System.Convert.ToSingle(SharkDespawnTime), () =>
                {
                    if (this == null) { mytimer.Destroy(); return; }
                    doactivation = false;
                });
            }

            void OnDestroy()
            {
                GameObject.Destroy(detectionradius);
                GameObject.Destroy(this);
            }
        }

        #endregion

        #region SharkEntity

        class SharkEntity : BaseEntity
        {
            SharkBait instance;
            BaseEntity sharkentity;
            BaseEntity sharkfront;
            BaseEntity sharkback;
            BaseEntity sharkfin;
            BaseEntity sharkbait;
            int counter;
            SphereCollider aggroradius;
            Rigidbody rigidbody;
            Vector3 initialspawn;
            Vector3 spawnlocation;
            Vector3 position;
            Vector3 attackpos;
            Vector3 offset;
            private float _angle;
            float speed;
            float despawntimer;
            float despawntimelimit;
            int attackcounter;
            bool didattack;
            bool reversemovment;
            bool moveback;

            void Awake()
            {
                instance = new SharkBait();
                sharkentity = GetComponentInParent<BaseEntity>();
                sharkbait = null;
                initialspawn = sharkentity.transform.position;
                spawnlocation = sharkentity.transform.position;
                counter = 0;
                speed = SharkSwimSpeed;
                attackcounter = 0;
                didattack = false;
                reversemovment = false;
                moveback = false;
                despawntimer = 0f;
                despawntimelimit = (SharkDespawnTime * 10);

                aggroradius = sharkentity.gameObject.AddComponent<SphereCollider>();
                aggroradius.gameObject.layer = (int)Layer.Reserved1;
                aggroradius.isTrigger = true;
                aggroradius.radius = SharkAggroRadius;
                MovementRoll();
                SpawnSharky();
            }

            void MovementRoll()
            {
                int moveroll = UnityEngine.Random.Range(0, 2);
                if (moveroll == 1) reversemovment = true;
            }

            void SpawnSharky()
            {
                bool spawnhammerhead = false;
                int typeroll = UnityEngine.Random.Range(0, 2);
                if (typeroll == 1) spawnhammerhead = true;

                ulong frontskinid = GWFront;
                ulong backskinid = GWBack;
                ulong finskinid = GWFin;

                if (spawnhammerhead)
                {
                    frontskinid = HHFront;
                    backskinid = HHBack;
                    finskinid = HHFin;
                }

                string prefabsharkfin = "assets/prefabs/deployable/rug/rug.deployed.prefab";
                sharkfront = GameManager.server.CreateEntity(prefabsharkfin, sharkentity.transform.position, sharkentity.transform.rotation, true);
                sharkfront.GetComponent<BaseNetworkable>()._limitedNetworking = false;
                sharkfront.enableSaving = false;
                sharkfront.skinID = frontskinid;
                var sfstab = sharkfront.GetComponent<StabilityEntity>();
                if (sfstab) sfstab.grounded = true;
                sharkfront.Spawn();
                sharkfront.SetParent(sharkentity, true, false);

                sharkfin = GameManager.server.CreateEntity(prefabsharkfin, sharkentity.transform.position, sharkentity.transform.rotation, true);
                sharkfin.GetComponent<BaseNetworkable>()._limitedNetworking = false;
                sharkfin.enableSaving = false;
                sharkfin.skinID = finskinid;
                var sfinstab = sharkfront.GetComponent<StabilityEntity>();
                if (sfinstab) sfstab.grounded = true;
                sharkfin.Spawn();
                sharkfin.SetParent(sharkentity, true, false);
                sharkfin.transform.localPosition = new Vector3(0f, 0.8f, -1f);
                sharkfin.transform.localEulerAngles = new Vector3(0, 180, 90);

                sharkback = GameManager.server.CreateEntity(prefabsharkfin, sharkentity.transform.position, sharkentity.transform.rotation, true);
                sharkback.GetComponent<BaseNetworkable>()._limitedNetworking = false;
                sharkback.enableSaving = false;
                sharkback.skinID = backskinid;
                var sbstab = sharkfront.GetComponent<StabilityEntity>();
                if (sbstab) sfstab.grounded = true;
                sharkback.Spawn();
                sharkback.SetParent(sharkentity, true, false);
                sharkback.transform.localPosition = new Vector3(0f, 0f, -2.9f);
                sharkback.transform.localEulerAngles = new Vector3(0, 0, 0);
            }

            private void OnTriggerStay(Collider col)
            {
                if (col == null) return;
                var target = col.GetComponentInParent<BasePlayer>();
                if (SharksCanAttackPlayers && target != null && target.WaterFactor() > 0.25f && target.Health() > 0)
                {
                    sharkbait = target;
                    return;
                }
                var boat = col.GetComponentInParent<BaseBoat>();
                if (SharksCanAttackBoats && boat != null && boat.Health() > 0f)
                {
                    sharkbait = boat;
                    return;
                }
                var corpse = col.GetComponentInParent<BaseCorpse>();
                if (corpse != null)
                {
                    sharkbait = corpse;
                    return;
                }
            }

            void MovementSplash()
            {
                Vector3 currentpos = sharkentity.transform.position;
                if (currentpos.y >= -1f) Effect.server.Run("assets/content/vehicles/boats/effects/splashloop.prefab", sharkentity.transform.position + new Vector3(0f, -0.6f, 0f));
            }

            void NearSharkBait()
            {
                if (moveback || didattack) return;
                List<BaseEntity> nearplayer = new List<BaseEntity>();
                Vis.Entities<BaseEntity>(sharkentity.transform.position, SharkBiteRange, nearplayer);
                foreach (BaseEntity ply in nearplayer)
                {
                    var iscorpse = ply.GetComponent<BaseCorpse>();
                    if (iscorpse)
                    {
                        iscorpse.Hurt(SharkDamageToPlayer);
                        didattack = true;
                        return;
                    }
                    var isplayer = ply.GetComponent<BasePlayer>();
                    if (isplayer)
                    {
                        isplayer.Hurt(SharkDamageToPlayer);
                        Effect.server.Run("assets/bundled/prefabs/fx/headshot.prefab", isplayer.transform.position);
                        Effect.server.Run("assets/bundled/prefabs/fx/explosions/water_bomb.prefab", isplayer.transform.position);
                        didattack = true;
                        return;
                    }
                    var isboat = ply.GetComponent<BaseBoat>();
                    if (isboat)
                    {
                        Effect.server.Run("assets/bundled/prefabs/fx/impacts/blunt/wood/wood1.prefab", isboat.transform.position);
                        Effect.server.Run("assets/bundled/prefabs/fx/explosions/water_bomb.prefab", isboat.transform.position);
                        isboat.myRigidBody.AddRelativeTorque(Vector3.forward * 10f, ForceMode.VelocityChange);
                        isboat.Hurt(999f);
                        didattack = true;
                        return;
                    }
                }
                didattack = false;
                return;
            }

            public bool IsWaterDeepEnough(Vector3 position)
            {
                var waterdepth = (TerrainMeta.WaterMap.GetHeight(position) - TerrainMeta.HeightMap.GetHeight(position));
                if (waterdepth >= 3f) return true;
                return false;
            }

            Vector3 GetNewPos()
            {
                if (!IsWaterDeepEnough(sharkentity.transform.position) && !moveback)
                {
                    sharkbait = null;
                    didattack = false;
                    moveback = true;
                    return initialspawn;
                }
                if (moveback)
                {
                    sharkbait = null;
                    didattack = false;
                    var checkpos = sharkentity.transform.position;
                    if (checkpos == initialspawn) { moveback = false; return initialspawn; }
                    return initialspawn;
                }

                if (didattack)
                {
                    despawntimer = 0f;
                    if (attackcounter == 1)
                    {
                        attackpos = new Vector3(sharkentity.transform.position.x, sharkentity.transform.position.y, sharkentity.transform.position.z);
                        position = new Vector3(UnityEngine.Random.Range(-5000f, 5000f), sharkentity.transform.position.y, UnityEngine.Random.Range(-5000f, 5000f));
                    }
                    attackcounter = attackcounter + 1;
                    if (attackcounter >= 50 && attackcounter < 100) { position = attackpos; }
                    if (attackcounter >= 100) { attackcounter = 0; MovementRoll(); sharkbait = null; didattack = false; }
                    return position;
                }
                if (sharkbait != null)
                {
                    despawntimer = 0f;
                    position = sharkbait.transform.position;
                    float adjustedy = position.y;
                    if (adjustedy > -0.5f) adjustedy = -0.5f;
                    position = new Vector3(position.x, adjustedy, position.z);
                    return position;
                }

                _angle += 0.5f * Time.deltaTime;
                offset = new Vector3(Mathf.Sin(_angle), 0f, Mathf.Cos(_angle)) * 15f;
                if (reversemovment) offset = new Vector3(Mathf.Sin(-_angle), 0f, Mathf.Cos(-_angle)) * 15f;
                var currentpos = sharkentity.transform.position;
                if (currentpos.y < -0.5f) currentpos.y = currentpos.y + 0.1f;
                position = currentpos + offset;
                didattack = false;
                return position;
            }

            void FixedUpdate()
            {
                if (sharkback == null || sharkfin == null || sharkfront == null) { OnDestroy(); return; }
                if (!didattack || !sharkbait) despawntimer = despawntimer + 1f;
                if (despawntimer >= despawntimelimit) { OnDestroy(); return; }
                Vector3 currentpos = sharkentity.transform.position;
                if (counter == 3)
                {
                    if (currentpos.y >= -1f) MovementSplash();
                    if (!didattack) NearSharkBait();
                    counter = 0;
                }

                var newpos = GetNewPos();

                var targetDir = newpos - sharkentity.transform.position;
                Vector3 newDir = Vector3.RotateTowards(sharkentity.transform.forward, targetDir, speed * Time.deltaTime, 0.0F);

                sharkentity.transform.rotation = Quaternion.LookRotation(newDir);
                sharkentity.transform.position = Vector3.MoveTowards(transform.position, newpos, (speed) * Time.deltaTime);
                if (currentpos.y > -0.5f) currentpos.y = -0.5f;
                spawnlocation = new Vector3(currentpos.x, currentpos.y, currentpos.z);

                sharkentity.transform.hasChanged = true;
                sharkentity.SendNetworkUpdateImmediate();
                sharkentity.UpdateNetworkGroup();

                counter = counter + 1;
            }

            void OnDestroy()
            {
                if (sharkentity != null && !sharkentity.IsDestroyed) { sharkentity.Invoke("KillMessage", 0.1f); }
            }
        }

        #endregion

    }
}

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