Skip to content

Commit 254c27a

Browse files
feat: Add Exiled.API.Features.Workstation (#568)
* Add Exiled.API.Features.Workstation * fix * Approve the feedback * omg * fix: Workstation ctor could be called twice * use Transform --------- Co-authored-by: Yamato <louismonneyron5@yahoo.com> Co-authored-by: Yamato <66829532+louis1706@users.noreply.github.com>
1 parent 573cc6a commit 254c27a

2 files changed

Lines changed: 206 additions & 0 deletions

File tree

Lines changed: 167 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,167 @@
1+
// -----------------------------------------------------------------------
2+
// <copyright file="Workstation.cs" company="ExMod Team">
3+
// Copyright (c) ExMod Team. All rights reserved.
4+
// Licensed under the CC BY-SA 3.0 license.
5+
// </copyright>
6+
// -----------------------------------------------------------------------
7+
8+
namespace Exiled.API.Features
9+
{
10+
using System;
11+
using System.Collections.Generic;
12+
using System.Diagnostics;
13+
using System.Linq;
14+
15+
using Exiled.API.Enums;
16+
using Exiled.API.Interfaces;
17+
using InventorySystem.Items.Firearms.Attachments;
18+
using Mirror;
19+
using UnityEngine;
20+
21+
/// <summary>
22+
/// A wrapper class for <see cref="WorkstationController"/>.
23+
/// </summary>
24+
public class Workstation : IWrapper<WorkstationController>, IWorldSpace
25+
{
26+
/// <summary>
27+
/// A dictionary mapping <see cref="WorkstationController"/> to <see cref="Workstation"/>.
28+
/// </summary>
29+
internal static readonly Dictionary<WorkstationController, Workstation> WorkstationControllerToWorkstation = new(new ComponentsEqualityComparer());
30+
31+
/// <summary>
32+
/// Initializes a new instance of the <see cref="Workstation"/> class.
33+
/// </summary>
34+
/// <param name="workstationController">The <see cref="WorkstationController"/> to wrap.</param>
35+
internal Workstation(WorkstationController workstationController)
36+
{
37+
WorkstationControllerToWorkstation.Add(workstationController, this);
38+
Base = workstationController;
39+
}
40+
41+
/// <summary>
42+
/// Gets a read-only collection of all <see cref="Workstation"/> instances.
43+
/// </summary>
44+
public static IReadOnlyCollection<Workstation> List => WorkstationControllerToWorkstation.Values;
45+
46+
/// <summary>
47+
/// Gets the underlying <see cref="WorkstationController"/> instance.
48+
/// </summary>
49+
public WorkstationController Base { get; }
50+
51+
/// <summary>
52+
/// Gets the <see cref="GameObject"/> of the workstation.
53+
/// </summary>
54+
public GameObject GameObject => Base.gameObject;
55+
56+
/// <summary>
57+
/// Gets the <see cref="Transform"/> of the workstation.
58+
/// </summary>
59+
public Transform Transform => Base.transform;
60+
61+
/// <summary>
62+
/// Gets the <see cref="Room"/> the workstation is located in.
63+
/// </summary>
64+
public Room Room => Room.Get(Position);
65+
66+
/// <summary>
67+
/// Gets the <see cref="ZoneType"/> of the workstation's room.
68+
/// </summary>
69+
public ZoneType Zone => Room.Zone;
70+
71+
/// <summary>
72+
/// Gets or sets the position of the workstation.
73+
/// </summary>
74+
public Vector3 Position
75+
{
76+
get => Transform.position;
77+
set
78+
{
79+
NetworkServer.UnSpawn(GameObject);
80+
Transform.position = value;
81+
NetworkServer.Spawn(GameObject);
82+
}
83+
}
84+
85+
/// <summary>
86+
/// Gets or sets the rotation of the workstation.
87+
/// </summary>
88+
public Quaternion Rotation
89+
{
90+
get => Transform.rotation;
91+
set
92+
{
93+
NetworkServer.UnSpawn(GameObject);
94+
Transform.rotation = value;
95+
NetworkServer.Spawn(GameObject);
96+
}
97+
}
98+
99+
/// <summary>
100+
/// Gets or sets the status of the workstation.
101+
/// </summary>
102+
public WorkstationController.WorkstationStatus Status
103+
{
104+
get => (WorkstationController.WorkstationStatus)Base.Status;
105+
set => Base.NetworkStatus = (byte)value;
106+
}
107+
108+
/// <summary>
109+
/// Gets the <see cref="Stopwatch"/> used by the workstation.
110+
/// </summary>
111+
public Stopwatch Stopwatch => Base.ServerStopwatch;
112+
113+
/// <summary>
114+
/// Gets or sets the player known to be using the workstation.
115+
/// </summary>
116+
public Player KnownUser
117+
{
118+
get => Player.Get(Base.KnownUser);
119+
set => Base.KnownUser = value.ReferenceHub;
120+
}
121+
122+
/// <summary>
123+
/// Gets a <see cref="Workstation"/> given a <see cref="WorkstationController"/> instance.
124+
/// </summary>
125+
/// <param name="workstationController">The <see cref="WorkstationController"/> instance.</param>
126+
/// <returns>The <see cref="Workstation"/> instance.</returns>
127+
public static Workstation Get(WorkstationController workstationController) => WorkstationControllerToWorkstation.TryGetValue(workstationController, out Workstation workstation) ? workstation : new(workstationController);
128+
129+
/// <summary>
130+
/// Gets all <see cref="Workstation"/> instances that match the specified predicate.
131+
/// </summary>
132+
/// <param name="predicate">The predicate to filter workstations.</param>
133+
/// <returns>An <see cref="IEnumerable{Workstation}"/> of matching workstations.</returns>
134+
public static IEnumerable<Workstation> Get(Func<Workstation, bool> predicate) => List.Where(predicate);
135+
136+
/// <summary>
137+
/// Tries to get all <see cref="Workstation"/> instances that match the specified predicate.
138+
/// </summary>
139+
/// <param name="predicate">The predicate to filter workstations.</param>
140+
/// <param name="workstations">The matching workstations, if any.</param>
141+
/// <returns><c>true</c> if any workstations were found; otherwise, <c>false</c>.</returns>
142+
public static bool TryGet(Func<Workstation, bool> predicate, out IEnumerable<Workstation> workstations)
143+
{
144+
workstations = Get(predicate);
145+
return workstations.Any();
146+
}
147+
148+
/// <summary>
149+
/// Determines whether the specified player is in range of the workstation.
150+
/// </summary>
151+
/// <param name="player">The player to check.</param>
152+
/// <returns><c>true</c> if the player is in range; otherwise, <c>false</c>.</returns>
153+
public bool IsInRange(Player player) => Base.IsInRange(player.ReferenceHub);
154+
155+
/// <summary>
156+
/// Interacts with the workstation as the specified player.
157+
/// </summary>
158+
/// <param name="player">The player to interact as.</param>
159+
public void Interact(Player player) => Base.ServerInteract(player.ReferenceHub, Base.ActivateCollider.ColliderId);
160+
161+
/// <summary>
162+
/// Returns the Room in a human-readable format.
163+
/// </summary>
164+
/// <returns>A string containing Workstation-related data.</returns>
165+
public override string ToString() => $"{GameObject.name} ({Zone}) [{Room}]";
166+
}
167+
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
// -----------------------------------------------------------------------
2+
// <copyright file="WorkstationListAdd.cs" company="ExMod Team">
3+
// Copyright (c) ExMod Team. All rights reserved.
4+
// Licensed under the CC BY-SA 3.0 license.
5+
// </copyright>
6+
// -----------------------------------------------------------------------
7+
8+
namespace Exiled.Events.Patches.Generic
9+
{
10+
#pragma warning disable SA1313
11+
#pragma warning disable SA1402
12+
13+
using HarmonyLib;
14+
using InventorySystem.Items.Firearms.Attachments;
15+
16+
/// <summary>
17+
/// Patch for adding <see cref="API.Features.Workstation"/> to list.
18+
/// </summary>
19+
[HarmonyPatch(typeof(WorkstationController), nameof(WorkstationController.Start))]
20+
internal class WorkstationListAdd
21+
{
22+
private static void Postfix(WorkstationController __instance)
23+
{
24+
API.Features.Workstation.Get(__instance);
25+
}
26+
}
27+
28+
/// <summary>
29+
/// Patch for removing <see cref="API.Features.Workstation"/> to list.
30+
/// </summary>
31+
[HarmonyPatch(typeof(WorkstationController), nameof(WorkstationController.OnDestroy))]
32+
internal class WorkstationListRemove
33+
{
34+
private static void Postfix(WorkstationController __instance)
35+
{
36+
API.Features.Workstation.WorkstationControllerToWorkstation.Remove(__instance);
37+
}
38+
}
39+
}

0 commit comments

Comments
 (0)