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

FREE CarCommander : 0.2.72 0.2.72

Нет прав для скачивания
C#:
//Reference: UnityEngine.VehiclesModule
using System;
using System.Collections;
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;
namespace Oxide.Plugins {
    [Info("CarCommander", "k1lly0u", "0.2.72")]
    [Description("A custom car controller with many options including persistence")]
    class CarCommander : RustPlugin {
#region Fields
        [PluginReference]
        Plugin Clans, Friends, Spawns, RandomSpawns;
        RestoreData storedData;
        private Dictionary<ulong, double> userCooldowns = new Dictionary<ulong, double>();
        private DynamicConfigFile data, cooldowns;
        private static CarCommander ins;
        private Dictionary<string, string> itemNames = new Dictionary<string, string>();
        private Dictionary<ulong, HotwireManager> isHotwiring = new Dictionary<ulong, HotwireManager>();
        private Dictionary<CommandType, BUTTON> controlButtons;
        private List<CarController> temporaryCars = new List<CarController>();
        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 boxPrefab = "assets/prefabs/deployable/woodenbox/woodbox_deployed.prefab";
        const string explosionPrefab = "assets/prefabs/npc/m2bradley/effects/bradley_explosion.prefab";
        const string uiHealth = "CCUI_Health";
        const string uiFuel = "CCUI_Fuel";
#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.canbuild", this);
            permission.RegisterPermission("carcommander.ignorecooldown", this);
            lang.RegisterMessages(Messages, this);
            data = Interface.Oxide.DataFileSystem.GetFile("carcommander_data");
            cooldowns = Interface.Oxide.DataFileSystem.GetFile("carcommander_cooldowns");
        }
        private void OnServerInitialized() {
            ins = this;
            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) {
            if (entity == null || info == null) return;
            if (entity.GetComponent<CarController>()) entity.GetComponent<CarController>().ManageDamage(info);
            else if (entity.GetComponent<StorageContainer>()) {
                if (entity.GetParentEntity()?.GetComponent<CarController>()) NullifyDamage(info);
            }
        }
        private void OnHammerHit(BasePlayer player, HitInfo info) {
            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 OnItemDeployed(Deployer deployer, BaseEntity entity) {
            if (!configData.Security.Trunk.RequireKey) return;
            BasePlayer player = deployer.GetOwnerPlayer();
            if (player == null || entity == null) return;
            CarController controller = entity.GetComponentInParent<CarController>();
            if (controller != null) {
                Deployable deployable = deployer.GetDeployable();
                if (deployable != null) {
                    if (deployable.prefabID == 3518824735 || deployable.prefabID == 2106860026) {
                        if (controller.HasVehicleKey(player)) return;
                        entity.GetSlot(deployable.slot)?.Kill();
                        if (deployable.prefabID == 3518824735) player.GiveItem(ItemManager.CreateByItemID(1159991980, 1, 0));
                        // Codelock
                        else player.GiveItem(ItemManager.CreateByItemID(-850982208, 1, 0));
                        SendReply(player, msg("no_key_deploy", 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(player, controller.entity);
                }
                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) {
            BasicCar BasicCar = networkable.GetComponent<BasicCar>();
            if (BasicCar != null) {
                if (storedData.HasRestoreData(BasicCar.net.ID)) storedData.RemoveData(BasicCar.net.ID);
                CarController controller = BasicCar.GetComponent<CarController>();
                if (controller != null) {
                    saveableCars.Remove(controller);
                    temporaryCars.Remove(controller);
                }
            }
        }
        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() {
            CarController[] objects = saveableCars.Union(temporaryCars).ToArray();
            for (int i = 0; i < objects.Length; i++) UnityEngine.Object.Destroy(objects[i]);
            objects = UnityEngine.Object.FindObjectsOfType<CarController>();
            if (objects != null) {
                foreach (CarController obj in objects) UnityEngine.Object.Destroy(obj);
            }
            ins = null;
        }
        private object CanPickupEntity(BaseCombatEntity entity, BasePlayer player) {
            if (entity.GetComponentInParent<CarController>()) return false;
            return null;
        }
        private void OnPlayerDisconnected(BasePlayer player) {
            if (isHotwiring.ContainsKey(player.userID)) isHotwiring[player.userID].CancelHotwire();
            if (configData.Decay.InstantDecay) ServerMgr.Instance.StartCoroutine(DelayedDestroy(player.userID));
        }
        private IEnumerator DelayedDestroy(ulong playerId) {
            List<CarController> controllers = Facepunch.Pool.GetList<CarController>();
            controllers.AddRange(saveableCars);
            controllers.AddRange(temporaryCars);
            for (int i = controllers.Count - 1; i >= 0; i--) {
                CarController controller = controllers[i];
                if (controller?.ownerId == playerId) {
                    BasicCar BasicCar = controller?.entity;
                    UnityEngine.Object.Destroy(controller);
                    if (BasicCar != null && !BasicCar.IsDestroyed) BasicCar.Kill();
                }
                yield return null;
            }
            Facepunch.Pool.FreeList(ref controllers);
        }
        private void OnEntityMounted(BaseMountable mountable, BasePlayer player) {
            CarController controller = mountable.VehicleParent()?.GetComponent<CarController>();
            if (controller != null) controller.OnEntityMounted(player, mountable == controller.entity.mountPoints[0].mountable);
        }
        private void OnEntityDismounted(BaseMountable mountable, BasePlayer player) {
            CarController controller = mountable.VehicleParent()?.GetComponent<CarController>();
            if (controller != null) {
                if (controller.Commander?.userID == player.userID) {
                    if (isHotwiring.ContainsKey(player.userID)) {
                        isHotwiring[player.userID].CancelHotwire();
                        SendReply(player, ins.msg("hotwire_fail_left", player.UserIDString));
                    }
                }
                controller.OnEntityDismounted(player, mountable);
            }
        }
        private object CanMountEntity(BasePlayer player, BaseMountable mountable) {
            CarController controller = mountable.VehicleParent()?.GetComponent<CarController>();
            if (controller != null) {
                if (player.isMounted) return false;
                if (controller.externallyManaged) return false;
                if (controller.isDieing) return false;
                if (controller.IsFlipped) return false;
                if (!permission.UserHasPermission(player.UserIDString, "carcommander.use")) {
                    SendReply(player, msg("nopermission", player.UserIDString));
                    return false;
                }
                if (mountable == controller.entity.mountPoints[0].mountable) return null;
                else {
                    if (configData.Passengers.Enabled) {
                        BasePlayer commander = controller.Commander;
                        if (commander == null) return null;
                        else {
                            if (!configData.Passengers.UseFriends && !configData.Passengers.UseClans) return null;
                            if (configData.Passengers.UseFriends && AreFriends(commander.userID, player.userID)) return null;
                            if (configData.Passengers.UseClans && IsClanmate(commander.userID, player.userID)) return null;
                            SendReply(player, msg("not_friend", player.UserIDString));
                            return false;
                        }
                    }
                    else {
                        SendReply(player, msg("not_enabled", player.UserIDString));
                        return false;
                    }
                }
            }
            return null;
        }
        private object CanDismountEntity(BasePlayer player, BaseMountable mountable) {
            CarController controller = mountable.VehicleParent()?.GetComponent<CarController>();
            if (controller != null) {
                if (controller.externallyManaged) return null;
                // Temporary solution for failed dismount
                controller.DismountPlayer(player, mountable);
                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.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 NullifyDamage(HitInfo info) {
            info.damageTypes = new DamageTypeList();
            info.HitEntity = null;
            info.HitMaterial = 0;
            info.PointStart = Vector3.zero;
        }
        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 RestoreVehicleInventories() {
            if (storedData.restoreData.Count > 0) {
                BaseEntity[] objects = BaseEntity.saveList.Where(x => x is BasicCar).ToArray();
                if (objects != null) {
                    foreach (BaseEntity obj in objects) {
                        if (obj == null || !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<BasicCar> entities = Facepunch.Pool.GetList<BasicCar>();
                        Vis.Entities((Vector3)position, 5f, entities);
                        if (entities.Count > 0) {
                            timer.In(10, CheckForSpawns);
                            return;
                        }
                        else SpawnAtLocation((Vector3)position, new Quaternion(), true);
                        Facepunch.Pool.FreeList(ref entities);
                    }
                }
                timer.In(configData.Spawnable.Time, CheckForSpawns);
            }
        }
        private int CountPlayerVehicles(ulong playerId) {
            int count = 0;
            for (int i = 0; i < saveableCars.Count; i++) {
                if (saveableCars[i].ownerId == playerId) count++;
            }
            for (int i = 0; i < temporaryCars.Count; i++) {
                if (temporaryCars[i].ownerId == playerId) count++;
            }
            return count;
        }
        private double GrabCurrentTime() => DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1, 0, 0, 0)).TotalSeconds;
        private string FormatTime(double time) {
            TimeSpan dateDifference = TimeSpan.FromSeconds((float)time);
            int days = dateDifference.Days;
            int hours = dateDifference.Hours;
            hours += (days * 24);
            int mins = dateDifference.Minutes;
            int secs = dateDifference.Seconds;
            return string.Format("{0:00}:{1:00}:{2:00}", hours, mins, secs);
        }
#endregion
#region API
        private BaseEntity SpawnAtLocation(Vector3 position, Quaternion rotation = default(Quaternion), bool enableSaving = false, bool isExternallyManaged = false, bool repairEnabled = true, bool disableFuel = false, bool disableSecurity = false, bool disableCollision = false) {
            BaseEntity entity = GameManager.server.CreateEntity(carPrefab, position + Vector3.up, rotation);
            entity.enableSaving = enableSaving;
            entity.Spawn();
            CarController controller = entity.gameObject.AddComponent<CarController>();
            if (enableSaving) {
                saveableCars.Add(controller);
                storedData.AddData(controller);
                SaveData();
            }
            else temporaryCars.Add(controller);
            if (isExternallyManaged) controller.SetExternallyManaged();
            else controller.SetFeatures(repairEnabled, disableFuel, disableSecurity, disableCollision);
            return entity;
        }
        private void ToggleController(BasicCar BasicCar, bool enabled) {
            if (BasicCar == null) return;
            CarController controller = BasicCar.GetComponent<CarController>();
            if (controller != null) {
                controller.enabled = enabled;
                if (!enabled) {
                    foreach (BasicCar.VehicleWheel wheel in controller.entity.wheels) wheel.wheelCollider.brakeTorque = 1f;
                }
            }
        }
        private void MountPlayerTo(BasePlayer player, BasicCar BasicCar) {
            if (player == null) return;
            CarController controller = BasicCar.GetComponent<CarController>();
            if (controller != null) {
                BaseMountable mountable = controller.entity.mountPoints[0].mountable;
                if (mountable != null && mountable.GetMounted() == null) {
                    player.EnsureDismounted();
                    mountable._mounted = player;
                    player.MountObject(mountable, 0);
                    player.MovePosition(mountable.mountAnchor.transform.position);
                    player.transform.rotation = mountable.mountAnchor.transform.rotation;
                    player.ServerRotation = mountable.mountAnchor.transform.rotation;
                    player.OverrideViewAngles(mountable.mountAnchor.transform.rotation.eulerAngles);
                    player.eyes.NetworkUpdate(mountable.mountAnchor.transform.rotation);
                    player.ClientRPCPlayer<Vector3>(null, player, "ForcePositionTo", player.transform.position);
                    mountable.SetFlag(BaseEntity.Flags.Busy, true, false);
                    controller.OnEntityMounted(player, true);
                }
            }
        }
        private void EjectAllPlayers(BasicCar BasicCar) {
            CarController controller = BasicCar.GetComponent<CarController>();
            if (controller != null) controller.EjectAllPlayers();
        }
        private ItemContainer GetVehicleInventory(BasicCar BasicCar) {
            CarController controller = BasicCar.GetComponent<CarController>();
            if (controller == null) return null;
            return controller.container.inventory;
        }
        private ItemContainer GetVehicleFuelTank(BasicCar BasicCar) {
            CarController controller = BasicCar.GetComponent<CarController>();
            if (controller == null) return null;
            return controller.fuelTank;
        }
#endregion
#region Component
        enum CommandType {
            Accelerate, Brake, Left, Right, Handbrake, FuelTank, Lights
        }
        public class CarController : MonoBehaviour {
#region Variables
            public BasicCar entity;
            public StorageContainer container;
            public ItemContainer fuelTank;
            private Rigidbody rb;
            private Dictionary<CommandType, BUTTON> cb;
            private ConfigData.SecurityOptions security;
            private ConfigData.CollisionOptions collision;
            private ConfigData.DecaySettings decay;
            public List<BasePlayer> occupants = new List<BasePlayer>();
            WheelCollider[] allWheels = new WheelCollider[4];
            WheelFrictionCurve sidewaysFriction = new WheelFrictionCurve();
            WheelFrictionCurve sidewaysFrictionHB = new WheelFrictionCurve();
            public ulong ownerId = 0UL;
            private float engineTorque;
            private float brakeTorque;
            private float reverseTorque;
            private float speed;
            private float maxSpeed;
            private bool useDefaultHandling;
            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 float consumptionRate;
            private int fuelId;
            private float pendingFuel;
            private float nextFuelCheckTime;
            private bool hasFuel = false;
            private bool isFlipped;
            private float upsideDownTime;
            private int ignitionCode;
            private bool hasBeenHotwired;
            private bool ignitionOn;
            private bool eBrake;
            private bool driftFriction;
            public bool externallyManaged;
            public bool isDieing;
            public bool lightsOn;
            // Temporary solution for dismounting players
            private Vector3[] dismountLocals = new Vector3[] {
                new Vector3(-1.4f, 0.1f, 0.5f), new Vector3(1.4f, 0.1f, 0.5f), new Vector3(-1.4f, 0.1f, -0.5f), new Vector3(1.4f, 0.1f, -0.5f)
            }
            ;
            public BasePlayer Commander {
                get {
                    return entity.mountPoints[0].mountable.GetMounted();
                }
            }
            public bool HasBeenHotwired {
                get {
                    return hasBeenHotwired;
                }
                set {
                    hasBeenHotwired = value;
                }
            }
            public int IgnitionCode {
                get {
                    return ignitionCode;
                }
                set {
                    ignitionCode = value;
                }
            }
            public bool IsFlipped {
                get {
                    return isFlipped;
                }
            }
#endregion
#region Initialization
            private void Awake() {
                entity = GetComponent<BasicCar>();
                entity.enabled = false;
                //if (entity.IsMounted())
                // entity.DismountAllPlayers();
                EjectAllPlayers();
                SetWheelColliders();
                InitializeSettings();
                InitializeFuel();
                InitializeInventory();
                InitializeDecay();
            }
            private void SetWheelColliders() {
                if (!ins.configData.Movement.CustomHandling) {
                    useDefaultHandling = true;
                    return;
                }
                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;
                ConfigData.MovementSettings 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 InitializeSettings() {
                rb = entity.GetComponent<Rigidbody>();
                cb = ins.controlButtons;
                security = ins.configData.Security;
                collision = ins.configData.Collision;
                ConfigData.MovementSettings 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;
                entity.mountPoints[0].mountable.canWieldItems = !ins.configData.ActiveItems.DisableDriver;
                for (int i = 1; i < entity.mountPoints.Count; i++) entity.mountPoints[i].mountable.canWieldItems = !ins.configData.ActiveItems.DisablePassengers;
            }
            private void InitializeFuel() {
                ConfigData.FuelOptions 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.onlyAllowedItems = new ItemDefinition[] {
                        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);
                    }
                }
                hasFuel = fuelEnabled ? GetFuelAmount() < 1 : false;
            }
            private void InitializeInventory() {
                if (ins.configData.Inventory.Enabled) {
                    container = GameManager.server.CreateEntity(boxPrefab, entity.transform.position, entity.transform.rotation) as StorageContainer;
                    container.enableSaving = false;
                    container.skinID = (ulong)1195832261;
                    container.Spawn();
                    Destroy(container.GetComponent<DestroyOnGroundMissing>());
                    Destroy(container.GetComponent<GroundWatch>());
                    Destroy(container.GetComponent<BoxCollider>());
                    container.SetParent(entity);
                    container.transform.localPosition = new Vector3(0, 0.475f, -2.15f);
                    container.transform.localRotation = Quaternion.Euler(-10, 180, 0);
                    container.panelName = "generic_resizable";
                    container.inventorySlots = ins.configData.Inventory.Size;
                    container.isLockable = ins.configData.Security.Trunk.CanLock;
                    container.pickup.enabled = false;
                    container.inventory = new ItemContainer();
                    container.inventory.ServerInitialize(null, ins.configData.Inventory.Size);
                    if ((int)container.inventory.uid == 0) container.inventory.GiveUID();
                }
                if (ins.storedData.HasRestoreData(entity.net.ID)) {
                    ins.storedData.RestoreVehicle(this);
                    ins.saveableCars.Add(this);
                }
            }
            private void InitializeDecay() {
                decay = ins.configData.Decay;
                StartDecayTimer();
            }
#endregion
#region Input
            private void FixedUpdate() {
                if (WaterLevel.Factor(entity.WorldSpaceBounds().ToBounds()) > 0.7f) {
                    isDieing = true;
                    enabled = false;
                    if (externallyManaged) Interface.CallHook("OnVehicleUnderwater", entity);
                    else StopToDie();
                    return;
                }
                CheckUpsideDown();
                hasFuel = fuelEnabled ? HasFuel(false) : true;
                BasePlayer player = Commander;
                if (useDefaultHandling) {
                    if (player == null || !hasFuel || !ignitionOn) entity.NoDriverInput();
                    DoSteering();
                    ApplyForceAtWheels();
                    if (player?.serverInput.WasJustPressed(cb[CommandType.Lights]) ?? false) ToggleLights();
                    entity.SetFlag(BaseEntity.Flags.Reserved1, entity.AnyMounted() && hasFuel && ignitionOn, false);
                    entity.SetFlag(BaseEntity.Flags.Reserved2, (!entity.AnyMounted() ? false : lightsOn), false);
                    if (fuelEnabled && ignitionOn) UseFuel(Time.deltaTime * (entity.gasPedal == 0 ? 0.0333f : 1f));
                }
                else {
                    if (player == null || !ignitionOn) {
                        accelInput = 0f;
                        brakeInput = 0.5f;
                        eBrake = true;
                    }
                    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 && ignitionOn) UseFuel(Time.deltaTime * (accelInput == 0 ? 0.0333f : 1f));
                    }
                    speed = rb.velocity.magnitude * 3.6f;
                    ApplyAcceleration();
                    AntiRollBars();
                    CheckForDrift();
                    AdjustSteering();
                    entity.SetFlag(BaseEntity.Flags.Reserved1, player != null && hasFuel && ignitionOn, false);
                }
            }
#endregion
#region Movement
#region Default Handling
            private void ApplyForceAtWheels() {
                if (entity.rigidBody == null) return;
                Vector3 vector3 = entity.rigidBody.velocity;
                float single = vector3.magnitude * Vector3.Dot(vector3.normalized, base.transform.forward);
                float single1 = entity.brakePedal;
                float single2 = entity.gasPedal;
                if (single > 0f && single2 < 0f) {
                    single1 = 100f;
                }
                else if (single < 0f && single2 > 0f) {
                    single1 = 100f;
                }
                BasicCar.VehicleWheel[] vehicleWheelArray = entity.wheels;
                for (int i = 0; i < vehicleWheelArray.Length; i++) {
                    BasicCar.VehicleWheel vehicleWheel = vehicleWheelArray[i];
                    if (vehicleWheel.wheelCollider.isGrounded) {
                        if (vehicleWheel.powerWheel) {
                            vehicleWheel.wheelCollider.motorTorque = single2 * entity.motorForceConstant;
                        }
                        if (vehicleWheel.brakeWheel) {
                            vehicleWheel.wheelCollider.brakeTorque = single1 * entity.brakeForceConstant;
                        }
                    }
                }
                entity.SetFlag(BaseEntity.Flags.Reserved3, (single1 < 100f ? false : entity.AnyMounted()), false);
            }
            private void DoSteering() {
                BasicCar.VehicleWheel[] vehicleWheelArray = entity.wheels;
                for (int i = 0; i < vehicleWheelArray.Length; i++) {
                    BasicCar.VehicleWheel vehicleWheel = vehicleWheelArray[i];
                    if (vehicleWheel.steerWheel) {
                        vehicleWheel.wheelCollider.steerAngle = entity.steering;
                    }
                }
                entity.SetFlag(BaseEntity.Flags.Reserved4, entity.steering < -2f, false);
                entity.SetFlag(BaseEntity.Flags.Reserved5, entity.steering > 2f, false);
            }
#endregion
            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 = hasFuel ? engineTorque * accelInput : 0;
                float _reverseTorque = hasFuel ? -reverseTorque : 0;
                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, Commander == null ? false : (velocity > 0f && accelInput < 0f) || (velocity < 0f && brakeInput > 0f), false);
                }
            }
            private void AdjustSteering() {
                float 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;
            }
            private void CheckUpsideDown() {
                if (externallyManaged) return;
                if (Vector3.Dot(entity.transform.up, Vector3.down) > 0) {
                    if (!isFlipped) {
                        upsideDownTime += Time.deltaTime;
                        if (upsideDownTime > 3f) OnCarFlipped();
                    }
                }
                else {
                    upsideDownTime = 0;
                    if (isFlipped) isFlipped = false;
                }
            }
            private void OnCarFlipped() {
                isFlipped = true;
                BasePlayer player = Commander;
                if (ins.configData.Repair.CanFlip && player != null) player.ChatMessage(ins.msg("carFlipped", player.UserIDString));
                EjectAllPlayers();
            }
            public void ResetCar() {
                entity.GetComponent<Rigidbody>().velocity = Vector3.zero;
                entity.transform.rotation = Quaternion.Euler(0, entity.transform.eulerAngles.y, 0);
                entity.SendNetworkUpdate();
                isFlipped = false;
            }
#endregion
#region Collision
            private void OnCollisionEnter(Collision col) {
                if (!collision.Enabled) return;
                bool damage = false;
                foreach(ContactPoint cp in col.contacts) {
                    float local = cp.point.y - entity.transform.position.y;
                    if (local > 0.4f) {
                        damage = true;
                        break;
                    }
                }
                if (damage) {
                    float force = col.relativeVelocity.magnitude;
                    if (force > 2) entity.Hurt(new HitInfo(null, entity, DamageType.Explosion, force * collision.Multiplier));
                }
            }
#endregion
#region Decay
            private void StartDecayTimer() {
                if (decay.Enabled && occupants.Count == 0) InvokeHandler.Invoke(this, DealDecayDamage, decay.Time);
            }
            private void DealDecayDamage() {
                if (entity.IsOutside()) {
                    float decayDamage = entity.MaxHealth() * (decay.Amount / 100);
                    if (decayDamage >= entity.health) {
                        entity.Die();
                        return;
                    }
                    else entity.Hurt(decayDamage, DamageType.Decay, null, false);
                }
                InvokeHandler.Invoke(this, DealDecayDamage, decay.Time);
            }
#endregion
#region Functions
            private void ToggleLights() {
                lightsOn = !lightsOn;
                entity.SetFlag(BaseEntity.Flags.Reserved2, lightsOn, false);
            }
            private int GetFuelAmount() => fuelTank.GetAmount(fuelId, true);
            private bool HasFuel(bool forceCheck = false) {
                if (Time.time > nextFuelCheckTime || forceCheck) {
                    hasFuel = (float)GetFuelAmount() > 0f;
                    nextFuelCheckTime = Ti
// ... [Code preview truncated due to length. Full source in attached file] ...

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