Skip to content

Commit c425509

Browse files
authored
Merge pull request ExMod-Team#5 from ExMod-Team/dev
Dev
2 parents a4348e0 + fb40d83 commit c425509

File tree

31 files changed

+885
-85
lines changed

31 files changed

+885
-85
lines changed

.github/workflows/programs.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ jobs:
3636
run: dotnet publish ${{ matrix.proj_name }} -r ${{ matrix.target }} -c release -o builds/${{ matrix.target }} --self-contained true
3737

3838
- name: Upload ${{ matrix.proj_name }}@${{ matrix.target }} build
39-
uses: actions/upload-artifact@v2
39+
uses: actions/upload-artifact@v4
4040
with:
4141
name: ${{ matrix.proj_name }}-${{ matrix.target }}
4242
path: EXILED/builds/${{ matrix.target }}

EXILED/Exiled.API/Enums/LockerType.cs

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
// -----------------------------------------------------------------------
2+
// <copyright file="LockerType.cs" company="Exiled Team">
3+
// Copyright (c) Exiled Team. All rights reserved.
4+
// Licensed under the CC BY-SA 3.0 license.
5+
// </copyright>
6+
// -----------------------------------------------------------------------
7+
8+
namespace Exiled.API.Enums
9+
{
10+
/// <summary>
11+
/// Unique identifier for different types of <see cref="Features.Lockers.Locker"/>s.
12+
/// </summary>
13+
public enum LockerType
14+
{
15+
/// <summary>
16+
/// The pedestal used by SCP items.
17+
/// </summary>
18+
Pedestal,
19+
20+
/// <summary>
21+
/// Large weapon locker.
22+
/// </summary>
23+
LargeGun,
24+
25+
/// <summary>
26+
/// Locker for rifles, known as a rifle rack.
27+
/// </summary>
28+
RifleRack,
29+
30+
/// <summary>
31+
/// Miscellaneous locker for various items.
32+
/// </summary>
33+
Misc,
34+
35+
/// <summary>
36+
/// Locker that contains medkits.
37+
/// </summary>
38+
Medkit,
39+
40+
/// <summary>
41+
/// Locker that contains adrenaline.
42+
/// </summary>
43+
Adrenaline,
44+
45+
/// <summary>
46+
/// Unknow type of locker.
47+
/// </summary>
48+
Unknow,
49+
}
50+
}

EXILED/Exiled.API/Enums/SpawnLocationType.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,10 @@
44
// Licensed under the CC BY-SA 3.0 license.
55
// </copyright>
66
// -----------------------------------------------------------------------
7-
87
namespace Exiled.API.Enums
98
{
9+
using System;
10+
1011
/// <summary>
1112
/// All of the valid spawn location types.
1213
/// </summary>
@@ -150,6 +151,7 @@ public enum SpawnLocationType
150151
/// <summary>
151152
/// Inside a random locker on the map.
152153
/// </summary>
154+
[Obsolete("Use LockerSpawnPoint instead")]
153155
InsideLocker,
154156
}
155157
}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
// -----------------------------------------------------------------------
2+
// <copyright file="LockerExtensions.cs" company="Exiled Team">
3+
// Copyright (c) Exiled Team. All rights reserved.
4+
// Licensed under the CC BY-SA 3.0 license.
5+
// </copyright>
6+
// -----------------------------------------------------------------------
7+
8+
namespace Exiled.API.Extensions
9+
{
10+
using System;
11+
12+
using Exiled.API.Enums;
13+
using MapGeneration.Distributors;
14+
15+
/// <summary>
16+
/// A set of extensions for <see cref="Enums.LockerType"/>.
17+
/// </summary>
18+
public static class LockerExtensions
19+
{
20+
/// <summary>
21+
/// Gets the <see cref="LockerType"/> from the given <see cref="Locker"/> object.
22+
/// </summary>
23+
/// <param name="locker">The <see cref="Locker"/> to check.</param>
24+
/// <returns>The corresponding <see cref="LockerType"/>.</returns>
25+
public static LockerType GetLockerType(this Locker locker) => locker.name.GetLockerTypeByName();
26+
27+
/// <summary>
28+
/// Gets the <see cref="LockerType"/> by name.
29+
/// </summary>
30+
/// <param name="name">The name to check.</param>
31+
/// <returns>The corresponding <see cref="LockerType"/>.</returns>
32+
public static LockerType GetLockerTypeByName(this string name) => name.Replace("(Clone)", string.Empty) switch
33+
{
34+
"Scp500PedestalStructure Variant" => LockerType.Pedestal,
35+
"LargeGunLockerStructure" => LockerType.LargeGun,
36+
"RifleRackStructure" => LockerType.RifleRack,
37+
"MiscLocker" => LockerType.Misc,
38+
"RegularMedkitStructure" => LockerType.Medkit,
39+
"AdrenalineMedkitStructure" => LockerType.Adrenaline,
40+
_ => LockerType.Unknow,
41+
};
42+
}
43+
}

EXILED/Exiled.API/Extensions/MirrorExtensions.cs

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -271,6 +271,15 @@ public static void ChangeAppearance(this Player player, RoleTypeId type, IEnumer
271271
writer.WriteByte(unitId);
272272
}
273273

274+
if (roleBase is ZombieRole)
275+
{
276+
if (player.Role.Base is not ZombieRole)
277+
isRisky = true;
278+
279+
writer.WriteUShort((ushort)Mathf.Clamp(Mathf.CeilToInt(player.MaxHealth), ushort.MinValue, ushort.MaxValue));
280+
writer.WriteBool(true);
281+
}
282+
274283
if (roleBase is FpcStandardRoleBase fpc)
275284
{
276285
if (player.Role.Base is not FpcStandardRoleBase playerfpc)
@@ -284,14 +293,6 @@ public static void ChangeAppearance(this Player player, RoleTypeId type, IEnumer
284293
writer.WriteUShort(value);
285294
}
286295

287-
if (roleBase is ZombieRole)
288-
{
289-
if (player.Role.Base is not ZombieRole)
290-
isRisky = true;
291-
292-
writer.WriteUShort((ushort)Mathf.Clamp(Mathf.CeilToInt(player.MaxHealth), ushort.MinValue, ushort.MaxValue));
293-
}
294-
295296
foreach (Player target in playersToAffect)
296297
{
297298
if (target != player || !isRisky)
Lines changed: 224 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,224 @@
1+
// -----------------------------------------------------------------------
2+
// <copyright file="Chamber.cs" company="Exiled Team">
3+
// Copyright (c) Exiled Team. All rights reserved.
4+
// Licensed under the CC BY-SA 3.0 license.
5+
// </copyright>
6+
// -----------------------------------------------------------------------
7+
namespace Exiled.API.Features.Lockers
8+
{
9+
using System.Collections.Generic;
10+
using System.Diagnostics;
11+
using System.Linq;
12+
13+
using Exiled.API.Enums;
14+
using Exiled.API.Extensions;
15+
using Exiled.API.Features.Pickups;
16+
using Exiled.API.Interfaces;
17+
using MapGeneration.Distributors;
18+
using UnityEngine;
19+
20+
/// <summary>
21+
/// A wrapper for <see cref="LockerChamber"/>.
22+
/// </summary>
23+
public class Chamber : IWrapper<LockerChamber>, IWorldSpace
24+
{
25+
/// <summary>
26+
/// <see cref="Dictionary{TKey,TValue}"/> with <see cref="LockerChamber"/> and <see cref="Chamber"/>.
27+
/// </summary>
28+
internal static readonly Dictionary<LockerChamber, Chamber> Chambers = new();
29+
30+
/// <summary>
31+
/// Initializes a new instance of the <see cref="Chamber"/> class.
32+
/// </summary>
33+
/// <param name="chamber"><see cref="LockerChamber"/> instance.</param>
34+
/// <param name="locker"><see cref="Lockers.Locker"/> where this chamber is located.</param>
35+
public Chamber(LockerChamber chamber, Locker locker)
36+
{
37+
Base = chamber;
38+
Locker = locker;
39+
40+
Chambers.Add(chamber, this);
41+
}
42+
43+
/// <summary>
44+
/// Gets a <see cref="IEnumerable{T}"/> of <see cref="Chamber"/> which contains all the <see cref="Chamber"/> instances.
45+
/// </summary>
46+
public static IReadOnlyCollection<Chamber> List => Chambers.Values;
47+
48+
/// <inheritdoc/>
49+
public LockerChamber Base { get; }
50+
51+
/// <summary>
52+
/// Gets the <see cref="Lockers.Locker"/> where this chamber is located at.
53+
/// </summary>
54+
public Locker Locker { get; }
55+
56+
/// <inheritdoc/>
57+
public Vector3 Position => Base.transform.position;
58+
59+
/// <inheritdoc/>
60+
public Quaternion Rotation => Base.transform.rotation;
61+
62+
/// <summary>
63+
/// Gets or sets all pickups that should be spawned when the door is initially opened.
64+
/// </summary>
65+
public IEnumerable<Pickup> ToBeSpawned
66+
{
67+
get => Base._toBeSpawned.Select(Pickup.Get);
68+
set
69+
{
70+
Base._toBeSpawned.Clear();
71+
72+
foreach (Pickup pickup in value)
73+
Base._toBeSpawned.Add(pickup.Base);
74+
}
75+
}
76+
77+
/// <summary>
78+
/// Gets or sets all spawn points.
79+
/// </summary>
80+
/// <remarks>
81+
/// Used if <see cref="UseMultipleSpawnpoints"/> is set to <see langword="true"/>.
82+
/// </remarks>
83+
public IEnumerable<Transform> Spawnpoints
84+
{
85+
get => Base._spawnpoints;
86+
set => Base._spawnpoints = value.ToArray();
87+
}
88+
89+
/// <summary>
90+
/// Gets or sets all the acceptable items which can be spawned in this chamber.
91+
/// </summary>
92+
public IEnumerable<ItemType> AcceptableTypes
93+
{
94+
get => Base.AcceptableItems;
95+
set => Base.AcceptableItems = value.ToArray();
96+
}
97+
98+
/// <summary>
99+
/// Gets or sets required permissions to open this chamber.
100+
/// </summary>
101+
public KeycardPermissions RequiredPermissions
102+
{
103+
get => (KeycardPermissions)Base.RequiredPermissions;
104+
set => Base.RequiredPermissions = (Interactables.Interobjects.DoorUtils.KeycardPermissions)value;
105+
}
106+
107+
/// <summary>
108+
/// Gets or sets a value indicating whether multiple spawn points should be used.
109+
/// </summary>
110+
/// <remarks>
111+
/// If <see langword="true"/>, <see cref="Spawnpoints"/> will be used over <see cref="Spawnpoint"/>.
112+
/// </remarks>
113+
public bool UseMultipleSpawnpoints
114+
{
115+
get => Base._useMultipleSpawnpoints;
116+
set => Base._useMultipleSpawnpoints = value;
117+
}
118+
119+
/// <summary>
120+
/// Gets or sets a spawn point for the items in the chamber.
121+
/// </summary>
122+
/// <remarks>
123+
/// Used if <see cref="UseMultipleSpawnpoints"/> is set to <see langword="false"/>.
124+
/// </remarks>
125+
public Transform Spawnpoint
126+
{
127+
get => Base._spawnpoint;
128+
set => Base._spawnpoint = value;
129+
}
130+
131+
/// <summary>
132+
/// Gets or sets a value indicating whether or not items should be spawned as soon as they one chamber is opened.
133+
/// </summary>
134+
public bool InitiallySpawn
135+
{
136+
get => Base._spawnOnFirstChamberOpening;
137+
set => Base._spawnOnFirstChamberOpening = value;
138+
}
139+
140+
/// <summary>
141+
/// Gets or sets the amount of time before a player can interact with the chamber again.
142+
/// </summary>
143+
public float Cooldown
144+
{
145+
get => Base._targetCooldown;
146+
set => Base._targetCooldown = value;
147+
}
148+
149+
/// <summary>
150+
/// Gets a value indicating whether the chamber is currently open.
151+
/// </summary>
152+
public bool IsOpen => Base.IsOpen;
153+
154+
/// <summary>
155+
/// Gets the <see cref="Stopwatch"/> of current cooldown.
156+
/// </summary>
157+
/// <remarks>Used in <see cref="CanInteract"/> check.</remarks>
158+
public Stopwatch CurrentCooldown => Base._stopwatch;
159+
160+
/// <summary>
161+
/// Gets a value indicating whether the chamber is interactable.
162+
/// </summary>
163+
public bool CanInteract => Base.CanInteract;
164+
165+
/// <summary>
166+
/// Spawns a specified item from <see cref="AcceptableTypes"/>.
167+
/// </summary>
168+
/// <param name="type"><see cref="ItemType"/> from <see cref="AcceptableTypes"/>.</param>
169+
/// <param name="amount">Amount of items that should be spawned.</param>
170+
public void SpawnItem(ItemType type, int amount) => Base.SpawnItem(type, amount);
171+
172+
/// <summary>
173+
/// Adds an item of the specified type to the chamber's spawn list.
174+
/// If the chamber is open and <paramref name="spawnIfIsOpen"/> is set to <see langword="true"/>,
175+
/// the item is spawned immediately at a random spawn point within the chamber.
176+
/// </summary>
177+
/// <param name="itemType">The type of item to add to the spawn list.</param>
178+
/// <param name="quantity">The number of items to add. Defaults to 1.</param>
179+
/// <param name="spawnIfIsOpen">
180+
/// If <see langword="true"/> and the chamber is open, the item is immediately spawned at a random spawn point.
181+
/// Otherwise, the item is added to the spawn list and will spawn when the chamber is opened.
182+
/// </param>
183+
public void AddItemToSpawn(ItemType itemType, int quantity = 1, bool spawnIfIsOpen = false)
184+
{
185+
for (int i = 0; i < quantity; i++)
186+
{
187+
Pickup pickup = Pickup.Create(itemType);
188+
189+
if (spawnIfIsOpen && IsOpen)
190+
{
191+
pickup.Position = GetRandomSpawnPoint();
192+
pickup.Spawn();
193+
continue;
194+
}
195+
196+
Base._toBeSpawned.Add(pickup.Base);
197+
}
198+
}
199+
200+
/// <summary>
201+
/// Gets a random spawn point within the chamber.
202+
/// If multiple spawn points are available and <see cref="UseMultipleSpawnpoints"/> is <see langword="true"/>,
203+
/// a random spawn point is selected from the available points.
204+
/// Otherwise, the default spawn point is used.
205+
/// </summary>
206+
/// <returns>A <see cref="Vector3"/> representing the position of the selected spawn point.</returns>
207+
public Vector3 GetRandomSpawnPoint()
208+
{
209+
if (UseMultipleSpawnpoints && Spawnpoints.Any())
210+
{
211+
return Spawnpoints.GetRandomValue().position;
212+
}
213+
214+
return Spawnpoint.position;
215+
}
216+
217+
/// <summary>
218+
/// Gets the chamber by its <see cref="LockerChamber"/>.
219+
/// </summary>
220+
/// <param name="chamber"><see cref="LockerChamber"/>.</param>
221+
/// <returns><see cref="Chamber"/>.</returns>
222+
internal static Chamber Get(LockerChamber chamber) => Chambers.TryGetValue(chamber, out Chamber chmb) ? chmb : new(chamber, Locker.Get(x => x.Chambers.Any(x => x.Base == chamber)).FirstOrDefault());
223+
}
224+
}

0 commit comments

Comments
 (0)