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

FREE RocketTurrets : 1.3.7 1.3.7

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

/*  TODO:
              - Finish anti-air turrets MonoBehviour                                                                              ✓
              - Heat seeking rockets?                                                                                             ✓
              - Give the anti-air turrets a different aesthetic                                                                   ✓
              - Handle the data for anti air turrets (loading / unloading)                                                        ✓
              - Return items on pickup / downgrade back to normal turret                                                          ✓
              - upgrades / different tiers for the rocket turret (increased rocket speed / shot speed / heatseeking rockets)
              - Grenade turrets?
              - Make custom permissions at least for per player limits, please.- Stop turrets from shooting animals

    BUGS:
            1.anti-air turrets don't lose their health on projectile impact/splash damage.(idk if this is (efficently) possible)
            2.make custom permissions at least for per player limits, please.(WIP)
            3.heat seeking rocket feature don't work or i don't understand how it should to work =]                              ✓

    UPDATE LOG:
            
            - Optimized plugin loading (using CoRoutine to initialize all rocket turrets)
*/

namespace Oxide.Plugins
{
    [Info("RocketTurrets", "redBDGR", "1.3.7")]
    [Description("Create rocket shooting turrets")]
    class RocketTurrets : RustPlugin
    {
        private bool changed;

        private List<AutoTurret> rocketTurrets = new List<AutoTurret>();
        private List<AutoTurret> antiairTurrets = new List<AutoTurret>();
        private List<AutoTurret> javelinTurrets = new List<AutoTurret>();
        private Dictionary<string, PlayerData> turretNumbers = new Dictionary<string, PlayerData>();
        private List<ulong> turretIDs = new List<ulong>();
        private List<ulong> antiAirIDs = new List<ulong>();
        private List<ulong> javelinIDs = new List<ulong>();
        private static RocketTurrets plugin;
        public static LayerMask collLayers = LayerMask.GetMask("Construction", "Deployed", "Tree", "Terrain", "Resource", "World", "Water", "Default", "AI");

        #region Config Variables

        // Rocket turrets
        private float rocketFireRate = 1.2f;
        private float rocketLockonTime = 5f;
        private float minHitDistance = 10f;
        private float rocketLockonRadius = 40f;
        private float rocketSpeed = 20f;
        private uint rocketLauncherSkin;
        private float explosionRadius = 4f;
        private bool explodeAtTarget = true;
        private int lockonSoundEveryxUpdate = 100;
        private bool requiresAmmo = true;
        private int maxNumberAllowed = 5;
        private bool rocketHeatSeeking;

        // AA turrets
        private float aaFireRate = 1.2f;
        private float aaLockonTime = 5f;
        private float aaminHitDistance = 5f;
        private float aaLockonRadius = 150f;
        private float aarocketSpeed = 40f;
        private uint aaLauncherSkin;
        private float aaexplosionRadius = 4f;
        private int aalockonSoundEveryxUpdate = 100;
        private float damageToHeli = 500f;
        private bool aaRequiresAmmo = true;
        private int aaMaxNumberAllowed = 5;
        private bool aaRequireBuildingRightsToAccessInventory = true;

        // Javelin Turrets
        private float jrocketFireRate = 1.2f;
        private float jrocketLockonTime = 5f;
        private float jminHitDistance = 10f;
        private float jrocketLockonRadius = 40f;
        private float jrocketSpeed = 20f;
        private uint jrocketLauncherSkin;
        private float jexplosionRadius = 4f;
        private int jlockonSoundEveryxUpdate = 100;
        private bool jrequiresAmmo = true;
        private int jmaxNumberAllowed = 5;
        private bool jSeekTarget = true;
        private float jHeightBeforeCurve = 40f;

        // Global vars
        private bool returnCostOnPickup;
        private bool returnCostOnDowngrade;

        #region Config Lists

        private static Dictionary<string, object> RocketUpgradeCost()
        {
            var at = new Dictionary<string, object> { { "rocket.launcher", 1 } };
            return at;
        }

        private static Dictionary<string, object> AntiAirUpgradeCost()
        {
            var at = new Dictionary<string, object> { { "targeting.computer", 1 }, { "cctv.camera", 2 }, { "rocket.launcher", 1 } };
            return at;
        }

        private static Dictionary<string, object> JavelinUpgradeCost()
        {
            var at = new Dictionary<string, object> { { "rocket.launcher", 1 } };
            return at;
        }

        private Dictionary<string, object> rocketUpgradeCost;
        private Dictionary<string, object> antiAirUpgradeCost;
        private Dictionary<string, object> javelinUpgradeCost;

        #endregion

        #endregion

        #region  Permissions

        private const string permissionName = "rocketturrets.use";
        private const string permissionNameROCKET = "rocketturrets.rocket";
        private const string permissionNameANTIAIR = "rocketturrets.antiair";
        private const string permissionNameJAVELIN = "rocketturrets.javelin";
        private const string permissionNameUNLIMITED = "rocketturrets.unlimited";

        #endregion

        #region Classes

        private class StoredData
        {
            public List<ulong> turretIDs = new List<ulong>();
            public List<ulong> antiAirIDs = new List<ulong>();
            public List<ulong> javelinIDs = new List<ulong>();
        }

        private class StoredData2
        {
            public Dictionary<string, PlayerData> turretNumbers = new Dictionary<string, PlayerData>();
        }

        private class PlayerData
        {
            public int RocketTurrets;
            public int AntiAirTurrets;
            public int JavelinTurrets;
        }

        #endregion

        #region Data Handling

        private DynamicConfigFile data;
        private DynamicConfigFile data2;
        private StoredData storedData;
        private StoredData2 storedData2;

        private void OnServerSave() => SaveData();

        private void SaveData()
        {
            storedData.turretIDs = turretIDs;
            storedData.antiAirIDs = antiAirIDs;
            storedData.javelinIDs = javelinIDs;
            storedData2.turretNumbers = turretNumbers;
            data.WriteObject(storedData);
            data2.WriteObject(storedData2);
        }

        private void LoadData()
        {
            try
            {
                storedData = data.ReadObject<StoredData>();
                storedData2 = data2.ReadObject<StoredData2>();
                turretNumbers = storedData2.turretNumbers;
                turretIDs = storedData.turretIDs;
                antiAirIDs = storedData.antiAirIDs;
                javelinIDs = storedData.javelinIDs;
            }
            catch
            {
                Puts("Failed to load data, creating new file");
                storedData = new StoredData();
            }
        }

        #endregion

        #region Config Loading

        protected override void LoadDefaultConfig()
        {
            Config.Clear();
            LoadVariables();
        }

        private void LoadVariables()
        {
            // Rocket turret settings
            rocketFireRate = Convert.ToSingle(GetConfig("Turret Settings", "Rocket fire rate", 2f));
            rocketLockonTime = Convert.ToSingle(GetConfig("Turret Settings", "Lockon length", 5f));
            minHitDistance = Convert.ToSingle(GetConfig("Turret Settings", "Min shoot distance", 4f));
            rocketLockonRadius = Convert.ToSingle(GetConfig("Turret Settings", "Rocket lockon radius", 40f));
            rocketSpeed = Convert.ToSingle(GetConfig("Turret Settings", "Rocket speed", 20f));
            rocketLauncherSkin = Convert.ToUInt32(GetConfig("Turret Settings", "Default rocket model skin", 0));
            explosionRadius = Convert.ToSingle(GetConfig("Turret Settings", "Explosion radius", 4f));
            explodeAtTarget = Convert.ToBoolean(GetConfig("Turret Settings", "Explode at target pos", true));
            lockonSoundEveryxUpdate = Convert.ToInt32(GetConfig("Turret Settings", "Lockon sound every x updates", 100));
            requiresAmmo = Convert.ToBoolean(GetConfig("Turret Settings", "Requires Ammo", true));
            maxNumberAllowed = Convert.ToInt16(GetConfig("Turret Settings", "Maximum Allowed Per Player", 5));
            rocketHeatSeeking = Convert.ToBoolean(GetConfig("Turret Settings", "Heatseeking Rockets", false));

            // AntiAir turret settings
            aaFireRate = Convert.ToSingle(GetConfig("AntiAir Settings", "Rocket fire rate", 2f));
            aaLockonTime = Convert.ToSingle(GetConfig("AntiAir Settings", "Lockon length", 5f));
            aaminHitDistance = Convert.ToSingle(GetConfig("AntiAir Settings", "Min shoot distance", 4f));
            aaLockonRadius = Convert.ToSingle(GetConfig("AntiAir Settings", "Lockon radius", 80f));
            aarocketSpeed = Convert.ToSingle(GetConfig("AntiAir Settings", "Rocket speed", 30f));
            aaLauncherSkin = Convert.ToUInt32(GetConfig("AntiAir Settings", "Default rocket model skin", 0));
            aaexplosionRadius = Convert.ToSingle(GetConfig("AntiAir Settings", "Explosion radius", 4f));
            aalockonSoundEveryxUpdate = Convert.ToInt32(GetConfig("AntiAir Settings", "Lockon sound every x updates", 100));
            damageToHeli = Convert.ToSingle(GetConfig("AntiAir Settings", "Damage to heli", 500f));
            aaRequiresAmmo = Convert.ToBoolean(GetConfig("AntiAir Settings", "Requires Ammo", true));
            aaMaxNumberAllowed = Convert.ToInt16(GetConfig("AntiAir Settings", "Maximum Allowed Per Player", 5));
            aaRequireBuildingRightsToAccessInventory = Convert.ToBoolean(GetConfig("AntiAir Settings", "Require Build Acces to Loot", true));

            // Javelin turret settings
            jrocketFireRate = Convert.ToSingle(GetConfig("Javelin Settings", "Rocket fire rate", 2f));
            jrocketLockonTime = Convert.ToSingle(GetConfig("Javelin Settings", "Lockon Length", 5f));
            jminHitDistance = Convert.ToSingle(GetConfig("Javelin Settings", "Min lockon distance", 10f));
            jrocketLockonRadius = Convert.ToSingle(GetConfig("Javelin Settings", "Lockon radius", 80f));
            jrocketSpeed = Convert.ToSingle(GetConfig("Javelin Settings", "Rocket speed", 15f));
            jrocketLauncherSkin = Convert.ToUInt32(GetConfig("Javelin Settings", "Default rocket model skin", 0));
            jexplosionRadius = Convert.ToSingle(GetConfig("Javelin Settings", "Explosion radius", 4f));
            jlockonSoundEveryxUpdate = Convert.ToInt16(GetConfig("Javelin Settings", "Lockon sound every x updates", 100));
            jrequiresAmmo = Convert.ToBoolean(GetConfig("Javelin Settings", "Requires ammo", true));
            jmaxNumberAllowed = Convert.ToInt16(GetConfig("Javelin Settings", "Max number allowed per player", 5));
            jSeekTarget = Convert.ToBoolean(GetConfig("Javelin Settings", "Seek target", true));
            jHeightBeforeCurve = Convert.ToSingle(GetConfig("Javelin Settings", "Height before curve starts", 40f));

            // Costs
            rocketUpgradeCost = (Dictionary<string, object>) GetConfig("Turret Settings", "[ Cost to upgrade - Rocket tier ]", RocketUpgradeCost());
            antiAirUpgradeCost = (Dictionary<string, object>) GetConfig("AntiAir Settings", "[Cost to Upgrade - AntiAir Tier ]", AntiAirUpgradeCost());
            javelinUpgradeCost = (Dictionary<string, object>) GetConfig("Javelin Settings", "[ Cost to upgrade - Javelin Tier ]", JavelinUpgradeCost());
            returnCostOnPickup = Convert.ToBoolean(GetConfig("General Settings", "Return upgrade cost on turret pickup", false));
            returnCostOnDowngrade = Convert.ToBoolean(GetConfig("General Settings", "Return upgrade cost on turret downgrade", false));

            if (!changed) return;
            SaveConfig();
            changed = false;
        }

        #endregion

        #region API

        [HookMethod("IsRocketTurret")]
        public bool IsRocketTurret(AutoTurret turret) => turret.GetComponent<RocketTurret>();

        [HookMethod("ToggleTurretAutomation")]
        public void ToggleTurretAutomation(AutoTurret turret, bool enabled)
        {
            if (turret.GetComponent<RocketTurret>())
                turret.GetComponent<RocketTurret>().enabled = true;
        }

        [HookMethod("TryFireRocket")]
        public void TryFireRocket(AutoTurret turret)
        {
            if (turret.GetComponent<RocketTurret>())
                turret.GetComponent<RocketTurret>().TryFireRocket();
        }

        #endregion

        #region MonoBehaviour Classes

        #region Turret Classes

        private class RocketTurret : MonoBehaviour
        {
            private float aimRadius = plugin.rocketLockonRadius;
            private float fireRate = plugin.rocketFireRate;
            private float rocketSpeed = plugin.rocketSpeed;
            private float minHitDistance = plugin.minHitDistance;
            private float lockonTime = plugin.rocketLockonTime;
            private uint rocketLauncherSkin = plugin.rocketLauncherSkin;
            private float explosionRadius = plugin.explosionRadius;
            private bool explodeOnTargetPos = plugin.explodeAtTarget;
            private int soundEveryxUpdates = plugin.lockonSoundEveryxUpdate;
            private bool requiresAmmo = plugin.requiresAmmo;
            private bool heatSeek = plugin.rocketHeatSeeking;

            private int updateCounter;
            private bool isLockedOn;
            private bool isLockingOn;
            private float lockonFinish;
            private float nextShoot;
            private AutoTurret turret;
            private BaseCombatEntity target;
            private DroppedItem launcher_1;
            private DroppedItem rocket_1;
            private DroppedItem rocket_2;
            private DestroyOnGroundMissing desGround;
            private GroundWatch groundWatch;

            private void Awake()
            {
                turret = gameObject.GetComponent<AutoTurret>();
                InitAesthetics();
                if (!plugin.rocketTurrets.Contains(turret))
                    plugin.rocketTurrets.Add(turret);
                turret.sightRange = aimRadius;
                if (!plugin.turretIDs.Contains(turret.net.ID))
                    plugin.turretIDs.Add(turret.net.ID);

                desGround = GetComponent<DestroyOnGroundMissing>();
                if (!desGround)
                    gameObject.AddComponent<DestroyOnGroundMissing>();
                groundWatch = GetComponent<GroundWatch>();
                if (!groundWatch)
                    gameObject.AddComponent<GroundWatch>();
                groundWatch.CancelInvoke("OnPhysicsNeighbourChanged");
                groundWatch.InvokeRepeating("OnPhysicsNeighbourChanged", 0, 0.5f);
            }

            private void Update()
            {
                if (!turret.HasTarget())
                {
                    if (isLockedOn)
                        isLockedOn = false;
                    if (isLockingOn)
                        isLockingOn = false;
                    return;
                }
                if (!isLockedOn)
                {
                    if (!isLockingOn)
                    {
                        lockonFinish = Time.time + lockonTime;
                        isLockingOn = true;
                    }
                    else if (isLockingOn && Time.time > lockonFinish)
                        LockToTarget(turret.target);
                    else if (isLockingOn)
                    {
                        if (updateCounter == soundEveryxUpdates)
                        {
                            Effect.server.Run("assets/prefabs/locks/keypad/effects/lock.code.unlock.prefab", turret.transform.position);
                            updateCounter = 0;
                            return;
                        }
                        updateCounter++;
                    }
                }
                else
                {
                    if (Time.time < nextShoot)
                        return;
                    if (Vector3.Distance(turret.muzzlePos.transform.position, turret.target.transform.position) < minHitDistance)
                        return;
                    var rocketItem = HasAmmo();
                    if (rocketItem == null)
                        return;
                    FireRocket(rocketItem);
                    nextShoot = Time.time + fireRate;
                }
            }

            private void OnDestroy()
            {
                if (!launcher_1.IsDestroyed)
                    launcher_1.Kill();
                if (!rocket_1.IsDestroyed)
                    rocket_1.Kill();
                if (!rocket_2.IsDestroyed)
                    rocket_2.Kill();
            }

            public void Destroy()
            {
                if (plugin.rocketTurrets.Contains(turret))
                    plugin.rocketTurrets.Remove(turret);
                if (plugin.turretIDs.Contains(turret.net.ID))
                    plugin.turretIDs.Remove(turret.net.ID);
                OnDestroy();
                //turret.Kill(BaseNetworkable.DestroyMode.Gib);
                if (this)
                    Destroy(this);
            }

            private void DestroyTurret()
            {
                if (turret != null)
                    turret.Kill(BaseNetworkable.DestroyMode.Gib);
            }

            public void UnloadDestroy()
            {
                if (plugin.rocketTurrets.Contains(turret))
                    plugin.rocketTurrets.Remove(turret);
                OnDestroy();
                Destroy(this);
            }

            private Item HasAmmo()
            {
                return !requiresAmmo ? ItemManager.CreateByItemID(-742865266) : turret.inventory.itemList.FirstOrDefault(item => item.info.itemid == -742865266 || item.info.itemid == 1638322904 || item.info.itemid == -1841918730);
            }

            private void LockToTarget(BaseCombatEntity entity)
            {
                isLockedOn = true;
                isLockingOn = false;
                nextShoot = Time.time + 0.3f;
                target = entity;
            }

            private void InitAesthetics()
            {
                // Rocket Launcher
                launcher_1 = ItemManager.CreateByItemID(442886268, 1, rocketLauncherSkin).Drop(turret.transform.position, Vector3.zero).GetComponent<DroppedItem>();
                launcher_1.GetComponent<Rigidbody>().isKinematic = true;
                launcher_1.GetComponent<Rigidbody>().useGravity = false;
                launcher_1.allowPickup = false;
                launcher_1.CancelInvoke((Action)Delegate.CreateDelegate(typeof(Action), launcher_1, "IdleDestroy"));

                // rocket_1
                rocket_1 = ItemManager.CreateByItemID(-742865266).Drop(turret.transform.position, Vector3.zero).GetComponent<DroppedItem>();
                rocket_1.GetComponent<Rigidbody>().isKinematic = true;
                rocket_1.GetComponent<Rigidbody>().useGravity = false;
                rocket_1.allowPickup = false;
                rocket_1.CancelInvoke((Action)Delegate.CreateDelegate(typeof(Action), rocket_1, "IdleDestroy"));

                // rocket_2
                rocket_2 = ItemManager.CreateByItemID(-742865266).Drop(turret.transform.position, Vector3.zero).GetComponent<DroppedItem>();
                rocket_2.GetComponent<Rigidbody>().isKinematic = true;
                rocket_2.GetComponent<Rigidbody>().useGravity = false;
                rocket_2.allowPickup = false;
                rocket_2.CancelInvoke((Action)Delegate.CreateDelegate(typeof(Action), rocket_2, "IdleDestroy"));

                var launcherRot = new Vector3();
                var rocketRot = new Vector3();

                foreach (var entry in turret.gameObject.transform.GetAllChildren())
                {
                    if (entry.name != "weapon_socket") continue;

                    // launcher rot
                    launcherRot = entry.gameObject.transform.localRotation.eulerAngles;
                    launcherRot = new Vector3(launcherRot.x, launcherRot.y + 180, launcherRot.z);

                    // rocket rot
                    rocketRot = entry.gameObject.transform.localRotation.eulerAngles;
                    rocketRot = new Vector3(rocketRot.x, rocketRot.y + 270, rocketRot.z);
                }

                // launcher_1
                launcher_1.SetParent(turret, "weapon_socket");
                launcher_1.transform.localPosition = new Vector3(0, 0, 0);
                launcher_1.transform.localRotation = Quaternion.Euler(launcherRot);

                // rocket_1
                rocket_1.SetParent(turret, "weapon_socket");
                rocket_1.transform.localPosition = new Vector3(0, -0.05f, 0.17f);
                rocket_1.transform.localRotation = Quaternion.Euler(rocketRot);

                // rocket_2
                rocket_2.SetParent(turret, "weapon_socket");
                rocket_2.transform.localPosition = new Vector3(0, -0.05f, -0.17f);
                rocket_2.transform.localRotation = Quaternion.Euler(rocketRot);
            }

            public void TryFireRocket()
            {
                if (Time.time < nextShoot)
                    return;
                var rocketItem = HasAmmo();
                if (rocketItem == null)
                    return;
                FireRocket(rocketItem);
                nextShoot = Time.time + fireRate;
            }

            private void FireRocket(Item rocketItem)
            {
                ServerProjectile rocket = CreateRocket(turret.muzzlePos.transform.position, rocketItem);
                if (rocket == null)
                    return;
                TimedExplosive expl = rocket.gameObject.GetComponent<TimedExplosive>();

                // Explosion settings
                if (enabled && explodeOnTargetPos)
                {
                    float dist = Vector3.Distance(turret.muzzlePos.position, turret.target.transform.position);
                    float time = dist / rocketSpeed;
                    expl.SetFuse(time);
                }
                expl.explosionRadius = explosionRadius;

                // Rocket settings
                rocket.gravityModifier = 0f;
                rocket.speed = rocketSpeed;
                rocket.InitializeVelocity(turret.muzzlePos.transform.forward);
                Effect.server.Run("assets/prefabs/npc/patrol helicopter/effects/rocket_fire.prefab", turret.muzzlePos.position);
                if (heatSeek)
                    if (this.target != null)
                        rocket.gameObject.AddComponent<HeatRocket>().target = target;
            }

            private ServerProjectile CreateRocket(Vector3 launchPos, Item rocketItem)
            {
                if (requiresAmmo)
                {
                    if (rocketItem == null)
                        return null;
                    if (rocketItem.amount == 1)
                        rocketItem.RemoveFromContainer();
                    else
                        rocketItem.UseItem();
                }
                else
                    rocketItem.RemoveFromContainer();

                BaseEntity rocket;
                switch (rocketItem.info.shortname)
                {
                    case "ammo.rocket.basic":
                        rocket = GameManager.server.CreateEntity("assets/prefabs/ammo/rocket/rocket_basic.prefab", launchPos);
                        break;
                    case "ammo.rocket.fire":
                        rocket = GameManager.server.CreateEntity("assets/prefabs/ammo/rocket/rocket_fire.prefab", launchPos);
                        break;
                    case "ammo.rocket.hv":
                        rocket = GameManager.server.CreateEntity("assets/prefabs/ammo/rocket/rocket_hv.prefab", launchPos);
                        break;
                    default:
                        return null;
                }
                if (rocket == null) return null;
                rocket.creatorEntity = turret;
                rocket.Spawn();
                if (target != null)
                {
                    rocket.transform.LookAt(target.transform);
                    rocket.GetComponent<ServerProjectile>()?.InitializeVelocity(target.transform.position);
                }
                else
                {
                    rocket.transform.LookAt(turret.muzzlePos.position + turret.muzzlePos.forward.normalized * 10);
                    rocket.GetComponent<ServerProjectile>()?.InitializeVelocity(turret.muzzlePos.position + turret.muzzlePos.forward * 10);
                }
                return rocket.GetComponent<ServerProjectile>();
            }
        }

        private class AntiAirTurret : MonoBehaviour
        {
            private float aimRadius = plugin.aaLockonRadius;
            private float fireRate = plugin.aaFireRate;
            private float rocketSpeed = plugin.aarocketSpeed;
            private float minHitDistance = plugin.aaminHitDistance;
            private float lockonTime = plugin.aaLockonTime;
            private uint rocketLauncherSkin = plugin.aaLauncherSkin;
            private float explosionRadius = plugin.aaexplosionRadius;
            private int soundEveryxUpdates = plugin.aalockonSoundEveryxUpdate;
            private float damage = plugin.damageToHeli;
            private bool requiresAmmo = plugin.aaRequiresAmmo;

            private int updateCounter;
            private bool isLockedOn;
            private bool isLockingOn;
            private float lockonFinish;
            private float nextShoot;
            private AutoTurret turret;
            private BaseEntity entity;
            private BaseCombatEntity target;
            private DestroyOnGroundMissing desGround;
            private GroundWatch groundWatch;

            // Models
            private DroppedItem launcher_1;
            private DroppedItem rocket_1;
            private DroppedItem rocket_2;
            private DroppedItem computer;
            private DroppedItem camera_1;
            private DroppedItem camera_2;

            private void Awake()
            {
                turret = gameObject.GetComponent<AutoTurret>();
                InitAesthetics();
                turret.SetIsOnline(false);
                if (!plugin.antiairTurrets.Contains(turret))
                    plugin.antiairTurrets.Add(turret);
                turret.sightRange = 0.1f;
                if (!plugin.antiAirIDs.Contains(turret.net.ID))
                    plugin.antiAirIDs.Add(turret.net.ID);
                entity = gameObject.GetComponent<BaseEntity>();

                var collider = entity.gameObject.AddComponent<SphereCollider>();
                collider.gameObject.layer = (int)Layer.Reserved1;
                collider.radius = aimRadius;
                collider.isTrigger = true;

                desGround = GetComponent<DestroyOnGroundMissing>();
                if (!desGround)
                    gameObject.AddComponent<DestroyOnGroundMissing>();
                groundWatch = GetComponent<GroundWatch>();
                if (!groundWatch)
                    gameObject.AddComponent<GroundWatch>();
                groundWatch.CancelInvoke("OnPhysicsNeighbourChanged");
                groundWatch.InvokeRepeating("OnPhysicsNeighbourChanged", 0, 0.5f);
            }

            private void Update()
            {
                if (target == null)
                {
                    if (isLockedOn)
                        isLockedOn = false;
                    if (isLockingOn)
                        isLockingOn = false;
                    return;
                }
                if (!isLockedOn)
                {
                    turret.target = target;
                    turret.UpdateFacingToTarget();
                    if (!isLockingOn)
                    {
                        lockonFinish = Time.time + lockonTime;
                        isLockingOn = true;
                    }
                    else if (isLockingOn && Time.time > lockonFinish)
                        LockToTarget(turret.target);
                    else if (isLockingOn)
                    {
                        if (updateCounter == soundEveryxUpdates)
                        {
                            Effect.server.Run("assets/prefabs/locks/keypad/effects/lock.code.unlock.prefab", turret.transform.position);
                            updateCounter = 0;
                            return;
                        }
                        updateCounter++;
                    }
                }
                else
                {
                    if (Time.time < nextShoot)
                        return;
                    if (Vector3.Distance(turret.muzzlePos.transform.position, turret.target.transform.position) < minHitDistance)
                        return;
                    var rocketItem = HasAmmo();
                    if (rocketItem == null)
                        return;
                    FireRocket(rocketItem);
                    nextShoot = Time.time + fireRate;
                }
            }

            private void OnTriggerEnter(Collider col)
            {
                if (col.name != "patrol_helicopter")
                    return;
                BaseCombatEntity heli = col.GetComponentInParent<BaseCombatEntity>();
                target = heli;
            }

            private void OnTriggerExit(Collider col)
            {
                if (col.name != "patrol_helicopter")
                    return;
                turret.target = null;
                turret.SetTarget(null);
                target = null;
            }

            /*
            private void OnTriggerExit(Collider col)
            {
                if (col.name != "patrol_helicopter")
                    return;
                turret.target = null;
                target = null;
            }
            */

            private void OnDestroy()
            {
                if (!launcher_1.IsDestroyed)
                    launcher_1.Kill();
                if (!rocket_1.IsDestroyed)
                    rocket_1.Kill();
                if (!rocket_2.IsDestroyed)
                    rocket_2.Kill();
                if (!computer.IsDestroyed)
                    computer.Kill();
                if (!camera_1.IsDestroyed)
                    camera_1.Kill();
                if (!camera_2.IsDestroyed)
                    camera_2.Kill();
            }

            public void Destroy()
            {
                if (plugin.antiairTurrets.Contains(turret))
                    plugin.antiairTurrets.Remove(turret);
                if (plugin.turretIDs.Contains(turret.net.ID))
                    plugin.turretIDs.Remove(turret.net.ID);
                OnDestroy();
                Destroy(this);
            }

            private void DestroyTurret()
            {
                if (turret != null)
                    turret.Kill(BaseNetworkable.DestroyMode.Gib);
            }

            public void UnloadDestroy()
            {
                if (plugin.antiairTurrets.Contains(turret))
                    plugin.antiairTurrets.Remove(turret);
                OnDestroy();
                Destroy(this);
            }

            private Item HasAmmo()
            {
                return !requiresAmmo ? ItemManager.CreateByItemID(-742865266) : turret.inventory.itemList.FirstOrDefault(item => item.info.itemid == -742865266 || item.info.itemid == 1638322904 || item.info.itemid == -1841918730);
            }

            private void LockToTarget(BaseCombatEntity _entity)
            {
                isLockedOn = true;
                isLockingOn = false;
                nextShoot = Time.time + 0.3f;
                target = _entity;
            }

            private void InitAesthetics()
            {
                // Rocket Launcher
                launcher_1 = ItemManager.CreateByItemID(442886268, 1, rocketLauncherSkin).Drop(turret.transform.position, Vector3.zero).GetComponent<DroppedItem>();
                launcher_1.GetComponent<Rigidbody>().isKinematic = true;
                launcher_1.GetComponent<Rigidbody>().useGravity = false;
                launcher_1.allowPickup = false;
                launcher_1.CancelInvoke((Action)Delegate.CreateDelegate(typeof(Action), launcher_1, "IdleDestroy"));

                // rocket_1
                rocket_1 = ItemManager.CreateByItemID(-742865266).Drop(turret.transform.position, Vector3.zero).GetComponent<DroppedItem>();
                rocket_1.GetComponent<Rigidbody>().isKinematic = true;
                rocket_1.GetComponent<Rigidbody>().useGravity = false;
                rocket_1.allowPickup = false;
                rocket_1.CancelInvoke((Action)Delegate.CreateDelegate(typeof(Action), rocket_1, "IdleDestroy"));

                // rocket_2
                rocket_2 = ItemManager.CreateByItemID(-742865266).Drop(turret.transform.position, Vector3.zero).GetComponent<DroppedItem>();
                rocket_2.GetComponent<Rigidbody>().isKinematic = true;
                rocket_2.GetComponent<Rigidbody>().useGravity = false;
                rocket_2.allowPickup = false;
                rocket_2.CancelInvoke((Action)Delegate.CreateDelegate(typeof(Action), rocket_2, "IdleDestroy"));

                // computer
                computer = ItemManager.CreateByItemID(1523195708).Drop(turret.transform.position, Vector3.zero).GetComponent<DroppedItem>();
                computer.GetComponent<Rigidbody>().isKinematic = true;
                computer.GetComponent<Rigidbody>().useGravity = false;
                computer.allowPickup = false;
                computer.CancelInvoke((Action)Delegate.CreateDelegate(typeof(Action), computer, "IdleDestroy"));

                // camera_1
                camera_1 = ItemManager.CreateByItemID(634478325).Drop(turret.transform.position, Vector3.zero).GetComponent<DroppedItem>();
                camera_1.GetComponent<Rigidbody>().isKinematic = true;
                camera_1.GetComponent<Rigidbody>().useGravity = false;
                camera_1.allowPickup = false;
                camera_1.CancelInvoke((Action)Delegate.CreateDelegate(typeof(Action), camera_1, "IdleDestroy"));

                // camera_2
                camera_2 = ItemManager.CreateByItemID(634478325).Drop(turret.transform.position, Vector3.zero).GetComponent<DroppedItem>();
                camera_2.GetComponent<Rigidbody>().isKinematic = true;
                camera_2.GetComponent<Rigidbody>().useGravity = false;
                camera_2.allowPickup = false;
                camera_2.CancelInvoke((Action)Delegate.CreateDelegate(typeof(Action), camera_2, "IdleDestroy"));

                Vector3 computerRot = turret.gameObject.transform.localRotation.eulerAngles;
                computerRot = new Vector3(computerRot.x, computerRot.y + 240, computerRot.z);
                computer.SetParent(turret);
                computer.transform.localPosition = new Vector3(0.45f, 0, 0.25f);
                computer.transform.rotation = Quaternion.Euler(computerRot);

                Vector3 launcherRot = new Vector3();
                Vector3 rocketRot = new Vector3();

                foreach (var entry in turret.gameObject.transform.GetAllChildren())
                {
                    if (entry.name != "weapon_socket") continue;
                    // launcher rot
                    launcherRot = entry.gameObject.transform.localRotation.eulerAngles;
                    launcherRot = new Vector3(launcherRot.x, launcherRot.y + 180, launcherRot.z);

                    // rocket rot
                    rocketRot = entry.gameObject.transform.localRotation.eulerAngles;
                    rocketRot = new Vector3(rocketRot.x, rocketRot.y + 270, rocketRot.z);
                }

                // launcher_1
                launcher_1.SetParent(turret, "weapon_socket");
                launcher_1.transform.localPosition = new Vector3(0, 0, 0);
                launcher_1.transform.localRotation = Quaternion.Euler(launcherRot);

                // rocket_1
                rocket_1.SetParent(turret, "weapon_socket");
                rocket_1.transform.localPosition = new Vector3(0, -0.05f, 0.17f);
                rocket_1.transform.localRotation = Quaternion.Euler(rocketRot);

                // rocket_2
                rocket_2.SetParent(turret, "weapon_socket");
                rocket_2.transform.localPosition = new Vector3(0, -0.05f, -0.17f);
                rocket_2.transform.localRotation = Quaternion.Euler(rocketRot);

                // camera_1
                camera_1.SetParent(turret, "weapon_socket");
                camera_1.transform.localPosition = new Vector3(0, 0.05f, -0.17f);
                camera_1.transform.localRotation = Quaternion.Euler(rocketRot);

                // camera_2
                camera_2.SetParent(turret, "weapon_socket");
                camera_2.transform.localPosition = new Vector3(0, 0.05f, 0.17f);
                camera_2.transform.localRotation = Quaternion.Euler(rocketRot);
            }

            private void FireRocket(Item rocketItem)
            {
                ServerProjectile rocket = CreateRocket(turret.muzzlePos.transform.position, rocketItem);
                if (rocket == null)
                    return;
                TimedExplosive expl = rocket.gameObject.GetComponent<TimedExplosive>();

                // Explosion settings
                float dist = Vector3.Distance(turret.muzzlePos.position, turret.target.transform.position);
                float time = dist / rocketSpeed;
                //expl.SetFuse(time);
                plugin.timer.Once(time - 4f, () =>
                {
                    if (target)
                        target.Hurt(damage);
                });
                expl.explosionRadius = explosionRadius;

                // Rocket settings
                rocket.gravityModifier = 0f;
                rocket.speed = rocketSpeed;
                rocket.InitializeVelocity(turret.muzzlePos.transform.forward);
                Effect.server.Run("assets/prefabs/npc/patrol helicopter/effects/rocket_fire.prefab", turret.muzzlePos.position);
                rocket.gameObject.AddComponent<HeatRocket>().target = turret.target;
            }

            private ServerProjectile CreateRocket(Vector3 launchPos, Item rocketItem)
            {
                if (requiresAmmo)
                {
                    if (rocketItem == null)
                        return null;
                    if (rocketItem.amount == 1)
                        rocketItem.RemoveFromContainer();
                    else
                        rocketItem.UseItem();
                }

                BaseEntity rocket;
                switch (rocketItem.info.shortname)
                {
                    case "ammo.rocket.basic":
                        rocket = GameManager.server.CreateEntity("assets/prefabs/ammo/rocket/rocket_basic.prefab", launchPos);
                        break;
                    case "ammo.rocket.fire":
                        rocket = GameManager.server.CreateEntity("assets/prefabs/ammo/rocket/rocket_fire.prefab", launchPos);
                        break;
                    case "ammo.rocket.hv":
                        rocket = GameManager.server.CreateEntity("assets/prefabs/ammo/rocket/rocket_hv.prefab", launchPos);
                        break;
                    default:
                        return null;
                }
                if (rocket == null) return null;
                rocket.Spawn();
                rocket.transform.LookAt(target.transform);
                return rocket.GetComponent<ServerProjectile>();
            }
        }

        private class JavelinTurret : MonoBehaviour
        {
            private float aimRadius = plugin.jrocketLockonRadius;
            private float fireRate = plugin.jrocketFireRate;
            private float rocketSpeed = plugin.jrocketSpeed;
            private float minHitDistance = plugin.jminHitDistance;
            private float lockonTime = plugin.jrocketLockonTime;
            private uint rocketLauncherSkin = plugin.jrocketLauncherSkin;
            private float explosionRadius = plugin.jexplosionRadius;
            private int soundEveryxUpdates = plugin.jlockonSoundEveryxUpdate;
            private bool requiresAmmo = plugin.jrequiresAmmo;
            private bool seekTarget = plugin.jSeekTarget;

            private int updateCounter;
            private bool isLockedOn;
            private bool isLockingOn;
            private float lockonFinish;
            private float nextShoot;
            private AutoTurret turret;
            private BaseCombatEntity target;
            private BaseCombatEntity externalTarget;
            private DroppedItem launcher_1;
            private DroppedItem rocket_1;
            private DroppedItem rocket_2;
            private DestroyOnGroundMissing desGround;
            private GroundWatch groundWatch;

            private void Awake()
            {
                turret = gameObject.GetComponent<AutoTurret>();
                InitAesthetics();
                if (!plugin.javelinTurrets.Contains(turret))
                    plugin.javelinTurrets.Add(turret);
                turret.sightRange = aimRadius;
                if (!plugin.javelinIDs.Contains(turret.net.ID))
                    plugin.javelinIDs.Add(turret.net.ID);

                desGround = GetComponent<DestroyOnGroundMissing>();
                if (!desGround)
                    gameObject.AddComponent<DestroyOnGroundMissing>();
                groundWatch = GetComponent<GroundWatch>();
                if (!groundWatch)
                    gameObject.AddComponent<GroundWatch>();
                groundWatch.CancelInvoke("OnPhysicsNeighbourChanged");
                groundWatch.InvokeRepeating("OnPhysicsNeighbourChanged", 0, 0.5f);

                // Collider add
                SphereCollider collider = turret.gameObject.AddComponent<SphereCollider>();
                collider.gameObject.layer = (int)Layer.Reserved1;
                collider.radius = aimRadius;
                collider.isTrigger = true;
            }

            private void Update()
            {
                if (externalTarget)
                {
                    turret.SetTarget(externalTarget);
                    turret.UpdateAiming();
                }
                if (!turret.HasTarget())
                {
                    if (isLockedOn)
                        isLockedOn = false;
                    if (isLockingOn)
                        isLockingOn = false;
                    return;
                }
                if (!isLockedOn)
                {
                    if (!isLockingOn)
                    {
                        lockonFinish = Time.time + lockonTime;
                        isLockingOn = true;
                    }
                    else if (isLockingOn && Time.time > lockonFinish)
                        LockToTarget(turret.target);
                    else if (isLockingOn)
                    {
                        if (updateCounter == soundEveryxUpdates)
                        {
                            Effect.server.Run("assets/prefabs/locks/keypad/effects/lock.code.unlock.prefab", turret.transform.position);
                            updateCounter = 0;
                            return;
                        }
                        updateCounter++;
                    }
                }
                else
                {
                    if (Time.time < nextShoot)
                        return;
                    if (Vector3.Distance(turret.muzzlePos.transform.position, turret.target.transform.position) < minHitDistance)
                        return;
                    var rocketItem = HasAmmo();
                    if (rocketItem == null)
                        return;
                    FireRocket(rocketItem);
                    nextShoot = Time.time + fireRate;
                }
            }

            private void OnTriggerEnter(Collider col)
            {
                if (col.name != "assets/prefabs/npc/m2bradley/bradleyapc.prefab")
                    return;
                turret.SetTarget(col.GetComponent<BaseCombatEntity>());
                externalTarget = col.GetComponent<BaseCombatEntity>();
                turret.UpdateAiming();
            }

            private void OnTriggerExit(Collider col)
            {
                if (col.name != "assets/prefabs/npc/m2bradley/bradleyapc.prefab")
                    return;
                turret.SetTarget(null);
                turret.TargetScan();
                externalTarget = null;
                turret.UpdateAiming();
                isLockedOn = false;
                isLockingOn = false;
            }

            private void OnDestroy()
            {
                if (!launcher_1.IsDestroyed)
                    launcher_1.Kill();
                if (!rocket_1.IsDestroyed)
                    rocket_1.Kill();
                if (!rocket_2.IsDestroyed)
                    rocket_2.Kill();
            }

            public void Destroy()
            {
                if (plugin.rocketTurrets.Contains(turret))
                    plugin.rocketTurrets.Remove(turret);
                if (plugin.turretIDs.Contains(turret.net.ID))
                    plugin.turretIDs.Remove(turret.net.ID);
                OnDestroy();
                //turret.Kill(BaseNetworkable.DestroyMode.Gib);
                if (this)
                    Destroy(this);
            }

            private void DestroyTurret()
            {
                if (turret != null)
                    turret.Kill(BaseNetworkable.DestroyMode.Gib);
            }

            public void UnloadDestroy()
            {
                if (plugin.rocketTurrets.Contains(turret))
                    plugin.rocketTurrets.Remove(turret);
                OnDestroy();
                Destroy(this);
            }

            private Item HasAmmo()
            {
                return !requiresAmmo ? ItemManager.CreateByItemID(-742865266) : turret.inventory.itemList.FirstOrDefault(item => item.info.itemid == -742865266 || item.info.itemid == 1638322904 || item.info.itemid == -1841918730);
            }

            private void LockToTarget(BaseCombatEntity entity)
            {
                isLockedOn = true;
                isLockingOn = false;
                nextShoot = Time.time + 0.3f;
                target = entity;
            }

            private void InitAesthetics()
            {
                // Rocket Launcher
                launcher_1 = ItemManager.CreateByItemID(442886268, 1, rocketLauncherSkin).Drop(turret.transform.position, Vector3.zero).GetComponent<DroppedItem>();
                launcher_1.GetComponent<Rigidbody>().isKinematic = true;
                launcher_1.GetComponent<Rigidbod
// ... [Code preview truncated due to length. Full source in attached file] ...

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