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

FREE MinicopterCombat : 01.00.02 01.00.02

Нет прав для скачивания
C#:
/* Copyright (c) 2019 Karuza */
using Oxide.Core;
using Oxide.Game.Rust.Cui;
using Oxide.Core.Libraries;
using System;
using System.Collections.Generic;
using UnityEngine;
using System.Linq;
using Rust;
using Newtonsoft.Json;
using ProtoBuf;
using Oxide.Core.Plugins;
namespace Oxide.Plugins {
    [Info("MinicopterCombat", "Karuza", "01.00.02")]
    public class MinicopterCombat : RustPlugin {
        [PluginReference]
        Plugin BulletProjectile;
#region Variables
        private static MinicopterCombat instance;
        private static string[] enabledMiniWeaponTypes;
        private static string[] enabledScrapWeaponTypes;
        private static readonly Dictionary<string, int> weaponsToAmmoTypeItemIdMap = new Dictionary<string, int>();
        private static Permission permissionHelper;
        private static string clear = "0 0 0 0";
        private static string green = "0 1 0 0.4";
        private static string darkGreen = "0 1 0 0.7";
        private static string red = "1 0 0 0.4";
        private static string darkRed = "1 0 0 0.7";
        private static string solidRed = "1 0 0 1";
        private static string white = "1.0 1.0 1.0";
        private static string orange = "0.7 0.4 0 0.7";
        private static string gold = "1.000000000 0.819607843 0.137254902";
        private static string permAdmin = "MinicopterCombat.AdminPerm";
        private static string reticleOverlayName = "AimReticle";
        private static string primaryAmmoOverlayName = "PrimaryAmmoCounter";
        private static string secondaryAmmoOverlayName = "SecondaryAmmoCounter";
        private static string flareAmmoOverlayName = "FlareAmmoCounter";
        private static string primaryCooldownOverlayName = "PrimaryCooldownGui";
        private static string secondaryCooldownOverlayName = "SecondaryCooldownGui";
        private static string flareCooldownOverlayName = "FlareCooldownGui";
        private static string weaponTypeOverlayName = "WeaponSelector";
        private static string targetLockGuiName = "TargetLockGui";
        private static string targetMessageGuiName = "TargetMessageGui";
        private static string flarePrefab = "assets/prefabs/tools/flareold/flare.deployed.prefab";
        private static LayerMask layerMask = LayerMask.GetMask("Vehicle Movement", "Vehicle Large");
        private static Configuration configuration;
#endregion
#region Methods
        private void RegisterPermissions() {
            permission.RegisterPermission(permAdmin, this);
            foreach (var weaponSetting in configuration.WeaponSettings) {
                permission.RegisterPermission(weaponSetting.Value.WeaponPermission, this);
            }
            foreach (var weaponSetting in configuration.ScrapcopterWeaponSettings) {
                permission.RegisterPermission(weaponSetting.Value.WeaponPermission, this);
            }
            permissionHelper = permission;
        }
        void DestroyMinicopterCombatWrappers() {
            var miniCopterCombatWrappers = UnityEngine.Object.FindObjectsOfType<MinicopterWrapper>();
            foreach (var miniCopterCombatWrapper in miniCopterCombatWrappers) UnityEngine.Object.Destroy(miniCopterCombatWrapper);
            var scrapWrappers = UnityEngine.Object.FindObjectsOfType<ScrapcopterWrapper>();
            foreach (var scrapWrapper in scrapWrappers) UnityEngine.Object.Destroy(scrapWrapper);
        }
        static void GetEnabledWeapons() {
            enabledMiniWeaponTypes = configuration.WeaponSettings.Where(kv => kv.Value.Enabled).Select(kv => kv.Key).ToArray();
            enabledScrapWeaponTypes = configuration.ScrapcopterWeaponSettings.Where(kv => kv.Value.Enabled).Select(kv => kv.Key).ToArray();
        }
        void UpdateExistingMinicopters() {
            DestroyMinicopterCombatWrappers();
            var miniCopters = BaseNetworkable.serverEntities.OfType<MiniCopter>();
            foreach (var miniCopter in miniCopters) {
                if (miniCopter.name.Contains("scraptransporthelicopter")) {
                    if (configuration.ApplyToScrapCopter) {
                        miniCopter.gameObject.AddComponent<ScrapcopterWrapper>();
                    }
                    continue;
                }
                else {
                    miniCopter.gameObject.AddComponent<MinicopterWrapper>();
                }
            }
        }
        void GetWeaponAmmoTypeItemIds() {
            foreach (var wt in configuration.WeaponSettings) {
                AddAmmoTypeToAmmoTypeMap(wt.Value.FlareShortName);
                AddAmmoTypeToAmmoTypeMap(wt.Value.PrimaryWeapon?.AmmoTypeShortName);
                AddAmmoTypeToAmmoTypeMap(wt.Value.SecondaryWeapon?.AmmoTypeShortName);
            }
            foreach (var wt in configuration.ScrapcopterWeaponSettings) {
                AddAmmoTypeToAmmoTypeMap(wt.Value.FlareShortName);
                AddAmmoTypeToAmmoTypeMap(wt.Value.PrimaryWeapon?.AmmoTypeShortName);
                AddAmmoTypeToAmmoTypeMap(wt.Value.SecondaryWeapon?.AmmoTypeShortName);
            }
        }
        private void AddAmmoTypeToAmmoTypeMap(string ammoTypeShortName) {
            if (string.IsNullOrEmpty(ammoTypeShortName)) return;
            if (!weaponsToAmmoTypeItemIdMap.ContainsKey(ammoTypeShortName)) weaponsToAmmoTypeItemIdMap[ammoTypeShortName] = ItemManager.itemList.Find(x => x.shortname == ammoTypeShortName)?.itemid ?? 0;
        }
        private static float AngleOffAroundAxis(Vector3 v, Vector3 forward, Vector3 axis) {
            Vector3 right = Vector3.Cross(forward, axis);
            forward = Vector3.Cross(axis, right);
            return Mathf.Atan2(Vector3.Dot(v, right), Vector3.Dot(v, forward)) * Mathf.Rad2Deg;
        }
#endregion
#region Config
        public class Configuration {
            [JsonProperty]
            public float DebounceTimeSeconds {
                get;
                set;
            }
            = 4;
            [JsonProperty]
            public bool DisplayOutOfAmmoMessage {
                get;
                set;
            }
            = true;
            [JsonProperty]
            public bool DisplaySelectedWeaponMessage {
                get;
                set;
            }
            = true;
            [JsonProperty]
            public bool UnlimitedAmmo {
                get;
                set;
            }
            = false;
            [JsonProperty]
            public bool DisablePermissionCheck {
                get;
                set;
            }
            = false;
            [JsonProperty]
            public bool ApplyToScrapCopter {
                get;
                set;
            }
            = false;
            [JsonProperty]
            public string FlareFiredSfx {
                get;
                set;
            }
            = "assets/prefabs/deployable/research table/effects/research-table-deploy.prefab";
            [JsonProperty]
            public string SwitchWeaponSfx {
                get;
                set;
            }
            = "assets/prefabs/deployable/dropbox/effects/submit_items.prefab";
            [JsonProperty]
            public string AlarmSfx {
                get;
                set;
            }
            = "assets/prefabs/locks/keypad/effects/lock.code.unlock.prefab";
            [JsonProperty]
            public float CounterMeasureDespawnTime {
                get;
                set;
            }
            = 5f;
            [JsonProperty]
            public float WeaponSwitchDelay {
                get;
                set;
            }
            = 1f;
            [JsonProperty]
            public BUTTON FirePrimaryButton {
                get;
                set;
            }
            = BUTTON.FIRE_PRIMARY;
            [JsonProperty]
            public BUTTON FireSecondaryButton {
                get;
                set;
            }
            = BUTTON.FIRE_SECONDARY;
            [JsonProperty]
            public BUTTON SwitchWeaponButton {
                get;
                set;
            }
            = BUTTON.FIRE_THIRD;
            [JsonProperty]
            public BUTTON FireFlareButton {
                get;
                set;
            }
            = BUTTON.USE;
            [JsonProperty]
            public bool EnableScrapcopterGibs {
                get;
                set;
            }
            [JsonProperty]
            public float GibsDespawnTimerOverride {
                get;
                set;
            }
            [JsonProperty]
            public bool DisableFire {
                get;
                set;
            }
            [JsonProperty]
            public bool HideUnauthorizedWeapons {
                get;
                set;
            }
            [JsonProperty]
            public Dictionary<string, WeaponSettings> WeaponSettings = new Dictionary<string, WeaponSettings>() {
                {
                    "Disarm", new WeaponSettings() {
                        DisplayShortName = "DISARM", DisplayFullName = "DISARMED", HudConfiguration = HUDConfiguration.None, Enabled = true
                    }
                }
            }
            ;
            [JsonProperty]
            public Dictionary<string, WeaponSettings> ScrapcopterWeaponSettings = new Dictionary<string, WeaponSettings>() {
                {
                    "Disarm", new WeaponSettings() {
                        DisplayShortName = "DISARM", DisplayFullName = "DISARMED", HudConfiguration = HUDConfiguration.None, Enabled = true
                    }
                }
            }
            ;
        }
        protected override void LoadConfig() {
            base.LoadConfig();
            try {
                configuration = Config.ReadObject<Configuration>();
                if (configuration == null) throw new Exception();
            }
            catch {
                Config.WriteObject(configuration, false, $"{Interface.Oxide.ConfigDirectory}/{Name}.jsonError");
                PrintError("The configuration file contains an error and has been replaced with a default config.");
                LoadDefaultConfig();
            }
            SaveConfig();
        }
        protected override void LoadDefaultConfig() {
            configuration = new Configuration();
        }
        protected override void SaveConfig() {
            Config.WriteObject(configuration);
        }
#endregion
#region Hooks
        void OnServerInitialized() {
            LoadConfig();
            GetEnabledWeapons();
            UpdateExistingMinicopters();
            GetWeaponAmmoTypeItemIds();
            RegisterPermissions();
            instance = this;
        }
        void Unload() {
            DestroyMinicopterCombatWrappers();
        }
        void OnEntityMounted(BaseMountable entity, BasePlayer player) {
            var heliWrapper = entity.VehicleParent()?.GetComponent<HelicopterWrapper>();
            if (heliWrapper == null) return;
            heliWrapper.SetPlayer(player);
        }
        void OnEntityDismounted(BaseMountable entity, BasePlayer player) {
            if (player == null || entity == null) return;
            var heliWrapper = entity.VehicleParent()?.GetComponent<HelicopterWrapper>();
            if (heliWrapper == null) return;
            heliWrapper.RemovePlayer(player);
        }
        void OnEntitySpawned(HelicopterDebris debris) {
            if (!debris.name.Contains("servergibs_scraptransport")) return;
            NextTick(() => {
                if (debris == null || debris.IsDestroyed) {
                    return;
                }
                if (!configuration.EnableScrapcopterGibs) {
                    debris.Kill();
                }
                else if (configuration.GibsDespawnTimerOverride > 0) {
                    timer.Once(configuration.GibsDespawnTimerOverride, () => {
                        debris.Kill();
                        debris.SendNetworkUpdate();
                    }
                    );
                    return;
                }
            }
            );
        }
        void OnEntitySpawned(MiniCopter miniCopter) {
            if (miniCopter == null) return;
            if (miniCopter.name.Contains("scraptransporthelicopter")) {
                if (configuration.ApplyToScrapCopter) {
                    miniCopter.gameObject.AddComponent<ScrapcopterWrapper>();
                }
                return;
            }
            miniCopter.gameObject.AddComponent<MinicopterWrapper>();
        }
#endregion
#region MinicopterWrapper
        public class ScrapcopterWrapper : HelicopterWrapper {
            // todo update
            protected override float maxAngle {
                get {
                    return 14f;
                }
            }
            protected override float minAngle {
                get {
                    return -14f;
                }
            }
            protected override float centerX {
                get {
                    return 0.491f;
                }
            }
            protected override float centerY {
                get {
                    return 0.57675f;
                }
            }
            protected override string reticleGuiOverlayMin {
                get {
                    return "0.4230 0.485";
                }
            }
            protected override string reticleGuiOverlayMax {
                get {
                    return "0.5730 0.635";
                }
            }
            protected override string primaryAmmoMin {
                get {
                    return "0.3445 0.586";
                }
            }
            protected override string primaryAmmoMax {
                get {
                    return "0.4215 0.609";
                }
            }
            protected override string secondaryAmmoMin {
                get {
                    return "0.5754 0.586";
                }
            }
            protected override string secondaryAmmoMax {
                get {
                    return "0.6524 0.609";
                }
            }
            protected override string flareMin {
                get {
                    return "0.473 0.4884";
                }
            }
            protected override string flareMax {
                get {
                    return "0.5236 0.5084";
                }
            }
            protected override string lockGuiMin {
                get {
                    return "0.46 0.461";
                }
            }
            protected override string lockGuiMax {
                get {
                    return "0.536 0.483";
                }
            }
            protected override string GetNextWeaponType(string current) {
                int i = Array.IndexOf<string>(enabledScrapWeaponTypes, current) + 1;
                return (enabledScrapWeaponTypes.Length == i) ? enabledScrapWeaponTypes[0] : enabledScrapWeaponTypes[i];
            }
            protected override Dictionary<string, WeaponSettings> GetAvailableWeapons() {
                return configuration.ScrapcopterWeaponSettings;
            }
        }
        public class MinicopterWrapper : HelicopterWrapper {
            protected override float maxAngle {
                get {
                    return 14f;
                }
            }
            protected override float minAngle {
                get {
                    return -14f;
                }
            }
            protected override float centerX {
                get {
                    return 0.491f;
                }
            }
            protected override float centerY {
                get {
                    return 0.47675f;
                }
            }
            protected override string reticleGuiOverlayMin {
                get {
                    return "0.4205 0.365";
                }
            }
            protected override string reticleGuiOverlayMax {
                get {
                    return "0.5705 0.515";
                }
            }
            protected override string primaryAmmoMin {
                get {
                    return "0.34295 0.466";
                }
            }
            protected override string primaryAmmoMax {
                get {
                    return "0.4195 0.489";
                }
            }
            protected override string secondaryAmmoMin {
                get {
                    return "0.573 0.466";
                }
            }
            protected override string secondaryAmmoMax {
                get {
                    return "0.65 0.489";
                }
            }
            protected override string flareMin {
                get {
                    return "0.473 0.368";
                }
            }
            protected override string flareMax {
                get {
                    return "0.5236 0.388";
                }
            }
            protected override string lockGuiMin {
                get {
                    return "0.46 0.341";
                }
            }
            protected override string lockGuiMax {
                get {
                    return "0.536 0.363";
                }
            }
            protected override string GetNextWeaponType(string current) {
                int i = Array.IndexOf<string>(enabledMiniWeaponTypes, current) + 1;
                return (enabledMiniWeaponTypes.Length == i) ? enabledMiniWeaponTypes[0] : enabledMiniWeaponTypes[i];
            }
            protected override Dictionary<string, WeaponSettings> GetAvailableWeapons() {
                return configuration.WeaponSettings;
            }
        }
        public class HelicopterWrapper : MonoBehaviour, Lock {
#region Variables
            public Guid Id {
                get;
                set;
            }
            public float ChanceToLoseLock {
                get {
                    return weaponSettings.ChanceToLoseLock;
                }
            }
            public bool IsAlive {
                get;
                set;
            }
            private BasePlayer player {
                get;
                set;
            }
            = null;
            private string selectedWeaponType {
                get;
                set;
            }
            = "Disarm";
            private WeaponSettings weaponSettings {
                get;
                set;
            }
            private bool IsLocked {
                get {
                    return locks.Count > 0;
                }
            }
            private bool primaryCooldownContainerActive = false;
            private bool primaryCooldownContainerContrastActive = false;
            private bool secondaryCooldownContainerActive = false;
            private bool secondaryCooldownContainerContrastActive = false;
            private bool flareCooldownContainerActive = false;
            private bool flareCooldownContainerContrastActive = false;
            // To prevent spamming the player, log the message time
            private float lastMsgTime = 0.0f;
            private float lastPrimaryWeaponFiredTime = 0.0f;
            private float lastSecondaryWeaponFiredTime = 0.0f;
            private float lastWeaponSwitchTime = 0.0f;
            private int primaryRoundsFired = 0;
            private int secondaryRoundsFired = 0;
            private int flareRoundsFired = 0;
            private float primaryCooldownTimer = 0f;
            private float secondaryCooldownTimer = 0f;
            private float flareCooldownTimer = 0f;
            private int primaryCurrentBarrel = 0;
            private int secondaryCurrentBarrel = 0;
            private BaseVehicle vehicle {
                get;
                set;
            }
            = null;
#region GuiOverrides
            protected virtual string reticleGuiOverlayMin {
                get {
                    return "0 0";
                }
            }
            protected virtual string reticleGuiOverlayMax {
                get {
                    return "0 0";
                }
            }
            protected virtual string primaryAmmoMin {
                get {
                    return "0 0";
                }
            }
            protected virtual string primaryAmmoMax {
                get {
                    return "0 0";
                }
            }
            protected virtual string secondaryAmmoMin {
                get {
                    return "0 0";
                }
            }
            protected virtual string secondaryAmmoMax {
                get {
                    return "0 0";
                }
            }
            protected virtual string flareMin {
                get {
                    return "0 0";
                }
            }
            protected virtual string flareMax {
                get {
                    return "0 0";
                }
            }
            protected virtual string lockGuiMin {
                get {
                    return "0 0";
                }
            }
            protected virtual string lockGuiMax {
                get {
                    return "0 0";
                }
            }
#endregion
#region AARocketProperties
            private float lockOnSeconds = 0f;
            private float lockedAt = 0.0f;
            private bool isLockAlarmPlaying = false;
            private bool targetLocked = false;
            private bool acquiringLock = false;
            private BaseEntity target = null;
            protected virtual float maxAngle {
                get {
                    return 0f;
                }
            }
            protected virtual float minAngle {
                get {
                    return 0f;
                }
            }
            protected virtual float centerX {
                get {
                    return 0f;
                }
            }
            protected virtual float centerY {
                get {
                    return 0f;
                }
            }
            private float targetAngleX = 0.0f;
            private float targetAngleY = 0.0f;
#endregion
#region CounterMeasures
            private float timeBeforeFlaresExpire = 2f;
            private float lastFlaresFiredTime = 0.0f;
            private bool leftFlareFiredLast {
                get;
                set;
            }
            = false;
            private Dictionary<Guid, Lock> locks {
                get;
                set;
            }
            = new Dictionary<Guid, Lock>();
#endregion
#endregion
#region WeaponSystemsMethods
            protected virtual Dictionary<string, WeaponSettings> GetAvailableWeapons() {
                return new Dictionary<string, WeaponSettings>();
            }
            private void UpdateWeapons() {
                UpdateTargetLock();
                Toggle_DrawTargetLock(true);
                Toggle_CooldownGui(true);
                if (player.serverInput.WasJustPressed(configuration.SwitchWeaponButton)) SwitchWeaponType();
                if (player.serverInput.WasJustPressed(configuration.FireFlareButton)) FireFlares();
                if (this.selectedWeaponType.Equals("Disarm", StringComparison.InvariantCultureIgnoreCase)) return;
                if (player.serverInput.IsDown(configuration.FirePrimaryButton)) {
                    FireProjectile(this.weaponSettings.PrimaryWeapon);
                }
                if (this.weaponSettings.SecondaryWeapon != null) {
                    if (player.serverInput.IsDown(configuration.FireSecondaryButton)) FireProjectile(this.weaponSettings.SecondaryWeapon);
                    else if (this.weaponSettings.SecondaryWeapon.ProjectileType == ProjectileType.TargetLocker) ClearTarget();
                }
            }
            private void FireFlares() {
                if (!weaponSettings.FlaresEnabled) return;
                if (weaponSettings.FlaresBeforeCooldown > 0 && weaponSettings.FlaresBeforeCooldown <= flareRoundsFired) return;
                float currentTime = UnityEngine.Time.realtimeSinceStartup;
                if (currentTime < (lastFlaresFiredTime + weaponSettings.FlareFireRate)) return;
                if (!weaponSettings.UnlimitedFlares && !DoesUserHaveAmmo(weaponSettings.FlareShortName, currentTime)) return;
                GameObject flareEnt = GameManager.server.CreatePrefab(flarePrefab, this.vehicle.transform.position, new Quaternion(), false);
                BaseEntity flareBaseEnt = flareEnt.GetComponent<BaseEntity>();
                flareBaseEnt.enableSaving = false;
                flareBaseEnt.Spawn();
                flareEnt.SetActive(true);
                flareBaseEnt.transform.position = Vector3.MoveTowards(this.vehicle.transform.position, this.vehicle.transform.localPosition + (this.vehicle.transform.right * (leftFlareFiredLast ? 25f : -25f)), 5f);
                flareEnt.AddComponent<CounterMeasure>();
                if (!string.IsNullOrEmpty(configuration.FlareFiredSfx)) {
                    Effect.server.Run(configuration.FlareFiredSfx, flareBaseEnt, 0, Vector3.back, Vector3.forward, null);
                }
                leftFlareFiredLast = !leftFlareFiredLast;
                lastFlaresFiredTime = currentTime;
                flareRoundsFired++;
                foreach (var lck in locks.Values.ToList()) {
                    if (lck.ChanceToLoseLock > 0 && lck.ChanceToLoseLock < 100 && Oxide.Core.Random.Range(0, 100) < lck.ChanceToLoseLock) continue;
                    lck.SetLockTarget(flareBaseEnt);
                }
                if (!weaponSettings.UnlimitedFlares) UseAmmo(weaponSettings.FlareShortName, null);
            }
            private void ResetRoundsFiredByConfig(WeaponConfiguration weaponConfiguration, float lastFiredTime, ref int roundsFired, ref float cooldownTimer) {
                // weaponConfiguration.ShotsBeforeCoolDown <= 0 ||
                if (weaponConfiguration == null) return;
                ResetRoundsFired(weaponConfiguration.CoolDownDecay, lastFiredTime, ref roundsFired, ref cooldownTimer);
            }
            private void ResetRoundsFired(float coolDownDecay, float lastFiredTime, ref int roundsFired, ref float cooldownTimer) {
                if (roundsFired <= 0) return;
                float currentTime = UnityEngine.Time.realtimeSinceStartup;
                float timeSinceLastFired = (currentTime - lastFiredTime);
                if (timeSinceLastFired <= 1) return;
                float timeSinceLastCooldownCheck = (currentTime - cooldownTimer);
                if (timeSinceLastCooldownCheck > coolDownDecay) {
                    --roundsFired;
                    cooldownTimer = currentTime;
                }
                if (roundsFired < 0) roundsFired = 0;
            }
            private Vector3 GetMuzzlePosition(WeaponConfiguration weaponConfiguration, int currentBarrel) {
                Vector3 muzzlePos = Vector3.zero;
                var vehicleTransform = this.vehicle.transform;
                switch (weaponConfiguration.BarrelConfiguration) {
                    case BarrelConfiguration.Bottom : muzzlePos = this.player.transform.localPosition + Vector3.down;
                    break;
                    case BarrelConfiguration.Side : muzzlePos = vehicleTransform.localPosition + ((vehicleTransform.forward * 2.5f) + (vehicleTransform.right * 1.5f * (currentBarrel % 2 == 0 ? 1 : -1)));
                    break;
                    case BarrelConfiguration.SideOuter : muzzlePos = vehicleTransform.localPosition + ((vehicleTransform.forward * 2.5f) + (vehicleTransform.right * 2f * (currentBarrel % 2 == 0 ? 1 : -1)));
                    break;
                    case BarrelConfiguration.DualFront : muzzlePos = vehicleTransform.localPosition + ((vehicleTransform.forward * 3.5f) + (vehicleTransform.right * 0.75f * (currentBarrel % 2 == 0 ? 1 : -1)));
                    break;
                    case BarrelConfiguration.CenterFront : muzzlePos = vehicleTransform.localPosition + (vehicleTransform.forward * 3.5f);
                    break;
                    case BarrelConfiguration.Gattling : muzzlePos = GetGattlingMuzzlePos(vehicleTransform, currentBarrel);
                    break;
                    default : break;
                }
                return muzzlePos;
            }
            private Vector3 GetGattlingMuzzlePos(Transform vehicleTransform, int currentBarrel) {
                Vector3 modifier = Vector3.zero;
                switch (currentBarrel) {
                    case 0 : modifier = (vehicleTransform.up * 0.30f);
                    break;
                    case 1 : modifier = (vehicleTransform.right * 0.30f);
                    break;
                    case 2 : modifier = ((vehicleTransform.right + (vehicleTransform.up * -1)) * 0.30f);
                    break;
                    case 3 : modifier = ((vehicleTransform.right + vehicleTransform.up) * 0.30f) * -1;
                    break;
                    case 4 : modifier = (vehicleTransform.right * 0.30f * -1);
                    break;
                    default : break;
                }
                return vehicleTransform.localPosition + ((vehicleTransform.forward * 3.5f) + modifier);
            }
            private void TriggerMuzzleEffect(WeaponConfiguration weaponConfiguration, int currentBarrel) {
                if (string.IsNullOrEmpty(weaponConfiguration.MuzzleEffect)) return;
                Vector3 posLocal;
                switch (weaponConfiguration.BarrelConfiguration) {
                    case BarrelConfiguration.Side : posLocal = (currentBarrel % 2 == 0 ? Vector3.right : Vector3.left) * 2 + (Vector3.forward / 1.8f);
                    break;
                    case BarrelConfiguration.SideOuter : posLocal = (currentBarrel % 2 == 0 ? Vector3.right : Vector3.left) * 3 + (Vector3.forward / 1.8f);
                    break;
                    case BarrelConfiguration.DualFront : posLocal = (currentBarrel % 2 == 0 ? Vector3.right : Vector3.left) / 2 + (Vector3.forward * 2.1f);
                    break;
                    case BarrelConfiguration.CenterFront : posLocal = (Vector3.forward);
                    break;
                    case BarrelConfiguration.Gattling : posLocal = GetGattlingEffectPos(currentBarrel);
                    break;
                    case BarrelConfiguration.Bottom : default : return;
                }
                Effect.server.Run(weaponConfiguration.MuzzleEffect, this.vehicle, 0, posLocal, Vector3.forward, null);
            }
            private Vector3 GetGattlingEffectPos(int currentBarrel) {
                Vector3 modifier = Vector3.zero;
                switch (currentBarrel) {
                    case 0 : modifier = Vector3.up;
                    break;
                    case 1 : modifier = Vector3.right;
                    break;
                    case 2 : modifier = Vector3.right + (Vector3.up * -1);
                    break;
                    case 3 : modifier = Vector3.right + Vector3.up * -1;
                    break;
                    case 4 : modifier = Vector3.left;
                    break;
                    default : break;
                }
                return modifier / 3f + (Vector3.forward * 2.1f);
            }
            private void FireProjectile(WeaponConfiguration weaponConfiguration) {
                int currentBarrel = 0;
                float lastFiredTime = 0f;
                int roundsFired = 0;
                float currentTime = UnityEngine.Time.realtimeSinceStartup;
                if (weaponConfiguration == weaponSettings.PrimaryWeapon) {
                    weaponConfiguration = this.weaponSettings.PrimaryWeapon;
                    lastFiredTime = lastPrimaryWeaponFiredTime;
                    currentBarrel = primaryCurrentBarrel;
                    roundsFired = primaryRoundsFired;
                }
                else {
                    weaponConfiguration = this.weaponSettings.SecondaryWeapon;
                    lastFiredTime = lastSecondaryWeaponFiredTime;
                    currentBarrel = secondaryCurrentBarrel;
                    roundsFired = secondaryRoundsFired;
                }
                if (weaponConfiguration.ShotsBeforeCoolDown > 0 && weaponConfiguration.ShotsBeforeCoolDown <= roundsFired) return;
                if (currentTime < (lastFiredTime + weaponConfiguration.FireRate)) return;
                if (weaponConfiguration.RequiresAmmo && !DoesUserHaveAmmo(weaponConfiguration.AmmoTypeShortName, currentTime)) return;
                Vector3 muzzlePos = GetMuzzlePosition(weaponConfiguration, currentBarrel);
                if (muzzlePos == Vector3.zero) return;
                switch (weaponConfiguration.ProjectileType) {
                    case ProjectileType.ServerProjectile : TriggerMuzzleEffect(weaponConfiguration, currentBarrel);
                    FireWithServerProjectile(weaponConfiguration, muzzlePos);
                    break;
                    case ProjectileType.Bullet : TriggerMuzzleEffect(weaponConfiguration, currentBarrel);
                    //FireWithProjectileSystem(weaponConfiguration, muzzlePos);
                    FireWithProjectileSystem(weaponConfiguration, muzzlePos);
                    break;
                    case ProjectileType.Air2Air : if (!targetLocked || target == null) return;
                    TriggerMuzzleEffect(weaponConfiguration, currentBarrel);
                    FireAARocket(weaponConfiguration, muzzlePos);
                    break;
                    case ProjectileType.TargetLocker : TriggerMuzzleEffect(weaponConfiguration, currentBarrel);
                    LockTarget(muzzlePos, weaponConfiguration);
                    break;
                    default : break;
                }
                if (weaponConfiguration == weaponSettings.PrimaryWeapon) {
                    lastPrimaryWeaponFiredTime = currentTime;
                    UpdateBarrel(weaponConfiguration.BarrelConfiguration, ref primaryCurrentBarrel);
                    primaryRoundsFired = ++roundsFired;
                    if (weaponConfiguration.RequiresAmmo) UseAmmo(weaponConfiguration.AmmoTypeShortName, true);
                }
                else {
                    lastSecondaryWeaponFiredTime = currentTime;
                    UpdateBarrel(weaponConfiguration.BarrelConfiguration, ref secondaryCurrentBarrel);
                    secondaryRoundsFired = ++roundsFired;
                    if (weaponConfiguration.RequiresAmmo) UseAmmo(weaponConfiguration.AmmoTypeShortName, false);
                }
            }
            private void UpdateBarrel(BarrelConfiguration barrelConfig, ref int nextBarrel) {
                switch (barrelConfig) {
                    case BarrelConfiguration.DualFront : case BarrelConfiguration.Side : case BarrelConfiguration.CenterFront : case BarrelConfiguration.SideOuter : if (++nextBarrel > 1) nextBarrel = 0;
                    break;
                    case BarrelConfiguration.Bottom : break;
                    case BarrelConfiguration.Gattling : if (++nextBarrel > 4) nextBarrel = 0;
                    break;
                    default : break;
                }
            }
            private bool DoesUserHaveAmmo(string ammoTypeShortName, float currentTime) {
                if (configuration.UnlimitedAmmo) return true;
                if (this.player.inventory.GetAmount(weaponsToAmmoTypeItemIdMap[ammoTypeShortName]) > 0) return true;
                if (configuration.DisplayOutOfAmmoMessage && currentTime >= (lastMsgTime + configuration.DebounceTimeSeconds)) {
                    player.ChatMessage("Out of Ammo");
                    lastMsgTime = currentTime;
                }
                return false;
            }
            private void FireWithProjectileSystem(WeaponConfiguration weaponConfiguration, Vector3 muzzlePos) {
                Vector3 modifiedAimDir = this.vehicle.transform.forward.normalized;
                if (weaponConfiguration.AimCone > 0) modifiedAimDir = AimConeUtil.GetAimConeQuat(weaponConfiguration.AimCone) * modifiedAimDir;
                instance.BulletProjectile.CallHook("ShootProjectile", this.player, muzzlePos, modifiedAimDir * weaponConfiguration.WeaponSpeed, weaponConfiguration.DamageTypes, weaponConfiguration.AmmoPrefabPath);
            }
            private GameObject FireWithServerProjectile(WeaponConfiguration weaponConfiguration, Vector3 muzzlePos) {
                GameObject bulletEnt = GameManager.server.CreatePrefab(weaponConfiguration.AmmoPrefabPath, muzzlePos, new Quaternion(), false);
                ServerProjectile serverProjectile = bulletEnt.GetComponent<ServerProjectile>();
                TimedExplosive timedExplosive = bulletEnt.GetComponent<TimedExplosive>();
                var baseEnt = bulletEnt.GetComponent<BaseEntity>();
                baseEnt.creatorEntity = this.player;
                if (timedExplosive != null) {
                    timedExplosive.OwnerID = player.userID;
                    if (weaponConfiguration.DamageTypes != null && weaponConfiguration.DamageTypes.Any()) {
                        timedExplosive.damageTypes = weaponConfiguration.DamageTypes;
                    }
                    if (weaponConfiguration.MinBlastRadius > 0) {
                        timedExplosive.minExplosionRadius = weaponConfiguration.MinBlastRadius;
                    }
                    if (weaponConfiguration.MaxBlastRadius > 0) {
                        timedExplosive.explosionRadius = weaponConfiguration.MaxBlastRadius;
                    }
                    if (weaponConfiguration.DetonationTimerMin > 0) {
                        timedExplosive.timerAmountMin = weaponConfiguration.DetonationTimerMin;
                    }
                    if (weaponConfiguration.DetonationTimerMax > 0) {
                        timedExplosive.timerAmountMax = weaponConfiguration.DetonationTimerMax;
                    }
                }
                if (serverProjectile != null) {
                    serverProjectile.gravityModifier = 1f;
                    serverProjectile.speed = weaponConfiguration.WeaponSpeed;
                    if (weaponConfiguration.BarrelConfiguration != BarrelConfiguration.Bottom) {
                        serverProjectile.InitializeVelocity(this.vehicle.transform.forward.normalized * weaponConfiguration.WeaponSpeed);
                    }
                }
                baseEnt.Spawn();
                bulletEnt.SetActive(true);
                return bulletEnt;
            }
            private void FireAARocket(WeaponConfiguration weaponConfiguration, Vector3 muzzlePos) {
                var projectile = FireWithServerProjectile(weaponConfiguration, muzzlePos);
                var homing = projectile.AddComponent<AARocket>();
                if (weaponConfiguration.AngleModifier > 0) homing.AngleModifier = weaponConfiguration.AngleModifier;
                homing.Initialize(target, ChanceToLoseLock);
                if (weaponConfiguration.ClearAATargetOnFire) ClearTarget();
            }
            private void UseAmmo(string ammoTypeShortName, bool? isPrimary) {
                var ammo = player.inventory.FindItemID(weaponsToAmmoTypeItemIdMap[ammoTypeShortName]);
                ammo?.UseItem(1);
                if (isPrimary == null) Toggle_FlareAmmoGui(true);
                else Toggle_AmmoGui(true, isPrimary);
            }
            private void SwitchWeaponType() {
                float currentTime = UnityEngine.Time.realtimeSinceStartup;
                if (currentTime < (lastWeaponSwitchTime + configuration.WeaponSwitchDelay)) return;
                string newSelection = selectedWeaponType;
                do {
                    newSelection = GetNextWeaponType(newSelection);
                }
                while (!newSelection.Equals("Disarm", StringComparison.InvariantCultureIgnoreCase) && !configuration.DisablePermissionCheck && !permissionHelper.UserHasPermission(this.player.userID.ToString(), this.GetAvailableWeapons()[newSelection].WeaponPermission));
                this.selectedWeaponType = newSelection;
                this.weaponSettings = this.GetAvailableWeapons()[this.selectedWeaponType];
                this.ResetWeapons();
                Effect.server.Run(configuration.SwitchWeaponSfx, this.player.transform.position + this.player.transform.forward);
                if (configuration.DisplaySelectedWeaponMessage) player.ChatMessage($"Selected Weapon: {weaponSettings.DisplayFullName}");
                Toggle_ReticleGui(true);
                Toggle_AmmoGui(true, null);
                Toggle_FlareAmmoGui(true);
                Toggle_WeaponTypesGui(true);
                Toggle_CooldownGui(true);
                lastWeaponSwitchTime = currentTime;
            }
            protected virtual string GetNextWeaponType(string current) {
                throw new NotImplementedException();
            }
            public void TriggerLockAcquired(Lock lck) {
                locks.Add(lck.Id, lck);
                Toggle_ReticleGui(true);
            }
            public void TriggerLockLost(Lock lck) {
                locks.Remove(lck.Id);
                Toggle_ReticleGui(true);
            }
            private void LockTarget(Vector3 muzzlePos, WeaponConfiguration weaponConfiguration) {
                float currentTime = UnityEngine.Time.realtimeSinceStartup;
                if (targetLocked) {
                    bool exceedHud = (targetAngleX > maxAngle || targetAngleX < minAngle) || (targetAngleY > maxAngle || targetAngleY < minAngle);
                    if (exceedHud || target == null || currentTime > (lockedAt + weaponConfiguration.TimeBeforeLockExpires)) {
                        ClearTarget();
                    }
                }
                RaycastHit rayHit;
                if (!targetLocked && Physics.SphereCast(muzzlePos, 1f, this.vehicle.transform.forward, out rayHit, 500)) {
                    var newTrack = rayHit.GetEntity();
                    var newTarget = newTrack;
                    if (newTarget != target) {
                        CancelInvoke();
                        lockOnSeconds = 0;
                        isLockAlarmPlaying = false;
                        acquiringLock = false;
                        targetAngleX = 0.0f;
                        targetAngleY = 0.0f;
                        target = newTarget;
                    }
                    bool validTarget = false;
                    if (weaponConfiguration.AllowCH47HSR && newTarget is CH47Helicopter) {
                        validTarget = true;
                    }
                    else if (weaponConfiguration.AllowPatrolHeliHSR && newTarget is BaseHelicopter) {
                        validTarget = true;
                    }
                    else {
                        var miniCopter = target as MiniCopter;
                        var miniCopterWrapper = target?.GetComponent<HelicopterWrapper>();
                        if (miniCopterWrapper == null) {
                            var targetPlayer = target as BasePlayer;
                            miniCopterWrapper = targetPlayer?.GetMountedVehicle()?.GetComponent<HelicopterWrapper>();
                        }
                        if (miniCopterWrapper != null) validTarget = true;
                    }
                    if (validTarget) {
                        acquiringLock = true;
                        if (!isLockAlarmPlaying) {
                            PlayLockAlarm();
                        }
                        lockOnSeconds += UnityEngine.Time.deltaTime;
                        if (lockOnSeconds >= weaponConfiguration.TimeToLock) {
                            SetLockTarget(newTarget);
                            lockedAt = currentTime;
                        }
                    }
                }
            }
            private void ResetWeapons() {
                this.lastPrimaryWeaponFiredTime = 0.0f;
                this.lastSecondaryWeaponFiredTime = 0.0f;
                this.primaryCooldownTimer = 0.0f;
                this.secondaryCooldownTimer = 0.0f;
                this.primaryRoundsFired = 0;
                this.secondaryRoundsFired = 0;
                this.primaryCurrentBarrel = 0;
                this.secondaryCurrentBarrel = 0;
            }
            public static Vector2 WorldPosToImagePos(Vector3 worldPos) {
                Vector3 vector3_2 = new Vector3();
                vector3_2.x = worldPos.x;
                vector3_2.y = worldPos.y;
                return (Vector2)vector3_2;
            }
            public void ClearTarget() {
                CancelInvoke();
                isLockAlarmPlaying = false;
                lockOnSeconds = 0;
                if (target != null) {
                    var miniCopter = target as MiniCopter;
                    var miniCopterWrapper = miniCopter?.GetComponent<HelicopterWrapper>();
                    if (miniCopterWrapper != null) miniCopterWrapper.TriggerLockLost(this);
                }
                targetAngleX = 0.0f;
                targetAngleY = 0.0f;
                target = null;
                targetLocked = false;
                acquiringLock = false;
            }
            private void PlayLockAlarm() {
                isLockAlarmPlaying = true;
                Effect.server.Run(configuration.AlarmSfx, this.player.transform.position);
                // Increase frequency if a lock is acquired
                Invoke("PlayLockAlarm", targetLocked ? 0.2f : 1f);
            }
            public void SetLockTarget(BaseEntity target) {
                acquiringLock = false;
                targetLocked = true;
                var miniCopterWrapper = this.target?.GetComponent<HelicopterWrapper>();
                if (miniCopterWrapper != null) miniCopterWrapper.TriggerLockLost(this);
                this.target = target;
                miniCopterWrapper = this.target.GetComponent<HelicopterWrapper>();
                if (miniCopterWrapper != null) miniCopterWrapper.TriggerLockAcquired(this);
            }
#endregion
#region Methods
            public void SetPlayer(BasePlayer player) {
                if (player == null) return;
                if (this.player == player && this.vehicle.GetPlayerSeat(player) != 0) {
                    RemovePlayer(player);
                    return;
                }
                else if (this.vehicle.GetPlayerSeat(player) != 0) return;
                this.player = player;
                ClearTarget();
                Toggle_WeaponTypesGui(true);
            }
            public void RemovePlayer(BaseP
// ... [Code preview truncated due to length. Full source in attached file] ...

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

Другие ресурсы пользователя 15FPS

Сверху