C#:
// Все права принадлежат дискорд сообществу https://discord.gg/VgNHPpNrz6
// Plugin formatted by redBDGR's Plugin Formatting Tool
using Network;
using Oxide.Core;
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Oxide.Core.Configuration;
namespace Oxide.Plugins {
[Info("SlidingDoors", "redBDGR", "1.0.7")]
[Description("Doors can now slide instead of opening outwards")]
class SlidingDoors : RustPlugin {
private static SlidingDoors plugin;
private bool Changed;
private Coroutine initRoutine = null;
private const string permissionNameWood = "slidingdoors.wood";
private const string permissionNameScrap = "slidingdoors.scrap";
private const string permissionNameMetal = "slidingdoors.metal";
private const string permissionNameUse = "slidingdoors.use";
private const string permissionNameAutoDoor = "slidingdoors.autodoor";
private const string permissionNameAll = "slidingdoors.all";
private const string permissionNameAutoDeploy = "slidingdoors.autodeploy";
private DynamicConfigFile data;
private StoredData storedData;
private class StoredData {
public List<uint> doorIDs = new List<uint>();
}
private void SaveData() {
storedData.doorIDs = doorIDs;
data.WriteObject(storedData);
}
private void LoadData() {
try {
storedData = data.ReadObject<StoredData>();
doorIDs = storedData.doorIDs;
}
catch {
Puts("Failed to load data, creating new file");
storedData = new StoredData();
}
}
private List<uint> doorIDs = new List<uint>();
private Dictionary<string, float> autoDoorTimings = new Dictionary<string, float>();
private float doorSpeedMultiplierWood = 1f;
private float doorSpeedMultiplierScrap = 1f;
private float doorSpeedMultiplierMetal = 1f;
private bool needsCodeLockAuthToEnable = true;
private bool needsBuildingAuthToEnabled = true;
private bool enableForAllDoors = false;
private bool autoDoorEnabled = true;
private float defaultAutoDoorTime = 5f;
private void Init() {
data = Interface.Oxide.DataFileSystem.GetFile("SlidingDoors");
LoadData();
LoadVariables();
plugin = this;
permission.RegisterPermission(permissionNameWood, this);
permission.RegisterPermission(permissionNameScrap, this);
permission.RegisterPermission(permissionNameMetal, this);
permission.RegisterPermission(permissionNameUse, this);
permission.RegisterPermission(permissionNameAutoDoor, this);
permission.RegisterPermission(permissionNameAll, this);
permission.RegisterPermission(permissionNameAutoDeploy, this);
lang.RegisterMessages(new Dictionary<string, string> {
["No Permission"]
= "You are not allowed to use this command", ["No Entity Found"] = "No door was found", ["No Permission For DoorType"] = "You are not allowed to upgrade this type of door", ["Need Building Auth"] = "You need building authorization to upgrade this door", ["Need Lock Auth"] = "You need to be authorized on the lock to upgrade this door", ["Sliding Door Enabled"] = "Sliding door enabled", ["Sliding Door Disabled"] = "Sliding door disabled", ["/SAD Invalid Syntax"] = "Invaild Syntax! /sad <time>", ["Invalid Input"] = "Invalid time input!", ["SAD timing updated"] = "Sliding Auto Door timing has been updated",
}
, this);
}
private void OnServerInitialized() {
Puts("Initializing SlidingDoors on all appropriate doors");
initRoutine = ServerMgr.Instance.StartCoroutine(InitDoors());
}
protected override void LoadDefaultConfig() {
Config.Clear();
LoadVariables();
}
private void LoadVariables() {
doorSpeedMultiplierWood = Convert.ToSingle(GetConfig("Door Settings", "Door Speed Multiplier (Wood)", 1f));
doorSpeedMultiplierScrap = Convert.ToSingle(GetConfig("Door Settings", "Door Speed Multiplier (Scrap)", 1f));
doorSpeedMultiplierMetal = Convert.ToSingle(GetConfig("Door Settings", "Door Speed Multiplier (Metal)", 1f));
needsCodeLockAuthToEnable = Convert.ToBoolean(GetConfig("Door Settings", "Need Code Lock Auth To Enable", true));
needsBuildingAuthToEnabled = Convert.ToBoolean(GetConfig("Door Settings", "Need Building Auth To Enable", true));
enableForAllDoors = Convert.ToBoolean(GetConfig("Door Settings", "Enable For All Doors", false));
autoDoorEnabled = Convert.ToBoolean(GetConfig("AutoDoor Settings", "AutoDoors Enabled", true));
defaultAutoDoorTime = Convert.ToSingle(GetConfig("AutoDoor Settings", "Default Length", 5f));
if (!Changed) return;
SaveConfig();
Changed = false;
}
private void OnServerSave() {
SaveData();
}
private void Unload() {
SaveData();
if (initRoutine != null) {
ServerMgr.Instance.StopCoroutine(initRoutine);
Puts("Halting SlidingDoors initalization");
}
foreach (SlidingDoor slidingDoor in UnityEngine.Object.FindObjectsOfType<SlidingDoor>()) slidingDoor.DestroyThis();
}
private void OnEntitySpawned(BaseNetworkable entity) {
if (enableForAllDoors == true) {
if (entity.GetComponent<Door>()) {
if (entity.ShortPrefabName != "door.hinged.wood" && entity.ShortPrefabName != "door.hinged.metal" && entity.ShortPrefabName != "door.hinged.toptier") return;
entity.gameObject.AddComponent<SlidingDoor>();
entity.GetComponent<SlidingDoor>().origPos = entity.transform.position;
}
return;
}
BaseEntity ent = entity.GetComponent<BaseEntity>();
if (ent) if (permission.UserHasPermission(ent.OwnerID.ToString(), permissionNameAutoDeploy)) {
if (entity.ShortPrefabName != "door.hinged.wood" && entity.ShortPrefabName != "door.hinged.metal" && entity.ShortPrefabName != "door.hinged.toptier") return;
if (!PlayerCanUpgradeDoor(ent.OwnerID.ToString(), ent.ShortPrefabName)) return;
entity.gameObject.AddComponent<SlidingDoor>();
entity.GetComponent<SlidingDoor>().origPos = entity.transform.position;
doorIDs.Add(ent.net.ID);
}
}
private void OnEntityKill(BaseNetworkable entity) {
if (!enableForAllDoors) if (entity.GetComponent<Door>()) if (doorIDs.Contains(entity.net.ID)) doorIDs.Remove(entity.net.ID);
if (entity.GetComponent<DoorCloser>()) {
Door door = entity.GetComponentInParent<Door>();
if (door) if (door.GetComponent<SlidingDoor>()) door.GetComponent<SlidingDoor>().DoorCloserCheck();
}
}
private void OnDoorOpened(Door door, BasePlayer player) {
if (!door.GetComponent<SlidingDoor>()) return;
door.SetOpen(false);
SlidingDoor slidingDoor = door.GetComponent<SlidingDoor>();
if (autoDoorTimings.ContainsKey(player.UserIDString)) slidingDoor.closeLength = autoDoorTimings[player.UserIDString];
if (slidingDoor.isOpening || slidingDoor.isClosing) {
slidingDoor.PauseDoor();
return;
}
if (slidingDoor.isPaused) {
slidingDoor.UnpauseDoor();
return;
}
if (slidingDoor.isOpen) slidingDoor.CloseDoor();
else slidingDoor.OpenDoor();
}
private class SlidingDoor : MonoBehaviour {
private Door baseDoor;
private DoorType doorType;
public Vector3 origPos;
private Vector3 openPos;
private float openFrac = 0f;
public bool isOpening;
public bool isClosing;
public bool isPaused;
public bool wasOpening;
public bool isOpen;
private float doorSpeed;
public bool isAutoDoor = plugin.autoDoorEnabled;
public float closeLength = plugin.defaultAutoDoorTime;
private enum DoorType {
Wood, Scrap, Metal
}
private void Awake() {
origPos = transform.position;
openPos = transform.position + -transform.forward * 1.15f;
baseDoor = GetComponent<Door>();
switch (baseDoor.ShortPrefabName) {
case "door.hinged.wood" : doorType = DoorType.Wood;
doorSpeed = plugin.doorSpeedMultiplierWood;
break;
case "door.hinged.metal" : doorType = DoorType.Scrap;
doorSpeed = plugin.doorSpeedMultiplierScrap;
break;
case "door.hinged.toptier" : doorType = DoorType.Metal;
doorSpeed = plugin.doorSpeedMultiplierMetal;
break;
}
DoorCloserCheck();
}
private void OnDestroy() {
}
private void Update() {
if (baseDoor == null) return;
if (isOpening) {
transform.position = Vector3.Lerp(origPos, openPos, openFrac);
UpdatePos(baseDoor);
openFrac += (0.008f * doorSpeed);
if (openFrac >= 1f) {
switch (this.doorType) {
case DoorType.Wood : Effect.server.Run("assets/prefabs/building/door.hinged/effects/door-wood-open-end.prefab", baseDoor.transform.position);
break;
case DoorType.Scrap : Effect.server.Run("assets/prefabs/building/door.hinged/effects/door-metal-open-end.prefab", baseDoor.transform.position);
break;
case DoorType.Metal : Effect.server.Run("assets/prefabs/building/door.hinged/effects/door-metal-open-end.prefab", baseDoor.transform.position);
break;
}
isOpening = false;
}
}
else if (isClosing) {
transform.position = Vector3.Lerp(origPos, openPos, openFrac);
UpdatePos(baseDoor);
openFrac -= (0.008f * doorSpeed);
if (openFrac <= 0f) {
if (baseDoor.transform.position != origPos) {
baseDoor.transform.position = origPos;
UpdatePos(baseDoor);
}
switch (this.doorType) {
case DoorType.Wood : Effect.server.Run("assets/prefabs/building/door.hinged/effects/door-wood-close-end.prefab", baseDoor.transform.position);
break;
case DoorType.Scrap : Effect.server.Run("assets/prefabs/building/door.hinged/effects/door-metal-close-end.prefab", baseDoor.transform.position);
break;
case DoorType.Metal : Effect.server.Run("assets/prefabs/building/door.hinged/effects/door-metal-close-end.prefab", baseDoor.transform.position);
break;
}
isClosing = false;
}
}
}
public void DestroyThis() {
if (baseDoor != null) {
transform.position = origPos;
UpdatePos(baseDoor);
}
Destroy(this);
}
public void OpenDoor() {
isOpening = true;
isClosing = false;
isOpen = true;
switch (this.doorType) {
case DoorType.Wood : Effect.server.Run("assets/prefabs/building/door.hinged/effects/door-wood-open-start.prefab", baseDoor.transform.position);
break;
case DoorType.Scrap : Effect.server.Run("assets/prefabs/building/door.hinged/effects/door-metal-open-start.prefab", baseDoor.transform.position);
break;
case DoorType.Metal : Effect.server.Run("assets/prefabs/building/door.hinged/effects/door-metal-open-start.prefab", baseDoor.transform.position);
break;
}
if (isAutoDoor) if (plugin.permission.UserHasPermission(baseDoor.OwnerID.ToString(), "slidingdoors.autodoor") || plugin.permission.UserHasPermission(baseDoor.OwnerID.ToString(), "slidingdoors.all")) baseDoor.Invoke(AutoCloseThink, closeLength);
}
public void CloseDoor() {
isClosing = true;
isOpening = false;
isOpen = false;
switch (this.doorType) {
case DoorType.Wood : Effect.server.Run("assets/prefabs/building/door.hinged/effects/door-wood-close-start.prefab", baseDoor.transform.position);
break;
case DoorType.Scrap : Effect.server.Run("assets/prefabs/building/door.hinged/effects/door-metal-close-start.prefab", baseDoor.transform.position);
break;
case DoorType.Metal : Effect.server.Run("assets/prefabs/building/door.hinged/effects/door-metal-close-start.prefab", baseDoor.transform.position);
break;
}
}
public void PauseDoor() {
if (isClosing) wasOpening = false;
else if (isOpening) wasOpening = true;
isClosing = false;
isOpening = false;
isOpen = true;
isPaused = true;
}
public void UnpauseDoor() {
if (!wasOpening) OpenDoor();
else CloseDoor();
isPaused = false;
}
private void AutoCloseThink() {
if (isPaused || isOpening || !isOpen || isClosing) return;
CloseDoor();
}
private void UpdatePos(BaseNetworkable entity) {
entity.transform.hasChanged = true;
if (Network.Net.sv.write.Start()) {
Network.Net.sv.write.PacketID(Message.Type.EntityDestroy);
Network.Net.sv.write.UInt32(entity.net.ID);
Network.Net.sv.write.UInt8(0);
Network.Net.sv.write.Send(new SendInfo(entity.net.group.subscribers));
}
entity.InvalidateNetworkCache();
List<Connection> subscribers = entity.net.group == null ? Network.Net.sv.connections : entity.net.group.subscribers;
if (subscribers != null && subscribers.Count > 0) {
for (int i = 0; i < subscribers.Count; i++) {
Connection connection = subscribers[i];
BasePlayer basePlayer = connection.player as BasePlayer;
if (!(basePlayer == null)) {
if (Network.Net.sv.write.Start()) {
connection.validate.entityUpdates = connection.validate.entityUpdates + 1u;
BaseNetworkable.SaveInfo saveInfo = new BaseNetworkable.SaveInfo {
forConnection = connection, forDisk = false
}
;
Network.Net.sv.write.PacketID(Message.Type.Entities);
Network.Net.sv.write.UInt32(connection.validate.entityUpdates);
entity.ToStreamForNetwork(Network.Net.sv.write, saveInfo);
Network.Net.sv.write.Send(new SendInfo(connection));
}
}
}
}
entity.SendNetworkUpdateImmediate();
entity.UpdateNetworkGroup();
}
public void DoorCloserCheck() {
if (baseDoor.GetComponentInChildren<DoorCloser>()) isAutoDoor = true;
}
}
[ChatCommand("sdoor")]
private void SlidingDoorChatCommand(BasePlayer player, string command, string[] args) {
if (!permission.UserHasPermission(player.UserIDString, permissionNameUse) && !permission.UserHasPermission(player.UserIDString, permissionNameAll)) {
player.ChatMessage(msg("No Permission", player.UserIDString));
return;
}
if (needsBuildingAuthToEnabled) if (player.IsBuildingBlocked()) {
player.ChatMessage(msg("Need Building Auth", player.UserIDString));
return;
}
RaycastHit hit;
if (!UnityEngine.Physics.Raycast(player.eyes.HeadRay(), out hit, 3f)) {
player.ChatMessage(msg("No Entity Found", player.UserIDString));
return;
}
BaseEntity ent = hit.GetEntity();
if (ent == null) {
player.ChatMessage(msg("No Entity Found", player.UserIDString));
return;
}
Door door = ent.GetComponent<Door>();
if (door == null) {
player.ChatMessage(msg("No Entity Found", player.UserIDString));
return;
}
if (door.ShortPrefabName != "door.hinged.wood" && door.ShortPrefabName != "door.hinged.metal" && door.ShortPrefabName != "door.hinged.toptier") {
player.ChatMessage(msg("No Entiy Found", player.UserIDString));
return;
}
if (needsCodeLockAuthToEnable) if (door.GetPlayerLockPermission(player) == false) {
player.ChatMessage(msg("Need Lock Auth", player.UserIDString));
return;
}
if (!PlayerCanUpgradeDoor(player.UserIDString, door.ShortPrefabName)) {
player.ChatMessage(msg("No Permission For DoorType", player.UserIDString));
return;
}
SlidingDoor slidingDoor = door.GetComponent<SlidingDoor>();
if (slidingDoor) {
player.ChatMessage(msg("Sliding Door Disabled", player.UserIDString));
slidingDoor.DestroyThis();
if (!enableForAllDoors) if (doorIDs.Contains(door.net.ID)) doorIDs.Remove(door.net.ID);
return;
}
player.ChatMessage(msg("Sliding Door Enabled", player.UserIDString));
slidingDoor = door.gameObject.AddComponent<SlidingDoor>();
slidingDoor.origPos = door.transform.position;
if (!enableForAllDoors) doorIDs.Add(door.net.ID);
}
[ChatCommand("sad")]
private void SlidingAutoDoorCMD(BasePlayer player, string command, string[] args) {
if (!permission.UserHasPermission(player.UserIDString, permissionNameAutoDoor) && !permission.UserHasPermission(player.UserIDString, permissionNameAll)) {
player.ChatMessage(msg("No Permission", player.UserIDString));
return;
}
if (args.Length != 1) {
player.ChatMessage(msg("/SAD Invalid Syntax", player.UserIDString));
return;
}
float time;
try {
time = Convert.ToSingle(args[0]);
}
catch(Exception e) {
player.ChatMessage(msg("Invalid Input", player.UserIDString));
return;
}
if (!autoDoorTimings.ContainsKey(player.UserIDString)) autoDoorTimings.Add(player.UserIDString, time);
else autoDoorTimings[player.UserIDString] = time;
player.ChatMessage(msg("SAD timing updated", player.UserIDString));
}
[ConsoleCommand("cleansdoors")]
private void CleanSDoorsCMD(ConsoleSystem.Arg args) {
if (args.Connection != null) return;
foreach (Door door in UnityEngine.Object.FindObjectsOfType<Door>()) if (door.ShortPrefabName != "door.hinged.wood" && door.ShortPrefabName != "door.hinged.metal" && door.ShortPrefabName != "door.hinged.toptier") {
if (door.GetComponent<SlidingDoor>()) door.GetComponent<SlidingDoor>().DestroyThis();
}
args.ReplyWith("SlidingDoors have been cleaned");
}
private bool PlayerCanUpgradeDoor(string ownerID, string doorType) {
switch(doorType) {
case "door.hinged.wood" : if (permission.UserHasPermission(ownerID, permissionNameWood) || permission.UserHasPermission(ownerID, permissionNameAll)) return true;
break;
case "door.hinged.metal" : if (permission.UserHasPermission(ownerID, permissionNameScrap) || permission.UserHasPermission(ownerID, permissionNameAll)) return true;
break;
case "door.hinged.toptier" : if (permission.UserHasPermission(ownerID, permissionNameMetal) || permission.UserHasPermission(ownerID, permissionNameAll)) return true;
break;
default : return false;
}
return false;
}
private IEnumerator InitDoors() {
if (enableForAllDoors) {
foreach (Door door in UnityEngine.Object.FindObjectsOfType<Door>()) {
if (door != null) if (door.ShortPrefabName == "door.hinged.wood" || door.ShortPrefabName == "door.hinged.metal" || door.ShortPrefabName == "door.hinged.toptier") {
SlidingDoor sdoor = door.gameObject.AddComponent<SlidingDoor>();
sdoor.origPos = door.transform.position;
}
yield return new WaitForSeconds(0.01f);
}
}
else {
foreach (var entr in doorIDs) {
BaseEntity ent = BaseNetworkable.serverEntities.Find(entr)?.GetComponent<BaseEntity>();
if (ent) {
Door door = ent.GetComponent<Door>();
if (door) {
SlidingDoor sdoor = door.gameObject.AddComponent<SlidingDoor>();
sdoor.origPos = door.transform.position;
}
}
yield return new WaitForSeconds(0.01f);
}
}
Puts("Finished SlidingDoor initialization");
initRoutine = null;
}
private object GetConfig(string menu, string datavalue, object defaultValue) {
var data = Config[menu] as Dictionary<string, object>;
if (data == null) {
data = new Dictionary<string, object>();
Config[menu] = data;
Changed = true;
}
object value;
if (data.TryGetValue(datavalue, out value)) return value;
value = defaultValue;
data[datavalue] = value;
Changed = true;
return value;
}
private string msg(string key, string id = null) => lang.GetMessage(key, this, id);
}
}
// Слив плагинов server-rust by Apolo YouGame
// Plugin formatted by redBDGR's Plugin Formatting Tool