diff --git a/CustomDoors.sln b/CustomDoors.sln
new file mode 100644
index 0000000..75a1b52
--- /dev/null
+++ b/CustomDoors.sln
@@ -0,0 +1,25 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 17
+VisualStudioVersion = 17.4.33205.214
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CustomDoors", "CustomDoors\CustomDoors.csproj", "{5C3C6AB7-7310-4079-841B-3B3746D6B4DA}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {5C3C6AB7-7310-4079-841B-3B3746D6B4DA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {5C3C6AB7-7310-4079-841B-3B3746D6B4DA}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {5C3C6AB7-7310-4079-841B-3B3746D6B4DA}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {5C3C6AB7-7310-4079-841B-3B3746D6B4DA}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {0AB60A2F-7585-419B-A7E6-1F1C7C40DBE3}
+ EndGlobalSection
+EndGlobal
diff --git a/CustomDoors/Config.cs b/CustomDoors/Config.cs
new file mode 100644
index 0000000..2c2f5a4
--- /dev/null
+++ b/CustomDoors/Config.cs
@@ -0,0 +1,41 @@
+using Interactables.Interobjects.DoorUtils;
+using System.ComponentModel;
+
+namespace CustomDoors
+{
+ public class Config
+ {
+ [Description("Debug command ? (sends a debug message to the server console when using position command) :")]
+ public bool DebugCommand { get; set; } = false;
+
+ [Description("List of doors and their caracteristics")]
+ public DoorConfig[] Doors { get; set; } = new DoorConfig[2]
+ {
+ new DoorConfig() { Type = "HCZ", RoomName = "Outside", RelativePositionX =29, RelativePositionY = -8.35f, RelativePositionZ = -42.8f, ScaleX = 1, ScaleY =1, ScaleZ = 1, KeycardPermissions = KeycardPermissions.ExitGates },
+ new DoorConfig() { Type = "EZ", RoomName = "LCZ_Airlock (1)", defaultRoomRotationYAxis = 90, RelativePositionX = -3.5f, RelativePositionY = 0.9685f, RelativePositionZ= 0, ScaleX = 1, ScaleY =1, ScaleZ = 1, KeycardPermissions = KeycardPermissions.ContainmentLevelOne, Opened = true }
+ };
+ }
+
+ public struct DoorConfig
+ {
+ public string Type { get; set; }
+ public string RoomName { get; set; }
+
+ public float defaultRoomRotationYAxis { get; set; }
+
+ public float RelativePositionX { get; set; }
+ public float RelativePositionY { get; set; }
+ public float RelativePositionZ { get; set; }
+
+ public float RotationX { get; set; }
+ public float RotationY { get; set; }
+ public float RotationZ { get; set; }
+
+ public float ScaleX { get; set; }
+ public float ScaleY { get; set; }
+ public float ScaleZ { get; set; }
+ public KeycardPermissions KeycardPermissions { get; set; }
+ public bool Opened { get; set; }
+ public bool Locked { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/CustomDoors/CustomDoors.csproj b/CustomDoors/CustomDoors.csproj
new file mode 100644
index 0000000..6d0a83e
--- /dev/null
+++ b/CustomDoors/CustomDoors.csproj
@@ -0,0 +1,38 @@
+
+
+
+ preview
+ net4.8
+ Bonjemus
+ Fondation Azarus
+ More doors = More fun ! Allows server owners to add custom doors.
+ Bonjemus
+ CustomDoors
+
+
+
+
+
+
+
+
+ Packages\Assembly-CSharp.dll
+
+
+ Packages\CommandSystem.Core.dll
+
+
+ Packages\Mirror.dll
+
+
+ Packages\NorthwoodLib.dll
+
+
+ Packages\UnityEngine.CoreModule.dll
+
+
+ Packages\UnityEngine.PhysicsModule.dll
+
+
+
+
diff --git a/CustomDoors/EventHandler.cs b/CustomDoors/EventHandler.cs
new file mode 100644
index 0000000..7eadd35
--- /dev/null
+++ b/CustomDoors/EventHandler.cs
@@ -0,0 +1,47 @@
+using PluginAPI.Core.Attributes;
+using Mirror;
+using PluginAPI.Enums;
+using UnityEngine;
+using Interactables.Interobjects.DoorUtils;
+using System.Linq;
+using MapGeneration;
+using System;
+
+namespace CustomDoors
+{
+ public class EventHandler
+ {
+ [PluginEvent(ServerEventType.WaitingForPlayers)]
+ public void WaitingForPlayers()
+ {
+ foreach (DoorConfig doorConfig in PluginClass.Singleton.config.Doors)
+ {
+ RoomIdentifier room = RoomIdentifier.AllRoomIdentifiers.FirstOrDefault(r => r.name == doorConfig.RoomName);
+
+ if (room == null)
+ continue;
+
+ Vector3 scale = new(doorConfig.ScaleX, doorConfig.ScaleY, doorConfig.ScaleZ);
+
+ float roomRotationDiffY = doorConfig.defaultRoomRotationYAxis - room.transform.rotation.eulerAngles.y;
+
+ Vector3 doorRotation = new(doorConfig.RotationX, doorConfig.RotationY + roomRotationDiffY, doorConfig.RotationZ);
+
+ Vector3 relativePosition = new(doorConfig.RelativePositionX, doorConfig.RelativePositionY, doorConfig.RelativePositionZ);
+
+ Vector3 rotatedRelativePosition = new(
+ relativePosition.x * (float)Math.Cos(roomRotationDiffY * Math.PI / 180) - relativePosition.z * (float)Math.Sin(roomRotationDiffY * Math.PI / 180), // Math.PI / 180 : convert angle to radian
+ relativePosition.y,
+ relativePosition.z * (float)Math.Cos(roomRotationDiffY * Math.PI / 180) + relativePosition.x * (float)Math.Sin(roomRotationDiffY * Math.PI / 180)
+ );
+
+ DoorVariant door = UnityEngine.Object.Instantiate(UnityEngine.Object.FindObjectsOfType().First(d => d.TargetPrefab.name.Contains(doorConfig.Type)).TargetPrefab, room.transform.position + rotatedRelativePosition, Quaternion.Euler(doorRotation));
+ door.transform.localScale = scale;
+ door.RequiredPermissions.RequiredPermissions = doorConfig.KeycardPermissions;
+ NetworkServer.Spawn(door.gameObject);
+ door.ServerChangeLock(DoorLockReason.SpecialDoorFeature, doorConfig.Locked);
+ door.TargetState = doorConfig.Opened;
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/CustomDoors/Packages/Assembly-CSharp.dll b/CustomDoors/Packages/Assembly-CSharp.dll
new file mode 100644
index 0000000..95a31b2
Binary files /dev/null and b/CustomDoors/Packages/Assembly-CSharp.dll differ
diff --git a/CustomDoors/Packages/CommandSystem.Core.dll b/CustomDoors/Packages/CommandSystem.Core.dll
new file mode 100644
index 0000000..ee682a6
Binary files /dev/null and b/CustomDoors/Packages/CommandSystem.Core.dll differ
diff --git a/CustomDoors/Packages/Mirror.dll b/CustomDoors/Packages/Mirror.dll
new file mode 100644
index 0000000..f48aff2
Binary files /dev/null and b/CustomDoors/Packages/Mirror.dll differ
diff --git a/CustomDoors/Packages/NorthwoodLib.dll b/CustomDoors/Packages/NorthwoodLib.dll
new file mode 100644
index 0000000..8f3386a
Binary files /dev/null and b/CustomDoors/Packages/NorthwoodLib.dll differ
diff --git a/CustomDoors/Packages/UnityEngine.CoreModule.dll b/CustomDoors/Packages/UnityEngine.CoreModule.dll
new file mode 100644
index 0000000..7cc5e08
Binary files /dev/null and b/CustomDoors/Packages/UnityEngine.CoreModule.dll differ
diff --git a/CustomDoors/Packages/UnityEngine.PhysicsModule.dll b/CustomDoors/Packages/UnityEngine.PhysicsModule.dll
new file mode 100644
index 0000000..1cd1e57
Binary files /dev/null and b/CustomDoors/Packages/UnityEngine.PhysicsModule.dll differ
diff --git a/CustomDoors/PluginClass.cs b/CustomDoors/PluginClass.cs
new file mode 100644
index 0000000..2ec9150
--- /dev/null
+++ b/CustomDoors/PluginClass.cs
@@ -0,0 +1,27 @@
+using PluginAPI.Core.Attributes;
+using PluginAPI.Core;
+using PluginAPI.Enums;
+using PluginAPI.Events;
+
+namespace CustomDoors
+{
+ public class PluginClass
+ {
+ public static PluginClass Singleton { get; private set; }
+
+ [PluginPriority(LoadPriority.Low)]
+ [PluginEntryPoint("Custom Doors", "1.0.0", "More doors = More fun ! Allows server owners to add custom doors.", "Bonjemus")]
+ void LoadPlugin()
+ {
+ Singleton = this;
+
+ EventManager.RegisterEvents(this);
+
+ PluginHandler eventHandler = PluginHandler.Get(this);
+ eventHandler.SaveConfig(this, nameof(config));
+ }
+
+ [PluginConfig("configs/CustomDoors.yml")]
+ public Config config;
+ }
+}
\ No newline at end of file
diff --git a/CustomDoors/PositionCommand.cs b/CustomDoors/PositionCommand.cs
new file mode 100644
index 0000000..e6b6169
--- /dev/null
+++ b/CustomDoors/PositionCommand.cs
@@ -0,0 +1,37 @@
+using CommandSystem;
+using MapGeneration;
+using PluginAPI.Core;
+using System;
+
+namespace CustomDoors
+{
+ [CommandHandler(typeof(RemoteAdminCommandHandler))]
+ public class PositionCommand : ICommand
+ {
+ public string Command { get; } = "Position";
+
+ public string[] Aliases { get; } = new string[] { };
+
+ public string Description { get; } = "Gives you your position.";
+
+ public bool Execute(ArraySegment arguments, ICommandSender sender, out string response)
+ {
+ Player player = Player.Get(((CommandSender)sender).SenderId);
+ RoomIdentifier room = player.Room;
+
+
+ /*if (RoomIdentifier.RoomsByCoordinates.TryGetValue(new Vector3Int(Mathf.RoundToInt(player.Position.x / RoomIdentifier.GridScale.x), Mathf.RoundToInt(player.Position.y / 100f), Mathf.RoundToInt(player.Position.z / RoomIdentifier.GridScale.x)), out var value))
+ room = value;
+ else
+ room = RoomIdentifier.RoomsByCoordinates.Values.OrderBy(r => Vector3.Distance(r.transform.position, player.Position)).FirstOrDefault();*/
+
+
+
+ response = $"{room.name} :\nRoom position : {room.transform.position}\nRoom rotation : {room.transform.rotation.eulerAngles}\nYour position : {player.Position}\nRelative position to room :\nx = {(player.Position - room.transform.position).x}\ny = {(player.Position - room.transform.position).y}\nz = {(player.Position - room.transform.position).z}";
+
+ if (PluginClass.Singleton.config.DebugCommand)
+ Log.Debug(response);
+ return true;
+ }
+ }
+}
\ No newline at end of file