using Newtonsoft.Json; using System.Linq; using UnityEngine; namespace Oxide.Plugins { [Info("Minicopter Licence Plate", "The Friendly Chap", "1.2.0")] [Description("Spawn a licence plate (Small Wooden Board) at the back of the minicopter, with optional permissions.")] class MiniPlate : RustPlugin { const string _platePrefab = "assets/prefabs/deployable/signs/sign.small.wood.prefab"; private static readonly Vector3 PlatePosition = new Vector3(0.0f, 0.20f, -0.85f); private static readonly Quaternion PlateRotation = Quaternion.Euler(180, 0, 180); #region ConfigData private ConfigData configData; class ConfigData { [JsonProperty(PropertyName = "Use Permissions")] public bool miniPerms = false; [JsonProperty(PropertyName = "Debug")] public bool miniDebug = false; } private bool LoadConfigVariables() { try { configData = Config.ReadObject(); } catch { return false; } SaveConfig(configData); return true; } protected override void LoadDefaultConfig() { Puts("Creating new config file."); configData = new ConfigData(); SaveConfig(configData); } void SaveConfig(ConfigData config) { Config.WriteObject(config, true); } void Init() { permission.RegisterPermission("miniplate.use", this); if (!LoadConfigVariables()) { Puts("Config file issue detected. Please delete file, or check syntax and fix."); } } #endregion private void OnServerInitialized() { CleanUpAndInitializePlates(); } void CleanUpAndInitializePlates() { foreach (var mini in BaseNetworkable.serverEntities.OfType()) { var existingPlates = mini.children?.Where(child => child.PrefabName == _platePrefab).ToList(); if (existingPlates != null && existingPlates.Count > 1) { for (int i = 1; i < existingPlates.Count; i++) { existingPlates[i].Kill(); // Remove duplicates } } if (existingPlates == null || !existingPlates.Any()) { SetupMini(mini); // Add a plate if none exists } if (configData.miniDebug) { Puts($"Minicopter {mini.net.ID}: Cleanup completed, plate setup verified."); } } } void OnEntitySpawned(Minicopter mini) { if (configData.miniPerms) { string userID = $"{mini.OwnerID}"; if (!permission.UserHasPermission(userID, "miniplate.use")) return; } if (mini.children != null && mini.children.Any(child => child.PrefabName == _platePrefab)) { if (configData.miniDebug) Puts($"License plate already exists for minicopter {mini.net.ID}"); return; } SetupMini(mini); } public void SetupMini(BaseVehicle vehicle) { MakeNumplate(vehicle, PlatePosition); } void MakeNumplate(BaseVehicle vehicle, Vector3 position) { BaseEntity entity = GameManager.server.CreateEntity(_platePrefab, vehicle.transform.position, PlateRotation); if (entity == null) return; DestroyUnnecessaryComponents(entity); entity.SetParent(vehicle); entity.transform.localPosition = position; entity.Spawn(); } void DestroyUnnecessaryComponents(BaseEntity entity) { DestroyGroundComp(entity); DestroyMeshCollider(entity); FixRigidBody(entity); } void FixRigidBody(BaseEntity entity) { if (configData.miniDebug) Puts($"FixRigidBody called for {entity}"); foreach (var rb in entity.GetComponentsInChildren()) { if (rb != null) { if (configData.miniDebug) Puts($"Processing Rigidbody {rb}"); rb.drag = 0f; rb.useGravity = false; rb.isKinematic = false; } } } void DestroyGroundComp(BaseEntity entity) { if (configData.miniDebug) Puts($"DestroyGroundComp called for {entity}"); UnityEngine.Object.DestroyImmediate(entity.GetComponent()); UnityEngine.Object.DestroyImmediate(entity.GetComponent()); UnityEngine.Object.DestroyImmediate(entity.GetComponent()); } void DestroyMeshCollider(BaseEntity entity) { if (configData.miniDebug) Puts($"DestroyMeshCollider called for {entity}"); foreach (var mesh in entity.GetComponentsInChildren()) { if (configData.miniDebug) Puts($"Processing MeshCollider {mesh}"); UnityEngine.Object.DestroyImmediate(mesh); if (entity.PrefabName == _platePrefab) { var boxCollider = entity.gameObject.AddComponent(); boxCollider.size = entity.bounds.size; } } } } }