diff --git a/Features/Enums/BlockType.cs b/Features/Enums/BlockType.cs index 7555b98..8c6ac17 100644 --- a/Features/Enums/BlockType.cs +++ b/Features/Enums/BlockType.cs @@ -44,4 +44,9 @@ public enum BlockType /// Represents a locker. /// Locker = 7, + + /// + /// Represents a Interactable. + /// + Interactable = 8, } diff --git a/Features/Enums/ToolGunObjectType.cs b/Features/Enums/ToolGunObjectType.cs index 7c5a07b..b2f822a 100644 --- a/Features/Enums/ToolGunObjectType.cs +++ b/Features/Enums/ToolGunObjectType.cs @@ -11,7 +11,8 @@ public enum ToolGunObjectType PlayerSpawnpoint = 6, Capybara = 7, Text = 8, - Scp079Camera = 9, - ShootingTarget = 10, - Teleport = 11, + Interactable = 9, + Scp079Camera = 10, + ShootingTarget = 11, + Teleport = 12, } diff --git a/Features/ObjectSpawner.cs b/Features/ObjectSpawner.cs index 821e3a6..64bb09c 100644 --- a/Features/ObjectSpawner.cs +++ b/Features/ObjectSpawner.cs @@ -14,6 +14,12 @@ public static PrimitiveObjectToy SpawnPrimitive(SerializablePrimitive serializab return gameObject.GetComponent(); } + public static InvisibleInteractableToy SpawnInteractable(SerializableInteractable serializableInteractable) + { + GameObject gameObject = serializableInteractable.SpawnOrUpdateObject(); + return gameObject.GetComponent(); + } + public static SchematicObject SpawnSchematic(SerializableSchematic serializableSchematic) { GameObject? gameObject = serializableSchematic.SpawnOrUpdateObject(); diff --git a/Features/PrefabManager.cs b/Features/PrefabManager.cs index c87ecfe..2953ed9 100644 --- a/Features/PrefabManager.cs +++ b/Features/PrefabManager.cs @@ -11,6 +11,8 @@ public static class PrefabManager public static PrimitiveObjectToy PrimitiveObjectPrefab { get; private set; } public static LightSourceToy LightSourcePrefab { get; private set; } + + public static InvisibleInteractableToy InvisibleInteractableToy { get; private set; } public static DoorVariant LczDoorPrefab { get; private set; } public static DoorVariant HczDoorPrefab { get; private set; } @@ -48,6 +50,12 @@ public static void RegisterPrefabs() LightSourcePrefab = lightSourceToy; continue; } + + if (gameObject.TryGetComponent(out InvisibleInteractableToy invisibleInteractableToy)) + { + InvisibleInteractableToy = invisibleInteractableToy; + continue; + } if (gameObject.TryGetComponent(out DoorVariant doorVariant)) { diff --git a/Features/Serializable/MapSchematic.cs b/Features/Serializable/MapSchematic.cs index e0e70aa..1bc2699 100644 --- a/Features/Serializable/MapSchematic.cs +++ b/Features/Serializable/MapSchematic.cs @@ -24,6 +24,8 @@ public MapSchematic(string mapName) public Dictionary Primitives { get; set; } = []; public Dictionary Lights { get; set; } = []; + + public Dictionary Interactables { get; set; } = []; public Dictionary Doors { get; set; } = []; @@ -51,6 +53,7 @@ public MapSchematic Merge(MapSchematic other) { Primitives.AddRange(other.Primitives); Lights.AddRange(other.Lights); + Interactables.AddRange(other.Interactables); Doors.AddRange(other.Doors); Workstations.AddRange(other.Workstations); ItemSpawnpoints.AddRange(other.ItemSpawnpoints); @@ -74,6 +77,7 @@ public void Reload() Primitives.ForEach(kVP => SpawnObject(kVP.Key, kVP.Value)); Lights.ForEach(kVP => SpawnObject(kVP.Key, kVP.Value)); + Interactables.ForEach(kVP => SpawnObject(kVP.Key, kVP.Value)); Doors.ForEach(kVP => { Door? vanillaDoor = Door.Get(kVP.Key); diff --git a/Features/Serializable/Schematics/SchematicBlockData.cs b/Features/Serializable/Schematics/SchematicBlockData.cs index f2ee1c8..aa5df37 100644 --- a/Features/Serializable/Schematics/SchematicBlockData.cs +++ b/Features/Serializable/Schematics/SchematicBlockData.cs @@ -41,6 +41,7 @@ public GameObject Create(SchematicObject schematicObject, Transform parentTransf BlockType.Light => CreateLight(), BlockType.Pickup => CreatePickup(schematicObject), BlockType.Workstation => CreateWorkstation(), + BlockType.Interactable => CreateInteractable(), _ => CreateEmpty(true) }; @@ -138,4 +139,16 @@ private GameObject CreateWorkstation() return workstation.gameObject; } + + private GameObject CreateInteractable() + { + InvisibleInteractableToy interactableToy = GameObject.Instantiate(PrefabManager.InvisibleInteractableToy); + interactableToy.NetworkMovementSmoothing = 60; + + interactableToy.NetworkShape = (InvisibleInteractableToy.ColliderShape)Convert.ToInt32(Properties["Shape"]); + interactableToy.NetworkInteractionDuration = float.Parse(Properties["InteractionDuration"].ToString()); + interactableToy.NetworkIsLocked = bool.Parse(Properties["IsLocked"].ToString()); + + return interactableToy.gameObject; + } } diff --git a/Features/Serializable/SerializableInteractable.cs b/Features/Serializable/SerializableInteractable.cs new file mode 100644 index 0000000..4e6d402 --- /dev/null +++ b/Features/Serializable/SerializableInteractable.cs @@ -0,0 +1,36 @@ +using AdminToys; +using Room = LabApi.Features.Wrappers.Room; +using Mirror; +using ProjectMER.Features.Extensions; +using ProjectMER.Features.Interfaces; +using UnityEngine; + +namespace ProjectMER.Features.Serializable; + +public class SerializableInteractable : SerializableObject +{ + public InvisibleInteractableToy.ColliderShape Shape { get; set; } = InvisibleInteractableToy.ColliderShape.Box; + public float InteractionDuration { get; set; } = 5f; + public bool Locked { get; set; } = false; + + public override GameObject SpawnOrUpdateObject(Room? room = null, GameObject? instance = null) + { + InvisibleInteractableToy interactableToy = instance == null ? UnityEngine.Object.Instantiate(PrefabManager.InvisibleInteractableToy) : instance.GetComponent(); + Vector3 position = room.GetAbsolutePosition(Position); + Quaternion rotation = room.GetAbsoluteRotation(Rotation); + _prevIndex = Index; + + interactableToy.transform.SetPositionAndRotation(position, rotation); + interactableToy.transform.localScale = Scale; + interactableToy.NetworkMovementSmoothing = 60; + + interactableToy.NetworkShape = Shape; + interactableToy.NetworkInteractionDuration = InteractionDuration; + interactableToy.NetworkIsLocked = Locked; + + if (instance == null) + NetworkServer.Spawn(interactableToy.gameObject); + + return interactableToy.gameObject; + } +} \ No newline at end of file diff --git a/Features/ToolGun/ToolGunItem.cs b/Features/ToolGun/ToolGunItem.cs index 2d26ec1..6362371 100644 --- a/Features/ToolGun/ToolGunItem.cs +++ b/Features/ToolGun/ToolGunItem.cs @@ -20,6 +20,7 @@ public class ToolGunItem { { ToolGunObjectType.Primitive, typeof(SerializablePrimitive) }, { ToolGunObjectType.Light, typeof(SerializableLight) }, + { ToolGunObjectType.Interactable, typeof(SerializableInteractable) }, { ToolGunObjectType.Door, typeof(SerializableDoor) }, { ToolGunObjectType.Workstation, typeof(SerializableWorkstation) }, { ToolGunObjectType.ItemSpawnpoint, typeof(SerializableItemSpawnpoint)},