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

FREE CarCommander : 0.1.87 0.1.87

Нет прав для скачивания
C#:
// Все права принадлежат дискорд сообществу https://discord.gg/VgNHPpNrz6
using System;
using System.Collections.Generic;
using Newtonsoft.Json;
using Oxide.Core;
using Oxide.Core.Configuration;
using Oxide.Core.Plugins;
using Oxide.Game.Rust.Cui;
using UnityEngine;
using Rust;
using System.Linq;
using System.Globalization;
using System.Reflection;
namespace Oxide.Plugins {
    [Info("CarCommander", "k1lly0u", "0.1.87", ResourceId = 0)]
    //  Слив плагинов server-rust by Apolo YouGame
    class CarCommander : RustPlugin {
#region Fields
        [PluginReference]
        Plugin Clans, Friends, Spawns, RandomSpawns;
        RestoreData storedData;
        private DynamicConfigFile data;
        static CarCommander ins;
        private Dictionary<string, string> itemNames = new Dictionary<string, string>();
        private Dictionary<CommandType, BUTTON> controlButtons;
        private List<CarController> saveableCars = new List<CarController>();
        private bool initialized;
        private bool wipeData = false;
        private int fuelType;
        private int repairType;
        private string fuelTypeName;
        private string repairTypeName;
        const string carPrefab = "assets/content/vehicles/sedan_a/sedantest.entity.prefab";
        const string heliExplosion = "assets/prefabs/npc/patrol helicopter/effects/heli_explosion.prefab";
        const string uiHealth = "CCUI_Health";
        const string uiFuel = "CCUI_Fuelh";
#endregion
#region Oxide Hooks
        private void Loaded() {
            permission.RegisterPermission("carcommander.admin", this);
            permission.RegisterPermission("carcommander.use", this);
            permission.RegisterPermission("carcommander.canspawn", this);
            permission.RegisterPermission("carcommander.carspawn", this);
            lang.RegisterMessages(Messages, this);
            data = Interface.Oxide.DataFileSystem.GetFile("carcommander_data");
        }
        private void OnServerInitialized() {
            ins = this;
            LoadVariables();
            LoadData();
            ConvertControlButtons();
            fuelType = ItemManager.itemList.Find(x => x.shortname == configData.Fuel.FuelType)?.itemid ?? 0;
            repairType = ItemManager.itemList.Find(x => x.shortname == configData.Repair.Shortname)?.itemid ?? 0;
            fuelTypeName = ItemManager.itemList.Find(x => x.shortname == configData.Fuel.FuelType)?.displayName.english ?? "Invalid fuel shortname set in config!";
            repairTypeName = ItemManager.itemList.Find(x => x.shortname == configData.Repair.Shortname)?.displayName.english ?? "Invalid repair item shortname set in config!";
            initialized = true;
            if (wipeData) {
                PrintWarning("Map wipe detected! Wiping previous car data");
                storedData.restoreData.Clear();
                SaveData();
            }
            timer.In(3, RestoreVehicleInventories);
        }
        private void OnEntityTakeDamage(BaseCombatEntity entity, HitInfo info)  //  Слив плагинов server-rust by Apolo YouGame
        {
            if (entity == null || info == null) return;
            if (entity.GetComponent<CarController>()) {
                entity.GetComponent<CarController>().ManageDamage(info);
            }
            else if (entity.GetComponent<CarController.InvisibleMount>()) {
                info.damageTypes = new DamageTypeList();
                info.HitEntity = null;
                info.HitMaterial = 0;
                info.PointStart = Vector3.zero;
            }
        }
        private object OnEntityGroundMissing(BaseEntity entity) {
            if (entity.GetComponent<CarController>() || entity.GetComponent<CarController.InvisibleMount>()) return false;
            return null;
        }
        private void OnHammerHit(BasePlayer player, HitInfo info)  //  Слив плагинов server-rust by Apolo YouGame
        {
            if (player == null || info == null || info.HitEntity == null || !configData.Repair.Enabled) return;
            CarController controller = info.HitEntity.GetComponent<CarController>();
            if (controller != null && controller.entity != null) {
                if (controller.entity.health < controller.entity.MaxHealth()) {
                    if (player.inventory.GetAmount(repairType) >= configData.Repair.Amount) {
                        player.inventory.Take(null, repairType, configData.Repair.Amount);
                        controller.entity.Heal(configData.Repair.Damage);
                        player.Command("note.inv", new object[] {
                            repairType, configData.Repair.Amount * -1
                        }
                        );
                    }
                    else SendReply(player, string.Format(msg("noresources", player.UserIDString), configData.Repair.Amount, repairTypeName));
                }
                else SendReply(player, msg("fullhealth", player.UserIDString));
            }
        }
        private void OnPlayerInput(BasePlayer player, InputState input) {
            if (!initialized || player == null) return;
            if (input.WasJustPressed(BUTTON.USE)) {
                RaycastHit hit;
                if (Physics.SphereCast(player.eyes.position, 0.5f, Quaternion.Euler(player.serverInput.current.aimAngles) * Vector3.forward, out hit, 3f)) {
                    CarController controller = hit.GetEntity()?.GetComponent<CarController>();
                    if (controller != null && controller.HasCommander() && !controller.occupants.Contains(player)) CanMountEntity(controller.entity, player);
                }
                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)) {
                    CarController controller = hit.GetEntity()?.GetComponent<CarController>();
                    if (controller != null && !controller.HasCommander() && !controller.occupants.Contains(player)) OpenInventory(player, controller, controller.inventory);
                }
                return;
            }
            if (configData.Fuel.Enabled && input.WasJustPressed(controlButtons[CommandType.FuelTank])) {
                RaycastHit hit;
                if (Physics.SphereCast(player.eyes.position, 0.5f, Quaternion.Euler(player.serverInput.current.aimAngles) * Vector3.forward, out hit, 3f)) {
                    CarController controller = hit.GetEntity()?.GetComponent<CarController>();
                    if (controller != null && !controller.HasCommander() && !controller.occupants.Contains(player)) OpenInventory(player, controller, controller.fuelTank);
                }
                return;
            }
        }
        private void OnEntityKill(BaseNetworkable networkable) {
            BaseCar baseCar = networkable.GetComponent<BaseCar>();
            if (baseCar != null) {
                if (storedData.HasRestoreData(baseCar.net.ID)) storedData.RemoveData(baseCar.net.ID);
            }
        }
        private void OnNewSave(string filename) => wipeData = true;
        private void OnServerSave() {
            for (int i = saveableCars.Count - 1; i >= 0; i--) {
                CarController controller = saveableCars[i];
                if (controller == null || controller.entity == null || !controller.entity.IsValid() || controller.entity.IsDestroyed) {
                    saveableCars.RemoveAt(i);
                    continue;
                }
                storedData.AddData(controller);
            }
            SaveData();
        }
        private void Unload() {
            var objects = UnityEngine.Object.FindObjectsOfType<CarController>();
            if (objects != null) {
                foreach (var obj in objects) UnityEngine.Object.Destroy(obj);
            }
        }
        private object CanPickupEntity(BaseCombatEntity entity, BasePlayer player) {
            if (entity.GetComponent<CarController.InvisibleMount>()) return false;
            return null;
        }
        private void OnEntityDismounted(BaseMountable mountable, BasePlayer player) {
            CarController controller = mountable.GetComponent<CarController>();
            if (controller != null && controller.Commander?.userID == player.userID) {
                controller.Commander = null;
                controller.mountPoints[0].OnEntityDismounted();
                return;
            }
            CarController.InvisibleMount invisibleMount = mountable.GetComponent<CarController.InvisibleMount>();
            if (invisibleMount != null) invisibleMount.MountPosition.OnEntityDismounted();
        }
        private object CanMountEntity(BaseMountable mountable, BasePlayer player) {
            CarController controller = mountable.GetComponent<CarController>();
            if (controller != null) {
                if (player.isMounted) return false;
                if (controller.externallyManaged) return false;
                if (controller.isDieing) return false;
                if (!permission.UserHasPermission(player.UserIDString, "carcommander.use")) {
                    SendReply(player, msg("nopermission", player.UserIDString));
                    return false;
                }
                CarController.MountPoint mountPoint = controller.GetClosestMountPoint(player.transform.position);
                if (mountPoint != null && !mountPoint.Entity.IsMounted()) {
                    if (mountPoint.IsDriver) {
                        MountPlayer(mountable, mountPoint, player);
                        return false;
                    }
                    else {
                        if (configData.Passengers.Enabled) {
                            BasePlayer commander = controller.Commander;
                            if (commander == null) {
                                MountPlayer(mountable, mountPoint, player);
                                return false;
                            }
                            else {
                                if (!configData.Passengers.UseFriends && !configData.Passengers.UseClans) {
                                    MountPlayer(mountable, mountPoint, player);
                                    return false;
                                }
                                if (configData.Passengers.UseFriends && AreFriends(commander.userID, player.userID)) {
                                    MountPlayer(mountable, mountPoint, player);
                                    return false;
                                }
                                if (configData.Passengers.UseClans && IsClanmate(commander.userID, player.userID)) {
                                    MountPlayer(mountable, mountPoint, player);
                                    return false;
                                }
                                SendReply(player, msg("not_friend", player.UserIDString));
                                return false;
                            }
                        }
                        else {
                            SendReply(player, msg("not_enabled", player.UserIDString));
                            return false;
                        }
                    }
                }
            }
            CarController.InvisibleMount invisibleMount = mountable.GetComponent<CarController.InvisibleMount>();
            if (invisibleMount != null) {
                if (configData.Passengers.Enabled) {
                    BasePlayer commander = invisibleMount.MountPosition.Controller.Commander;
                    if (commander != null) {
                        if (!configData.Passengers.UseFriends && !configData.Passengers.UseClans) return true;
                        if (configData.Passengers.UseFriends && AreFriends(commander.userID, player.userID)) return true;
                        if (configData.Passengers.UseClans && IsClanmate(commander.userID, player.userID)) return true;
                        SendReply(player, msg("not_friend", player.UserIDString));
                        return false;
                    }
                }
                else {
                    SendReply(player, msg("not_enabled", player.UserIDString));
                    return false;
                }
            }
            return null;
        }
        private object CanDismountEntity(BaseMountable mountable, BasePlayer player) {
            CarController controller = mountable.GetComponent<CarController>();
            if (controller != null) {
                if (controller.externallyManaged) return false;
            }
            CarController.InvisibleMount invisibleMount = mountable.GetComponent<CarController.InvisibleMount>();
            if (invisibleMount != null) {
                invisibleMount.MountPosition.DismountPlayer();
                return false;
            }
            return null;
        }
#endregion
#region Functions
        private T ParseType<T>(string type) {
            try {
                return (T)Enum.Parse(typeof(T), type, true);
            }
            catch {
                PrintError($"INVALID CONFIG OPTION DETECTED! The value \"{type}\" is an incorrect selection.\nAvailable options are: {Enum.GetNames(typeof(T)).ToSentence()}");
                return default(T);
            }
        }
        private bool HasPermission(BasePlayer player, string perm) => permission.UserHasPermission(player.UserIDString, perm) || permission.UserHasPermission(player.UserIDString, "Carcommander.admin");
        private void ConvertControlButtons() {
            controlButtons = new Dictionary<CommandType, BUTTON> {
                [CommandType.Accelerate]
                = ParseType<BUTTON>(configData.Buttons.Accelerate), [CommandType.Brake] = ParseType<BUTTON>(configData.Buttons.Brake), [CommandType.Inventory] = ParseType<BUTTON>(configData.Buttons.Inventory), [CommandType.Left] = ParseType<BUTTON>(configData.Buttons.Left), [CommandType.Right] = ParseType<BUTTON>(configData.Buttons.Right), [CommandType.Handbrake] = ParseType<BUTTON>(configData.Buttons.HBrake), [CommandType.Lights] = ParseType<BUTTON>(configData.Buttons.Lights), [CommandType.FuelTank] = ParseType<BUTTON>(configData.Buttons.FuelTank)
            }
            ;
        }
        private void OpenInventory(BasePlayer player, CarController controller, ItemContainer container) {
            player.inventory.loot.Clear();
            player.inventory.loot.entitySource = controller.entity;
            player.inventory.loot.itemSource = null;
            player.inventory.loot.AddContainer(container);
            player.inventory.loot.SendImmediate();
            player.ClientRPCPlayer(null, player, "RPC_OpenLootPanel", "generic");
            player.SendNetworkUpdate();
        }
        private void MountPlayer(BaseMountable mountable, CarController.MountPoint mountPoint, BasePlayer player) {
            if (mountPoint.IsDriver) mountPoint.Controller.Commander = player;
            mountPoint.MountPlayer(player);
        }
        private void RestoreVehicleInventories() {
            if (storedData.restoreData.Count > 0) {
                BaseEntity[] objects = BaseEntity.saveList.Where(x => x is BaseCar).ToArray();
                if (objects != null) {
                    foreach (var obj in objects) {
                        if (!obj.IsValid() || obj.IsDestroyed) continue;
                        if (storedData.HasRestoreData(obj.net.ID)) {
                            obj.gameObject.AddComponent<CarController>();
                        }
                    }
                }
            }
            CheckForSpawns();
        }
        private void CheckForSpawns() {
            if (configData.Spawnable.Enabled) {
                if (saveableCars.Count < configData.Spawnable.Max) {
                    object position = null;
                    if (configData.Spawnable.RandomSpawns) {
                        if (!RandomSpawns) {
                            PrintError("RandomSpawns can not be found! Unable to autospawn cars");
                            return;
                        }
                        object success = RandomSpawns.Call("GetSpawnPoint");
                        if (success != null) position = (Vector3)success;
                        else PrintError("Unable to find a valid spawnpoint from RandomSpawns");
                    }
                    else {
                        if (!Spawns) {
                            PrintError("Spawns Database can not be found! Unable to autospawn cars");
                            return;
                        }
                        object success = Spawns.Call("GetSpawnsCount", configData.Spawnable.Spawnfile);
                        if (success is string) {
                            PrintError("An invalid spawnfile has been set in the config.Unable to autospawn cars : " + (string)success);
                            return;
                        }
                        success = Spawns.Call("GetRandomSpawn", configData.Spawnable.Spawnfile);
                        if (success is string) {
                            PrintError((string)success);
                            return;
                        }
                        else position = (Vector3)success;
                    }
                    if (position != null) {
                        List<BaseCar> entities = Facepunch.Pool.GetList<BaseCar>();
                        Vis.Entities((Vector3)position, 5f, entities);
                        if (entities.Count > 0) timer.In(60, CheckForSpawns);
                        else {
                            SpawnAtLocation((Vector3)position, new Quaternion(), true);
                            timer.In(configData.Spawnable.Time, CheckForSpawns);
                        }
                        Facepunch.Pool.FreeList(ref entities);
                    }
                }
            }
        }
#endregion
#region API
        private BaseEntity SpawnAtLocation(Vector3 position, Quaternion rotation = default(Quaternion), bool enableSaving = false, bool isExternallyManaged = false) {
            BaseEntity entity = GameManager.server.CreateEntity(carPrefab, position + Vector3.up, rotation);
            entity.Spawn();
            entity.enableSaving = enableSaving;
            CarController controller = entity.gameObject.AddComponent<CarController>();
            if (enableSaving) {
                saveableCars.Add(controller);
                storedData.AddData(controller);
                SaveData();
            }
            if (isExternallyManaged) controller.SetExternallyManaged();
            return entity;
        }
        private void ToggleController(BaseCar baseCar, bool enabled) {
            if (baseCar == null) return;
            CarController controller = baseCar.GetComponent<CarController>();
            if (controller != null) {
                controller.enabled = enabled;
                if (!enabled) {
                    foreach (var wheel in controller.entity.wheels) wheel.wheelCollider.brakeTorque = 1f;
                }
            }
        }
        private void MountPlayerTo(BasePlayer player, BaseCar baseCar) {
            if (player == null) return;
            CarController controller = baseCar.GetComponent<CarController>();
            if (controller != null) {
                controller.Commander = player;
                controller.mountPoints[0].MountPlayer(player);
            }
        }
        private void EjectAllPlayers(BaseCar baseCar) {
            CarController controller = baseCar.GetComponent<CarController>();
            if (controller != null) controller.EjectAllPlayers();
        }
#endregion
#region Component
        enum CommandType {
            Accelerate, Brake, Left, Right, Handbrake, Inventory, FuelTank, Lights
        }
        public class CarController : MonoBehaviour {
#region Variables
            private BasePlayer player;
            public BaseCar entity;
            public ItemContainer inventory;
            public ItemContainer fuelTank;
            private Rigidbody rb;
            private Dictionary<CommandType, BUTTON> cb;
            public List<MountPoint> mountPoints = new List<MountPoint>();
            public List<BasePlayer> occupants = new List<BasePlayer>();
            WheelCollider[] allWheels = new WheelCollider[4];
            WheelFrictionCurve sidewaysFriction = new WheelFrictionCurve();
            WheelFrictionCurve sidewaysFrictionHB = new WheelFrictionCurve();
            private float engineTorque;
            private float brakeTorque;
            private float reverseTorque;
            private float speed;
            private float maxSpeed;
            private float maxSteeringAngleSpeed;
            private float maxSteeringAngle;
            private bool applyCounterSteer;
            private float driftAngle;
            private bool isDrifting;
            public float antiRollFrontHorizontal = 5000f;
            public float antiRollRearHorizontal = 5000f;
            public float antiRollVertical = 500f;
            private float accelInput = 0f;
            private float brakeInput = 0f;
            private float steerInput = 0f;
            private bool repairEnabled;
            private bool fuelEnabled;
            private int consumptionRate;
            private int fuelId;
            private float nextFuelTick;
            private bool outOfFuel;
            private bool eBrake;
            private bool driftFriction;
            public bool externallyManaged;
            public bool isDieing;
            public bool lightsOn;
            public BasePlayer Commander {
                get {
                    return player;
                }
                set {
                    player = value;
                }
            }
#endregion
#region Initialization
            private void Awake() {
                entity = GetComponent<BaseCar>();
                entity.enabled = false;
                if (entity.IsMounted()) entity.DismountAllPlayers();
                SetWheelColliders();
                CreatePassengers();
                InitializeSettings();
                InitializeFuel();
                InitializeInventory();
            }
            private void SetWheelColliders() {
                allWheels = new WheelCollider[] {
                    entity.wheels[0].wheelCollider, entity.wheels[1].wheelCollider, entity.wheels[2].wheelCollider, entity.wheels[3].wheelCollider
                }
                ;
                WheelFrictionCurve forwardFriction = new WheelFrictionCurve();
                forwardFriction.extremumSlip = 0.2f;
                forwardFriction.extremumValue = 1;
                forwardFriction.asymptoteSlip = 0.8f;
                forwardFriction.asymptoteValue = 0.75f;
                forwardFriction.stiffness = 1.5f;
                sidewaysFriction.extremumSlip = 0.2f;
                sidewaysFriction.extremumValue = 0.8f;
                sidewaysFriction.asymptoteSlip = 0.4f;
                sidewaysFriction.asymptoteValue = 0.6f;
                sidewaysFriction.stiffness = 1.0f;
                sidewaysFrictionHB.extremumSlip = 0.15f;
                sidewaysFrictionHB.extremumValue = 0.7f;
                sidewaysFrictionHB.asymptoteSlip = 0.2f;
                sidewaysFrictionHB.asymptoteValue = 0.5f;
                sidewaysFrictionHB.stiffness = 0.75f;
                var movement = ins.configData.Movement;
                foreach (WheelCollider wc in allWheels) {
                    JointSpring spring = wc.suspensionSpring;
                    spring.spring = movement.Spring;
                    spring.damper = movement.Damper;
                    spring.targetPosition = movement.Target;
                    wc.suspensionSpring = spring;
                    wc.suspensionDistance = movement.Distance;
                    wc.forceAppPointDistance = 0.1f;
                    wc.mass = 40f;
                    wc.wheelDampingRate = 1f;
                    wc.sidewaysFriction = sidewaysFriction;
                    wc.forwardFriction = forwardFriction;
                }
            }
            private void CreatePassengers() {
                mountPoints = new List<MountPoint> {
                    new MountPoint(this, new Vector3(-0.5f, 0.16f, 0.57f), new Vector3(-1.2f, 0.1f, 0.5f), true)
                }
                ;
                if (ins.configData.Passengers.Enabled) {
                    mountPoints.Add(new MountPoint(this, new Vector3(0.54f, 0.16f, 0.57f), new Vector3(1.2f, 0.1f, 0.5f)));
                    mountPoints.Add(new MountPoint(this, new Vector3(-0.48f, 0.16f, -0.55f), new Vector3(-1.2f, 0.1f, -0.5f)));
                    mountPoints.Add(new MountPoint(this, new Vector3(0.48f, 0.16f, -0.55f), new Vector3(1.2f, 0.1f, -0.5f)));
                }
            }
            private void InitializeSettings() {
                rb = entity.GetComponent<Rigidbody>();
                cb = ins.controlButtons;
                var movement = ins.configData.Movement;
                engineTorque = movement.Acceleration;
                brakeTorque = movement.Brakes;
                reverseTorque = movement.Reverse;
                maxSteeringAngle = movement.Steer;
                maxSteeringAngleSpeed = movement.SteerSpeed;
                applyCounterSteer = movement.CounterSteer;
                antiRollFrontHorizontal = movement.AntiRollFH;
                antiRollRearHorizontal = movement.AntiRollRH;
                antiRollVertical = movement.AntiRollV;
                maxSpeed = movement.Speed;
                repairEnabled = ins.configData.Repair.Enabled;
            }
            private void InitializeFuel() {
                var fuel = ins.configData.Fuel;
                fuelId = ins.fuelType;
                fuelEnabled = fuel.Enabled;
                consumptionRate = fuel.Consumption;
                if (fuelEnabled) {
                    fuelTank = new ItemContainer();
                    fuelTank.ServerInitialize(null, 1);
                    if ((int)fuelTank.uid == 0) fuelTank.GiveUID();
                    fuelTank.onlyAllowedItem = ItemManager.itemList.Find(x => x.itemid == fuelId);
                    if (fuel.GiveFuel && !ins.storedData.HasRestoreData(entity.net.ID)) {
                        Item fuelItem = ItemManager.CreateByItemID(fuelId, UnityEngine.Random.Range(fuel.FuelAmountMin, fuel.FuelAmountMax));
                        fuelItem.MoveToContainer(fuelTank);
                    }
                }
                outOfFuel = fuelEnabled ? fuelTank.GetAmount(fuelId, false) < 1 : false;
            }
            private void InitializeInventory() {
                if (ins.configData.Inventory.Enabled) {
                    inventory = new ItemContainer();
                    inventory.ServerInitialize(null, ins.configData.Inventory.Size);
                    if ((int)inventory.uid == 0) inventory.GiveUID();
                }
                if (ins.storedData.HasRestoreData(entity.net.ID)) {
                    ins.storedData.RestoreInventory(this);
                    ins.saveableCars.Add(this);
                }
            }
#endregion
#region Input
            private void FixedUpdate() {
                foreach (var point in mountPoints) {
                    point.UpdatePosition();
                }
                if (WaterLevel.Factor(entity.WorldSpaceBounds().ToBounds()) > 0.7f) {
                    enabled = false;
                    if (externallyManaged) Interface.CallHook("OnVehicleUnderwater", entity);
                    else StopToDie();
                    return;
                }
                if (player == null) {
                    accelInput = 0f;
                    brakeInput = 0.5f;
                }
                else {
                    rb.drag = rb.velocity.magnitude / 250;
                    if (player.serverInput.WasJustPressed(cb[CommandType.Lights])) ToggleLights();
                    eBrake = player.serverInput.IsDown(cb[CommandType.Handbrake]);
                    if (player.serverInput.IsDown(cb[CommandType.Accelerate])) {
                        accelInput = 1f;
                        brakeInput = 0f;
                    }
                    else if (player.serverInput.IsDown(cb[CommandType.Brake])) {
                        brakeInput = 1f;
                        accelInput = 0f;
                    }
                    else {
                        brakeInput = 0f;
                        accelInput = 0f;
                    }
                    steerInput = player.serverInput.IsDown(cb[CommandType.Left]) ? -1f : player.serverInput.IsDown(cb[CommandType.Right]) ? 1f : 0f;
                    if (fuelEnabled) CheckFuel(accelInput > 0);
                }
                speed = rb.velocity.magnitude * 3.6f;
                ApplyAcceleration();
                AntiRollBars();
                CheckForDrift();
                AdjustSteering();
                entity.SetFlag(BaseEntity.Flags.Reserved1, player != null && !outOfFuel, false);
            }
#endregion
#region Movement
            private void ApplyAcceleration() {
                if (accelInput > 0 && speed > maxSpeed) accelInput = 0;
                float velocity = rb.velocity.magnitude * Vector3.Dot(rb.velocity.normalized, entity.transform.forward);
                float _motorTorque = outOfFuel ? 0 : engineTorque * accelInput;
                float _reverseTorque = outOfFuel ? 0 : -reverseTorque;
                float _brakeTorque = brakeTorque * brakeInput;
                if (velocity < 0.01f && brakeInput > 0.5f) {
                    for (int i = 0; i < allWheels.Length; i++) {
                        WheelCollider wc = allWheels[i];
                        wc.brakeTorque = 0;
                        if (i < 2) wc.motorTorque = _reverseTorque * 0.8f;
                        else wc.motorTorque = _reverseTorque;
                    }
                }
                else {
                    if (eBrake) {
                        for (int i = 2; i < allWheels.Length; i++) {
                            WheelCollider wc = allWheels[i];
                            wc.motorTorque = 0;
                            wc.brakeTorque = brakeTorque;
                            if (steerInput != 0 && allWheels[i].isGrounded) {
                                rb.angularVelocity = new Vector3(rb.angularVelocity.x, rb.angularVelocity.y + (steerInput / 60f), rb.angularVelocity.z);
                                wc.sidewaysFriction = sidewaysFrictionHB;
                                driftFriction = true;
                            }
                        }
                    }
                    else {
                        for (int i = 0; i < allWheels.Length; i++) {
                            WheelCollider wc = allWheels[i];
                            if (i > 1 && driftFriction) {
                                wc.sidewaysFriction = sidewaysFriction;
                                driftFriction = false;
                            }
                            wc.motorTorque = _motorTorque;
                            wc.brakeTorque = _brakeTorque;
                        }
                    }
                    entity.SetFlag(BaseEntity.Flags.Reserved3, (velocity > 0f && accelInput < 0f) || (velocity < 0f && brakeInput > 0f), false);
                }
            }
            private void AdjustSteering() {
                var steerAngle = Mathf.Lerp(maxSteeringAngle, maxSteeringAngleSpeed, (speed / maxSpeed)) * steerInput;
                if (applyCounterSteer) steerAngle = Mathf.Clamp((steerAngle * (steerInput + driftAngle)), -steerAngle, steerAngle);
                allWheels[0].steerAngle = steerAngle;
                allWheels[1].steerAngle = steerAngle;
                entity.SetFlag(BaseEntity.Flags.Reserved4, steerInput == -1f, false);
                entity.SetFlag(BaseEntity.Flags.Reserved5, steerInput == 1f, false);
            }
            private void AntiRollBars() {
                WheelHit FrontWheelHit;
                float travelFL = 1.0f;
                float travelFR = 1.0f;
                bool groundedFL = allWheels[0].GetGroundHit(out FrontWheelHit);
                if (groundedFL) travelFL = (-allWheels[0].transform.InverseTransformPoint(FrontWheelHit.point).y - allWheels[0].radius) / allWheels[0].suspensionDistance;
                bool groundedFR = allWheels[1].GetGroundHit(out FrontWheelHit);
                if (groundedFR) travelFR = (-allWheels[1].transform.InverseTransformPoint(FrontWheelHit.point).y - allWheels[1].radius) / allWheels[1].suspensionDistance;
                float antiRollForceFrontHorizontal = (travelFL - travelFR) * antiRollFrontHorizontal;
                if (groundedFL) rb.AddForceAtPosition(allWheels[0].transform.up * -antiRollForceFrontHorizontal, allWheels[0].transform.position);
                if (groundedFR) rb.AddForceAtPosition(allWheels[1].transform.up * antiRollForceFrontHorizontal, allWheels[1].transform.position);
                WheelHit RearWheelHit;
                float travelRL = 1.0f;
                float travelRR = 1.0f;
                bool groundedRL = allWheels[2].GetGroundHit(out RearWheelHit);
                if (groundedRL) travelRL = (-allWheels[2].transform.InverseTransformPoint(RearWheelHit.point).y - allWheels[2].radius) / allWheels[2].suspensionDistance;
                bool groundedRR = allWheels[3].GetGroundHit(out RearWheelHit);
                if (groundedRR) travelRR = (-allWheels[3].transform.InverseTransformPoint(RearWheelHit.point).y - allWheels[3].radius) / allWheels[3].suspensionDistance;
                float antiRollForceRearHorizontal = (travelRL - travelRR) * antiRollRearHorizontal;
                if (groundedRL) rb.AddForceAtPosition(allWheels[2].transform.up * -antiRollForceRearHorizontal, allWheels[2].transform.position);
                if (groundedRR) rb.AddForceAtPosition(allWheels[3].transform.up * antiRollForceRearHorizontal, allWheels[3].transform.position);
                float antiRollForceFrontVertical = (travelFL - travelRL) * antiRollVertical;
                if (groundedFL) rb.AddForceAtPosition(allWheels[0].transform.up * -antiRollForceFrontVertical, allWheels[0].transform.position);
                if (groundedRL) rb.AddForceAtPosition(allWheels[2].transform.up * antiRollForceFrontVertical, allWheels[2].transform.position);
                float antiRollForceRearVertical = (travelFR - travelRR) * antiRollVertical;
                if (groundedFR) rb.AddForceAtPosition(allWheels[1].transform.up * -antiRollForceRearVertical, allWheels[1].transform.position);
                if (groundedRR) rb.AddForceAtPosition(allWheels[3].transform.up * antiRollForceRearVertical, allWheels[3].transform.position);
            }
            private void CheckForDrift() {
                WheelHit hit;
                allWheels[3].GetGroundHit(out hit);
                if (speed > 1f && isDrifting && !eBrake) driftAngle = hit.sidewaysSlip * 1f;
                else driftAngle = 0f;
                if (Mathf.Abs(hit.sidewaysSlip) >.25f) isDrifting = true;
                else isDrifting = false;
            }
#endregion
#region Functions
            private void ToggleLights() {
                lightsOn = !lightsOn;
                entity.SetFlag(BaseEntity.Flags.Reserved2, lightsOn, false);
            }
            private void CheckFuel(bool isAccelerating) {
                if (outOfFuel) {
                    if (fuelTank.GetAmount(fuelId, true) > 0) {
                        outOfFuel = false;
                        if (player != null) ins.CreateFuelUI(player, this);
                    }
                }
                else {
                    nextFuelTick += isAccelerating ? Time.deltaTime : Time.deltaTime / 2;
                    if (nextFuelTick >= consumptionRate) {
                        nextFuelTick = 0f;
                        fuelTank.Take(null, fuelId, 1);
                        if (fuelTank.GetAmount(fuelId, true) < 1) outOfFuel = true;
                        if (player != null) ins.CreateFuelUI(player, this);
                    }
                }
            }
            public bool HasCommander() => player != null;
            public MountPoint GetClosestMountPoint(Vector3 position) {
                MountPoint mountPoint = null;
                float closestDistance = 10f;
                foreach (var point in mountPoints) {
                    float distance = Vector3.Distance(point.Position, position);
                    if (distance < closestDistance) {
                        if (point.Entity.IsMounted()) continue;
                        mountPoint = point;
                        closestDistance = distance;
                    }
                }
                return mountPoint;
            }
#endregion
#region Damage and Destruction
            private void OnDestroy() {
                EjectAllPlayers();
                DestroyAllMounts();
                if (entity != null && !entity.IsDestroyed && !entity.enableSaving) entity.Kill();
            }
            public void EjectAllPlayers() {
                foreach (MountPoint point in mountPoints) point.DismountPlayer();
            }
            private void DestroyAllMounts() {
                foreach (MountPoint point in mountPoints) {
                    InvokeHandler.CancelInvoke(entity, point.UpdateHeldItems);
                    point.DestroyMountPoint();
                }
            }
            public void ManageDamage(HitInfo info)  //  Слив плагинов server-rust by Apolo YouGame
            {
                if (info.damageTypes.GetMajorityDamageType() == DamageType.Bullet) info.damageTypes.ScaleAll(200);
                if (info.damageTypes.Total() >= entity.health) {
                    info.damageTypes = new DamageTypeList();
                    info.HitEntity = null;
                    info.HitMaterial = 0;
                    info.PointStart = Vector3.zero;
                    OnDeath();
                    return;
                }
                foreach (var occupant in occupants) ins.CreateHealthUI(occupant, this);
            }
            public void StopToDie() {
                enabled = false;
                isDieing = true;
                entity.SetFlag(BaseEntity.Flags.Reserved1, false, false);
                foreach (var wheel in entity.wheels) {
                    wheel.wheelCollider.motorTorque = 0;
                    wheel.wheelCollider.brakeTorque = float.MaxValue;
                }
                rb.velocity = Vector3.zero;
                EjectAllPlayers();
                entity.Invoke(OnDeath, 5f);
            }
            private void OnDeath() {
                EjectAllPlayers();
                Effect.server.Run(heliExplosion, transform.position);
                if (ins.configData.Inventory.DropInv) {
                    inventory.Drop("assets/prefabs/misc/item drop/item_drop.prefab", transform.position + Vector3.up + (UnityEngine.Random.onUnitSphere * UnityEngine.Random.Range(2f, 3f)), new Quaternion());
                    fuelTank.Drop("assets/prefabs/misc/item drop/item_drop.prefab", transform.position + Vector3.up + (UnityEngine.Random.onUnitSphere * UnityEngine.Random.Range(2f, 3f)), new Quaternion());
                }
                ins.NextTick(() => {
                    if (entity != null && !entity.IsDestroyed) entity.DieInstantly();
                }
                );
            }
#endregion
#region External Toggles
            public void SetExternallyManaged() {
                externallyManaged = true;
                repairEnabled = false;
                DisableFuelConsumption();
            }
            public void DisableFuelConsumption() {
                if (fuelEnabled) {
                    fuelEnabled = false;
                    outOfFuel = false;
                    foreach (var occupant in occupants) ins.DestroyUI(occupant, uiFuel);
                }
            }
#endregion
            public class MountPoint {
#region Variables
                private BaseMountable entity;
                private CarController controller;
                private BasePlayer player;
                private Vector3 dismountLocal;
                private Vector3 offset;
                private bool isDriver;
                private bool allowHeldItems;
                private string[] disallowedItems;
                public CarController Controller {
                    get {
                        return controller;
                    }
                }
                public BaseMountable Entity {
                    get {
                        return entity;
                    }
                }
                public Vector3 Position {
                    get {
                        if (entity == null && !isDriver) GeneratePrefab();
                        return isDriver ? entity.transform.position + (entity.transform.forward * 0.5f) + (entity.transform.up * 0.1f) + (entity.transform.right * -0.5f) : entity.transform.position;
                    }
                }
                public bool IsDriver {
                    get {
                        return isDriver;
                    }
                }
#endregion
#region Constructor
                public MountPoint() {
                }
                public MountPoint(CarController controller, Vector3 offset, Vector3 dismountLocal, bool isDriver = false) {
                    this.isDriver = isDriver;
                    this.dismountLocal = dismountLocal;
                    this.controller = controller;
                    this.offset = offset;
                    if (isDriver) entity = controller.entity;
                    else GeneratePrefab();
                    allowHeldItems = isDriver ? !ins.configData.ActiveItems.DisableDriver : !ins.configData.ActiveItems.DisablePassengers;
                    disallowedItems = isDriver ? ins.configData.ActiveItems.DriverBlackList : ins.configData.ActiveItems.PassengerBlackList;
                    InvokeHandler.InvokeRepeating(entity, UpdateHeldItems, 0f, 0.5f);
                }
                public void GeneratePrefab() {
                    entity = GameManager.server.CreateEntity(controller.entity.chairRef.resourcePath, controller.transform.position) as BaseMountable;
                    entity.Spawn();
                    entity.enableSaving = false;
                    entity.maxMountDistance = 2f;
                    entity.GetComponent<DestroyOnGroundMissing>().enabled = false;
                    entity.GetComponent<GroundWatch>().enabled = false;
                    entity.GetComponent<MeshCollider>().convex = true;
                    InvisibleMount invisibleMount = entity.gameObject.AddComponent<InvisibleMount>();
                    invisibleMount.MountPosition = this;
                    entity.SetParent(controller.entity);
                    entity.transform.localPosition = offset;
                }
#endregion
#region Mounting
                public void OnEntityMounted() {
                    controller.occupants.Add(player);
                    ins.CreateHealthUI(player, controller);
                    if (isDriver) {
                        string message = string.Format(ins.msg("controls1", player.UserIDString), controller.cb[CommandType.Accelerate], controller.cb[CommandType.Brake], controller.cb[CommandType.Left], controller.cb[CommandType.Right], controller.cb[CommandType.Handbrake], controller.cb[CommandType.Lights]);
                        if (controller.inventory != null) message += $"\n{string.Format(ins.msg("access_inventory", player.UserIDString), controller.cb[CommandType.Inventory])}";
                        if (controller.fuelEnabled) {
                            message += $"\n{string.Format(ins.msg("access_fuel", player.UserIDString), controller.cb[CommandType.FuelTank])}";
                            message += $"\n{string.Format(ins.msg("fuel_type", player.UserIDString), ins.fuelTypeName)}";
                            ins.CreateFuelUI(player, controller);
                        }
                        if (controller.repairEnabled) message += $"\n{string.Format(ins.msg("repairhelp", player.UserIDString), ins.configData.Repair.Amount, ins.repairTypeName)}";
                        player.ChatMessage(message);
                    }
                    else {
                        string message = string.Empty;
                        if (controller.inventory != null) message += string.Format(ins.msg("access_inventory", player.UserIDString), controller.cb[CommandType.Inventory]);
                        if (controller.fuelEnabled) {
                            message += $"\n{string.Format(ins.msg("access_fuel", player.UserIDString), controller.cb[CommandType.FuelTank])}";
                            message += $"\n{string.Format(ins.msg("fuel_type", player.UserIDString), ins.fuelTypeName)}";
                        }
                        if (controller.repairEnabled) message += $"\n{string.Format(ins.msg("repairhelp", player.UserIDString), ins.configData.Repair.Amount, ins.repairTypeName)}";
                        if (!string.IsNullOrEmpty(message)) player.ChatMessage(message);
                    }
                }
                public void OnEntityDismounted() {
                    ins.DestroyAllUI(player);
                    controller.occupants.Remove(player);
                    player = null;
                }
                public void MountPlayer(BasePlayer player) {
                    this.player = player;
                    player.EnsureDismounted();
                    typeof(BaseMountable).GetField("_mounted", (BindingFlags.Static | BindingFlags.Instance | BindingFlags.NonPublic)).SetValue(entity, player);
                    player.MountObject(entity, 0);
                    player.MovePosition(entity.mountAnchor.transform.position);
                    player.transform.rotation = entity.mountAnchor.transform.rotation;
                    player.ServerRotation = entity.mountAnchor.transform.rotation;
                    player.OverrideViewAngles(entity.mountAnchor.transform.rotation.eulerAngles);
                    player.eyes.NetworkUpdate(entity.mountAnchor.transform.rotation);
                    player.ClientRPCPlayer(null, player, "ForcePositionTo", player.transform.position);
                    entity.SetFlag(BaseEntity.Flags.Busy, true, false);
                    OnEntityMounted();
                }
                public void DismountPlayer() {
                    if (player == null) return;
                    Vector3 dismountPosition = controller.entity.transform.position + (controller.entity.transform.right * dismo
// ... [Code preview truncated due to length. Full source in attached file] ...

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