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

FREE TankCommander : 0.1.5 0.1.5

Нет прав для скачивания
C#:
// Все права принадлежат дискорд сообществу https://discord.gg/VgNHPpNrz6
using System;
using System.Collections.Generic;
using UnityEngine;
using System.Reflection;
using System.Linq;
using System.Globalization;
using Rust;
using Facepunch;
using Newtonsoft.Json;
using Oxide.Core;
using Oxide.Core.Configuration;
using Oxide.Core.Plugins;
using Oxide.Game.Rust.Cui;
namespace Oxide.Plugins {
    [Info("TankCommander", "k1lly0u", "0.1.5", ResourceId = 2560)]
    class TankCommander : RustPlugin {
#region Fields
        [PluginReference]
        Plugin Friends, Clans, Godmode;
        RestoreData restoreData;
        private DynamicConfigFile restorationdata;
        static TankCommander ins;
        private FieldInfo spectateFilter = typeof(BasePlayer).GetField("spectateFilter", (BindingFlags.Instance | BindingFlags.NonPublic));
        private static FieldInfo meshLookupField = typeof(MeshColliderBatch).GetField("meshLookup", BindingFlags.Instance | BindingFlags.NonPublic);
        private List<Controller> controllers = new List<Controller>();
        private List<ulong> passengers = new List<ulong>();
        private Dictionary<ulong, Controller> commanders = new Dictionary<ulong, Controller>();
        private Dictionary<string, string> itemNames = new Dictionary<string, string>();
        private Dictionary<CommandType, BUTTON> controlButtons;
        private bool initialized;
        private int rocketId;
        private int mgId;
        const string tankPrefab = "assets/prefabs/npc/m2bradley/bradleyapc.prefab";
        const string uiHealth = "TCUI_Health";
        const string uiAmmoMg = "TCUI_Ammo_MG";
        const string uiAmmoRocket = "TCUI_Ammo_Rocket";
#endregion
#region Oxide Hooks
        void Loaded() {
            lang.RegisterMessages(Messages, this);
            permission.RegisterPermission("tankcommander.admin", this);
            permission.RegisterPermission("tankcommander.use", this);
            restorationdata = Interface.Oxide.DataFileSystem.GetFile("tankcommander_data");
        }
        void OnServerInitialized() {
            ins = this;
            LoadVariables();
            LoadData();
            ConvertControlButtons();
            itemNames = ItemManager.itemList.ToDictionary(x => x.shortname, y => y.displayName.english);
            rocketId = ItemManager.itemList.Find(x => x.shortname == configData.Weapons.Cannon.Type)?.itemid ?? 0;
            mgId = ItemManager.itemList.Find(x => x.shortname == configData.Weapons.MG.Type)?.itemid ?? 0;
            initialized = true;
        }
        void OnEntityTakeDamage(BaseCombatEntity entity, HitInfo info) {
            if (entity is BradleyAPC) {
                Controller controller = entity.GetComponent<Controller>();
                if (controller != null) controller.ManageDamage(info);
            }
            if (entity is BasePlayer) {
                if (commanders.ContainsKey((entity as BasePlayer).userID) || passengers.Contains((entity as BasePlayer).userID)) {
                    info.damageTypes = new DamageTypeList();
                    info.HitEntity = null;
                    info.HitMaterial = 0;
                    info.PointStart = Vector3.zero;
                    return;
                }
                if (info.Initiator is BradleyAPC) {
                    Controller controller = (info.Initiator as BradleyAPC).GetComponent<Controller>();
                    if (controller != null) {
                        if (!controller.HasCommander()) {
                            info.damageTypes = new DamageTypeList();
                            info.HitEntity = null;
                            info.HitMaterial = 0;
                            info.PointStart = Vector3.zero;
                        }
                    }
                }
            }
        }
        void OnPlayerInput(BasePlayer player, InputState input) {
            if (!initialized || player == null || commanders.ContainsKey(player.userID) || passengers.Contains(player.userID) || !HasPermission(player, "tankcommander.use")) return;
            if (configData.Inventory.Enabled && input.WasJustPressed(controlButtons[CommandType.Inventory])) {
                RaycastHit hit;
                if (Physics.SphereCast(player.eyes.position, 0.5f, Quaternion.Euler(player.serverInput.current.aimAngles) * Vector3.forward, out hit, 3f)) {
                    Controller controller = hit.GetEntity()?.GetComponent<Controller>();
                    if (controller != null && !controller.HasCommander()) OpenTankInventory(player, controller);
                }
                return;
            }
            if (input.WasJustPressed(controlButtons[CommandType.EnterExit])) {
                RaycastHit hit;
                if (Physics.SphereCast(player.eyes.position, 0.5f, Quaternion.Euler(player.serverInput.current.aimAngles) * Vector3.forward, out hit, 3f)) {
                    Controller controller = hit.GetEntity()?.GetComponent<Controller>();
                    if (controller != null) {
                        if (player.IsFlying) {
                            SendReply(player, msg("is_flying", player.UserIDString));
                            return;
                        }
                        if (!controller.HasCommander()) {
                            commanders.Add(player.userID, controller);
                            controller.EnterTank(player);
                        }
                        else {
                            if (configData.Passengers.Enabled) {
                                BasePlayer commander = controller.GetCommander();
                                if (!configData.Passengers.UseFriends && !configData.Passengers.UseClans) {
                                    controller.PassengerEnter(player);
                                    return;
                                }
                                if (configData.Passengers.UseFriends && AreFriends(commander.userID, player.userID)) {
                                    controller.PassengerEnter(player);
                                    return;
                                }
                                if (configData.Passengers.UseClans && IsClanmate(commander.userID, player.userID)) {
                                    controller.PassengerEnter(player);
                                    return;
                                }
                                SendReply(player, msg("not_friend", player.UserIDString));
                            }
                            else SendReply(player, msg("in_use", player.UserIDString));
                        }
                    }
                }
            }
        }
        void OnPlayerDisconnected(BasePlayer player) {
            if (commanders.ContainsKey(player.userID)) commanders[player.userID].ExitTank();
        }
        object OnRunPlayerMetabolism(PlayerMetabolism metabolism, BaseCombatEntity entity) {
            var player = entity.ToPlayer();
            if (player == null || !commanders.ContainsKey(player.userID)) return null;
            if (Godmode && (bool)Godmode.Call("IsGod", player.UserIDString)) return null;
            return true;
        }
        void Unload() {
            foreach (var controller in controllers) UnityEngine.Object.Destroy(controller);
            var objects = UnityEngine.Object.FindObjectsOfType<Controller>();
            if (objects != null) {
                foreach(var obj in objects) UnityEngine.Object.Destroy(obj);
            }
            controllers.Clear();
        }
#endregion
#region Functions
        private T ParseType<T>(string type) => (T)Enum.Parse(typeof(T), type, true);
        private bool HasPermission(BasePlayer player, string perm) => permission.UserHasPermission(player.UserIDString, perm) || permission.UserHasPermission(player.UserIDString, "tankcommander.admin");
        private void ConvertControlButtons() {
            controlButtons = new Dictionary<CommandType, BUTTON> {
                [CommandType.EnterExit]
                = ParseType<BUTTON>(configData.Buttons.Enter), [CommandType.Lights] = ParseType<BUTTON>(configData.Buttons.Lights), [CommandType.Inventory] = ParseType<BUTTON>(configData.Buttons.Inventory), [CommandType.Boost] = ParseType<BUTTON>(configData.Buttons.Boost), [CommandType.Cannon] = ParseType<BUTTON>(configData.Buttons.Cannon), [CommandType.Coax] = ParseType<BUTTON>(configData.Buttons.Coax), [CommandType.MG] = ParseType<BUTTON>(configData.Buttons.MG)
            }
            ;
        }
        void OpenTankInventory(BasePlayer player, Controller controller) {
            player.inventory.loot.Clear();
            player.inventory.loot.entitySource = controller.entity;
            player.inventory.loot.itemSource = null;
            player.inventory.loot.AddContainer(controller.inventory);
            player.inventory.loot.SendImmediate();
            player.ClientRPCPlayer(null, player, "RPC_OpenLootPanel", "generic");
            player.SendNetworkUpdate();
        }
        private void StartSpectating(BasePlayer player, Controller controller, bool isOperator) {
            spectateFilter.SetValue(player, $"@123nofilter123");
            player.SetPlayerFlag(BasePlayer.PlayerFlags.Spectating, true);
            player.SetPlayerFlag(BasePlayer.PlayerFlags.ThirdPersonViewmode, true);
            player.gameObject.SetLayerRecursive(10);
            player.CancelInvoke("InventoryUpdate");
            player.SendNetworkUpdateImmediate();
            timer.In(0.5f, () => {
                player.transform.position = controller.transform.position;
                player.SetParent(controller.entity, 0);
                player.Command("client.camoffset", new object[] {
                    new Vector3(0, 3.5f, 0)
                }
                );
                if (isOperator) {
                    controller.enabled = true;
                    string ctrlStr = msg("controls", player.UserIDString);
                    if (configData.Weapons.Cannon.Enabled) ctrlStr += $"\n{string.Format(msg("fire_cannon", player.UserIDString), configData.Buttons.Cannon)}";
                    if (configData.Weapons.Coax.Enabled) ctrlStr += $"\n{string.Format(msg("fire_coax", player.UserIDString), configData.Buttons.Coax)}";
                    if (configData.Weapons.MG.Enabled) ctrlStr += $"\n{string.Format(msg("fire_mg", player.UserIDString), configData.Buttons.MG)}";
                    ctrlStr += $"\n{string.Format(msg("speed_boost", player.UserIDString), configData.Buttons.Boost)}";
                    ctrlStr += $"\n{string.Format(msg("enter_exit", player.UserIDString), configData.Buttons.Enter)}";
                    ctrlStr += $"\n{string.Format(msg("toggle_lights", player.UserIDString), configData.Buttons.Lights)}";
                    if (configData.Inventory.Enabled) ctrlStr += $"\n{string.Format(msg("access_inventory", player.UserIDString), configData.Buttons.Inventory)}";
                    SendReply(player, ctrlStr);
                    CreateHealthUI(player, controller);
                    CreateMGAmmoUI(player, controller);
                    CreateRocketAmmoUI(player, controller);
                }
                else {
                    controller.SetPassengerActive(player);
                    SendReply(player, string.Format(msg("enter_exit", player.UserIDString), configData.Buttons.Enter));
                    if (configData.Inventory.Enabled) SendReply(player, string.Format(msg("access_inventory", player.UserIDString), configData.Buttons.Inventory));
                    CreateHealthUI(player, controller);
                }
            }
            );
        }
        private void EndSpectating(BasePlayer player, Controller commander, bool isOperator) {
            spectateFilter.SetValue(player, string.Empty);
            player.SetParent(null);
            player.SetPlayerFlag(BasePlayer.PlayerFlags.Spectating, false);
            player.SetPlayerFlag(BasePlayer.PlayerFlags.ThirdPersonViewmode, false);
            player.gameObject.SetLayerRecursive(17);
            player.InvokeRepeating("InventoryUpdate", 1f, 0.1f * UnityEngine.Random.Range(0.99f, 1.01f));
            player.Command("client.camoffset", new object[] {
                new Vector3(0, 1.2f, 0)
            }
            );
            player.transform.position = commander.transform.position + Vector3.up + (commander.transform.right * 3);
            if (isOperator) commanders.Remove(player.userID);
        }
#endregion
#region Component
        enum CommandType {
            EnterExit, Lights, Inventory, Boost, Cannon, Coax, MG
        }
        class Controller : MonoBehaviour {
            private BasePlayer player;
            public BradleyAPC entity;
            private Rigidbody rigidBody;
            private WheelCollider[] leftWheels;
            private WheelCollider[] rightWheels;
            public ItemContainer inventory;
            private float accelTimeTaken;
            private float accelTimeToTake = 3f;
            private float forwardTorque = 2000f;
            private float maxBrakeTorque = 50f;
            private float turnTorque = 2000f;
            private float lastFireCannon;
            private float lastFireMG;
            private float lastFireCoax;
            private Vector3 aimVector = Vector3.forward;
            private Vector3 aimVectorTop = Vector3.forward;
            private Dictionary<CommandType, BUTTON> controlButtons;
            private ConfigData.WeaponOptions.WeaponSystem cannon;
            private ConfigData.WeaponOptions.WeaponSystem mg;
            private ConfigData.WeaponOptions.WeaponSystem coax;
            private ConfigData.CrushableTypes crushables;
            private List<ulong> enteringPassengers = new List<ulong>();
            private List<BasePlayer> passengers = new List<BasePlayer>();
            private void Awake() {
                entity = GetComponent<BradleyAPC>();
                entity.enabled = false;
                enabled = false;
                entity.CancelInvoke(entity.UpdateTargetList);
                entity.CancelInvoke(entity.UpdateTargetVisibilities);
                rigidBody = entity.myRigidBody;
                leftWheels = entity.leftWheels;
                rightWheels = entity.rightWheels;
                forwardTorque = ins.configData.Movement.ForwardTorque;
                turnTorque = ins.configData.Movement.TurnTorque;
                maxBrakeTorque = ins.configData.Movement.BrakeTorque;
                accelTimeToTake = ins.configData.Movement.Acceleration;
                controlButtons = ins.controlButtons;
                cannon = ins.configData.Weapons.Cannon;
                mg = ins.configData.Weapons.MG;
                coax = ins.configData.Weapons.Coax;
                crushables = ins.configData.Crushables;
                if (ins.configData.Inventory.Enabled) {
                    inventory = new ItemContainer();
                    inventory.ServerInitialize(null, ins.configData.Inventory.Size);
                    if ((int)inventory.uid == 0) inventory.GiveUID();
                }
            }
            private void OnDestroy() {
                if (player != null) ExitTank();
                if (entity != null && !entity.IsDestroyed) entity.Kill();
            }
            private void FixedUpdate() {
                CheckOtherInput();
            }
            private void LateUpdate() {
                CheckForMovement();
                AdjustAiming();
                entity.SendNetworkUpdate();
            }
            private void OnCollisionEnter(Collision collision) {
                if (!HasCommander()) return;
                GameObject gObject = collision.gameObject;
                if (gObject == null) return;
                if (crushables.Players) {
                    var triggerPlayer = gObject.GetComponentInParent<BasePlayer>();
                    if (triggerPlayer != null && triggerPlayer != player && !passengers.Contains(triggerPlayer) && !enteringPassengers.Contains(triggerPlayer.userID)) {
                        triggerPlayer.Die(new HitInfo(player, triggerPlayer, DamageType.Blunt, 200f));
                        return;
                    }
                }
                if (crushables.Animals) {
                    var npc = gObject.GetComponentInParent<BaseNpc>();
                    if (npc != null) {
                        npc.Die(new HitInfo(player, npc, DamageType.Blunt, 200f));
                        return;
                    }
                }
                float impactForce = CalculateImpactForce(collision);
                if (crushables.Buildings) {
                    var buildingBlock = gObject.GetComponentInParent<BuildingBlock>();
                    if (buildingBlock != null && impactForce >= crushables.GradeForce[buildingBlock.grade.ToString()]) {
                        buildingBlock.Die(new HitInfo(player, buildingBlock, DamageType.Blunt, 1000f));
                        return;
                    }
                    var colliderBatch = gObject.GetComponent<MeshColliderBatch>();
                    if (colliderBatch != null) {
                        var colliders = ((MeshColliderLookup)meshLookupField.GetValue(colliderBatch)).src.data;
                        if (colliders == null) return;
                        foreach (var instance in colliders) {
                            var block = instance.collider?.GetComponentInParent<BuildingBlock>();
                            if (block != null && Vector3.Distance(block.transform.position, entity.transform.position) < 4 && impactForce >= crushables.GradeForce[block.grade.ToString()]) {
                                block.Die(new HitInfo(player, block, DamageType.Blunt, 1000f));
                                return;
                            }
                        }
                        return;
                    }
                    var simpleBlock = gObject.GetComponentInParent<SimpleBuildingBlock>();
                    if (simpleBlock != null && impactForce >= crushables.WallForce) {
                        simpleBlock.Die(new HitInfo(player, simpleBlock, DamageType.Blunt, 1500));
                        return;
                    }
                }
                if (crushables.Loot) {
                    var loot = gObject.GetComponentInParent<LootContainer>();
                    if (loot != null) {
                        loot.Die(new HitInfo(player, loot, DamageType.Blunt, 200f));
                        return;
                    }
                }
                if (crushables.Resources) {
                    var resource = gObject.GetComponentInParent<ResourceEntity>();
                    if (resource != null && impactForce >= crushables.ResourceForce) {
                        resource.Kill(BaseNetworkable.DestroyMode.None);
                        return;
                    }
                }
            }
            private float CalculateImpactForce(Collision col) {
                var impactVelocityX = rigidBody.velocity.x;
                impactVelocityX *= Mathf.Sign(impactVelocityX);
                var impactVelocityY = rigidBody.velocity.y;
                impactVelocityY *= Mathf.Sign(impactVelocityY);
                var impactVelocity = impactVelocityX + impactVelocityY;
                var impactForce = impactVelocity * rigidBody.mass;
                impactForce *= Mathf.Sign(impactForce);
                return impactForce;
            }
            private void CheckOtherInput() {
                for (int i = 0; i < passengers.Count; i++) {
                    var passenger = passengers[i];
                    if (passenger.serverInput.WasJustPressed(controlButtons[CommandType.EnterExit])) PassengerExit(passenger);
                }
                if (player.serverInput.WasJustPressed(controlButtons[CommandType.EnterExit])) {
                    ExitTank();
                    return;
                }
                if (player.serverInput.WasJustPressed(controlButtons[CommandType.Lights])) ToggleLights();
                if (player.serverInput.WasJustPressed(controlButtons[CommandType.Cannon])) FireCannon();
                if (player.serverInput.IsDown(controlButtons[CommandType.MG]) || player.serverInput.WasJustPressed(controlButtons[CommandType.MG])) FireMG();
                if (player.serverInput.IsDown(controlButtons[CommandType.Coax]) || player.serverInput.WasJustPressed(controlButtons[CommandType.Coax])) FireCoax();
            }
            private void CheckForMovement() {
                float accelerate = 0f;
                float steer = 0f;
                if (player.serverInput.IsDown(BUTTON.FORWARD)) accelerate += 1f;
                if (player.serverInput.IsDown(BUTTON.BACKWARD)) accelerate -= 1f;
                if (player.serverInput.IsDown(BUTTON.RIGHT)) steer += 1f;
                if (player.serverInput.IsDown(BUTTON.LEFT)) steer -= 1f;
                bool boost = player.serverInput.IsDown(controlButtons[CommandType.Boost]);
                SetThrottleSpeed(accelerate, steer, boost);
            }
            private void AdjustAiming() {
                Vector3 aimAngle = player.serverInput.current.aimAngles;
                float adjustedY = aimAngle.y + entity.transform.rotation.eulerAngles.y;
                Vector3 targetPos = new Ray(entity.CannonMuzzle.transform.position, Quaternion.Euler(new Vector3(aimAngle.x, adjustedY, 0)) * Vector3.forward).GetPoint(10);
                Vector3 desiredAim = targetPos - (entity.transform.position + (Vector3.up * 2));
                aimVector = Vector3.Lerp(aimVector, desiredAim, Time.deltaTime * 5f);
                entity.turretAimVector = aimVector;
                AimCannon();
                AimMG();
            }
            private void AimCannon() {
                entity.AimWeaponAt(entity.mainTurret, entity.coaxPitch, aimVector, -90f, 90f, 360f, null);
                entity.AimWeaponAt(entity.mainTurret, entity.CannonPitch, aimVector, -90f, 7f, 360f, null);
            }
            private void AimMG() {
                Vector3 aimAngle = player.serverInput.current.aimAngles;
                float adjustedY = aimAngle.y + entity.transform.rotation.eulerAngles.y;
                RaycastHit hit;
                if (Physics.Raycast(new Ray(entity.topTurretMuzzle.transform.position, Quaternion.Euler(new Vector3(aimAngle.x, adjustedY, 0)) * Vector3.forward), out hit, 500f)) {
                    Vector3 desiredAim = hit.point - (entity.topTurretMuzzle.transform.position + (Vector3.up * 2));
                    aimVectorTop = Vector3.Lerp(aimVectorTop, desiredAim, Time.deltaTime * 5f);
                    entity.topTurretAimVector = aimVector;
                    entity.AimWeaponAt(entity.topTurretYaw, entity.topTurretPitch, aimVectorTop, -360f, 360f, 360f, entity.mainTurret);
                }
            }
            private void FireCannon() {
                if (cannon.RequireAmmo) {
                    if (inventory.itemList.Find(x => x.info.shortname == cannon.Type) == null) {
                        if (ins.itemNames.ContainsKey(cannon.Type)) ins.SendReply(player, string.Format(ins.msg("no_ammo_cannon", player.UserIDString), ins.itemNames[cannon.Type]));
                        else print($"Invalid ammo type for the cannon set in config: {cannon.Type}");
                        return;
                    }
                }
                if (Time.realtimeSinceStartup >= lastFireCannon) {
                    Vector3 modifiedAimConeDirection = AimConeUtil.GetModifiedAimConeDirection(cannon.Accuracy, entity.CannonMuzzle.rotation * Vector3.forward, true);
                    Vector3 cannonPitch = (entity.CannonPitch.transform.rotation * Vector3.back) + (base.transform.up * -1f);
                    Vector3 vector3 = cannonPitch.normalized;
                    entity.myRigidBody.AddForceAtPosition(vector3 * entity.recoilScale, entity.CannonPitch.transform.position, ForceMode.Impulse);
                    Effect.server.Run(entity.mainCannonMuzzleFlash.resourcePath, entity, StringPool.Get(entity.CannonMuzzle.gameObject.name), Vector3.zero, Vector3.zero, null, false);
                    BaseEntity rocket = GameManager.server.CreateEntity(entity.mainCannonProjectile.resourcePath, entity.CannonMuzzle.transform.position, Quaternion.LookRotation(modifiedAimConeDirection), true);
                    rocket.SendMessage("InitializeVelocity", modifiedAimConeDirection);
                    rocket.Spawn();
                    TimedExplosive projectile = rocket.GetComponent<TimedExplosive>();
                    if (projectile != null) projectile.damageTypes.Add(new DamageTypeEntry {
                        amount = cannon.Damage, type = DamageType.Explosion
                    }
                    );
                    lastFireCannon = Time.realtimeSinceStartup + cannon.Interval;
                    if (cannon.RequireAmmo) inventory.itemList.Find(x => x.info.shortname == cannon.Type)?.UseItem(1);
                    ins.CreateRocketAmmoUI(player, this);
                }
            }
            private void FireCoax() {
                if (coax.RequireAmmo) {
                    if (inventory.itemList.Find(x => x.info.shortname == coax.Type) == null) {
                        if (ins.itemNames.ContainsKey(coax.Type)) ins.SendReply(player, string.Format(ins.msg("no_ammo_coax", player.UserIDString), ins.itemNames[coax.Type]));
                        else print($"Invalid ammo type for the coaxial gun set in config: {coax.Type}");
                        return;
                    }
                }
                if (Time.realtimeSinceStartup >= lastFireCoax) {
                    Transform transforms = entity.coaxMuzzle;
                    Vector3 vector3 = transforms.transform.position - (transforms.forward * 0.25f);
                    Vector3 vector31 = transforms.transform.forward;
                    Vector3 modifiedAimConeDirection = AimConeUtil.GetModifiedAimConeDirection(coax.Accuracy, vector31, true);
                    Vector3 targetPos = vector3 + (modifiedAimConeDirection * 300f);
                    List<RaycastHit> list = Pool.GetList<RaycastHit>();
                    GamePhysics.TraceAll(new Ray(vector3, modifiedAimConeDirection), 0f, list, 300f, 1084435201, QueryTriggerInteraction.UseGlobal);
                    for (int i = 0; i < list.Count; i++) {
                        RaycastHit item = list[i];
                        BaseEntity entity = item.GetEntity();
                        if (!(entity != null) || !(entity == this) && !entity.EqualNetID(entity)) {
                            BaseCombatEntity baseCombatEntity = entity as BaseCombatEntity;
                            if (baseCombatEntity != null) ApplyDamage(baseCombatEntity, coax.Damage, item.point, modifiedAimConeDirection);
                            if (!(entity != null) || entity.ShouldBlockProjectiles()) {
                                targetPos = item.point;
                                break;
                            }
                        }
                    }
                    entity.ClientRPC(null, "CLIENT_FireGun", true, targetPos);
                    Pool.FreeList<RaycastHit>(ref list);
                    lastFireCoax = Time.realtimeSinceStartup + coax.Interval;
                    if (coax.RequireAmmo) inventory.itemList.Find(x => x.info.shortname == coax.Type)?.UseItem(1);
                    ins.CreateMGAmmoUI(player, this);
                }
            }
            private void FireMG() {
                if (mg.RequireAmmo) {
                    if (inventory.itemList.Find(x => x.info.shortname == mg.Type) == null) {
                        if (ins.itemNames.ContainsKey(mg.Type)) ins.SendReply(player, string.Format(ins.msg("no_ammo_mg", player.UserIDString), ins.itemNames[mg.Type]));
                        else print($"Invalid ammo type for the machine gun set in config: {mg.Type}");
                        return;
                    }
                }
                if (Time.realtimeSinceStartup >= lastFireMG) {
                    Transform transforms = (entity.topTurretMuzzle);
                    Vector3 vector3 = transforms.transform.position - (transforms.forward * 0.25f);
                    Vector3 vector31 = transforms.transform.forward;
                    Vector3 modifiedAimConeDirection = AimConeUtil.GetModifiedAimConeDirection(mg.Accuracy, vector31, true);
                    Vector3 targetPos = vector3 + (modifiedAimConeDirection * 300f);
                    List<RaycastHit> list = Pool.GetList<RaycastHit>();
                    GamePhysics.TraceAll(new Ray(vector3, modifiedAimConeDirection), 0f, list, 300f, 1084435201, QueryTriggerInteraction.UseGlobal);
                    for (int i = 0; i < list.Count; i++) {
                        RaycastHit item = list[i];
                        BaseEntity entity = item.GetEntity();
                        if (!(entity != null) || !(entity == this) && !entity.EqualNetID(entity)) {
                            BaseCombatEntity baseCombatEntity = entity as BaseCombatEntity;
                            if (baseCombatEntity != null) ApplyDamage(baseCombatEntity, mg.Damage, item.point, modifiedAimConeDirection);
                            if (!(entity != null) || entity.ShouldBlockProjectiles()) {
                                targetPos = item.point;
                                break;
                            }
                        }
                    }
                    entity.ClientRPC(null, "CLIENT_FireGun", false, targetPos);
                    Pool.FreeList<RaycastHit>(ref list);
                    lastFireMG = Time.realtimeSinceStartup + mg.Interval;
                    if (mg.RequireAmmo) inventory.itemList.Find(x => x.info.shortname == mg.Type)?.UseItem(1);
                    ins.CreateMGAmmoUI(player, this);
                }
            }
            private void FireSideGuns() {
            }
            private void ApplyDamage(BaseCombatEntity entity, float damage, Vector3 point, Vector3 normal) {
                float single = damage * UnityEngine.Random.Range(0.9f, 1.1f);
                entity.OnAttacked(new HitInfo(this.entity, entity, DamageType.Bullet, single, point));
                if (entity is BasePlayer || entity is BaseNpc) {
                    HitInfo hitInfo = new HitInfo() {
                        HitPositionWorld = point, HitNormalWorld = -normal, HitMaterial = StringPool.Get("Flesh")
                    }
                    ;
                    Effect.server.ImpactEffect(hitInfo);
                }
            }
            private void SetThrottleSpeed(float acceleration, float steering, bool boost) {
                if (acceleration == 0 && steering == 0) {
                    ApplyBrakes(0.5f);
                    if (accelTimeTaken > 0) accelTimeTaken = Mathf.Clamp(accelTimeTaken -= (Time.deltaTime * 2), 0, accelTimeToTake);
                }
                else {
                    ApplyBrakes(0f);
                    accelTimeTaken += Time.deltaTime;
                    float engineRpm = Mathf.InverseLerp(0f, accelTimeToTake, accelTimeTaken);
                    float throttle = Mathf.InverseLerp(0f, 1f, engineRpm);
                    float leftTrack = 0;
                    float rightTrack = 0;
                    float torque = 0;
                    if (acceleration > 0) {
                        torque = forwardTorque;
                        leftTrack = 1f;
                        rightTrack = 1f;
                    }
                    else if (acceleration < 0) {
                        torque = forwardTorque;
                        leftTrack = -1f;
                        rightTrack = -1f;
                    }
                    if (steering > 0) {
                        if (acceleration == 0) {
                            torque = turnTorque;
                            leftTrack = 1f;
                            rightTrack = -1f;
                        }
                        else {
                            torque = (forwardTorque + turnTorque) * 0.75f;
                            rightTrack *= 0.5f;
                        }
                    }
                    else if (steering < 0) {
                        if (acceleration == 0) {
                            torque = turnTorque;
                            leftTrack = -1f;
                            rightTrack = 1f;
                        }
                        else {
                            torque = (forwardTorque + turnTorque) * 0.75f;
                            leftTrack *= 0.5f;
                        }
                    }
                    if (boost) {
                        if (torque > 0) torque += ins.configData.Movement.BoostTorque;
                        if (torque < 0) torque -= ins.configData.Movement.BoostTorque;
                    }
                    ApplyMotorTorque(Mathf.Clamp(leftTrack * throttle, -1f, 1f) * torque, false);
                    ApplyMotorTorque(Mathf.Clamp(rightTrack * throttle, -1f, 1f) * torque, true);
                }
            }
            private void ApplyBrakes(float amount) {
                amount = Mathf.Clamp(maxBrakeTorque * amount, 0, maxBrakeTorque);
                ApplyBrakeTorque(amount, true);
                ApplyBrakeTorque(amount, false);
            }
            private void ApplyBrakeTorque(float amount, bool rightSide) {
                WheelCollider[] wheelColliderArray = (!rightSide ? leftWheels : rightWheels);
                for (int i = 0; i < wheelColliderArray.Length; i++) wheelColliderArray[i].brakeTorque = maxBrakeTorque * amount;
            }
            private void ApplyMotorTorque(float torque, bool rightSide) {
                WheelCollider[] wheelColliderArray = (!rightSide ? leftWheels : rightWheels);
                for (int i = 0; i < wheelColliderArray.Length; i++) wheelColliderArray[i].motorTorque = torque;
            }
            public void EnterTank(BasePlayer player) {
                this.player = player;
                ins.restoreData.AddData(player);
                player.inventory.Strip();
                ins.StartSpectating(player, this, true);
            }
            public void ExitTank() {
                this.enabled = false;
                ApplyBrakes(1f);
                if (passengers.Count > 0) {
                    for (int i = 0; i < passengers.Count; i++) PassengerExit(passengers[i]);
                }
                ins.EndSpectating(player, this, true);
                ins.DestroyAllUI(player);
                print("");
                ins.restoreData.RestorePlayer(player);
                player = null;
            }
            public void PassengerEnter(BasePlayer passenger) {
                ins.restoreData.AddData(passenger);
                passenger.inventory.Strip();
                ins.passengers.Add(passenger.userID);
                enteringPassengers.Add(passenger.userID);
                ins.StartSpectating(passenger, this, false);
                ins.SendReply(player, ins.msg("passenger_enter", player.UserIDString));
            }
            private void PassengerExit(BasePlayer passenger) {
                ins.DestroyAllUI(passenger);
                ins.passengers.Remove(passenger.userID);
                passengers.Remove(passenger);
                ins.EndSpectating(passenger, this, false);
                ins.restoreData.RestorePlayer(player);
            }
            public void SetPassengerActive(BasePlayer passenger) {
                passengers.Add(passenger);
                if (enteringPassengers.Contains(passenger.userID)) enteringPassengers.Remove(passenger.userID);
            }
            public bool HasCommander() => player != null;
            public BasePlayer GetCommander() => player;
            public bool IsAtMaxCapacity() => passengers.Count >= ins.configData.Passengers.Max;
            private void ToggleLights() => entity.SetFlag(BaseEntity.Flags.Reserved5, !entity.HasFlag(BaseEntity.Flags.Reserved5), false);
            public void ManageDamage(HitInfo info) {
                if (info.damageTypes.Total() >= entity.health) {
                    info.damageTypes = new DamageTypeList();
                    info.HitEntity = null;
                    info.HitMaterial = 0;
                    info.PointStart = Vector3.zero;
                    OnDeath();
                }
                else {
                    ins.NextTick(() => {
                        ins.CreateHealthUI(player, this);
                        foreach (var passenger in passengers) ins.CreateHealthUI(passenger, this);
                    }
                    );
                }
            }
            private void OnDeath() {
                if (player != null) ExitTank();
                Effect.server.Run(entity.explosionEffect.resourcePath, entity.transform.position, Vector3.up, null, true);
                List<ServerGib> serverGibs = ServerGib.CreateGibs(entity.servergibs.resourcePath, entity.gameObject, entity.servergibs.Get().GetComponent<ServerGib>()._gibSource, Vector3.zero, 3f);
                for (int i = 0; i < 12 - entity.maxCratesToSpawn; i++) {
                    BaseEntity fireBall = GameManager.server.CreateEntity(entity.fireBall.resourcePath, entity.transform.position, entity.transform.rotation, true);
                    if (fireBall) {
                        Vector3 onSphere = UnityEngine.Random.onUnitSphere;
                        fireBall.transform.position = (entity.transform.position + new Vector3(0f, 1.5f, 0f)) + (onSphere * UnityEngine.Random.Range(-4f, 4f));
                        Collider collider = fireBall.GetComponent<Collider>();
                        fireBall.Spawn();
                        fireBall.SetVelocity(Vector3.zero + (onSphere * UnityEngine.Random.Range(3, 10)));
                        foreach (ServerGib serverGib in serverGibs) Physics.IgnoreCollision(collider, serverGib.GetCollider(), true);
                    }
                }
                if (ins.configData.Inventory.DropInv) {
                    inventory.Drop("assets/prefabs/misc/item drop/item_drop.prefab", (entity.transform.position + new Vector3(0f, 1.5f, 0f)) + (UnityEngine.Random.onUnitSphere * UnityEngine.Random.Range(2f, 3f)), new Quaternion());
                }
                if (ins.configData.Inventory.DropLoot) {
                    for (int j = 0; j < entity.maxCratesToSpawn; j++) {
                        Vector3 onSphere = UnityEngine.Random.onUnitSphere;
                        BaseEntity lootCrate = GameManager.server.CreateEntity(entity.crateToDrop.resourcePath, (entity.transform.position + new Vector3(0f, 1.5f, 0f)) + (onSphere * UnityEngine.Random.Range(2f, 3f)), Quaternion.LookRotation(onSphere), true);
                        lootCrate.Spawn();
                        LootContainer lootContainer = lootCrate as LootContainer;
                        if (lootContainer) lootContainer.Invoke(new Action(lootContainer.RemoveMe), 1800f);
                        Collider collider = lootCrate.GetComponent<Collider>();
                        Rigidbody rigidbody = lootCrate.gameObject.AddComponent<Rigidbody>();
                        rigidbody.useGravity = true;
                        rigidbody.collisionDetectionMode = CollisionDetectionMode.ContinuousDynamic;
                        rigidbody.mass = 2f;
                        rigidbody.interpolation = RigidbodyInterpolation.Interpolate;
                        rigidbody.velocity = Vector3.zero + (onSphere * UnityEngine.Random.Range(1f, 3f));
                        rigidbody.angularVelocity = Vector3Ex.Range(-1.75f, 1.75f);
                        rigidbody.drag = 0.5f * (rigidbody.mass / 5f);
                        rigidbody.angularDrag = 0.2f * (rigidbody.mass / 5f);
                        FireBall fireBall = GameManager.server.CreateEntity(entity.fireBall.resourcePath, lootCrate.transform.position, new Quaternion(), true) as FireBall;
                        if (fireBall) {
                            fireBall.transform.position = lootCrate.transform.position;
                            fireBall.Spawn();
                            fireBall.GetComponent<Rigidbody>().isKinematic = true;
                            fireBall.GetComponent<Collider>().enabled = false;
                            fireBall.transform.parent = lootCrate.transform;
                        }
                        lootCrate.SendMessage("SetLockingEnt", fireBall.gameObject, SendMessageOptions.DontRequireReceiver);
                        foreach (ServerGib serverGib1 in serverGibs) Physics.IgnoreCollision(collider, serverGib1.GetCollider(), true);
                    }
                }
                if (entity != null && !entity.IsDestroyed) entity.Kill(BaseNetworkable.DestroyMode.Gib);
            }
        }
#endregion
#region Commands
        [ChatCommand("spawntank")]
        void cmdTank(BasePlayer player, string command, string[] args) {
            if (!permission.UserHasPermission(player.UserIDString, "tankcommander.admin")) return;
            Vector3 position = player.transform.position + (player.transform.forward * 3) + Vector3.up;
            RaycastHit hit;
            if (Physics.SphereCast(player.eyes.position, 0.5f, Quaternion.Euler(player.serverInput.current.aimAngles) * Vector3.forward, out hit, 20f)) position = hit.point;
            BaseEntity entity = GameManager.server.CreateEntity(tankPrefab, position);
            entity.Spawn();
            Controller commander = entity.gameObject.AddComponent<Controller>();
        }
        [ConsoleCommand("spawntank")]
        void ccmdSpawnTank(ConsoleSystem.Arg arg) {
            if (arg.Connection != null || arg.Args == null) return;
            if (arg.Args.Length == 1) {
                BasePlayer player = covalence.Players.Connected.FirstOrDefault(x => x.Id == arg.GetString(0))?.Object as BasePlayer;
                if (player != null) {
                    Vector3 position = player.transform.position + (player.transform.forward * 3) + Vector3.up;
                    RaycastHit hit;
                    if (Physics.SphereCast(player.eyes.position, 0.5f, Quaternion.Euler(player.serverInput.current.aimAngles) * Vector3.forward, out hit, 20f)) position = hit.point;
                    BaseEntity entity = GameManager.server.CreateEntity(tankPrefab, position);
                    entity.Spawn();
                    Controller commander = entity.gameObject.AddComponent<Controller>();
                }
                return;
            }
            if (arg.Args.Length == 3) {
                float x;
                float y;
                float z;
                if (float.TryParse(arg.GetString(0), out x)) {
                    if (float.TryParse(arg.GetString(1), out y)) {
                        if (float.TryParse(arg.GetString(2), out z)) {
                            BaseEntity entity = GameManager.server.CreateEntity(tankPrefab, new Vector3(x, y, z));
                            entity.Spawn();
                            Controller commander = entity.gameObject.AddComponent<Controller>();
                            return;
                        }
                    }
                }
                PrintError($"Invalid arguments supplied to spawn a tank at position : (x = {arg.GetString(0)}, y = {arg.GetString(1)}, z = {arg.GetString(2)})");
            }
        }
#endregion
#region Friends
        private bool AreFriends(ulong playerId, ulong friendId) {
            if (Friends && configData.Passengers.UseFriends) return (bool)Friends?.Call("AreFriendsS", playerId.ToString(), friendId.ToString());
            return true;
        }
        private bool IsClanmate(ulong playerId, ulong friendId) {
            if (Clans && configData.Passengers.UseClans) {
                object playerTag = Clans?.Call("GetClanOf", playerId);
                object friendTag = Clans?.Call("GetClanOf", friendId);
                if (playerTag is string && friendTag is string) {
                    if (!string.IsNullOrEmpty((string)playerTag) && !string.IsNullOrEmpty((string)friendTag) && (playerTag == friendTag)) return true;
                }
                return false;
            }
            return true;
        }
#endregion
#region UI
#region UI Elements
        public static class UI {
            static public CuiElementContainer ElementContainer(string panelName, string color, UI4 dimensions, bool useCursor = false, string parent = "Overlay") {
                var NewElement = new CuiElementContainer() {
                    {
                        new CuiPanel {
                            Image = {
                                Color = color
                            }
                            , RectTransform = {
                                AnchorMin = dimensions.GetMin(), AnchorMax = dimensions.GetMax()
                            }
                            , CursorEnabled = useCursor
                        }
                        , new CuiElement().Parent = parent, panelName
                    }
                }
                ;
                return NewElement;
            }
            static public void Panel(ref CuiElementContainer container, string panel, string color, UI4 dimensions, bool cursor = false) {
                container.Add(new CuiPanel {
                    Image = {
                        Color = color
                    }
                    , RectTransform = {
                        AnchorMin = dimensions.GetMin(), AnchorMax = dimensions.GetMax()
                    }
                    , CursorEnabled = cursor
                }
                , panel);
            }
            static public void Label(ref CuiElementContainer container, string panel, string text, int size, UI4 dimensions, TextAnchor align = TextAnchor.MiddleCenter) {
                container.Add(new CuiLabel {
                    Text = {
                        FontSize = size, Align = align, Text = text, Font = "droidsansmono.ttf"
                    }
                    , RectTransform = {
                        AnchorMin = dimensions.GetMin(), AnchorMax = dimensions.GetMax()
                    }
                }
                , panel);
            }
            public static string Color(string hexColor, float alpha) {
                if (hexColor.StartsWith("#")) hexColor = hexColor.Substring(1);
                int red = int.Parse(hexColor.Substring(0, 2), NumberStyles.AllowHexSpecifier);
                int green = int.Parse(hexColor.Substring(2, 2), NumberStyles.AllowHexSpecifier);
                int blue = int.Parse(hexColor.Substring(4, 2), NumberStyles.AllowHexSpecifier);
                return $"{(double)red / 255} {(double)green / 255} {(double)blue / 255} {alpha}";
            }
        }
        public class UI4 {
            public float xMin, yMin, xMax, yMax;
            public UI4(float xMin, float yMin, float xMax, float yM
// ... [Code preview truncated due to length. Full source in attached file] ...

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