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

FREE AdvAirstrike : 0.1.76 0.1.76

Нет прав для скачивания
C#:
using System;
using System.Collections.Generic;
using Newtonsoft.Json;
using Oxide.Core;
using Oxide.Core.Configuration;
using Oxide.Core.Plugins;
using UnityEngine;
using System.Linq;
using Rust;
using Facepunch;
using System.Collections;
namespace Oxide.Plugins {
    [Info("Advanced Airstrike", "k1lly0u", "0.1.76")]
    class AdvAirstrike : RustPlugin {
#region Fields
        [PluginReference]
        Plugin Economics, ServerRewards, Spawns, NoEscape;
        StoredData storedData;
        private DynamicConfigFile data;
        private Dictionary<ulong, StrikeType> toggleList = new Dictionary<ulong, StrikeType>();
        private Dictionary<string, int> shortnameToId = new Dictionary<string, int>();
        private Dictionary<string, string> shortnameToDn = new Dictionary<string, string>();
        private Hash<ulong, double> playerCooldowns = new Hash<ulong, double>();
        private List<StrikeType> availableTypes = new List<StrikeType>();
        private List<RadiationEntry> radiationZones = new List<RadiationEntry>();
        private List<BaseEntity> strikeSignals = new List<BaseEntity>();
        private static AdvAirstrike ins;
        const string cargoPlanePrefab = "assets/prefabs/npc/cargo plane/cargo_plane.prefab";
        const string basicRocket = "assets/prefabs/npc/patrol helicopter/rocket_heli.prefab";
        const string fireRocket = "assets/prefabs/npc/patrol helicopter/rocket_heli_napalm.prefab";
        const string tankShell = "assets/prefabs/npc/m2bradley/maincannonshell.prefab";
        const string heliExplosion = "assets/prefabs/npc/patrol helicopter/effects/heli_explosion.prefab";
        const string fireball = "assets/bundled/prefabs/oilfireballsmall.prefab";
        const string c4Explosion = "assets/prefabs/tools/c4/effects/c4_explosion.prefab";
        const string debris = "assets/prefabs/npc/patrol helicopter/damage_effect_debris.prefab";
        const string bulletExp = "assets/bundled/prefabs/fx/impacts/additive/explosion.prefab";
        const string fireCannonEffect = "assets/prefabs/npc/m2bradley/effects/maincannonattack.prefab";
        static int layerMaskExpl = LayerMask.GetMask("Deployed", "AI", "Vehicle_Movement", "Player_Server", "Construction");
        enum StrikeType {
            None, Strike, Squad, Napalm, Nuke, Spectre
        }
        enum FireType {
            Rocket, Bullet, Cannon, Combined
        }
#endregion
#region Oxide Hooks
        private void Loaded() {
            data = Interface.Oxide.DataFileSystem.GetFile("advairstrike_data");
            lang.RegisterMessages(Messages, this);
            foreach(var type in Enum.GetValues(typeof(StrikeType))) {
                permission.RegisterPermission($"advairstrike.signal.{type.ToString().ToLower()}", this);
                permission.RegisterPermission($"advairstrike.purchase.{type.ToString().ToLower()}", this);
                permission.RegisterPermission($"advairstrike.chat.{type.ToString().ToLower()}", this);
            }
            permission.RegisterPermission("advairstrike.ignorecooldown", this);
        }
        private void OnServerInitialized() {
            ins = this;
            LoadData();
            shortnameToId = ItemManager.itemList.ToDictionary(x => x.shortname, y => y.itemid);
            shortnameToDn = ItemManager.itemList.ToDictionary(x => x.shortname, y => y.displayName.translated);
            PrepareRandomStrikes();
        }
        private void Unload() {
            ins = null;
            BasePlane[] objects = UnityEngine.Object.FindObjectsOfType<BasePlane>();
            if (objects != null) {
                foreach (BasePlane obj in objects) UnityEngine.Object.Destroy(obj);
            }
            RocketMonitor[] monitors = UnityEngine.Object.FindObjectsOfType<RocketMonitor>();
            if (monitors != null) {
                foreach (RocketMonitor obj in monitors) UnityEngine.Object.Destroy(obj);
            }
            for (int i = 0; i < radiationZones.Count; i++) {
                radiationZones[i].time.Destroy();
                UnityEngine.Object.Destroy(radiationZones[i].zone);
            }
            radiationZones.Clear();
        }
        private void OnServerSave() => SaveData();
        private void OnExplosiveDropped(BasePlayer player, BaseEntity entity) => OnExplosiveThrown(player, entity);
        private void OnExplosiveThrown(BasePlayer player, BaseEntity entity) {
            if (toggleList.ContainsKey(player.userID) && entity is SupplySignal) {
                strikeSignals.Add(entity);
                StrikeType type = toggleList[player.userID];
                toggleList.Remove(player.userID);
                AddCooldownData(player, type);
                entity.CancelInvoke((entity as SupplySignal).Explode);
                entity.Invoke(() => {
                    strikeSignals.Remove(entity);
                    entity.KillMessage();
                }
                , 30f);
                timer.Once(3, () => {
                    Effect.server.Run("assets/bundled/prefabs/fx/smoke_signal_full.prefab", entity, 0, new Vector3(), new Vector3());
                    SendStrike(player, type, entity.transform.position);
                }
                );
            }
        }
#endregion
#region Plane Control
        private class NapalmPlane : BasePlane {
            private void Awake() {
                entity = GetComponent<CargoPlane>();
                entity.enabled = false;
                rocketOptions = ins.configData.Rocket;
                fireDistance = ins.configData.Plane.Distance;
                forcedType = fireRocket;
                enabled = false;
            }
            public override void LaunchRocket() {
                if (projectilesFired >= rocketOptions.Amount) {
                    InvokeHandler.CancelInvoke(this, LaunchRocket);
                    return;
                }
                BaseEntity rocket = FireRocket();
                rocket.gameObject.AddComponent<RocketMonitor>().SetType(StrikeType.Napalm);
                ++projectilesFired;
            }
        }
        private class NukePlane : BasePlane {
            private void Awake() {
                entity = GetComponent<CargoPlane>();
                entity.enabled = false;
                rocketOptions = ins.configData.Rocket;
                forcedType = basicRocket;
                enabled = false;
            }
            public override void LaunchRocket() {
                InvokeHandler.CancelInvoke(this, LaunchRocket);
                BaseEntity rocket = FireRocket();
                rocket.gameObject.AddComponent<RocketMonitor>().SetType(StrikeType.Nuke);
                ++projectilesFired;
            }
        }
        private class SpectrePlane : BasePlane {
            private bool inOrbit;
            private float flightRadius;
            private Vector3 beginOrbit;
            private float distance;
            private float speed;
            private int rotations;
            private bool isLeaning;
            private void Awake() {
                entity = GetComponent<CargoPlane>();
                entity.enabled = false;
                rocketOptions = ins.configData.Rocket;
                this.flightRadius = ins.configData.Plane.FlightRadius;
                distance = Convert.ToSingle(Math.PI * (flightRadius * 2));
                speed = ins.configData.Plane.Speed;
                enabled = false;
            }
            public override void InitializeFlightPath(Vector3 targetPos, StrikeType strikeType = StrikeType.Spectre) {
                CheckFireType(strikeType);
                this.strikeType = strikeType;
                this.targetPos = targetPos;
                float size = TerrainMeta.Size.x;
                float highestPoint = 170f;
                startPos = Vector3Ex.Range(-1f, 1f);
                startPos.y = 0f;
                startPos.Normalize();
                startPos = startPos * (size * 2f);
                startPos.y = highestPoint;
                endPos = startPos * -1f;
                endPos.y = startPos.y;
                startPos = startPos + targetPos;
                endPos = endPos + targetPos;
                secondsToTake = (Vector3.Distance(startPos, endPos) / ins.configData.Plane.Speed) * UnityEngine.Random.Range(0.95f, 1.05f);
                entity.transform.rotation = Quaternion.LookRotation(endPos - startPos);
                startPos = startPos + (-entity.transform.right * flightRadius);
                endPos = endPos + (-entity.transform.right * flightRadius);
                beginOrbit = targetPos + (-entity.transform.right * flightRadius);
                beginOrbit.y = startPos.y;
                entity.transform.position = startPos;
                enabled = true;
            }
            public override void MovePlane() {
                if (!inOrbit) {
                    Rotate();
                    secondsTaken += Time.deltaTime;
                    float single = Mathf.InverseLerp(0f, secondsToTake, secondsTaken);
                    entity.transform.position = Vector3.Lerp(startPos, endPos, single);
                    entity.transform.hasChanged = true;
                    if (single >= 1f) entity.Kill(BaseNetworkable.DestroyMode.None);
                }
                else {
                    Rotate();
                    entity.transform.RotateAround(targetPos, Vector3.up, distance / speed * Time.deltaTime);
                }
            }
            private void Rotate() {
                if (rotations < 600 && isLeaning) {
                    entity.transform.rotation = Quaternion.Euler(new Vector3(entity.transform.rotation.eulerAngles.x, entity.transform.rotation.eulerAngles.y, entity.transform.rotation.eulerAngles.z - 0.05f));
                    ++rotations;
                }
                if (rotations > 0 && !isLeaning) {
                    entity.transform.rotation = Quaternion.Euler(new Vector3(entity.transform.rotation.eulerAngles.x, entity.transform.rotation.eulerAngles.y, entity.transform.rotation.eulerAngles.z + 0.05f));
                    --rotations;
                }
            }
            public override void CanFireRockets() {
                if (!isFiring && Vector3.Distance(entity.transform.position, beginOrbit) < 2) {
                    entity.transform.rotation = Quaternion.Euler(new Vector3(entity.transform.rotation.eulerAngles.x, entity.transform.rotation.eulerAngles.y, 359.95f));
                    isLeaning = true;
                    inOrbit = true;
                    isFiring = true;
                    TryFireWeapons();
                }
            }
            public override void OnAmmunitionDepleted() {
                startPos = entity.transform.position;
                endPos = entity.transform.forward * Vector3.Distance(entity.transform.position, endPos);
                secondsToTake /= 2;
                secondsTaken = 0;
                isLeaning = false;
                inOrbit = false;
            }
        }
        private class BasePlane : MonoBehaviour {
            internal CargoPlane entity;
            internal RocketOptions rocketOptions;
            internal CannonOptions cannonOptions;
            internal GunOptions gunOptions;
            internal FireType fireType = FireType.Rocket;
            internal StrikeType strikeType = StrikeType.None;
            internal Vector3 startPos;
            internal Vector3 endPos;
            internal Vector3 targetPos;
            internal float secondsToTake;
            internal float secondsTaken;
            internal bool isFiring;
            internal int projectilesFired;
            internal int projectilesFiredGun;
            internal string forcedType;
            internal float fireDistance;
            private AutoTurret autoTurret;
            private void Awake() {
                entity = GetComponent<CargoPlane>();
                entity.enabled = false;
                rocketOptions = ins.configData.Rocket;
                fireDistance = ins.configData.Plane.Distance;
                enabled = false;
            }
            private void Update() {
                CanFireRockets();
                MovePlane();
            }
            private void OnDestroy() {
                InvokeHandler.CancelInvoke(this, FireGun);
                InvokeHandler.CancelInvoke(this, LaunchRocket);
                if (autoTurret != null && !autoTurret.IsDestroyed) autoTurret.Kill();
                if (entity != null && !entity.IsDestroyed) entity.Kill();
            }
            public virtual void InitializeFlightPath(Vector3 targetPos, StrikeType strikeType) {
                CheckFireType(strikeType);
                this.strikeType = strikeType;
                this.targetPos = targetPos;
                float size = TerrainMeta.Size.x;
                float highestPoint = 170f;
                startPos = Vector3Ex.Range(-1f, 1f);
                startPos.y = 0f;
                startPos.Normalize();
                startPos = startPos * (size * 2f);
                startPos.y = highestPoint;
                endPos = startPos * -1f;
                endPos.y = startPos.y;
                startPos = startPos + targetPos;
                endPos = endPos + targetPos;
                secondsToTake = (Vector3.Distance(startPos, endPos) / ins.configData.Plane.Speed) * UnityEngine.Random.Range(0.95f, 1.05f);
                entity.transform.position = startPos;
                entity.transform.rotation = Quaternion.LookRotation(endPos - startPos);
                if (fireType == FireType.Bullet && fireDistance > 250) fireDistance = 250;
                if (strikeType == StrikeType.Nuke) fireDistance = (entity.transform.position.y - targetPos.y) + 10f;
                enabled = true;
            }
            internal void CheckFireType(StrikeType strikeType) {
                if (ins.configData.Types.ContainsKey(strikeType)) fireType = ins.ParseType<FireType>(ins.configData.Types[strikeType]);
                if (fireType == FireType.Bullet || fireType == FireType.Combined) {
                    cannonOptions = ins.configData.Cannon;
                    gunOptions = ins.configData.Gun[strikeType];
                    autoTurret = (AutoTurret)GameManager.server.CreateEntity("assets/prefabs/npc/autoturret/autoturret_deployed.prefab", transform.position);
                    autoTurret.Spawn();
                    autoTurret.enableSaving = false;
                    autoTurret.SetParent(entity, 0);
                    autoTurret.transform.localEulerAngles = new Vector3(0, 0, 180);
                    autoTurret.transform.localPosition = new Vector3();
                    (autoTurret as BaseCombatEntity).baseProtection = Resources.FindObjectsOfTypeAll<ProtectionProperties>().ToList().FirstOrDefault(p => p.name == "Immortal");
                }
                else if (fireType == FireType.Cannon) cannonOptions = ins.configData.Cannon;
            }
            public virtual void CanFireRockets() {
                if (!isFiring && Vector3.Distance(transform.position, targetPos) <= fireDistance) {
                    isFiring = true;
                    TryFireWeapons();
                }
            }
            public virtual void MovePlane() {
                secondsTaken += Time.deltaTime;
                float single = Mathf.InverseLerp(0f, secondsToTake, secondsTaken);
                entity.transform.position = Vector3.Lerp(startPos, endPos, single);
                entity.transform.hasChanged = true;
                if (single >= 1f) entity.Kill(BaseNetworkable.DestroyMode.None);
            }
            public void GetFlightData(out Vector3 startPos, out Vector3 endPos, out float secondsToTake) {
                startPos = this.startPos;
                endPos = this.endPos;
                secondsToTake = this.secondsToTake;
            }
            public void SetFlightData(Vector3 startPos, Vector3 endPos, Vector3 targetPos, float secondsToTake) {
                strikeType = StrikeType.Squad;
                CheckFireType(strikeType);
                this.startPos = startPos;
                this.endPos = endPos;
                this.targetPos = targetPos;
                this.secondsToTake = secondsToTake;
                entity.transform.position = startPos;
                entity.transform.rotation = Quaternion.LookRotation(endPos - startPos);
                enabled = true;
            }
            internal void TryFireWeapons() {
                if (fireType == FireType.Bullet) InvokeHandler.InvokeRepeating(this, FireGun, 0, gunOptions.FireRate);
                else if (fireType == FireType.Combined) {
                    InvokeHandler.InvokeRepeating(this, FireGun, 0, gunOptions.FireRate);
                    InvokeHandler.InvokeRepeating(this, LaunchRocket, 0, strikeType == StrikeType.Spectre ? cannonOptions.IntervalSpectre : cannonOptions.Interval);
                }
                else InvokeHandler.InvokeRepeating(this, LaunchRocket, 0, strikeType == StrikeType.Spectre ? (fireType == FireType.Rocket ? rocketOptions.IntervalSpectre : cannonOptions.IntervalSpectre) : (fireType == FireType.Rocket ? rocketOptions.Interval : cannonOptions.Interval));
            }
            public virtual void LaunchRocket() {
                if (projectilesFired >= (fireType == FireType.Rocket ? rocketOptions.Amount : cannonOptions.Amount)) {
                    if (fireType != FireType.Combined || (fireType == FireType.Combined && !InvokeHandler.IsInvoking(this, FireGun))) OnAmmunitionDepleted();
                    InvokeHandler.CancelInvoke(this, LaunchRocket);
                    return;
                }
                if (fireType == FireType.Combined || fireType == FireType.Cannon) FireCannon();
                else FireRocket();
                ++projectilesFired;
            }
            public virtual void OnAmmunitionDepleted() {
            }
            internal BaseEntity FireCannon() {
                Effect.server.Run(fireCannonEffect, entity, 0u, Vector3.zero, Vector3.zero, null, false);
                float accuracy = GetComponent<SpectrePlane>() ? cannonOptions.SpectreAccuracy : cannonOptions.Accuracy;
                Vector3 launchPos = entity.transform.position;
                Vector3 newTarget = Quaternion.Euler(GetRandom(accuracy), GetRandom(accuracy), GetRandom(accuracy)) * targetPos;
                BaseEntity rocket = GameManager.server.CreateEntity(tankShell, launchPos, new Quaternion(), true);
                TimedExplosive rocketExplosion = rocket.GetComponent<TimedExplosive>();
                for (int i = 0; i < rocketExplosion.damageTypes.Count; i++) rocketExplosion.damageTypes[i].amount *= cannonOptions.Damage;
                Vector3 newDirection = (newTarget - launchPos);
                rocket.SendMessage("InitializeVelocity", newDirection);
                rocket.Spawn();
                return rocket;
            }
            internal BaseEntity FireRocket() {
                string rocketType = forcedType;
                if (string.IsNullOrEmpty(forcedType)) {
                    rocketType = rocketOptions.Type == "Normal" ? basicRocket : fireRocket;
                    if (rocketOptions.Mixed && UnityEngine.Random.Range(1, rocketOptions.FireChance) == 1) rocketType = fireRocket;
                }
                float accuracy = GetComponent<SpectrePlane>() ? rocketOptions.SpectreAccuracy : GetComponent<NukePlane>() ? 0.5f : rocketOptions.Accuracy;
                Vector3 launchPos = entity.transform.position;
                Vector3 newTarget = Quaternion.Euler(GetRandom(accuracy), GetRandom(accuracy), GetRandom(accuracy)) * targetPos;
                Effect.server.Run("assets/prefabs/npc/m2bradley/effects/maincannonattack.prefab", entity, 0u, Vector3.zero, Vector3.zero, null, false);
                BaseEntity rocket = GameManager.server.CreateEntity(rocketType, launchPos, new Quaternion(), true);
                TimedExplosive rocketExplosion = rocket.GetComponent<TimedExplosive>();
                ServerProjectile rocketProjectile = rocket.GetComponent<ServerProjectile>();
                rocketProjectile.speed = rocketOptions.Speed;
                rocketProjectile.gravityModifier = 0;
                rocketExplosion.timerAmountMin = 60;
                rocketExplosion.timerAmountMax = 60;
                for (int i = 0; i < rocketExplosion.damageTypes.Count; i++) rocketExplosion.damageTypes[i].amount *= rocketOptions.Damage;
                Vector3 newDirection = (newTarget - launchPos);
                rocket.SendMessage("InitializeVelocity", newDirection);
                rocket.Spawn();
                return rocket;
            }
            internal void FireGun() {
                if (projectilesFiredGun >= gunOptions.Amount) {
                    if (fireType == FireType.Bullet || (fireType == FireType.Combined && !InvokeHandler.IsInvoking(this, LaunchRocket))) OnAmmunitionDepleted();
                    InvokeHandler.CancelInvoke(this, FireGun);
                    return;
                }
                ++projectilesFiredGun;
                UpdateFacingToTarget();
                Vector3 centerMuzzle = autoTurret.GetCenterMuzzle().transform.position;
                Vector3 modifiedAimConeDir = AimConeUtil.GetModifiedAimConeDirection(gunOptions.Accuracy * 0.2f, targetPos - centerMuzzle, true);
                Vector3 newTargetPosition = centerMuzzle + (modifiedAimConeDir * 400f);
                List<RaycastHit> list = Pool.GetList<RaycastHit>();
                GamePhysics.TraceAll(new Ray(centerMuzzle, modifiedAimConeDir), 0f, list, 400f, 1219701521, QueryTriggerInteraction.UseGlobal);
                for (int i = 0; i < list.Count; i++) {
                    RaycastHit hit = list[i];
                    BaseEntity entity = hit.GetEntity();
                    if ((!(entity != null) || (!(entity == this) && !entity.EqualNetID(autoTurret))) && (!(entity != null) || !(entity.GetComponent<BasePlayer>() != null))) {
                        BaseCombatEntity baseCombatEntity = entity as BaseCombatEntity;
                        if (baseCombatEntity != null) {
                            HitInfo info = new HitInfo(autoTurret, entity, DamageType.Bullet, gunOptions.Damage, hit.point);
                            entity.OnAttacked(info);
                            if (entity is BasePlayer || entity is BaseNpc) {
                                Effect.server.ImpactEffect(new HitInfo {
                                    HitPositionWorld = hit.point, HitNormalWorld = -modifiedAimConeDir, HitMaterial = StringPool.Get("Flesh")
                                }
                                );
                            }
                        }
                        if (!(entity != null) || entity.ShouldBlockProjectiles()) {
                            newTargetPosition = hit.point;
                            break;
                        }
                        else newTargetPosition = hit.point;
                    }
                }
                if (gunOptions.IsExplosive) {
                    DamageUtil.RadiusDamage(autoTurret, null, newTargetPosition, 0.5f, 0.5f, new List<DamageTypeEntry> {
                        new DamageTypeEntry {
                            amount = 5f, type = DamageType.Explosion
                        }
                    }
                    , layerMaskExpl, false);
                    Effect.server.Run(bulletExp, newTargetPosition);
                }
                autoTurret.ClientRPC(null, "CLIENT_FireGun", StringPool.Get(autoTurret.muzzlePos.gameObject.name), newTargetPosition);
                Pool.FreeList(ref list);
            }
            private void UpdateFacingToTarget() {
                Vector3 a = targetPos;
                Vector3 b = autoTurret.gun_pitch.transform.InverseTransformPoint(autoTurret.muzzlePos.transform.position);
                b.z = (b.x = 0f);
                Vector3 vector = a - (autoTurret.gun_pitch.position + b);
                autoTurret.aimDir = vector;
                autoTurret.UpdateAiming();
            }
            internal float GetRandom(float accuracy) => UnityEngine.Random.Range(-accuracy * 0.2f, accuracy * 0.2f);
        }
#endregion
#region Rockets and Radiation
        private class RocketMonitor : MonoBehaviour {
            StrikeType type;
            public void SetType(StrikeType type) {
                this.type = type;
            }
            private void OnDestroy() {
                if (type == StrikeType.Napalm) {
                    SpawnFireball(transform.position);
                }
                if (type == StrikeType.Nuke) {
                    new NukeExplosion(transform.position);
                    InitializeZone(transform.position);
                }
            }
            FireBall SpawnFireball(Vector3 position) {
                FireBall fireBall = GameManager.server.CreateEntity(fireball, position, new Quaternion(), true) as FireBall;
                if (fireBall) {
                    fireBall.GetComponent<Rigidbody>().isKinematic = true;
                    fireBall.GetComponent<Collider>().enabled = false;
                    fireBall.Spawn();
                    fireBall.CancelInvoke("Extinguish");
                    fireBall.Invoke("Extinguish", ins.configData.Rocket.FireLife);
                    return fireBall;
                }
                return null;
            }
            private void InitializeZone(Vector3 location) {
                if (!ConVar.Server.radiation) ConVar.Server.radiation = true;
                RadiationZone newZone = new GameObject("RadiationZone").AddComponent<RadiationZone>();
                newZone.transform.position = location;
                newZone.Activate(ins.configData.Rocket.RadRadius, ins.configData.Rocket.RadIntensity);
                RadiationEntry listEntry = new RadiationEntry {
                    zone = newZone
                }
                ;
                listEntry.time = ins.timer.Once(ins.configData.Rocket.RadDuration, () => ins.DestroyZone(listEntry));
                ins.radiationZones.Add(listEntry);
                if (ins.configData.Rocket.NukeAmount > 0) {
                    float radius = ins.configData.Rocket.NukeRadius;
                    List<BaseCombatEntity> entities = Pool.GetList<BaseCombatEntity>();
                    Vis.Entities<BaseCombatEntity>(location, radius, entities);
                    if (entities.Count > 0) {
                        for (int i = entities.Count - 1; i >= 0; i--) {
                            BaseCombatEntity entity = entities[i];
                            if (entity == null) continue;
                            float distance = Vector3.Distance(location, entity.transform.position);
                            entity.Hurt(ins.configData.Rocket.NukeAmount * (1 - (distance / radius)), DamageType.Explosion, null);
                        }
                    }
                    Pool.FreeList(ref entities);
                }
            }
        }
        public class NukeExplosion {
            private int count;
            private Vector3 position;
            private List<KeyValuePair<int, int>> blastRadius = new List<KeyValuePair<int, int>> {
                new KeyValuePair<int, int> (25, 18), new KeyValuePair<int, int> (15, 12), new KeyValuePair<int, int> (10, 10), new KeyValuePair<int, int> (5, 5), new KeyValuePair<int, int> (5, 5), new KeyValuePair<int, int> (5, 5), new KeyValuePair<int, int> (5, 5), new KeyValuePair<int, int> (5, 5), new KeyValuePair<int, int> (5, 5), new KeyValuePair<int, int> (10, 10), new KeyValuePair<int, int> (25, 18), new KeyValuePair<int, int> (25, 18), new KeyValuePair<int, int> (20, 16), new KeyValuePair<int, int> (20, 16)
            }
            ;
            public NukeExplosion() {
            }
            public NukeExplosion(Vector3 position) {
                this.position = position;
                BeginExplosion();
            }
            private void BeginExplosion() {
                Effect.server.Run(heliExplosion, position, Vector3.up, null, true);
                Next();
            }
            private void Next() => ServerMgr.Instance.StartCoroutine(CreateRing());
            IEnumerator CreateRing() {
                if (count == blastRadius.Count - 1) yield break;
                yield return new WaitForSeconds(0.1f);
                ExplosionRing(position + ((Vector3.up * 3) * count), blastRadius[count].Key, blastRadius[count].Value);
                ++count;
                Next();
            }
            private void ExplosionRing(Vector3 position, float radius, int amount) {
                int angle = 360 / amount;
                for (int i = 0; i < amount; i++) {
                    int a = i * angle;
                    Vector3 pos = RandomCircle(position, radius, a);
                    Effect.server.Run(c4Explosion, pos, Vector3.up, null, true);
                }
            }
            private Vector3 RandomCircle(Vector3 center, float radius, int angle) {
                Vector3 pos;
                pos.x = center.x + radius * Mathf.Sin(angle * Mathf.Deg2Rad);
                pos.z = center.z + radius * Mathf.Cos(angle * Mathf.Deg2Rad);
                pos.y = center.y;
                return pos;
            }
        }
        public class RadiationEntry {
            public RadiationZone zone;
            public Timer time;
        }
        public class RadiationZone : MonoBehaviour {
            SphereCollider collider;
            private void Awake() {
                gameObject.layer = (int)Layer.Reserved1;
                Rigidbody rigidbody = gameObject.AddComponent<Rigidbody>();
                rigidbody.useGravity = false;
                rigidbody.isKinematic = true;
                rigidbody.detectCollisions = true;
                rigidbody.collisionDetectionMode = CollisionDetectionMode.Discrete;
                collider = gameObject.AddComponent<SphereCollider>();
                collider.isTrigger = true;
            }
            public void Activate(float radius, float amount) {
                collider.radius = radius;
                TriggerRadiation radiation = gameObject.AddComponent<TriggerRadiation>();
                radiation.RadiationAmountOverride = amount;
                radiation.interestLayers = LayerMask.GetMask("Player (Server)");
                radiation.enabled = true;
            }
            private void OnDestroy() {
                Destroy(gameObject);
            }
        }
        private void DestroyZone(RadiationEntry zone) {
            if (radiationZones.Contains(zone)) {
                var index = radiationZones.FindIndex(a => a.zone == zone.zone);
                radiationZones[index].time.Destroy();
                UnityEngine.Object.Destroy(radiationZones[index].zone);
                radiationZones.Remove(zone);
            }
        }
#endregion
#region Functions
        private void SendStrike(BasePlayer player, StrikeType type, Vector3 position, string targetName = "") {
            switch (type) {
                case StrikeType.Strike : CallStrike(position, player.displayName);
                SendReply(player, string.IsNullOrEmpty(targetName) ? string.Format(msg("strikeConfirmed", player.UserIDString), position) : string.Format(msg("strikePlayer", player.UserIDString), targetName));
                break;
                case StrikeType.Squad : CallSquad(position, player.displayName);
                SendReply(player, string.IsNullOrEmpty(targetName) ? string.Format(msg("squadConfirmed", player.UserIDString), position) : string.Format(msg("squadPlayer", player.UserIDString), targetName));
                break;
                case StrikeType.Napalm : CallNapalm(position, player.displayName);
                SendReply(player, string.IsNullOrEmpty(targetName) ? string.Format(msg("napalmConfirmed", player.UserIDString), position) : string.Format(msg("napalmPlayer", player.UserIDString), targetName));
                break;
                case StrikeType.Nuke : CallNuke(position, player.displayName);
                SendReply(player, string.IsNullOrEmpty(targetName) ? string.Format(msg("nukeConfirmed", player.UserIDString), position) : string.Format(msg("nukePlayer", player.UserIDString), targetName));
                break;
                case StrikeType.Spectre : CallSpectre(position, player.displayName);
                SendReply(player, string.IsNullOrEmpty(targetName) ? string.Format(msg("spectreConfirmed", player.UserIDString), position) : string.Format(msg("spectrePlayer", player.UserIDString), targetName));
                break;
                default : return;
            }
        }
        private void PrepareRandomStrikes() {
            if (configData.Other.RandomStrikes.Count == 0) return;
            foreach (var type in configData.Other.RandomStrikes) availableTypes.Add(ParseType<StrikeType>(type));
            CallRandomStrike();
        }
        private void CallRandomStrike() {
            timer.In(UnityEngine.Random.Range(configData.Other.RandomTimer[0], configData.Other.RandomTimer[1]), () => {
                StrikeType type = availableTypes.GetRandom();
                Vector3 position = GetRandomPosition();
                if (!string.IsNullOrEmpty(configData.Other.RandomStrikeLocations) && Spawns) {
                    object success = Spawns.Call("GetRandomSpawn", configData.Other.RandomStrikeLocations);
                    if (success is string) PrintError($"Unable to retrieve a position from the designated spawnfile.Error: {(string)success}");
                    else position = (Vector3)success;
                }
                switch (type) {
                    case StrikeType.Strike : CallStrike(position, string.Empty);
                    break;
                    case StrikeType.Squad : CallSquad(position, string.Empty);
                    break;
                    case StrikeType.Napalm : CallNapalm(position, string.Empty);
                    break;
                    case StrikeType.Nuke : CallNuke(position, string.Empty);
                    break;
                    case StrikeType.Spectre : CallSpectre(position, string.Empty);
                    break;
                    default : break;
                }
                CallRandomStrike();
            }
            );
        }
        private void CallStrike(Vector3 position, string ownerName) {
            CargoPlane entity = CreatePlane();
            entity.Spawn();
            BasePlane plane = entity.gameObject.AddComponent<BasePlane>();
            plane.InitializeFlightPath(position, StrikeType.Strike);
            if (configData.Other.Broadcast) {
                if (configData.Other.BroadcastNames && !string.IsNullOrEmpty(ownerName)) PrintToChat(string.Format(msg("strikeInboundName"), ownerName));
                else PrintToChat(msg("strikeInbound"));
            }
        }
        private void CallSquad(Vector3 position, string ownerName) {
            CargoPlane leaderEnt = CreatePlane();
            leaderEnt.Spawn();
            BasePlane leaderPlane = leaderEnt.gameObject.AddComponent<BasePlane>();
            leaderPlane.InitializeFlightPath(position, StrikeType.Squad);
            Vector3 startPos;
            Vector3 endPos;
            float secondsToTake;
            leaderPlane.GetFlightData(out startPos, out endPos, out secondsToTake);
            CargoPlane leftEnt = CreatePlane();
            leftEnt.Spawn();
            BasePlane leftPlane = leftEnt.gameObject.AddComponent<BasePlane>();
            Vector3 leftOffset = (leaderEnt.transform.right * 70) + (-leaderEnt.transform.forward * 80);
            leftPlane.SetFlightData(startPos + leftOffset, endPos + leftOffset, position + (leftOffset / 4), secondsToTake);
            CargoPlane rightEnt = CreatePlane();
            rightEnt.Spawn();
            BasePlane rightPlane = rightEnt.gameObject.AddComponent<BasePlane>();
            Vector3 rightOffset = (-leaderEnt.transform.right * 70) + (-leaderEnt.transform.forward * 80);
            rightPlane.SetFlightData(startPos + rightOffset, endPos + rightOffset, position + (rightOffset / 4), secondsToTake);
            if (configData.Other.Broadcast) {
                if (configData.Other.BroadcastNames && !string.IsNullOrEmpty(ownerName)) PrintToChat(string.Format(msg("squadInboundName"), ownerName));
                else PrintToChat(msg("squadInbound"));
            }
        }
        private void CallNuke(Vector3 position, string ownerName) {
            CargoPlane entity = CreatePlane();
            entity.Spawn();
            NukePlane plane = entity.gameObject.AddComponent<NukePlane>();
            plane.InitializeFlightPath(position, StrikeType.Nuke);
            if (configData.Other.Broadcast) {
                if (configData.Other.BroadcastNames && !string.IsNullOrEmpty(ownerName)) PrintToChat(string.Format(msg("nukeInboundName"), ownerName));
                else PrintToChat(msg("nukeInbound"));
            }
        }
        private void CallNapalm(Vector3 position, string ownerName) {
            CargoPlane entity = CreatePlane();
            entity.Spawn();
            NapalmPlane plane = entity.gameObject.AddComponent<NapalmPlane>();
            plane.InitializeFlightPath(position, StrikeType.Napalm);
            if (configData.Other.Broadcast) {
                if (configData.Other.BroadcastNames && !string.IsNullOrEmpty(ownerName)) PrintToChat(string.Format(msg("napalmInboundName"), ownerName));
                else PrintToChat(msg("napalmInbound"));
            }
        }
        private void CallSpectre(Vector3 position, string ownerName) {
            CargoPlane entity = CreatePlane();
            entity.Spawn();
            SpectrePlane plane = entity.gameObject.AddComponent<SpectrePlane>();
            plane.InitializeFlightPath(position, StrikeType.Spectre);
            if (configData.Other.Broadcast) {
                if (configData.Other.BroadcastNames && !string.IsNullOrEmpty(ownerName)) PrintToChat(string.Format(msg("spectreInboundName"), ownerName));
                else PrintToChat(msg("spectreInbound"));
            }
        }
        private bool CanBuyStrike(BasePlayer player, StrikeType type) {
            Dictionary<string, int> costToBuy = null;
            switch (type) {
                case StrikeType.None : return false;
                case StrikeType.Strike : costToBuy = configData.Buy.StrikeCost;
                break;
                case StrikeType.Squad : costToBuy = configData.Buy.SquadCost;
                break;
                case StrikeType.Napalm : costToBuy = configData.Buy.NapalmCost;
                break;
                case StrikeType.Nuke : costToBuy = configData.Buy.NukeCost;
                break;
                case StrikeType.Spectre : costToBuy = configData.Buy.SpectreCost;
                break;
            }
            foreach (var item in costToBuy) {
                if (item.Key == "RP") {
                    if (ServerRewards) {
                        if ((int)ServerRewards.Call("CheckPoints", player.userID) < item.Value) {
                            SendReply(player, string.Format(msg("buyItem", player.UserIDString), item.Value, item.Key));
                            Effect.server.Run("assets/prefabs/locks/keypad/effects/lock.code.denied.prefab", player.transform.position);
                            return false;
                        }
                    }
                }
                if (item.Key == "Economics") {
                    if (Economics) {
                        if ((double)Economics.Call("Balance", player.userID) < item.Value) {
                            SendReply(player, string.Format(msg("buyItem", player.UserIDString), item.Value, item.Key));
                            Effect.server.Run("assets/prefabs/locks/keypad/effects/lock.code.denied.prefab", player.transform.position);
                            return false;
                        }
                    }
                }
                if (shortnameToId.ContainsKey(item.Key)) {
                    if (player.inventory.GetAmount(shortnameToId[item.Key]) < item.Value) {
                        SendReply(player, string.Format(msg("buyItem", player.UserIDString), item.Value, shortnameToDn[item.Key]));
                        Effect.server.Run("assets/prefabs/locks/keypad/effects/lock.code.denied.prefab", player.transform.position);
                        return false;
                    }
                }
            }
            Effect.server.Run("assets/prefabs/locks/keypad/effects/lock.code.updated.prefab", player.transform.position);
            return true;
        }
        private void BuyStrike(BasePlayer player, StrikeType type, Vector3 targetPosition, string targetName = "") {
            Dictionary<string, int> costToBuy = null;
            switch (type) {
                case StrikeType.None : return;
                case StrikeType.Strike : costToBuy = configData.Buy.StrikeCost;
                break;
                case StrikeType.Squad : costToBuy = configData.Buy.SquadCost;
                break;
                case StrikeType.Napalm : costToBuy = configData.Buy.NapalmCost;
                break;
                case StrikeType.Nuke : costToBuy = configData.Buy.NukeCost;
                break;
                case StrikeType.Spectre : costToBuy = configData.Buy.SpectreCost;
                break;
            }
            foreach (var item in costToBuy) {
                if (item.Key == "RP") {
                    if (ServerRewards) ServerRewards.Call("TakePoints", player.userID, item.Value);
                }
                if (item.Key == "Economics") {
                    if (Economics) Economics.Call("Withdraw", player.userID, (double)item.Value);
                }
                if (shortnameToId.ContainsKey(item.Key)) player.inventory.Take(null, shortnameToId[item.Key], item.Value);
            }
            SendStrike(player, type, targetPosition, targetName);
        }
#endregion
#region NoEscape
        private bool CanCallStrike(BasePlayer player) {
            if (player.IsAdmin) return true;
            if (NoEscape) {
                if (configData.Other.FromRB) {
                    bool success = NoEscape.Call<bool>("IsRaidBlocked", player);
                    if (success) {
                        SendReply(player, msg("playerRaidBlocked", player.UserIDString));
                        return false;
                    }
                }
                if (configData.Other.FromCB) {
                    bool success = NoEscape.Call<bool>("IsCombatBlocked", player);
                    if (success) {
                        SendReply(player, msg("playerCombatBlocked", player.UserIDString));
                        return false;
                    }
                }
            }
            return true;
        }
        private bool CanStrikeTarget(BasePlayer player, BasePlayer target) {
            if (player.IsAdmin) return true;
            if (NoEscape) {
                if (configData.Other.AgainstRB) {
                    bool success = NoEscape.Call<bool>("IsRaidBlocked", target);
                    if (success) {
                        SendReply(player, msg("targetRaidBlocked", player.UserIDString));
                        return false;
                    }
                }
                if (configData.Other.AgainstCB) {
                    bool success = NoEscape.Call<bool>("IsCombatBlocked", target);
                    if (success) {
                        SendReply(player, msg("targetCombatBlocked", player.UserIDString));
                        return false;
                    }
                }
            }
            return true;
        }
#endregion
#region Helpers
        private double GrabCurrentTime() => DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1, 0, 0, 0)).TotalSeconds;
        private CargoPlane CreatePlane() => (CargoPlane)GameManager.server.CreateEntity(cargoPlanePrefab, new Vector3(), new Quaternion(), true);
        private bool isStrikePlane(CargoPlane plane) => plane.GetComponent<BasePlane>();
        private bool isStrikeSignal(BaseEntity entity) => strikeSignals.Contains(entity);
        private bool HasPermission(BasePlayer player, string perm) => permission.UserHasPermission(player.UserIDString, perm);
        private Vector3 GetRandomPosition() {
            float mapSize = (TerrainMeta.Size.x / 2) - 600f;
            float randomX = UnityEngine.Random.Range(-mapSize, mapSize);
            float randomY = UnityEngine.Random.Range(-mapSize, mapSize);
            return new Vector3(randomX, 0f, randomY);
        }
        private string FormatTime(double time) {
            TimeSpan dateDifference = TimeSpan.FromSeconds((float)time);
            var days = dateDifference.Days;
            var hours = dateDifference.Hours;
            hours += (days * 24);
            var mins = dateDifference.Minutes;
            var secs = dateDifference.Seconds;
            return string.Format("{0:00}:{1:00}:{2:00}", hours, mins, secs);
        }
        private void AddCooldownData(BasePlayer player, StrikeType type) {
            if (!configData.Cooldown.Enabled) return;
            if (!storedData.cooldowns.ContainsKey(player.userID)) storedData.cooldowns.Add(player.userID, new CooldownData());
            if (configData.Cooldown.Combine) storedData.cooldowns[player.userID].globalCd = GrabCurrentTime() + configData.Cooldown.Time;
            else {
                switch (type) {
                    case StrikeType.None : return;
                    case StrikeType.Strike : storedData.cooldowns[player.userID].strikeCd = GrabCurrentTime() + configData.Cooldown.Times[type.ToString()];
                    return;
                    case StrikeType.Squad : storedData.cooldowns[player.userID].squadCd = GrabCurrentTime() + configData.Cooldown.Times[type.ToString()];
                    return;
                    case StrikeType.Napalm : storedData.cooldowns[player.userID].napalmCd = GrabCurrentTime() + configData.Cooldown.Times[type.ToString()];
                    return;
                    case StrikeType.Nuke : storedData.cooldowns[player.userID].nukeCd = GrabCurrentTime() + configData.Cooldown.Times[type.ToString()];
                    return;
                    case StrikeType.Spectre : storedData.cooldowns[player.userID].spectreCd = GrabCurrentTime() + configData.Cooldown.Times[type.ToString()];
                    return;
                }
            }
        }
        private List<BasePlayer> FindPlayer(string arg) {
            List<BasePlayer> foundPlayers = new List<BasePlayer>();
            ulong steamid;
            ulong.TryParse(arg, out steamid);
            foreach (BasePlayer player in BasePlayer.activePlayerList) {
                if (steamid != 0L) {
                    if (player.userID == steamid) {
                        fou
// ... [Code preview truncated due to length. Full source in attached file] ...

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

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

Сверху