using System.Collections.Generic; using Oxide.Core; using Oxide.Core.Plugins; using UnityEngine; namespace Oxide.Plugins { [Info("HelicopterHonk", "PwndwithStyleTV", "1.2.3")] [Description("Plays a horn sound when a player presses the action key (LMB) while mounted as the pilot on a scrap transport helicopter or a minicopter, or E while on an attack helicopter, and toggles the closest authorized door.")] public class HelicopterHonk : RustPlugin { private const string PluginName = "helicopterhonk"; private const string PermissionName = "honk.use"; private const float DoorOpenRange = 10f; // Adjust the range as needed private Dictionary lastToggleTimes = new Dictionary(); private const float GarageDoorCooldown = 4f; private const float HingedDoorCooldown = 1f; void Init() { permission.RegisterPermission($"{PluginName}.{PermissionName}", this); } void OnPlayerInput(BasePlayer player, InputState input) { if (player == null || input == null) return; BaseVehicle mountedVehicle = player.GetMountedVehicle() as BaseVehicle; if (mountedVehicle != null) { string prefabName = mountedVehicle.ShortPrefabName; // Ensure the player is the pilot if (!IsPilot(player, mountedVehicle)) return; if ((prefabName == "scraptransporthelicopter" || prefabName == "minicopter.entity") && input.WasJustPressed(BUTTON.FIRE_PRIMARY)) { if (permission.UserHasPermission(player.UserIDString, $"{PluginName}.{PermissionName}")) { Vector3 soundPosition = mountedVehicle.transform.position; // Play sound at the position of the mounted vehicle EmitSound(soundPosition, "assets/content/nexus/ferry/effects/nexus-ferry-departure-horn.prefab"); ToggleClosestAuthorizedDoor(player); } } else if (prefabName == "attackhelicopter.entity" && input.WasJustPressed(BUTTON.USE)) { if (permission.UserHasPermission(player.UserIDString, $"{PluginName}.{PermissionName}")) { Vector3 soundPosition = mountedVehicle.transform.position; // Play sound at the position of the mounted vehicle EmitSound(soundPosition, "assets/content/nexus/ferry/effects/nexus-ferry-departure-horn.prefab"); ToggleClosestAuthorizedDoor(player); } } } } private bool IsPilot(BasePlayer player, BaseVehicle vehicle) { var mountable = player.GetMounted(); if (mountable == null) return false; // Check if the mount points list is not empty and the player is in the first seat (pilot seat) return vehicle.mountPoints.Count > 0 && vehicle.mountPoints[0].mountable == mountable; } private void ToggleClosestAuthorizedDoor(BasePlayer player) { RaycastHit[] hits = Physics.SphereCastAll(player.transform.position, DoorOpenRange, Vector3.up, DoorOpenRange, LayerMask.GetMask("Construction")); BaseEntity closestDoor = null; float closestDistance = DoorOpenRange; foreach (var hit in hits) { BaseEntity entity = hit.GetEntity(); if (entity != null && IsDoor(entity) && IsAuthorized(player, entity)) { float distance = Vector3.Distance(player.transform.position, entity.transform.position); if (distance < closestDistance) { closestDistance = distance; closestDoor = entity; } } } if (closestDoor != null) { if (CanToggleDoor(closestDoor)) { Door door = closestDoor as Door; if (door != null) { door.SetOpen(!door.IsOpen()); UpdateLastToggleTime(closestDoor); } else { var garageDoor = closestDoor as AnimatedBuildingBlock; if (garageDoor != null) { garageDoor.SetFlag(BaseEntity.Flags.Open, !garageDoor.HasFlag(BaseEntity.Flags.Open)); garageDoor.SendNetworkUpdateImmediate(); UpdateLastToggleTime(closestDoor); } } } } } private bool CanToggleDoor(BaseEntity door) { float currentTime = Time.time; float lastToggleTime; if (lastToggleTimes.TryGetValue(door, out lastToggleTime)) { float cooldown = GetDoorCooldown(door); if (currentTime - lastToggleTime < cooldown) { return false; } } return true; } private void UpdateLastToggleTime(BaseEntity door) { lastToggleTimes[door] = Time.time; } private float GetDoorCooldown(BaseEntity door) { string prefabName = door.ShortPrefabName; if (prefabName.Contains("door.garage") || prefabName.Contains("wall.frame.garagedoor")) { return GarageDoorCooldown; } else if (prefabName.Contains("door.hinged") || prefabName.Contains("door.double.hinged") || prefabName.Contains("door.sheet") || prefabName.Contains("door.armored")) { return HingedDoorCooldown; } return 0f; } private bool IsAuthorized(BasePlayer player, BaseEntity entity) { var buildingPrivilege = entity.GetBuildingPrivilege(); return buildingPrivilege != null && buildingPrivilege.IsAuthed(player); } private bool IsDoor(BaseEntity entity) { return entity.ShortPrefabName.Contains("door.hinged") || entity.ShortPrefabName.Contains("door.double.hinged") || entity.ShortPrefabName.Contains("door.garage") || entity.ShortPrefabName.Contains("door.sheet") || entity.ShortPrefabName.Contains("door.armored") || entity.ShortPrefabName.Contains("wall.frame.garagedoor") || entity.ShortPrefabName.Contains("gates.external.high.wood") || entity.ShortPrefabName.Contains("gates.external.high.stone"); } private void EmitSound(Vector3 position, string soundPath) { Effect.server.Run(soundPath, position); } } }